Article

Updating Your App with Background App Refresh

Fetch content opportunistically in the background and update your app's interface.

Overview

Background App Refresh lets your app run periodically in the background so that it can update its content. Apps that update their content frequently, such as news apps or social media apps, can use this feature to ensure that their content is always up to date. Downloading data in the background before it is needed minimizes the lag time in displaying that data when the user launches the app.

To support Background App Refresh for your app, do the following:

  1. Enable the background fetch capability in your app ().

  2. Call the setMinimumBackgroundFetchInterval(_:) method of UIApplication at launch time.

  3. Implement the application(_:performFetchWithCompletionHandler:) method in your app delegate.

Enable the background fetch option from the Background Modes section of the Capabilities tab.

When the system calls your app delegate’s application(_:performFetchWithCompletionHandler:) method, configure a URLSession object to download any new data. The system waits until network and power conditions are good, so you should be able to retrieve adequate amounts of data quickly. When you finish updating your app, call the completion handler and provide an accurate result of your outcome, which can include saying that no new data was available.

Listing 1 shows how to request and handle background updates. The Xcode project for the app enables the background fetch capability and the app requests hourly updates at launch time. When it receives execution time, the app checks to see if new data is available. If it is, the app adds that data to its main feed.

Listing 1

Fetching data from a server in the background

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions:
                 [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
   // Override point for customization after application launch.
        
   // Fetch data once an hour.
   UIApplication.shared.setMinimumBackgroundFetchInterval(3600)

   // Other initialization…
   return true
}
    
func application(_ application: UIApplication, 
                 performFetchWithCompletionHandler completionHandler:
                 @escaping (UIBackgroundFetchResult) -> Void) {
   // Check for new data. 
   if let newData = fetchUpdates() {
      addDataToFeed(newData: newData)
      completionHandler(.newData)
   }
   completionHandler(.noData)
}

If the absence of Background App Refresh would have a significant impact on your app’s user experience, you can check the backgroundRefreshStatus property of UIApplication to determine whether the feature is available. Users can disable Background App Refresh for your app or for all apps in Settings. If you prompt the user to enable the feature for your app, respect the user’s decision and don’t prompt a second time.

See Also

Background Execution

Extending Your App's Background Execution Time

Ensure that critical tasks finish when your app moves to the background.

About the Background Execution Sequence

Learn the order in which your custom code is executed when your app moves to the background.