问题
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.
来源:https://stackoverflow.com/questions/43821141/app-hangs-deleting-icloud-document-when-following-guideline-using-nsfilecoordi