Sunteți pe pagina 1din 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

NSURLSession Tutorial: Getting Started


Ken Toh on January 14, 2016

Whether an app retrieves application data from a server, updates


your social media status or downloads remote files to disk, its
the HTTP network requests living at the heart of mobile applications that make the magic happen. To help you with the numerous requirements for network requests, Apple provides
NSURLSession
NSURLSession, which is a complete suite of networking API
methods for uploading and downloading content via HTTP.
In this NSURLSession tutorial, youll learn how to use
NSURLSession to build the Half Tunes app, which lets you
query the iTunes Search API and download 30-second previews of
selected songs. The finished app will also support background
transfers and let the user pause, resume or cancel in-progress
downloads.

Getting Started
Download the starter project; it already contains a user interface
for searching for songs and displaying search results, as well as
some helper methods to parse JSON and play tracks. This lets
you focus on implementing the networking aspects of the app.

Learn how to make HTTP data requests and


implement file downloads with
NSURLSession !

Build and run your project; you should see a view with a search
bar at the top and an empty table view below:

https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 1 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

Type a query in the search bar and tap Search. The view remains empty, but dont worry; youll change this with your
new NSURLSession calls.

Overview of NSURLSession
Before you begin, its important to appreciate NSURLSession and its constituent classes, so take a minute to walk
through the quick overview below.
NSURLSession is technically both a class and a suite of classes for handling HTTP/HTTPS-based requests:

https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 2 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

NSURLSession is the key object responsible for sending and receiving HTTP requests. You create it via
NSURLSessionConfiguration
NSURLSessionConfiguration, which comes in three flavors:
defaultSessionConfiguration
defaultSessionConfiguration: Creates a default configuration object that uses the disk-persisted global cache, credential and cookie storage objects.
ephemeralSessionConfiguration
ephemeralSessionConfiguration: Similar to the default configuration, except that all session-related
data is stored in memory. Think of this as a private session.
backgroundSessionConfiguration
backgroundSessionConfiguration: Lets the session perform upload or download tasks in the background. Transfers continue even when the app itself is suspended or terminated.
NSURLSessionConfiguration also lets you configure session properties such as timeout values, caching policies and additional HTTP headers. Refer to the documentation for a full list of configuration options.
NSURLSessionTask is an abstract class that denotes a task object. A session creates a task, which does the actual
work of fetching data and downloading or uploading files.
There are three types of concrete session tasks in this context:
NSURLSessionDataTask
NSURLSessionDataTask: Use this task for HTTP GET requests to retrieve data from servers to memory.
NSURLSessionUploadTask
NSURLSessionUploadTask: Use this task to upload a file from disk to a web service, typically via a HTTP
POST or PUT method.
NSURLSessionDownloadTask
NSURLSessionDownloadTask: Use this task to download a file from a remote service to a temporary file
location.

https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 3 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

You can also suspend, resume and cancel tasks. NSURLSessionDownloadTask has the additional ability to
pause for future resumption.
Generally, NSURLSession returns data in two ways: via a completion handler when a task finishes either successfully or with an error, or by calling methods on a delegate that you set upon session creation.
Now that you have an overview of what NSURLSession can do, youre ready to put the theory into practice!

Querying for Tracks


Youll start by adding the code to query the iTunes Search API when the user searches for a track.
In SearchViewController.swift, add the following code to the top of the class:

