Tutorial: How To Use iOS NSURLConnection By Example

Most of the apps you’ll build will have to fetch some sort of data through the network whether it’s as simple as high scores, a configuration file or more complex data such as a large movie catalogue.

While there are a few ways you could fetch data in your iPhone application and more than a few networking libraries you could integrate, it’s still an asset to understand this handy class, NSURLConnection, since the libraries you’re using are probably using NSURLConnection under the hood. In the future, I hope to cover some of the networking libraries out there!


ARTICLE CONTENTS
1. An Asynchronous Example
2. A Synchronous Example
3. Performing a POST request
4. Example With Connection Timeout
5. Cache Policies


1. An Asynchronous Example

To fetch some data, we’ll follow these 3 basic steps:

1. Have our class conform to the NSURLConnectionDelegate protocol and declare a var to store the response data
2. Implement the NSURLConnectionDelegate protocol methods
3. Create an instance of NSURLRequest and NSURLConnection to kick off the request

The idea is that when you kick off the request in Step 3, you want to be notified of certain events that will happen, such as when the response comes back. And you’ll be handling such events via methods you implement in Step 2. In Step 1, you’re basically telling the system that you intend handle those NSURLConnection events.

Step 1.
In the class you’ll be using NSURLConnection, specify in the header file that it conforms to the NSURLConnectionDelegate protocol. Also declare an instance variable to hold the response data.

Step 2.
Next, in the implementation file, you’ll implement the NSURLConnection protocol methods. In the comments in the code block below, you can see what each protocol method is used for:

Step 3.
Now you’re finally ready to perform the asynchronous request. Create an instance of NSURLRequest, assign it the URL. Next, create an instance of a NSURLConnection and call the initWithRequest method, passing in your NSURLRequest.

Step 4.
What should happen is when your request is fired in Step 3, your handler, connection:didReceiveResponse will be hit first, indicating that the server has responded. Then the handler, connection:didReceiveData: will be hit several times. This is where you’ll append the latest data to the response data variable you declared in Step 1. Then finally, connectionDidFinishLoading: will be hit and you can parse the response data variable.

If you want to do a synchronous request, you can use the sendSynchronousRequest method of NSURLConnection.

2. A Synchronous Example

A synchronous request looks like the below:

A NSURLRequest is still required. The NSURLResponse and NSError vars are passed into the sendSynchronousReqeust method so when it returns, they will be populated with the raw response and error (if any). If you need to check for stuff like response codes you can do so via the “response” variable you pass in Line 6.

In Line 5, the request will be performed synchronously and the results assigned to the NSData variable. Before you work with the data, you should check that the error variable you passed in is still nil.

Async or Sync?
So should you perform an asynchronous request or use a synchronous one for your application? I find that in the large majority of times, I’m using the async request because otherwise the UI would be frozen while the synchronous request is doing its thing and that’s a big problem when the user is performing gestures or touches and the screen is unresponsive. Unless I’m firing off a request to do something really simple and quick like ping a server, I default to using the async pattern.

3. Performing a POST Request

To POST data, all you need to do is to use NSURLRequest like we did before previously, but this time you’ll set the HTTPMethod property to POST and you’ll assign the header fields and value in the body. Then we send it with NSURLConnection like before. The only difference is that this time, we’ll use an instance of NSMutableURLRequest because we need to modify and set it’s properties after initialization.

4. Example With Connection Timeout

If you want to set a timeout for your data retrieval, you can set the timeoutInterval property of your NSURLRequest. If you’re getting an error in XCode, ensure that you’re using an instance of NSMutableURLRequest because NSURLRequest is immutable.

5. Cache Policies

To specify how your data should be cached locally, you can set a cache policy with your NSURLRequest. For example, the following snippet shows you how you can define a cache policy and a timeout.

If you don’t specify any caching policy with your NSURLRequest, then it will try to conform to whatever the protocol states. For example, with HTTP it will look at the server response headers and try to conform to what it dictates about caching. For more examples and information about NSURLConnection and caching, read my post on preventing caching problems with NSURLConnection.

Written by Chris Ching

