Guides and Sample Code

Developer

Energy Efficiency Guide for iOS Apps

On This Page

Defer Networking

Apps that perform network operations should batch transactions and use appropriate APIs to minimize radio use, limit impact on the system, and increase energy efficiency. Apps should also let the system defer nonessential network activity for optimal times, such as when the device is plugged in or using Wi-Fi.

Batch Transactions

Downloading content a bit at a time keeps the radios powered up almost continuously, wasting power. To the extent possible, your app should perform network operations together. For example:

  • If your app streams video, download the entire file (or a large portion of the file) at once instead of requesting it in small pieces.

  • If your app serves ads, download several at once and show them over a period of time, rather than downloading them as needed.

  • If your app downloads email from a server, download multiple messages at once. Assume that the user will probably read most of them, rather than downloading each one individually as the user selects it.

Delay Deferrable Network Operations

For upload and download activities over HTTP, the NSURLSession API provides the ability to create deferrable background sessions. A background session lets your app send URL requests to the system, which performs them at an optimal time and notifies your app when they are complete. There are several advantages to using this method for network activity:

  • Activity is performed out-of-process. Because the network operations are performed by the system, your app stays responsive, letting the user continue doing other work. Your app also doesn’t need to continue running for activity to complete.

  • Notifications keep your app informed. The system notifies your app when the activity is completed and if problems occur. Your app can even quit, relaunch, reconnect to a previous session, and resume receiving notifications. If your app isn’t running when the activities complete, or if authentication is required, the system can relaunch your app in the background.

  • Network activity is performed efficiently. It’s inefficient to perform network activity over a slow connection. Bandwidth monitoring lets the system defer the activity when throughput falls below a certain threshold.

  • Activity self-corrects. URL sessions can be automatically retried by the system when errors occur.

Configure Background Session Options

Start by creating a background session configuration object. Give it a unique session identifier and flag it as a discretionary activity. Later, once the session is created, you can use the unique identifier to reconnect to the session even if your app is terminated and relaunched. See Listing 10-1.

Listing 10-1Configuring an NSURLSession background session

Objective-C

  1. // Set up a configuration with a background session ID
  2. NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.<YourApp>.<YourBackgroundSessionIdentifier>"];
  3. // Set the configuration to discretionary
  4. [configuration setDiscretionary: YES];

Swift

  1. // Set up a configuration with a background session ID
  2. let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("com.<YourApp>.<YourBackgroundSessionIdentifier>")
  3. // Set configuration to discretionary
  4. configuration.discretionary = true

Restrict the Background Session to only Wi-Fi

If desired, set the allowsCellularAccess property of the configuration object to perform the activity strictly when connected to Wi-Fi, as shown in Listing 10-2.

Listing 10-2Configuring a background NSURLSession session to run on Wi-Fi only

Objective-C

  1. // Set the configuration to run on Wi-Fi only
  2. configuration.allowsCellularAccess = NO;

Swift

  1. // Set the configuration to run on Wi-Fi only
  2. configuration.allowsCellularAccess = false

Adjust Scheduling Tolerance for the Background Session

By default, the system allows up to seven days for a background session to run. This means that the activity will occur at a power-optimal time sometime within this timeframe. You can adjust the timeframe by changing the value (specified in seconds) of the timeoutIntervalForResource property of the configuration object. See Listing 10-3.

Listing 10-3Configuring a background NSURLSession session to run within a specified timeframe

Objective-C

  1. // Set the configuration to run sometime in the next 18 hours
  2. [configuration setTimeoutIntervalForResource: 18 * 60 * 60];

Swift

  1. // Set the configuration to run sometime in the next 18 hours
  2. configuration.timeoutIntervalForResource(18 * 60 * 60)

Create a Background Session Object

Once you set up a background session configuration object, create a new NSURLSession object for the configuration, as demonstrated in Listing 10-4.

Listing 10-4Creating an NSURLSession session using a configuration

Objective-C

  1. // Create the URL session
  2. NSURLSession *backgroundSession = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];

Swift

  1. // Create the URL session
  2. let backgroundSession = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)

Add a URL Request to the Background Session

Finally, create an instance of NSURLRequest and pass it to the background session, as shown in Listing 10-5.

Listing 10-5Creating a URL request and adding it to a background session

Objective-C

  1. // Set up a URL
  2. NSURL *someURLToDownload = [NSURL URLWithString:<YourURLString>];
  3. // Create a URL request
  4. NSURLRequest *downloadRequest = [NSURLRequest requestWithURL:someURLToDownload];
  5. // Add the request to the background session
  6. NSURLSessionDownloadTask *downloadTask = [backgroundSession downloadTaskWithRequest:downloadRequest];
  7. // Initiate the activity
  8. [downloadTask resume];

Swift

  1. // Set up a URL
  2. let someURLToDownload = NSURL.URLWithString(<YourURLString>)
  3. // Create a URL request
  4. let downloadRequest = NSURLRequest.requestWithURL(someURLToDownload)
  5. // Add request to background session
  6. let downloadTask = backgroundSession.downloadTaskWithRequest(downloadRequest)
  7. // Initiate activity
  8. downloadTask.resume()

Get Notified About Background Session Activity

To receive callbacks when the background session receives a reply from the server, finishes downloading, or encounters an error, implement the appropriate delegate methods. Lists of available delegate methods are found in the following documents:

Listing 10-6 demonstrates how to respond to a callback once a URL download is complete.

Listing 10-6Example delegate method that is called once a URL finishes downloading

Objective-C

  1. - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
  2. // Do any work following the completed download
  3. };

Swift

  1. func URLSession(session: NSURLSession, downloadTask downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
  2. // Do any work following completed download
  3. }