I'm trying to mimic this code I got from Apple's ShapeEdit sample project. The difference is that I use two operation queues -- one to encase the NSFileCoordinator.coordinate() code, and the other as an argument to the coordinate method. I set the maxConcurrentOperationCount to both those queues to 1 because I am performing file operations that have to be done sequentially. If iCloud renames a file and reports it to MetadataQuery, I have to handle the file rename after the file creation. I am trying to figure out how to do this without causing a thread lock, where an operation doesn't finish executing or is not released, so it keeps the other operations behind it from execuing. That is why I am using two operation queues.
I also would like to know where the scope of the file manager variable should be so as not to cause a thread lock because the operation doesn't get released because of variables it received through capturing not being released, thus keeping other operations behind it from even beginning to get executed. I remember documentation about not to do anything inside the coordinate closure except the file process. Is it a good idea to create the variable for the file manager object in the coordinate closure?
There isn't really a need for me to show my code, but I did anyways. I basically explained above what the problem is.
I'm open to any suggestions. I'm quite unsure about what I'm doing. Any help will be appreciated.
Following code segments are edited code from ShapeEdit:
fileprivate let coordinationQueue: OperationQueue = {
let coordinationQueue = OperationQueue()
coordinationQueue.name = "com.example.apple-samplecode.ShapeEdit.documentbrowser.coordinationQueue"
return coordinationQueue
}()
coordinationQueue.addOperation {
let readIntent = NSFileAccessIntent.readingIntent(with: templateURL, options: [])
let writeIntent = NSFileAccessIntent.writingIntent(with: target, options: .forReplacing)
NSFileCoordinator().coordinate(with: [readIntent, writeIntent], queue: self.coordinationQueue) { error in
if error != nil {
return
}
do {
try fileManager.copyItem(at: readIntent.url, to: writeIntent.url)
try (writeIntent.url as NSURL).setResourceValue(true, forKey: URLResourceKey.hasHiddenExtensionKey)
OperationQueue.main.addOperation {
self.openDocumentAtURL(writeIntent.url)
}
}
catch {
fatalError("Unexpected error during trivial file operations: \(error)")
}
}
}
The folowing code segments are my code:
internal let operationQueue: OperationQueue = {
let operationQueue = OperationQueue()
operationQueue.name = "us.gnolaum.IPv4Calculator.operationQueue"
operationQueue.maxConcurrentOperationCount = 1
return operationQueue
}()
internal let coordinationQueue: OperationQueue = {
let coordinationQueue = OperationQueue()
coordinationQueue.name = "us.gnolaum.IPv4Calculator.coordinationQueue"
coordinationQueue.maxConcurrentOperationCount = 1
return coordinationQueue
}()
operationQueue.addOperation {
let readIntent = NSFileAccessIntent.readingIntent(with: item.url, options: [])
let destinationURL = self.localDocumentsURL.appendingPathComponent(item.url.lastPathComponent)
let writeIntent = NSFileAccessIntent.writingIntent(with: destinationURL, options: .forReplacing)
NSFileCoordinator().coordinate(with: [readIntent, writeIntent], queue: coordinationQueue) { error in
if error != nil {
return
}
do {
try self.defaultFileManager.copyItem(at: readIntent.url, to: writeIntent.url)
print("\(readIntent.url.lastPathComponent) copied to iCloud")
} catch {
print(error.localizedDescription)
}
}
}