// 1
let defaultSession = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
// 2
var dataTask: NSURLSessionDataTask?
Heres what youre doing in the above code:
1. You create a NSURLSession and initialize it with a default session configuration.
2. You declare a NSURLSessionDataTask variable which youll used to make an HTTP GET request to the
iTunes Search web service when the user performs a search. The data task will be re-initialized and reused each
time the user creates a new query.
Now, replace searchBarSearchButtonClicked(_:) with the following:
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
dismissKeyboard()
if !searchBar.text!.isEmpty {
// 1
if dataTask != nil {
dataTask?.cancel()
}
// 2
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 4 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

// 3
let expectedCharSet = NSCharacterSet.URLQueryAllowedCharacterSet()
let searchTerm =
searchBar.text!.stringByAddingPercentEncodingWithAllowedCharacters(expectedCharSet)!
// 4
let url = NSURL(string: "https://itunes.apple.com/search?media=music&entity=song&term=\(searchTerm)")
// 5
dataTask = defaultSession.dataTaskWithURL(url!) {
data, response, error in
// 6
dispatch_async(dispatch_get_main_queue()) {
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
}
// 7
if let error = error {
print(error.localizedDescription)
} else if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode == 200 {
self.updateSearchResults(data)
}
}
}
// 8
dataTask?.resume()
}
}
Taking each numbered comment in turn:
1. Upon each user query, you check if the data task is already initialized. If so, you cancel the task as you want to
reuse the data task object for the latest query.
2. You enable the network activity indicator on the status bar to indicate to the user that a network process is
running.
3. Before passing the users search string as a parameter to the query URL, you call stringByAddingPercentEncodingWithAllowedCharacters(_:) on the string to ensure that its properly escaped.
4. Next you construct a NSURL by appending the escaped search string as a GET parameter to the iTunes Search
API base url.
5. From the session you created, you initialize a NSURLSessionDataTask to handle the HTTP GET request. The
constructor of NSURLSessionDataTask takes in the NSURL that you constructed along with a completion
handler to be called when the data task is completed.
6. Upon receiving a callback that the task completed, you hide the activity indicator and invoke the UI update in the
main thread.
7. If the HTTP request is successful, you call updateSearchResults(_:)
updateSearchResults(_:), which parses the response NSData into Track
Tracks and updates the table view.
8. All tasks start in a suspended state by default; calling resume() starts the data task.
Build and run your app; search for any song and you should see the table view populate with the relevant track results like so:

https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 5 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

With a little bit of NSURLSession magic added, Half Tunes is now somewhat functional!

Downloading a Track
Being able to view song results is nice, but wouldnt it be better if you could tap on a song to download it? Thats precisely your next order of business.
To make it easy to handle multiple downloads, youll first create a custom object to hold the state of an active
download.
Create a new file named Download.swift in the Data Objects group.
Open Download.swift and add the following implementation:
class Download: NSObject {
var url: String
var isDownloading = false
var progress: Float = 0.0
var downloadTask: NSURLSessionDownloadTask?
var resumeData: NSData?
init(url: String) {
self.url = url
https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 6 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

}
}
Heres a rundown of the properties of Download
Download:
url: The URL of the file to download. This also acts as a unique identifier for a Download
Download.
isDownloading: Whether the download is ongoing or paused.
progress: The fractional progress of the download; a float between 0.0 and 1.0.
downloadTask: The NSURLSessionDownloadTask that downloads the file.
resumeData: Stores the NSData produced when you pause a download task. If the host server supports it, you
can use this to resume a paused download in the future.
Switch to SearchViewController.swift and add the following code to the top of your class:
var activeDownloads = [String: Download]()
This simply maintains a mapping between URLs and their active Download
Download, if any.

Creating a Download Task


With all the preparatory work out of the way, youre now ready to implement file downloads. Youll first create a dedicated session to handle your download tasks.
In SearchViewController.swift, add the following code right before viewDidLoad()
viewDidLoad():
lazy var downloadsSession: NSURLSession = {
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: configuration, delegate: self,
delegateQueue: nil)
return session
}()
Here you initialize a separate session with a default configuration to handle all your download tasks. You also specify
a delegate, which lets you receive NSURLSession events via delegate calls. This is useful for tracking not just when
a task is complete, but also the progress of the task.
Setting the delegate queue to nil causes the session to create a serial operation queue, by default, to perform all
calls to the delegate methods and completion handlers.
Note the lazy creation of downloadsSession
downloadsSession: this lets you delay the creation of the session until its needed. Most
importantly, it lets you pass self as the delegate parameter to the initializer even if self isnt initialized.
In SearchViewController.swift, find the empty NSURLSessionDownloadDelegate extension and make it look
like this:
extension SearchViewController: NSURLSessionDownloadDelegate {
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
print("Finished downloading.")
}
}
NSURLSessionDownloadDelegate defines delegate methods that you need to implement when using
NSURLSession download tasks. The only non-optional method is URLSession(_:downloadTask:didFinishDownloadingToURL:)
ishDownloadingToURL:), which you call whenever a download finishes. For now, youll print a simple message
whenever a download completes.

