Chapter 11.  Being Proactive with Background Fetch

So far, the FamilyMovies application should be shaping up quite nice. We can add family members and associate movies with them, and these movies are automatically enriched with the first rating we can find from the movie database API. There still are some movies we added earlier that don't have a rating, and although the ratings for the existing movies might be correct for now, we don't know whether they will still be accurate after a couple of days, weeks, or months. We could update the ratings whenever the user accesses them, but it's not very efficient to do this. We would potentially reload the same movie a couple of times in a single session.

Ideally, we'd update the movies in the background, when the user isn't using the app. We can do this relatively easily with background fetching. This chapter is all about fetching data on behalf of the user while the app isn't active in the foreground. Implementing this feature can greatly benefit your users because your app has fresh content every time the user opens up the app. No pull to refresh is needed, and users love these little touches of magic in the apps they use.

In this chapter, we'll cover the following topics:

  • Understanding how background fetch works
  • Implementing the prerequisites for background fetch
  • Updating movies in the background

By the end of this chapter, you will be able to enrich your applications with background fetch behavior in a responsible, effective way. You'll know exactly how this feature works and how it will benefit your users by providing them with up-to-date content whenever they launch your application.

Besides implementing the background fetch feature, we will also do a lot of refactoring. It's important to understand how and when to refactor your code because it's highly unlikely that you'll be able to exactly nail a flexible setup for your app that can adapt to any requirement that is thrown at it. Being able to refactor your code whenever you see duplication or readability issues is an extremely important skill that you will utilize almost every day as your understanding of your code base, the requirements, and the iOS platform grows.

Understanding how background fetch works

Any application that provides users with some form of data that updates over time is able to implement background fetch. An application that implements background fetch is woken up by iOS periodically, and it's given a small window of time to fetch and process the new data. The OS expects applications to call a callback when they're done with fetching and processing the data. The application uses this callback to inform the OS about whether or not a new data was fetched. We'll take a look at a broad overview of background fetch first and then at the moving parts in more detail before implementing background fetch in the FamilyMovies application.

Looking at background fetch from a distance

Background fetch allows apps to download new content in the background without draining the battery because iOS will manage these fetch intervals as efficiently as possible. Since your application won't be able to stay active for a very long time, you will need to take into account that you might not be able to perform all the tasks you'd like to perform. If this is the case, you're probably implementing background fetch for the wrong reasons. Sometimes, it's a better idea to split the work between your background fetch and application launch.

One example of this would be to download a large amount of data and perform some expensive processing with the downloaded data. If your app takes too long to process the data, it won't be able to finish. It may be a good idea to continue processing as the app launches. An even better idea would be to download only the data and perform all of the expensive processing once the app launches. Background fetch is intended to pull in quick, small updates and not to process large amounts of data.

The time intervals that iOS use to wake your app up aren't entirely transparent. You can specify a desired time interval for your application if you want to, but ultimately the OS itself decides whether or not your app has woken and how much time it has to perform its tasks.

A neat feature of background fetch is that iOS learns how often your app actually has updated data because you have to report this to the callback and also the time your users are most likely to use your app. If a user tends to open your app every morning around 10:00 AM, chances are that your app will be awakened from the background sometime before 10:00 AM. This feature makes sure that your users will see recent contents for your application. Similarly, if iOS notices that your app rarely has a new content within a certain time interval, it's likely that your app isn't awoken as often as you'd like.

Leaving this interval in the hands of the OS might seem a bit scary at first; you often want as much control over these things as possible. What if you know that once a month at a certain time you will publish a bunch of new content and you want your app to fetch this in the background? How will you know that all users will receive this new content in time? The answer to this is simple, you don't. Background fetch is a service that makes an attempt to help your users to receive contents in the background. There are no guarantees made.

You should always be aware that your app might have to update contents in the foreground since users can turn off background fetching entirely. One more important aspect of background fetch is that it will only work if your app isn't completely killed. If a user opens the multitasking window and swipes your app upward to close it, you won't be awakened for a background refresh, and your app will have to refresh whenever the user launches it the next time.

A nice way to facilitate this is to implement your background fetch logic in a separate method or helper you can call. You could invoke a method that's responsible for fetching a new content whenever your application is freshly launched or when it's awakened to perform a background fetch. This strategy will make sure that your users always receive the latest content whenever they open your app.

This is really all you will need to know about background fetching; on the surface, it's simply a feature that periodically wakes up your application so it can perform a task for a short time. You don't exactly have control over when and how your app is awakened, which is okay, because iOS learns how often your app should be awoken, and more importantly, iOS learns the best time to wake your app up. All you have to do is make sure that iOS knows that your app wants to be woken up.

Looking at background fetch in more depth

Now that you have a broad understanding of background fetch, let's investigate what your app needs to do in order to be compatible with background fetch. First of all, you will need to let iOS know that your app wants to be woken up periodically. To do this, you will need to turn on the Background Modes capability for your app. Within this capability, you can opt in for background fetch. Enabling this mode will automatically add a key for this service to your app's Info.plist.

When this capability is enabled, iOS will allow your app to be woken up periodically. However, it won't magically work right away. In the AppDelegate'sapplication(_:didFinishLaunchingWithOptions:) method, we will need to inform the system that we actually want our app to become active every once in a while and also specify the interval we desire.

Then, once this is done, our application will be awake in the background, and the application(_:performFetchWithCompletionHandler:) method will be called whenever we're allowed to do work. This method should be implemented in AppDelegate, and it's expected to call the provided completion handler once the work is completed. If you fail to call this method in time, iOS will make a note of this, and missing the window to call this completion handler could result in your app not being awakened as often as you'd like.

Once the completion handler is called, your app will be put back to sleep until the user opens the app or until the next time your app is allowed to perform a background fetch. Calling the completion handler shouldn't be done until all of the work that you intended to do is done because once the completion handler is called, there are no guarantees about how and when your app will make a transition to the background, except that it will happen soon.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset