Suppose that I use another SDK (which I do not have control of) with an API that imports 1 file asynchronously, and calls a completion callback on completion. The following is an example API.
func importFile(filePath: String, completion: () -> Void)
I need to import 10 files (one by one) using this API, but I need it to be cancellable, e.g. after Files 1,2,3 has been successfully imported, while File 4 is being imported, I want to be able to cancel the whole set of operations (import of the 10 Files), such that File 4 will finish (since it already started), but Files 5-10 will not be imported anymore.
In addition, I also need to report progress of the import. When File 1 has been imported successfully, then I should report progress of 10% (1 out of 10 has been finished).
How can I achieve this?
I am considering using NSOperationQueue with 10 NSOperations, but it seems that progress reporting will be difficult.
So, I believe that this is the following you want from your question:
It can be achieved using
NSOperationQueue
andNSBlockOperation
in the following way.AsyncBlockOperation
andNSOperationQueue+AsyncBlockOperation
classes from code given in answer for the following StackOverflow question: NSOperation wait until asynchronous block executesCreate an operation queue
Create a function which gives you a callback for getting progress
Inside the function defined in
2
, useNSBlockOperation
for performing your operations in theNSOperationQueue
For cancelling operations, we can simply use the
operationQueue
that we created in the 1st stepI tried this code myself. It's working well. Feel free to suggest improvements to make it better :)
I think you should add dependencies on your operation. The idea is this:
Then your operation subclass should override the cancel method in this way
NSOperationQueue
offers a nice object oriented abstaraction and is the way I would go.NSOperationQueue
namedimportQueue
For each import:
NSOperation
importQueue
In regards to the progress state:
Option 1:
NSOperationQueue
has a property calledoperations
, whichs count you are able to observe. (importQueue.operations.count
).Option 2:
NSOperation
offers completion blocks. You can increase a counter when queueing the operation and decrease it within the completion block or when cancelling.Further reading: Apple documentation, asynchronous-nsoperation-why-and-how, nice but oldish tutorial.