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.
Objective-C
// Set up a configuration with a background session ID
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.<YourApp>.<YourBackgroundSessionIdentifier>"];
// Set the configuration to discretionary
[configuration setDiscretionary: YES];
Swift
// Set up a configuration with a background session ID
let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("com.<YourApp>.<YourBackgroundSessionIdentifier>")
// Set configuration to discretionary
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.
Objective-C
// Set the configuration to run on Wi-Fi only
configuration.allowsCellularAccess = NO;
Swift
// Set the configuration to run on Wi-Fi only
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.
Objective-C
// Set the configuration to run sometime in the next 18 hours
[configuration setTimeoutIntervalForResource: 18 * 60 * 60];
Swift
// Set the configuration to run sometime in the next 18 hours
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.
Objective-C
// Create the URL session
NSURLSession *backgroundSession = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
Swift
// Create the URL session
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.
Objective-C
// Set up a URL
NSURL *someURLToDownload = [NSURL URLWithString:<YourURLString>];
// Create a URL request
NSURLRequest *downloadRequest = [NSURLRequest requestWithURL:someURLToDownload];
// Add the request to the background session
NSURLSessionDownloadTask *downloadTask = [backgroundSession downloadTaskWithRequest:downloadRequest];
// Initiate the activity
[downloadTask resume];
Swift
// Set up a URL
let someURLToDownload = NSURL.URLWithString(<YourURLString>)
// Create a URL request
let downloadRequest = NSURLRequest.requestWithURL(someURLToDownload)
// Add request to background session
let downloadTask = backgroundSession.downloadTaskWithRequest(downloadRequest)
// Initiate activity
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.
Objective-C
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
// Do any work following the completed download
};
Swift
func URLSession(session: NSURLSession, downloadTask downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
// Do any work following completed download
}
Copyright © 2018 Apple Inc. All rights reserved. Terms of Use | Privacy Policy | Updated: 2016-09-13