Chris is the founder of CodeWithChris and when he's not teaching or coding, he loves to sit on the couch with his family watching TV or to play strategy and collectible card games.

Follow me on Twitter

  • Rick

    Thanks, Chris!
    This well-written tutorial helped my solve a bug in my app that I’ve been fighting with for months!
    Rick

    • Chris

      Thanks for your comment Rick! Makes me feel like it’s all worth it!

      • Ri

        Hi Chris,
        Thank you from me too, for the same reason!

        • Chris Ching

          Thank you Ri :)

  • Roman

    Hi! Thanks for the Article! It gave me the quick, clean start that i needed.

  • Rajendra

    Thanks chris. It gave me a clear understanding about NSURLConnection.

  • Pingback: NSUrl example | Long Wharf

  • Swaroop S

    Very Good Tutorial..

  • Matt

    Why are you splitting this into two lines:
    NSURLConnection *conn = [[NSURLConnection alloc] init];
    (void)[conn initWithRequest:request delegate:self];

    ** This is not good practice or style, this should be:

    NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];

    • Chris Ching

      Oops, you’re right! I’ve edited it to reflect this.
      Thank you!

      • Matt

        You have the error again:

        // Create url connection and fire request
        NSURLConnection *conn = [[NSURLConnection alloc] init];
        (void)[conn initWithRequest:request delegate:self];

        Normally, I wouldn’t care but because people are coming here to learn I want to make sure they are seeing the correct way to do it.

        Anything that starts with init is an initializer and so you are basically initializing things twice.

        • Chris Ching

          Made the 2nd correction.
          You’re absolutely right, the old code was initializing the object twice. I’m quite embarrassed to miss it so thank you for catching it.

          • Mario

            Maybe this is also right?
            [NSURLConnection connectionWithRequest:request delegate:self];
            You don’t have to allocate or initialize anything. You just want to fire the connection.

  • http://www.singlespeed.ca Matt

    Also, this UIViewController should be UIViewController or people are going to have code completion problems. See: http://stackoverflow.com/questions/7803472/nsurlconnection-methods-no-more-available-in-ios5

    Having said that, I did appreciate your sample code!

    • Matt

      It stripped my code but basically you need both of these protocols: NSURLConnectionDelegate,NSURLConnectionDataDelegate

  • Saikat

    Excellent stuff. Well documented. Thanks for the detailed explanation Chris.

  • http://nestorgames.com/#linkage_detail Almo

    Hi!

    Apparently, in Part 3, the NSURLRequest should be an NSMutableURLRequest.

    http://stackoverflow.com/questions/5168811/exception-while-adding-argument-to-nsmutableurlrequest

  • https://metsrambles.wordpress.com Ali Almohsen

    Hi,

    Thanks a lot for the very simple and straightforward tutorial. It helped a lot.

    There’s just 1 thing I’m unsure of that you didn’t really address. Let’s say you want to POST a few fields (like userName and userPassword). How would you go about doing so?

  • http://sherihansliit.blogspot.com/ Sherihan

    Thanks a lot Chris. It’s really a valuable post. Helped me to overcome my issues with an app that I’m currently struggling with.

  • JITHIN M

    Thanks Chris very simple and detailed explanation of how NSUrlconnection works!!!!!!!!

    • Chris Ching

      Thank you! Glad to help :)

  • Charles

    Great, helpful post!

    • Chris Ching

      Thank you charles! I really appreciate the feedback :)

  • Israel Osuna

    This its a great tutorial but for some reason i cant make it work my code :(! i’ll appreciate if you can post the source code using all the stuff you explain here! thanks a lot!! Hello from Venezuela

  • Khashayar

    Thank you so much for this article! Its well written, clean formatted and to the point. Thx again! :)

    • Chris Ching

      Thanks for reading!!

  • Pingback: Launching URL in ios - iOS Solutions - Developers Q & A

  • http://AIApplied Mark Tindal

    Excellent guide thanks!

    • Chris Ching

      Thanks for reading!!

  • Deep

    Really Helpful..

    • Chris Ching

      Thanks for reading, Deep!

  • Jake

    Good Tutorials, both here and on youtube. I learned a lot from you!

    • Chris Ching

      Thanks a lot Jake! Hope you continue to visit!

  • rahul sharma

    Hi Chris..
    i saw lot of article bt i did’t get like ur article..in ur article explanation is nice …
    so when ever i feel difficulty i use to search ur article..
    thanks..

    • Chris Ching

      Thanks for reading Rahul!

  • Kisuk Park

    Simple! Useful! Great tutorial!! Thanks Chris : )

    • Chris Ching

      Thanks for reading, Kisuk!

  • http://sketchytech.blogspot.com Anthony

    A great tutorial and really easy to follow. I found that instead of using the instance method in Step 3:

    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    That the class method:

    [NSURLConnection connectionWithRequest:request delegate:self];

    Avoids the warnings that arise from an unused variable.

  • Rodney

    This is excellent! it’s easy to follow, to-the-point and very usable!!! thanks!

    • Chris Ching

      Thanks for reading, Rodney. I’m glad it helped. Thanks for taking the time to leave a note.

  • Jim

    Your tutorial continues to help; thanks for taking the time to write it, post it, maintain it and answer questions!

    • Chris Ching

      It’s the funnest part of my day :) Thanks for reading!

  • tusharghate

    Awesome tutorial, very well-written and super easy to follow. Thanks man!

    • http://codewithchris.com/ Chris Ching

      Thanks for taking the time to comment!

  • sankar ram

    Hey Chris your tutorial about NSUrlConnection is not working in my xcode 4.3.2 when the conn is initialized its not hits the didrecieveresponse method please help me in this I want to dowmload a image using NSUrlConnection here i enclosed the screenshot

    • http://codewithchris.com/ Chris Ching

      Hey, can you confirm in ViewController.h that you are conforming to the protocol? (step 1) Thanks!

  • Sankar Ram

    hai chris from this Connectiondidrecievedata I am downloading a image , in this thread data how to set the progress view for recieved data and how to calculate the total data before recieving it since I need to show in the ProgressView in here

  • Sankar Ram

    from your tutorial of NSUrlConnection connectiondidreceivedata recieving data I want to calculate it in Progress View for Recieved data is measured in data length total data I want to calculate in Progress View to display it here I enclosed of my project to download a image

  • Nilesh

    Nice explanation

  • john

    This line : _responseData = [[NSMutableData alloc] init]; will cause memory issue as didReceiveResponse can be called multiple times during a request. As per : https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html , – (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ // This method is called when the server has determined that it // has enough information to create the NSURLResponse object. // It can be called multiple times, for example in the case of a // redirect, so each time we reset the data. // receivedData is an instance variable declared elsewhere. [receivedData setLength:0];}

  • Joey Clover

    So much help! Thanks Chris, it got me exactly what I needed and I’m new to iOS Code, so thanks again!

    • http://codewithchris.com/ Chris Ching

      Hey Joey, thanks for reading!

  • Lawrence Pires

    Thanks for taking the time to write this tutorial/example, as a newbie to coding cocoa its great to have an easy to follow along tutorial, thumbs up

    • http://codewithchris.com/ Chris Ching

      Hey Lawrence, thanks for reading it! :)

  • Alex Zhao

    Excellent Article. Thumb up.

    • http://codewithchris.com/ Chris Ching

      Thanks for reading Alex!!

  • Nathan

    Crisp and clear
    Thank you

    • http://codewithchris.com/ Chris Ching

      Thanks for stopping by Nathan!

  • http://saurabh-rane.appspot.com Saurabh Rane

    Hey, thanks for the tutorial!! Can you tell more about how to post an xml with the request?

    Thanks in advance!

    • Soma C

      Hi,

      Did you get to know how to post XML data in HTTP POST. If yes, kindly let us know. Thanks.

  • Felipe Miranda Costa

    Thank you for this material. Very useful. Pretty didatic explanation.

  • Joshua

    I am making a program that has a login thing, it has the NSTextFeild, and NSSecureTextFeild, or UserName and password. And i was wondering how i’d get the response back in an if statement, so i can see if the username or password were wrong or correct.

  • Phil

    Hi Chris, thanks for your tutorials.
    Where does the Step 3 code go?

    • http://codewithchris.com/ Chris Ching

      Hey Phil, in step 3, that code goes into whatever method where you want to kick off the request! If you want to trigger the request upon view load then put it in “viewDidLoad” or put it in some other method if you want to trigger it when that method is called.

      Thanks for reading!

  • http://www.davidchristy.com artistdavid2000

    Thanks Chris. A question on “Part 3. Performing a Post Request.” XCode – Version 5.1 (5B130a), created an iPad app.

    In order to get the URLRequest to fire I had to change the NSURLRequest line 2 to: NSMutableURLRequest *request = [NSURLMutableURLRequest . . . . . . . . . . . Otherwise I would get ‘NSInvalidArgumentException’ error on execution.

    I’m using the same .PHP script to receive the POST as the html form page uses, however there is no data received for the entry from my app. My request, stringData, HTTPMethod and HTTPBody all return NSLog content.

    my sql insert is:
    $sql=”INSERT INTO users (FirstName, LastName, password, repNumber) VALUES (‘$_POST[FirstName]‘,’$_POST[LastName]‘,’$_POST[password]‘,’$_POST[repNumber]‘)”;

    any thoughts?

    • http://codewithchris.com/ Chris Ching

      Hello! It’s probably because your stringData is not actually xml although your header values indicates that it is..
      Try using “application/x-www-form-urlencoded;charset=utf-8″ instead.

      • http://www.davidchristy.com artistdavid2000

        Chris, Works perfectly! Thanks a million!! Really!!

  • Spencer Fontein

    I’ve been using the Hpple code on github to parse my XML and it works but it gets it asynchronously and I’m trying to get it synchronously with this. But I’m not sure where to put part3, i just need the html data in NSData, any thoughs

  • Suthan M

    Hi Chris ,

    This is suthan first of all thanks for your valuable blogs.
    Its really helpful for me to understand the flow of connections.

    I need to ask one questions in this time , while using post method i’m getting the crash in “HttpMethod” , do you have any idea about this chris ??

    Warm regards ,
    Suthan M

    • Suthan M

      Hi Chris ,

      I found one small issues in the code please note it thanks for your useful blogs :)

      Your 3rd Step —->>>> Performing a POST Request

      Line 2) Error occurred

      NSMutableURLRequest *request = [NSURLRequest requestWithURL:…
      should be
      NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:…

      • http://codewithchris.com/ Chris Ching

        Thanks for spotting that Suthan!

  • Claus Kjeldsen

    Great tutorial

    I would like to do the same to this method, how can I do this? After I call NSURLConnection, I would like to split the reply into methods, that is called when NSURLConnection is done….just like you do (I am VERY new to IOS development)

    -(void) ControlDigitalPortOnSparkCore:(NSString*)MethodName :(NSString*)Command

    {
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://api.spark.io/v1/devices/%@/%@", deviceID, MethodName]];

    NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL: url cachePolicy: NSURLRequestReloadIgnoringCacheData timeoutInterval: 60.0];

    [postRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

    [postRequest setHTTPMethod:@"POST"];

    NSString *bodyData = [NSString stringWithFormat:@"access_token=%@&params=%@", token, Command];

    [postRequest setHTTPBody:[NSData dataWithBytes:[bodyData UTF8String] length:strlen([bodyData UTF8String])]];

    [NSURLConnection sendAsynchronousRequest:postRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
    {

    if (!connectionError)
    {
    //self.Result.text = [[NSString alloc] initWithBytes:data.bytes length:data.length encoding:NSUTF8StringEncoding];

    NSDictionary *retData = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&connectionError];

    NSNumber *val = [retData objectForKey:@"return_value"];

    self.Result.text = [NSString stringWithFormat:@"%@", val];
    }
    else
    {
    self.Result.text = [NSString stringWithFormat:@"%@",connectionError];
    }
    }];
    }

  • Arif Fikri Abas

    THANK YOU VERY MUCH! very helpful, u’re awesome *thumbs up*