The NSURLSession class and related classes provide an API for downloading content. This API provides a rich set of delegate methods for supporting authentication and gives your app the ability to perform background downloads when your app is not running or, in iOS, while your app is suspended.
At a high level, NSURLSession is based around the concept of sessions and tasks. A task represents a single request for a single URL (or a single upload to a single URL). A session is a group of related requests.
The operating system provides a single preexisting session—the shared session, which basically works like NSURLConnection. Additionally, you can create your own sessions in your app as needed.
Different apps use sessions in different ways. Many apps create a single session on launch and just keep reusing it. Other apps benefit from being able to cancel a group of related tasks (e.g. a web browser canceling all outstanding requests when you close a tab), and thus create one session to hold each group of related requests.
The first step when using NSURLSession is to create a session configuration object. The (usually) reusable object contains various session settings that you can tweak for your particular needs, such as maximum concurrency, extra headers to send with each request, whether to allow requests to be sent over the cellular radio (iOS only), timeouts, credential storage, minimum TLS version, and even proxy settings.
There are three types of session configurations, depending on how you want the resulting session to behave:
Default configurations create sessions that work much like NSURLConnection.
Background configurations create sessions in which requests happen out-of-process, allowing downloads to continue even when the app is no longer running.
Ephemeral configurations create sessions that do not cache anything to disk, do not store cookies to disk, etc. and thus are suitable for backing things like incognito browser windows.
When you create a background configuration, you must provide a session identifier that allows you to reassociate the background session later (if your app exits or is suspended or terminated by the OS). You must not have more than one instance of a session with the same identifier active in your app, so as a rule, these configurations are not reusable. All other session configurations can be reused to create as many sessions as you want. So if you need to create multiple sessions with similar settings, you can create the configuration once and reuse it every time you create a new session.
After you create a session, you can create tasks in that session. There are three types of tasks:
Data tasks return data as an NSData object. These are suitable for general use, but are not supported in background sessions.
Download tasks return data as a file on disk. These are suitable for larger requests, or for use in background sessions.
Upload tasks upload data from an NSData object or from a file on disk. You provide a data object or file that provides the POST body. The body data/file that you provide on the task overrides any body data/file provided in the NSURLRequest object (if applicable).
Each of these types lets you obtain the response data in a couple of different ways—either by using block-based callbacks or by providing a delegate on the session and implementing delegate methods.
Additionally NSURLSession lets you provide delegate methods for handling authentication, performing custom TLS certificate handling (both for client certificates and server validation), changing the caching behavior, and so on.
Objective-C Create a Session And Data Task
Sending a POST Request with arguments using NSURLSession in Objective-C
There are two common ways to encode a POST request body: URL encoding (application/x-www-form-urlencoded) and form data (multipart/form-data). Much of the code is similar, but the way you construct the body data is different.
Sending a request using URL encoding
Be it you have a server for your small application or your working in a team with a full out back-end engineer, you'll want to talk to that server at one point with your iOS application.
In the following code we will be composing a string of arguments that the destination server script will use to do something that changes depending on your case. For example we may want to send the string:
To the server when a user signs up to your application, so the server can store this information in a database.
Let's get started. You'll want to create a NSURLSession POST request with the following code.
The above code just created and fired the POST request to the server. Remember that the script URL and the POST data string changes depending on your situation. If you're reading this, you'll know what to fill those variables with.
You'll also need to add a small method that does the URL encoding:
So, when the server is finished processing this data it will send a return to your iOS app. So we need to process this return, but how?
We use event-driven programming and use NSURLSession's delegate methods. This means as the server sends back a response these methods will start triggering. The following 5 methods are the ones that'll be triggered throughout the ENTIRE request, each time one is made:
Below you'll see the above methods used in context. Each of their purposes are pretty self-explanatory thanks to Apple, but I've commented their uses anyway:
So that's it! That's all the code you need to send, receive and parse a request for an API in iOS 9! Okay...it was kind of a lot of code. But if implemented right like above, it'll be fail-safe! Make sure to always handle errors where suggested above.
Sending a request using form encoding
URL encoding is a broadly compatible way to encode arbitrary data. However, it is relatively inefficient for uploading binary data (such as photos) because every non-ASCII byte turns into a three-character code. It also does not support file attachments, so you would have to pass filenames and file data as separate fields.
Suppose we want to upload a photograph in a way that is efficient and actually looks like a file on the server side. One way to do that is to use form encoding instead. To do this, edit the code that creates the NSURLSession as follows:
This creates and fires the NSURLSession request just as before, and as a result the delegate methods will behave exactly the same way. Make sure that the script the image is being sent to (located at the url in the variable url) is expecting an image and can parse it correctly.
Setting up background configuration
To create a background session
Additionally, in iOS, you must set up support for handling background app relaunch. When your app's application:handleEventsForBackgroundURLSession:completionHandler: method (Objective-C) or
application(_:handleEventsForBackgroundURLSession:completionHandler:) method (Swift) gets called, it means your app has been relaunched in the background to handle activity on a session.
In that method, you should create a new session with the provided identifier and configure it with a delegate to handle events just like you normally would in the foreground. Additionally, you should store the provided completion handler in a dictionary, using the session as the key.
When the delegate's URLSessionDidFinishEventsForBackgroundURLSession: (Obj-C) / URLSessionDidFinishEventsForBackgroundURLSession (Swift) method gets called to tell you that there are no more events to handle, your app should look up the completion handler for that session, remove the session from the dictionary, and call the completion handler, thus telling the operating system that you no longer have any outstanding processing related to the session. (If you are still doing something for some reason when you get that delegate call, wait until done.) As soon as you call that method, the background session immediately gets invalidated.
If your application then receives an application:application:didFinishLaunchingWithOptions: call (likely indicating that the user foregrounded your app while you were busy processing background events), it is safe to create a background session with that same identifier, because the old session with that identifier no longer exists.
If you're curious about the details, at a high level, when you create a background session, you're doing two things:
Creating a session in an external daemon (nsurlsessiond) to handle the downloads
Creating a session within your app that talks to that external daemon via NSXPC
Normally, it is dangerous to create two sessions with the same session ID in a single launch of the app, because they both are trying to talk to the same session in the background daemon. This is why the official documentation says to never create multiple sessions with the same identifier. However, if the first session was a temporary session created as part of a handleEventsForBackgroundURLSession call, the association between the now-invalidated in-app session and the session in the background daemon no longer exists.
Simple GET request
This modified text is an extract of the original Stack Overflow Documentation created by following contributors and released under CC BY-SA 3.0