https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 7 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

With your session and delegate configured, youre finally ready to create a download task when the user requests a
track download.
In SearchViewController.swift, replace startDownload(_:) with the following implementation:
func startDownload(track: Track) {
if let urlString = track.previewUrl, url = NSURL(string: urlString) {
// 1
let download = Download(url: urlString)
// 2
download.downloadTask = downloadsSession.downloadTaskWithURL(url)
// 3
download.downloadTask!.resume()
// 4
download.isDownloading = true
// 5
activeDownloads[download.url] = download
}
}
When you tap the Download button for a track, you call startDownload(_:) with the corresponding Track
Track.
Heres whats going on :
1. You first initialize a Download with the preview URL of the track.
2. Using your new session object, you create a NSURLSessionDownloadTask with the preview URL, and set it
to the downloadTask property of the Download
Download.
3. You start the download task by calling resume() on it.
4. You indicate that the download is in progress.
5. Finally, you map the download URL to its Download in the activeDownloads dictionary.
Build and run your app; search for any track and tap the Download button on a cell. You should see a message printed on your console after a while, signifying that the download is complete.

Saving and Playing the Track


When a download task completes, URLSession(_:downloadTask:didFinishDownloadingToURL:) provides a URL to the temporary file location. Your job is to move it to a permanent location in your apps sandbox container directory before you return from the method. As well, youll have to remove the active download from the dictionary and update the table view.
Youll add a helper method to make things easy. In SearchViewController.swift, add the following method to the
class:
func trackIndexForDownloadTask(downloadTask: NSURLSessionDownloadTask) -> Int? {
if let url = downloadTask.originalRequest?.URL?.absoluteString {
for (index, track) in searchResults.enumerate() {
if url == track.previewUrl! {
return index
}
}
}
return nil
}
This method simply returns the the index of the Track in the searchResults list that has the given URL.
Next, replace URLSession(_:downloadTask:didFinishDownloadingToURL:) with the following code:
https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 8 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {


// 1
if let originalURL = downloadTask.originalRequest?.URL?.absoluteString,
destinationURL = localFilePathForUrl(originalURL) {
print(destinationURL)

// 2
let fileManager = NSFileManager.defaultManager()
do {
try fileManager.removeItemAtURL(destinationURL)
} catch {
// Non-fatal: file probably doesn't exist
}
do {
try fileManager.copyItemAtURL(location, toURL: destinationURL)
} catch let error as NSError {
print("Could not copy file to disk: \(error.localizedDescription)")
}

// 3
if let url = downloadTask.originalRequest?.URL?.absoluteString {
activeDownloads[url] = nil
// 4
if let trackIndex = trackIndexForDownloadTask(downloadTask) {
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: trackIndex,
inSection: 0)], withRowAnimation: .None)
})
}
}
}
Heres the key steps from above:
1. You extract the original request URL from the task and pass it to the provided localFilePathForUrl(_:)
helper method. localFilePathForUrl(_:) then generates a permanent local file path to save to by appending the lastPathComponent of the URL (i.e. the file name and extension of the file) to the path of the
apps Documents directory.
2. Using NSFileManager
NSFileManager, you move the downloaded file from its temporary file location to the desired destination file path by clearing out any item at that location before you start the copy task.
3. You look up the corresponding Download in your active downloads and remove it.
4. Finally, you look up the Track in your table view and reload the corresponding cell.
Build and run your project; pick any track and download it. When the download has finished, you should see the file
path location printed to your console:

