0

I'm trying to use -[UIDocument saveToURL:(NSURL *)url forSaveOperation:(UIDocumentSaveOperation)saveOperation completionHandler:(void (^ __nullable)(BOOL success))completionHandler] to save a duplicate at a new URL, however the original file -[UIDocument fileURL] is deleted when doing so?

catlan
  • 25,100
  • 8
  • 67
  • 78

2 Answers2

0

I couldn't find any documentation regarding this, but it seems to be intend. ¯\_(ツ)_/¯ Here is the Hopper disassembly of iOS 15.2:

enter image description here

catlan
  • 25,100
  • 8
  • 67
  • 78
0

Yeah, UIDocument does that. It's a pain.

If you want to save a UIDocument to a new URL without losing the original, you can do it with a function like this:

func saveDocument(_ document: UIDocument, asCopyTo url: URL, completion: @escaping (Bool, Error?) -> Void) {
    let oldUrl = document.fileURL
    document.save(to: url, for: .forOverwriting) { success in
        if success {
            do {
                try FileManager.default.copyItem(at: url, to: oldUrl)
            } catch let error {
                completion(false, error)
            }
        }
        completion(success, nil)
    }
}

This first saves the existing document at its new url, updating the fileURL so that the UIDocument object remains current and doesn't keep on saving over the old file. Once that's done, and assuming it succeeds, we use FileManager to copy the new file's data back to its original location.

It might seem weird to delete and recreate the file at its original location, and I agree that UIDocument is a pretty horrible creation, but this does at least save you from having to reload the document from the file system to maintain the correct location.

Ash
  • 9,064
  • 3
  • 48
  • 59