App hangs deleting iCloud Document when following  guideline using NSFileCoordinator and DispatchQueue
Asked Answered
S

0

2

I have a todo list app that stores document in iCloud as UIDocument object. The following function in the table view controller is created to delete a todo list item both locally and remotely in iCloud but hang the app when executed it via swipe to delete gesture on the table view cell:

fileprivate func deleteNote(at indexPath: IndexPath) {
    let noteDocument = self.noteDocuments[indexPath.row]

    let fileCoordinator = NSFileCoordinator(filePresenter: nil)
    fileCoordinator.coordinate(writingItemAt: noteDocument.fileURL,
                               options: NSFileCoordinator.WritingOptions.forDeleting,
                               error: nil) { [weak self] (passedURL: URL) in
                                guard let weakSelf = self else { return }
                                do {
                                    try FileManager.default.removeItem(at: passedURL)
                                    weakSelf.noteDocuments.remove(at: indexPath.row)
                                    weakSelf.tableView.deleteRows(at: [indexPath], with: .bottom)
                                    weakSelf.tableView.reloadData()
                                }
                                catch let error as NSError {
                                    print("Error occured deleting a document. Reason: \(error.localizedDescription)")
                                }
    }
}

The  Document-based Programming guide for iOS document stated in Deleting a Document section that removing item in iCloud should be performed asynchronously in the background thread. So I encapsulated the NSFileCoordinator instantiation w/ GCD as followed but every time after a deletion operation is performed, it briefly disappears then reappear (I can see this happening in the iCloud Drive). So, essentially, it doesn't get deleted.

fileprivate func deleteNote(at indexPath: IndexPath) {
    let noteDocument = self.noteDocuments[indexPath.row]

    DispatchQueue.global(qos: .default).async {
        let fileCoordinator = NSFileCoordinator(filePresenter: nil)
        fileCoordinator.coordinate(writingItemAt: noteDocument.fileURL,
                                   options: NSFileCoordinator.WritingOptions.forDeleting,
                                   error: nil) { (passedURL: URL) in
                                    do {
                                        try FileManager.default.removeItem(at: passedURL)
                                    }
                                    catch let error as NSError {
                                        print("Error occured deleting a document. Reason: \(error.localizedDescription)")
                                    }
        }
    }
    self.noteDocuments.remove(at: indexPath.row)
    self.tableView.deleteRows(at: [indexPath], with: .fade)
    self.tableView.reloadData()
}

The only way I can successfully delete it is actually by not following  guideline. I don't use NSFileCoordinator coordinate(writingItemAt:options:error:byAccessor:) and I don't set the delete operation asynchronously in the background thread w/ DispatchQueue global(qos:) like so

fileprivate func deleteNote(at indexPath: IndexPath) {
    let noteDocument = self.noteDocuments[indexPath.row]

    do {
        try FileManager.default.removeItem(at: noteDocument.fileURL)
    }
    catch let error as NSError {
        print("Error occurred deleting a document. Reason: \(error.localizedDescription)")
    }
    self.noteDocuments.remove(at: indexPath.row)
    self.tableView.deleteRows(at: [indexPath], with: .fade)
    self.tableView.reloadData()
}

Any pointer on what can I do to achieve conformance to  guideline while still being able to successfully perform the delete operation? Thanks.

Slab answered 6/5, 2017 at 13:41 Comment(2)
In Apple's sample code they do not use the default file manager, but a new instance of NSFileManager created for the background context. Could that potentially be your issue?Mumbletypeg
@ScottThompson the issue still persists w/ the NSFileManager instance method approach.Slab

© 2022 - 2024 — McMap. All rights reserved.