Submit your appAboutContact

NSURLSession in Swift: get and post data

In this new Swift 2 tutorial you'll learn how to use the NSURLSession Swift function. You'll see different examples that illustrate how to define the different NSURLSession methods in various scenario, for downloading data or sending post requests.

Let's start this new tutorial by creating a new Swift iOS single view application.

swift create new single view activity

For this tutorial we'll use iOS 9 as a deployment target and the examples are based on a server side script to get the data located on the server that does not have the https, so, for  this reason, we have to edit the info.plist file, in order to allow this domain.

Edit the Info.plist to allow an http domain

Right click on the info.plist file, select open as, Source code. Add the lines of code that allow the http connection to this server.

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>www.kaleidosblog.com</key>
            <dict>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
        </dict>
    </dict>

swift info.plist htt https allow block

The NSURLSession is an asynchronous function and has three main principal methods: 

  • dataTaskWithUrldataTaskWithRequest
  • downloadTaskWithUrldownloadTaskWithRequest
  • uploadTaskWithUrluploadTaskWithRequest

The dataTaskWithUrl is for normal data requests (when for example you'll have to ask to a web server for some data).
The downloadTaskWithUrl is for downloading files. It can resume the downloads for you and, as soon as the data is ready you'll have the temporary path in which the data is stored.
The uploadTaskWithUrl is for uploading data.

Server definition

The server in this example receives the data through a post request and simply replies it back. The post parameter has this format:

Post Request : 'data' > String

In this way we'll see if everythings works fine.
The url for the requests is located at this address:
 http://www.kaleidosblog.com/tutorial/nsurlsession_tutorial.php

In swift I've defined a constant variable with this url, called url_to_request.

NSURLSession: dataTaskWithUrl example

Let's start this example  with the dataTaskWithUrl function.


    func data_request()
    {
        let url:NSURL = NSURL(string: url_to_request)!
        let session = NSURLSession.sharedSession()
        
        let request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "POST"
        request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
        
        let paramString = "data=Hello"
        request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)
        
        let task = session.dataTaskWithRequest(request) {
        (
            let data, let response, let error) in
            
            guard let _:NSData = data, let _:NSURLResponse = response  where error == nil else {
                print("error")
                return
            }
            
            let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
            print(dataString)
            
        }
        
        task.resume()
        
    }

The difference between dataTaskWithUrl and dataTaskWithRequest, as the name suggests, is that dataTaskWithUrl requires an URL as input, while the dataTaskWithRequest requires a NSMutableURLRequest variable. The difference between the URL and the NSMutableURLRequest is that the URL has to been initialized first with your requirments and nothing can change then, while with the NSMutableURLRequest you can define the variable and then you can set the behaviour like the cache policy, timeout, or the http method used. In  this example the cache has been disabled in order to reload from the original source the request. The guard method let us check the response data.

NSURLSession: downloadTaskWithUrl example


  func download_request()
    {
        let url:NSURL = NSURL(string: url_to_request)!
        let session = NSURLSession.sharedSession()
        
        let request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "POST"
        request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
        
        let paramString = "data=Hello"
        request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)
        
        
        let task = session.downloadTaskWithRequest(request) {
            (
            let location, let response, let error) in
            
            guard let _:NSURL = location, let _:NSURLResponse = response  where error == nil else {
                print("error")
                return
            }
            
            let urlContents = try! NSString(contentsOfURL: location!, encoding: NSUTF8StringEncoding)
            
            guard let _:NSString = urlContents else {
                print("error")
                return
            }
            
            print(urlContents)
            
        }
        
        task.resume()
        
    }

The downloadTaskWithUrl stores in a temporary file the data you've received from the server. With the location variable you can access directly to this temporary file, or get the data from this file. This method is able to resume a suspended download.

NSURLSession: uploadTaskWithUrl example


  func upload_request()
    {
        let url:NSURL = NSURL(string: url_to_request)!
        let session = NSURLSession.sharedSession()
        
        let request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "POST"
        request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
    
        
        let data = "data=Hi".dataUsingEncoding(NSUTF8StringEncoding)

        
        let task = session.uploadTaskWithRequest(request, fromData: data, completionHandler:
            {(data,response,error) in
            
                guard let _:NSData = data, let _:NSURLResponse = response  where error == nil else {
                    print("error")
                    return
                }
                
                let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print(dataString)
            }
        );
        
        task.resume()
        
    }

This method is able to upload data to a server, by directly putting the data inside the formData variable.

Download the example
UPDATE: Download the swift 3 project example



Leave a comment








Comments