The Download button will also disappear, since the track is now on your device. Tap the track and youll hear it play in
the presented MPMoviePlayerViewController as shown below:

https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 9 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

Monitoring Download Progress


Currently, you have no way to monitor the progress of the download. To improve the user experience, youll change
your app to listen for download progress events and display the progress in the cells.
In SearchViewController.swift, find the extension that implements NSURLSessionDownloadDelegate and
add the following delegate method:
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {

// 1
if let downloadUrl = downloadTask.originalRequest?.URL?.absoluteString,
download = activeDownloads[downloadUrl] {
// 2
download.progress = Float(totalBytesWritten)/Float(totalBytesExpectedToWrite)
// 3
let totalSize = NSByteCountFormatter.stringFromByteCount(totalBytesExpectedToWrite, countStyle: NSByteCountFormatterCountStyle.Binary)
// 4
if let trackIndex = trackIndexForDownloadTask(downloadTask), let trackCell =
tableView.cellForRowAtIndexPath(NSIndexPath(forRow: trackIndex, inSection: 0)) as?
TrackCell {
dispatch_async(dispatch_get_main_queue(), {
trackCell.progressView.progress = download.progress
https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 10 of 17

NSURLSession Tutorial: Getting Started

trackCell.progressLabel.text =
.progress * 100, totalSize)
})
}
}
}

