iosswiftuidocumentinteractioncontroller

Sharing a Document with UIDocumentInteractionController


I'm trying to share a document stored in the temporary directory using UIDocumentInteractionController. Essentially, I'm using the following code:

@IBAction func createDocumentButtonClicked(_ sender: Any) {
    do {
        // create temporary file
        let tempUrl = FileManager.default.temporaryDirectory.appendingPathComponent("fileName.txt")
        try "abc".write(to: tempUrl, atomically: true, encoding: .utf8)

        // share file
        let documentInteractionController = UIDocumentInteractionController(url: tempUrl)
        documentInteractionController!.name = "filename.txt"
        documentInteractionController!.presentOptionsMenu(from: view.frame, in: view, animated: true)
    } catch {
        // ...
    }
}

When run, this code presents the share action sheet. The log indicates some problem: Could not instantiate class NSURL. Error: Error Domain=NSCocoaErrorDomain Code=4864 "The URL archive of type “public.url” contains invalid data." UserInfo={NSDebugDescription=The URL archive of type “public.url” contains invalid data. Selecting any of the options results in failure handling the document.

This is reduced to pretty much textbook level code, yet it is not working. What am I missing?

Update: Added context that better emphasizes the cause of the problem (see my answer below).


Solution

  • It turned out to be trivial, even silly. I leave the question anyhow in case someone else stumbles over it.

    I need to maintain the instance of UIDocumentInteractionController outside the button action handler that presents the controller. I will update the question to better show this problem. With a small change, it works as expected:

    var documentInteractionController: UIDocumentInteractionController?
    
    @IBAction func createDocumentButtonClicked(_ sender: Any) {
        do {
            // create temporary file
            let tempUrl = FileManager.default.temporaryDirectory.appendingPathComponent("fileName.txt")
            try "abc".write(to: tempUrl, atomically: true, encoding: .utf8)
    
            // share file
            documentInteractionController = UIDocumentInteractionController(url: tempUrl)
            documentInteractionController!.name = "filename.txt"
            documentInteractionController!.presentOptionsMenu(from: view.frame, in: view, animated: true)
        } catch {
            // ...
        }
    }