- 09 June 2017 at 13:14
I get this warning in line 79 (see sample) and don't know how to solve it. Can anybody give me a hand? Thanks! guard let _:NSString = urlContents else { print("error") return } nsurlsession_tutorial_swift_3/nsurlsession_tutorial/ViewController.swift:79:19: Non-optional expression of type 'NSString' used in a check for optionals
Ton - 09 June 2017 at 13:22
Solved it!! let urlContents = try? NSString(contentsOf: location!, encoding: String.Encoding.utf8.rawValue) guard let _:NSString = urlContents else { print("error") return } print(urlContents!)
Ton - 09 June 2017 at 13:25
I got this warning with iOS 10.3
- 08 May 2017 at 10:41
Thanks for review sbobe
Ton - 09 June 2017 at 13:24
I got this warning with iOS 10.3
- 11 November 2016 at 13:46
Hi thanks for tutorial please help me how can I fix this problem. I create Registration page and I make providedEmailAddress for userEmail, userPassword, UserRepeatPassword that user have to complete these fields for access application. I am very new in swift and do I have to use "POST" or "GET"??? where can I define my parameters in your code? for example I don't understand this line of your code: let paramString = "data=Hello" what is this line code??
Andrea - 16 November 2016 at 20:51
Hi, thank you for your comment. For login or registration purpose you can use the post request method. The parameters have to been written into the body request in the form of key=value&key2=value2.. In the paramString part you define the parameter to send with the post request. So you have to concatenate all the keys and values that you have to send in this part!
- 31 October 2016 at 14:09
Thank you for great tutorial. Could you also post the content of the php - file?
Andrea - 03 November 2016 at 08:21
Hi! Thank you for your comment. Sure, it is very simple, you can find it here: http://www.kaleidosblog.com/tutorial/nsurlsession_tutorial.txt
- 28 October 2016 at 17:19
Would this work if the website we are communicating with is HTTPS? normally your browser does the SSL "handshake" with the HTTPS site and everything is secure.. is the iPhone capable of doing this? So My question is 2 parts, 1) will this code and data transfer work with a website that is https? and 2) if it does work, is the data actually secured (encrypted)? Thank you very much
Andrea - 29 October 2016 at 13:36
Hi, yes https is supported by NSURLSession, just write the link as https and everything is done by nsurlsession. Yes with the above code you can use http or https as you want, just write the link. Sure when you use https the data is always encrypted.
- 30 September 2016 at 00:57
Hi Andrea, thanks for the wonderful tutorial. one question regarding "request". In case of GET method, is it possible to skip "request" part? let task = session.dataTask(with:" url "- instead of "request") .... seems to work. Will it be a problem somewhere else?
Andrea - 30 September 2016 at 20:42
Hi, thank you for your comment, the difference is that you cannot customize your request, by adding a post parameter, header information, define the cache policy, the timeout and so on. It will just use the default parameter, but the request will work fine too!
David - 01 October 2016 at 08:40
Hi Andrea, Thank you for your answer.
- 25 September 2016 at 17:26
hey in swift 3 are some changes: func data_request(){ let url:NSURL = NSURL(string: "http://example.com/")! let session = URLSession.shared let request = NSMutableURLRequest(url: url as URL) //request.addValue("application/json", forHTTPHeaderField: "Content-Type") //request.addValue("application/json", forHTTPHeaderField: "Accept") request.httpMethod = "POST" request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData let paramString = "data=Hello" request.httpBody = paramString.data(using: String.Encoding.utf8) let task = session.dataTask(with: request as URLRequest) { ( data, response, error) in // No idea // guard let _:NSData = data, let _:NSURLResponse = response , error == nil else { // print("error") // return // } let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue) print(dataString) } task.resume() }
- 24 September 2016 at 16:29
Hi, my question is similar to Venkatesh. "HI if i send request to server which way i can fallow i mean code and how to send login details to server and get how to get some data please tell me........" Will you be able to give me some concrete example. I've used dataTaskWithUrl with my api link created in Flask. It return: Optional({ "success": false } ) Seems like I did not login successfully. I don't know what have I missed out.
Andrea - 25 September 2016 at 10:49
Hi, in the next days I will write a tutorial about the login page with username and password and how to send the login details to a server in order to perform the login and keep the session active!
- 10 August 2016 at 22:32
I'm a little confused about something. The code and explanation seem very straight forward, but when I run the data_request() function as copied from this page (url_to_reuquest replace with variable) the program never executes the code in the body under the line let task = session.dataTaskWithRequest(request) { Any idea what I'm doing wrong?
Andrea - 01 September 2016 at 09:29
Hi, can you please send me your project to let me help you?
- 25 June 2016 at 16:11
Thank you for this very clear and usable example.
- 14 June 2016 at 23:24
Hey, great tutorial! I am a little confused about the idea though. Is it possible to do something like the user clicks a button on your app and it posts a message to your twitter/facebook or something along those lines?
Andrea - 01 September 2016 at 09:33
Hi, thank you for your comment. You can for sure add a button that once clicked perform some data post request. However for facebook or twitter you need to use their api in order to let the user login, add access to your app and post messages. If you need I can write a tutorial about it! Just let me know
- 10 June 2016 at 12:08
Nice tutorial. Simple illustration. Easy to understand.
- 25 March 2016 at 09:36
thank you for the tutorial. i faced a problem when building the app. it said that "Value of type 'NSURLSession' has no member 'dataTaskWithRequest'
Andrea - 25 March 2016 at 19:43
Hi, thank you for your comment. Have you implemented the NSurlsession function inside a new swift file? If yes, be sure to import all the required libraries at the top of the file (import UIKIt..). Otherwise, it is better if I can see your project to help you a bit more.
- 17 March 2016 at 15:07
great tutorial
- 13 March 2016 at 10:47
Amazing Tutorial, Thank you.
- 03 March 2016 at 04:21
HI if i send request to server which way i can fallow i mean code and how to send login details to server and get how to get some data please tell me........
Andrea - 03 March 2016 at 20:44
Hi, thank you for your comment. You can use the dataTaskWithUrl function, send the data using a post request to your server (better to use https when sending sensible information) with the login information, then your server can respond with the data in json format. Hope it helps, if you need a more concrete example let me know.
- 25 February 2016 at 20:24
Hey, Nice Article. Learnt a lot from this. Have some doubts: 1. Shouldn't the downloadTask request.HTTPMethod be equal to Get, instead of Post? 2. Why is the dataTask Post? 3. I think you forgot to set the body of the request in UploadTask.
Andrea - 25 February 2016 at 20:38
Hi, thank you for your comment. The requests with the NSURLSession can be both Post or Get requests. In this example, I've prepared a php script that allows only post requests. In all the cases the same php script is called, and in all cases the post parameter are properly sent.
Nikita - 25 February 2016 at 21:11
I appreciate the quick reply. Thank you for explaining. Just wanted to clarify on the third point again. you have not set the HTTPBody of the request in Upload Task.
- 20 February 2016 at 19:22
Fantastico! Finalmente ho trovato ciò che cercavo! Se con la funzione data_request() io volessi inviare un array oppure un Json, cosa dovrei modificare? Spero tanto in una tua risposta. Grazie mille
Andrea - 20 February 2016 at 19:30
Ciao, grazie per il tuo commento. Nella funzione data_request dovresti inserire i parametri oppure la stringa contenente il json, ad esempio in questo modo data_request(String: dati). Quindi puoi utilizzare la variabile paramString per concatenare i tuoi parametri o la stringa in json. In questo articolo puoi trovare un esempio più concreto: http://www.kaleidosblog.com/how-to-parse-and-extract-json-data-in-swift
Fabrizio - 20 February 2016 at 23:34
Grazie mille, mi studio il tutorial! Ma c'è un limite di grandezza della stringa che inviamo? Grazie di nuovo
Andrea - 21 February 2016 at 08:14
Non c'è un limite di lunghezza, c'è però un limite sulla dimensione della richiesta post che fai. Questo limite può comunque essere modificato dalle impostazioni del server. Ma finchè invii solo array di testo in formato json, senza inserirci immagini all'interno, difficilmente lo raggiungi.
Fabrizio - 21 February 2016 at 14:54
Grazie mille di nuovo!
- 08 February 2016 at 06:35
Thanks a lot for this tutorial & appreciate your pains for the below tutorial also, http://www.kaleidosblog.com/protocol-delegate-in-swift-how-to-define-and-use-a-protocol-function-to-handle-external-events I was struggling for these points.
Andrea - 09 February 2016 at 17:40
You are welcome!
- 03 February 2016 at 10:00
Thank you for such detailed teaching!!
- 13 January 2016 at 19:07
this is awesome!
- 06 January 2016 at 21:09
I love the code, but I'm trying to work out how I can put it into a separate file so I don't have multiple lines of the same code. I am trying to do it with a completion handler but not having much luck getting it to work. Any help or a tutorial on it would be great. :)
Andrea - 06 January 2016 at 21:30
You've to define a protocol for your completion handler. In this protocol you'll define the function that will be called as soon as the data is arrived. When the function for downloading the data is called, you also have to pass the class that will be called (the class that implement the function of the protocol). Hope it helps, but in the next days I'll write a tutorial about that :-)
Chris - 06 January 2016 at 22:57
Thanks for the reply, I kind of know what you're saying but still a little confused. I'll have another look at it tomorrow when I have more time. Hopefully you'll get time to do a tutorial on it and that might help a little more but if you don't then it doesn't matter. Either way thanks for the tutorials already here :)
Chris - 07 January 2016 at 22:49
Wow! Didn't expect that so quickly.. Thank you very much i'll check it out :)
- 28 September 2015 at 08:40
Hi, Can I get to see nsurlsession_tutorial.php file, I want to c how the php code is written.. Also how can load my tableview from php file
Andrea - 28 September 2015 at 08:51
Hi, thank you for your comment. It's very simple, here is the link: http://www.kaleidosblog.com/tutorial/nsurlsession_tutorial.txt . If you have more data to send (array, objects), yoy have to encode the array in a string using the php json_encode function. In this tutorial you'll see the table parsing from the json format http://www.kaleidosblog.com/swift-uitableview-load-data-from-json





Submit your appAboutContactPrivacy