19/12/16, 1(57 AM

String(format: "%.1f%% of %@",

download-

Looking through the delegate method step-by-step:


1. Using the provided downloadTask
downloadTask, you extract the URL and use it to find the Download in your dictionary of
active downloads.
2. The method also returns the total bytes written and the total bytes expected to be written. You calculate the
progress as the ratio of the two values and save the result in the Download
Download. Youll use this value to update the
progress view.
3. NSByteCountFormatter takes a byte value and generates a human-readable string showing the total
download file size. Youll use this string to show the size of the download alongside the percentage complete.
4. Finally, you find the cell responsible for displaying the Track
Track, and update both its progress view and progress
label with the values derived from the previous steps.
Next, youll configure the cells to properly display the progress view and status whenever a download is in progress.
Find the following line of code in tableView(_:cellForRowAtIndexPath:)
tableView(_:cellForRowAtIndexPath:):
let downloaded = localFileExistsForTrack(track)
Add the following code just before the line above:
var showDownloadControls = false
if let download = activeDownloads[track.previewUrl!] {
showDownloadControls = true
cell.progressView.progress = download.progress
cell.progressLabel.text = (download.isDownloading) ? "Downloading..." : "Paused"

}
cell.progressView.hidden = !showDownloadControls
cell.progressLabel.hidden = !showDownloadControls

For tracks with active downloads, you set showDownloadControls to true


true; otherwise, you set it to false
false. You
then display the progress views and labels, provided with the sample project, in accordance with the value of showDownloadControls
DownloadControls.
For paused downloads, display Paused for the status; otherwise, display Downloading.
Finally, replace the following line:
cell.downloadButton.hidden = downloaded
with the following code:
cell.downloadButton.hidden = downloaded || showDownloadControls
Here, you tell the cell to also hide the Download button if its track is downloading.
Build and run your project; download any track and you should see the progress bar status update as the download
progresses:

https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 11 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

Hurray, youve made, erm, progress! :]

Pausing, Resuming and Cancelling Downloads


What if you need to pause a download, or cancel it altogether? In this section, youll implement the pause, resume
and cancel features to give the user complete control over the download process.
Youll start by allowing the user to cancel an active download.
Replace cancelDownload(_:) with the following code:
func cancelDownload(track: Track) {
if let urlString = track.previewUrl,
download = activeDownloads[urlString] {
download.downloadTask?.cancel()
activeDownloads[urlString] = nil
}
}
To cancel a download, you retrieve the download task from the corresponding Download in the dictionary of active
downloads and call cancel() on it to cancel the task. You then remove it from the dictionary of active downloads.
Pausing a download is conceptually similar to cancelling; the difference is pausing cancels the download task, but also
produces resume data, which contains enough information to resume the download at a later time, should the host
server support that functionality.

Note: You can only resume a download under certain conditions. For instance, the resource must not have
changed since you first requested it. For a full list of conditions, check out the Apple documentation here.

Now, replace pauseDownload(_:) with the following code:


func pauseDownload(track: Track) {
if let urlString = track.previewUrl,
download = activeDownloads[urlString] {
if(download.isDownloading) {
download.downloadTask?.cancelByProducingResumeData { data in
if data != nil {
download.resumeData = data
}
}
download.isDownloading = false
}
}
}
The key difference here is the call to cancelByProducingResumeData(_:) instead of cancel()
cancel(). You retrieve the resume data from the closure provided by cancelByProducingResumeData(:_) and save it to the
appropriate Download for future resumption.
You also set the isDownloading property of the Download to false to signify that the download is paused.
https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 12 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

With the pause function completed, the next order of business is to allow the resumption of a paused download.
Replace resumeDownload(_:) with the following code:
func resumeDownload(track: Track) {
if let urlString = track.previewUrl,
download = activeDownloads[urlString] {
if let resumeData = download.resumeData {
download.downloadTask = downloadsSession.downloadTaskWithResumeData(resumeData)
download.downloadTask!.resume()
download.isDownloading = true
} else if let url = NSURL(string: download.url) {
download.downloadTask = downloadsSession.downloadTaskWithURL(url)
download.downloadTask!.resume()
download.isDownloading = true
}
}
}
When the user resumes a download, you check the appropriate Download for the presence of resume data. If
found, you create a new download task by invoking downloadTaskWithResumeData(_:) with the resume
data and start the task by calling resume()
resume(). If the resume data is absent for some reason, you create a new download task from scratch with the download URL anyway and start it.
In both cases, you set the isDownloading flag of the Download to true to indicate the download has resumed.
Theres only one thing left to do for the three functions to work properly: you need to show or hide the Pause, Cancel
and Resume buttons as appropriate.
Go to tableView(_:cellForRowAtIndexPath:) and find the following line of code:
if let download = activeDownloads[track.previewUrl!] {
Add the following lines to the end of the let block above:
let title = (download.isDownloading) ? "Pause" : "Resume"
cell.pauseButton.setTitle(title, forState: UIControlState.Normal)
Since the pause and resume functions share the same button, the code above toggles the button between the two
states as appropriate.
Next, add the following code to the end of tableView(_:cellForRowAtIndexPath:)
tableView(_:cellForRowAtIndexPath:), just before the return statement:
cell.pauseButton.hidden = !showDownloadControls
cell.cancelButton.hidden = !showDownloadControls
Here you simply show the buttons for a cell only if a download is active.
Build and run your project; download a few tracks concurrently and youll be able to pause, resume and cancel them
at will:

https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 13 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

Enabling Background Transfers


Your app is quite functional at this point, but theres one major enhancement left to add: background transfers. In
this mode, downloads continue even when your app is backgrounded or crashes for any reason.
But if your app isnt running, how can this work? Theres a separate daemon that runs outside the app and manages
background transfer tasks; it sends the appropriate delegate messages to the app as the download tasks run. In the
event the app terminates during an active transfer, the tasks will continue to run unaffected in the background.
When a task completes, the daemon will relaunch the app in the background. The re-launched app will reconnect to
the same session, receive the relevant completion delegate messages and perform any required actions such as persisting downloaded files to disk.

Note: If you terminate the app by force-quiting from the app switcher, the system will cancel all of the sessions
background transfers and wont attempt to relaunch the app.

Still in SearchViewController.swift, in the initialization of downloadsSession


downloadsSession, find the following line of code:
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
and replace it with the following line:
https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 14 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("bgSessionConfiguration")


Instead of using a default session configuration, you use a special background session configuration. Note that you
also set a unique identifier for the session here to allow you to reference and reconnect to the same background
session if needed.
Next, in viewDidLoad()
viewDidLoad(), add the following code:
_ = self.downloadsSession
Calling the lazily-loaded downloadsSession ensures the app creates exactly one background session upon initialization of SearchViewController
SearchViewController.
If a background task completes when app isnt running, the app will be relaunched into the background. Youll need to
handle this event from your app delegate.
Switch to AppDelegate.swift and add the following code near the top of the class:
var backgroundSessionCompletionHandler: (() -> Void)?
Next, add the following method to AppDelegate.swift
AppDelegate.swift:
func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) {
backgroundSessionCompletionHandler = completionHandler
}
Here, you save the provided completionHandler as a variable in your app delegate for later use.
application(_:handleEventsForBackgroundURLSession:) wakes up the app to deal with the completed background task. You need to handle two things in this event:
First, the app needs to reconnect to the appropriate background session with the identifier provided by the delegate method. But since you create and use one background session every time you instantiate SearchViewController
Controller, youre already reconnected at this point!
Second, youll need to capture the completion handler provided by the delegate method. Invoking the completion handler causes the OS to snapshot your updated UI for display in the app switcher, as well as tells the OS
that your apps done working with all background activities for the current session.
But when should you invoke the completion handler? URLSessionDidFinishEventsForBackgroundURLSession(_:) would be a good choice; its a NSURLSessionDelegate method that fires when all tasks pertaining to the background session have finished.
Implement the following extension in SearchViewController.swift
SearchViewController.swift:
extension SearchViewController: NSURLSessionDelegate {

func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession) {


if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
if let completionHandler = appDelegate.backgroundSessionCompletionHandler {
appDelegate.backgroundSessionCompletionHandler = nil
dispatch_async(dispatch_get_main_queue(), {
completionHandler()
})
}
}
}

