skip to Main Content

So in my app I have created a Test.JSON file that I want the user to be able to move to the documents directory, outside of the app. I understand I have to do this by using UIDocumentPickerViewController, but haven’t found any way to proceed. I have created the Test.JSON file, and can use it from variable data.

I have this following code to open the UIDocumentPickerViewController:

let documentPicker =
UIDocumentPickerViewController(forExporting: [.documentsDirectory])
        
documentPicker.delegate = self

// Set the initial directory.
documentPicker.directoryURL = .documentsDirectory

// Present the document picker.
present(documentPicker, animated: true, completion: nil)

How can I attach the data file to the UIDocumentPickerViewController, so I can place it in the documents directory?

2

Answers


  1. Have you followed the instructions that Apple provides here? I’m summarizing the important bits here:

    After the user taps Done, the system calls your delegate’s documentPicker(_:didPickDocumentsAt:) method, passing an array of security-scoped URLs for the user’s selected directories …. When the user selects a directory in the document picker, the system gives your app permission to access that directory and all of its contents.

    So first, you need to implement the delegate methods so that you know what the user selects. Specifically, documentPicker(_:didPickDocumentsAt:) is the important one, although you’ll want to listen for "cancel" as well. Then you need to access that scoped resource and write to it.

    Here is an example that I took from the documentation linked above. This example only reads from the directory, but you can also write to it in the same way.

    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
        // Start accessing a security-scoped resource.
        guard url.startAccessingSecurityScopedResource() else {
            // Handle the failure here.
            return
        }
    
        // Make sure you release the security-scoped resource when you finish.
        defer { url.stopAccessingSecurityScopedResource() }
    
        // Use file coordination for reading and writing any of the URL’s content.
        var error: NSError? = nil
        NSFileCoordinator().coordinate(readingItemAt: url, error: &error) { (url) in
                
            let keys : [URLResourceKey] = [.nameKey, .isDirectoryKey]
                
            // Get an enumerator for the directory's content.
            guard let fileList =
                FileManager.default.enumerator(at: url, includingPropertiesForKeys: keys) else {
                Swift.debugPrint("*** Unable to access the contents of (url.path) ***n")
                return
            }
                
            for case let file as URL in fileList {
                // Start accessing the content's security-scoped URL.
                guard url.startAccessingSecurityScopedResource() else {
                    // Handle the failure here.
                    continue
                }
    
                // Do something with the file here.
                Swift.debugPrint("chosen file: (file.lastPathComponent)")
                    
                // Make sure you release the security-scoped resource when you finish.
                url.stopAccessingSecurityScopedResource()
            }
        }
    }
    
    Login or Signup to reply.
  2. If you already have the URL for the document replace ‘newFile’ with the document URL. ‘vc’ is the current ViewController

    Note asCopy = false will move the the document, asCopy = true will copy the document. There appears to be bug in iOS 16+ which disables the Move button when asCopy = false. Bug fixed in subsequent release FB11627056

    //Present Document Picker
    let controller = UIDocumentPickerViewController(forExporting: [newFile], asCopy: false)
    vc.present(controller, animated: true) {
        //this will be called as soon as the picker is launched NOT after save
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search