This article is part of a 4-part series on Building robust, reliable code with NSOperations.
- Getting Started With NSOperation and NSOperationQueue
- Chaining a Series of NSOperations
- Grouping Common Operations Together
- Handling UI with NSOperations
So far, we’ve seen how to create concurrent operations and how to chain them one after the other. Together, these are excellent tools, but they can lead to something that’s a bit of a pain.
Unfortunately, you’ll quickly find that you’ll be repeating yourself often. For example, think about downloading and parsing content. How many times are you going to repeat this sequence in your app?
Today, we’ll look into how we can group operations together in order to keep our code DRY and make life a little easier on ourselves.
Creating a Group Operation
In order to wrap these operations together, we’re going to use another
That’s right! It’s operations all the way down!
We’re going to create an
NSOperation that wraps its own
NSOperationQueue. To begin, the queue will be suspended. Then when we get to the main() method, we’ll unsuspend the queue and let it do its thing!
In order to complete the operation, we’ll use a ‘BlockOperation’ that calls the complete method. Whenever we add an operation to our ‘GroupOperation’, we’ll create a dependency between it and the finishing operation.
Only once all the operations we added are complete will the finishing operation execute and complete the group. Ingenious, isn’t it?
As for cancelling our GroupOperation, we’re in luck! If we ever need to cancel it, we can simply cancel the operations in its queue.
And there you have it! A functional
GroupOperation that will allow us to wrap our smaller blocks together!
Creating an API Operation from Download + Parse
Now that we have our
GroupOperation ready to go, how exactly do we use it? My preferred way is subclassing, and then creating the necessary operations inside the initializer.
Let’s go back to our Download + Parse operation we had before. How would we create an
APIOperation that could wrap these two?
I think it would look something like this:
Alright! With this class in hand, we can now change our code from repeating this everywhere:
Doesn’t that feel better?
Not only were we able to abstract away all this downloading and parsing, but we’re also giving it more meaning. Now, instead of seeing disjointed operations in our code, we can see a single
APIOperation and think to ourselves “Ah, that’s what it means!”
It also makes cancelling and failure much easier to deal with since we can handle those cases inside our APIOperation. The rest of the app only needs to know about how to handle the failure, and not what caused it.
Grouping parallel Operations together
I’d be remiss if I didn’t tell you about the other great advantage you get from grouping your operations.
GroupOperation is also an excellent way to run many operations in parallel and know when they’re all done.
Imagine we have a bunch of image URLs and we want to download them and create an array of UIImages. Using a group operation is an excellent way of downloading in parallel, in the background. The class would end up looking something like this:
And that’s it! Our GroupOperation will automatically finish once all the operations it contains are finished as well.
So let’s say you have an art gallery, and an
IncredibleGalleryViewController. You want to fetch your gallery object, parse it, the use its image URLs to populate your View Controller before pushing it on the navigation stack. Your code would now look like:
The power of not repeating yourself
In this article we saw:
- How to group commonly used operations together.
- How grouping operations abstracts away the details and gives them meaning
- How to use group operations to wrap operations in series (like downloading and parsing) or in parallel (like fetching images)
Next time, in the final article of this series, we’ll look at how to use NSOperations with UIKit. If you’ve been looking for an easy way to run your login flow or your onboarding, this’ll be the article for you!