The above code simply grabs the stored completion handler from the app delegate and invokes it on the main
https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 15 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

thread.
Build and run your app; start a few concurrent downloads and tap the Home button to background the app. Wait until you think the downloads have completed, then double-tap the Home button to reveal the app switcher.
The downloads should have finished and their new status reflected in the app screenshot. Open the app to confirm
this:

You now have a fully functional music streaming app! Your move now, Apple Music! :]

Where to Go From Here?


You can download the complete project for this tutorial here.
Congratulations! Youre now well-equipped to handle most common networking requirements in your app. There are
more details to NSURLSession than would fit in this NSURLSession tutorial, such as upload tasks and session
configuration settings such as timeout values and caching policies.
To learn more about these features (and others!), check out the following resources:
Apples documentation which contains comprehensive details on all the API methods.
Our own iOS 7 By Tutorials book, with two full chapters dedicated to NSURLSession
NSURLSession. You can also check out
our earlier NSURLSession tutorial.
AlamoFire is a popular third-party iOS networking library; we covered the basics of it in our Beginning Alamofire
https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 16 of 17

NSURLSession Tutorial: Getting Started

19/12/16, 1(57 AM

tutorial.
I hope you found this tutorial useful. Feel free to join the discussion below!

Ken Toh
Ken Toh is a software engineer from Singapore with more than 5 years of experience in iOS
development. During his free time, he likes to work on various side projects. He has also
launched several apps on the AppStore, namely RPS Mutants, Where's My Tea? and SG
Libraries.
When he is not coding, he enjoys reading and playing football.
You can follow him on Twitter or visit his website at kentoh.com.

Razeware LLC. All rights reserved.

https://www.raywenderlich.com/110458/nsurlsession-tutorial-getting-started

Page 17 of 17

S-ar putea să vă placă și