Fetching data with GET,POST methods by using NSURLConnection

Today, I want to make a demonstration of fetching data from web servers by using NSURLConnection on objective-c platform. Before starting to my post, I need to give you a little brief about some http methods, GET and POST,  that are going to be used in our project.

HTTP GET Method:

GET method is oftenly used as query parameters. The parameters that are going to be sent to server can be identified in request uri. You don’t need to do any other things to send data. For instance, look at Google example below:

http://www.google.com/#q=get+example&output=search

This means that there are variables q and output with respect to “get example” and search” as values . Google will make a search with the value of q and the output function is stated as “search”. Normally instead of # sign, ?(question mark) is used. However, the syntax of google is a bit different.

HTTP POST Method:

In some cases, let’s say the sending data is really huge, GET method is inefficient. Because, the data sending with GET method is restricted with 8KB.This is the situation where POST Method overcomes the problem to send a large amount of data to server. Another case can be sending username and password data to a form in a web page. Unlike GET Method, posted data is not shown on request URI, hence, there should be a FORM in the web page to post data.

If you wish to know more detailed information about http methods, take a look at here.

What are we going to do? 

We are going to create an application that will demonstrate you guys to make a GET and POST request with NSURLConnection. After that, the retrieved data will be shown in UIWebView in another view. The project screenshots will be as like as below:

Now first of all create a new project on Xcode as a single view application. You may use any other of them however the project that I have started with was single view application.

Put 3 buttons onto a xib, and make the bindings related to the view controller’s header file.

Objective-c has a delegation structure which is very powerful and easy to implement without concerning what’s going on at the back-end. NSURLConnection has a delegate “NSURLConnectionDelegate”. With iOS 5 this delegate has been split to varying delegates. If you are using iOs5 right now, you need to call “NSURLConnectionDataDelegate” while using NSURLConnection. Now how will you use it? 

Open your view controller’s header class. In my example it is called “ConnectionExampleViewController.h” and modify it as like as below.

 

#import 

@interface ConnectionExampleViewController : UIViewController 

@property (retain, nonatomic) NSURLConnection *connection;
@property (retain, nonatomic) IBOutlet UIButton *btn_syncronous;
@property (retain, nonatomic) IBOutlet UIButton *btn_post;
@property (retain, nonatomic) IBOutlet UIButton *btn_get;
@property (retain, nonatomic) NSMutableData *receivedData;

/*BUTTON EVENTS*/
-(IBAction)btn_get_clicked:(id)sender;
-(IBAction)btn_post_clicked:(id)sender;
-(IBAction)btn_syncronous_clicked:(id)sender;

@end

What we have done in here, we have created 3 buttons, 1 NSURLConnection object, and 1 NSMutableData object. One of the most important thing in here is that our view controller has implemented NSURLConnectionDataDelegate. Whenever our connection object start to fetching from a web page, if the delegate of our connection object is set to this view controller, it will call delegate methods to warn our view controller about the state of connection. Now let’s make some coding over view controller’s .m file.

First of all, I would like to implement the event methods of our buttons. Whenever we click a button it will call relevant method that we have bound to our button previously.

-(IBAction)btn_get_clicked:(id)sender{

    //initialize new mutable data
    NSMutableData *data = [[NSMutableData alloc] init];
    self.receivedData = data;
    [data release];

    //initialize url that is going to be fetched.
    NSURL *url = [NSURL URLWithString:@"http://www.yahoo.com"];

    //initialize a request from url
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    //initialize a connection from request
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    self.connection = connection;
    [connection release];

    //start the connection
    [connection start];

}
-(IBAction)btn_post_clicked:(id)sender{

    //if there is a connection going on just cancel it.
    [self.connection cancel];

    //initialize new mutable data
    NSMutableData *data = [[NSMutableData alloc] init];
    self.receivedData = data;
    [data release];

    //initialize url that is going to be fetched.
    NSURL *url = [NSURL URLWithString:@"http://www.snee.com/xml/crud/posttest.cgi"];

    //initialize a request from url
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[url standardizedURL]];

    //set http method
    [request setHTTPMethod:@"POST"];
    //initialize a post data
    NSString *postData = [[NSString alloc] initWithString:@"fname=example&lname=example"];
    //set request content type we MUST set this value.

    [request setValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-Type"];

    //set post data of request
    [request setHTTPBody:[postData dataUsingEncoding:NSUTF8StringEncoding]];

    //initialize a connection from request
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    self.connection = connection;
    [connection release];

    //start the connection
    [connection start];

}
-(IBAction)btn_syncronous_clicked:(id)sender{

    //if there is a connection going on just cancel it.
    [self.connection cancel];

    //initialize new mutable data
    NSMutableData *data = [[NSMutableData alloc] init];
    self.receivedData = data;
    [data release];

    //initialize url that is going to be fetched.
    NSURL *url = [NSURL URLWithString:@"http://www.engadget.com"];

    //initialize a request from url
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    NSURLResponse *response = [[NSURLResponse alloc] init];

    [self.receivedData appendData:[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]];

    //initialize convert the received data to string with UTF8 encoding
    NSString *htmlSTR = [[NSString alloc] initWithData:self.receivedData
                                              encoding:NSUTF8StringEncoding];

    //initialize a new webviewcontroller
    WebViewController *controller = [[WebViewController alloc] initWithString:htmlSTR];

    //show controller with navigation
    [self.navigationController pushViewController:controller animated:YES];

}

I will just talk about -(IBAction)btn_post_clicked:(id)sender method because the other two is just as like as this one. In addition, this method is much more complex than the others.

Now firstly, I’m trying to cancel the connection. Why? Because, think of the end-user clicked button twice in a row. Before finishing the first request, it will try to fetch for second request, however both connections will write data into same NSMutableData object. Moreover, some of the data will be lost because every time we click a button we create a new instance of NSMutableData object.

Secondly, I create url, and afterwards a request with respect to instance of url. These are the same procedures for every requests. Now in order to make a POST to a web page, we need to set the request object’s http method. Afterwards, we MUST set the content-type of our request which will be located at http header field. This means, whenever we make a request to a server, it will know what kind of data will be posted. And lastly, we set httpBody of our request that is going to be sent to server and then create connection with our request and start created connection. This procedure is always the same in every platform. It does not differ whether or not you are using java, c# and so on.

The tricky part , the delegation, comes into play at this time. The folks at Apple has created a simple way to deal with the states of connection by using delegation structure.For those who are using C#, It is actually equal to event firing. There are actually lots of delegate methods in NSURLConnectionDataDelegate however, just only 3 of them is required to be implemented in class. Those are;

/*
 this method might be calling more than one times according to incoming data size
 */
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    [self.receivedData appendData:data];
}
/*
 if there is an error occured, this method will be called by connection
 */
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{

    NSLog(@"%@" , error);
}

/*
 if data is successfully received, this method will be called by connection
 */
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{

    //initialize convert the received data to string with UTF8 encoding
    NSString *htmlSTR = [[NSString alloc] initWithData:self.receivedData
                                              encoding:NSUTF8StringEncoding];
    NSLog(@"%@" , htmlSTR);
    //initialize a new webviewcontroller
    WebViewController *controller = [[WebViewController alloc] initWithString:htmlSTR];

    //show controller with navigation
    [self.navigationController pushViewController:controller animated:YES];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data this method is called more than ones if the data returned by server is huge. NSURLConnection is clever enough how to split and whenever it gets any kind of data it calls this method from bound delegate class.

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error this method is called if something is abnormally going on during the connection.

-(void)connectionDidFinishLoading:(NSURLConnection *)connection this method is called when connection finishes its job successfully. All the actions after fetching data from server can be done here. In our example, we have filled our data into our object “receivedData”. Now that, we can  convert our data into string with UTF8 encoding, and then pass it to our WebViewController class. WebViewController class is just a class which contains UIWebView in its xib. We call

[self.webView loadHTMLString:self.str baseURL:nil];

in order to show HTML string that came from server.

I attach my all project so that you can work on it. If you have any questions please leave me a message.

P.S: When you download and open my project, make sure that you need to change code signing from project’s build settings tab.

ConnectionExample

19 Thoughts on “Fetching data with GET,POST methods by using NSURLConnection

  1. Navneeth Baliga on July 10, 2012 at 12:56 pm said:

    Hi,

    I am very new to iOS apps. So please help me in my following task .
    I am currently designing an app for BASECAMP , which will allow me to login into my account. I downloaded your project and did some changes. I want to know how can I connect to the BASECAMP web service and perform a login operation into my account through my login app ?

    • Sorry for late reply. Firstly, you should know whether the web service that you are going to use POST or GET method. If GET method is in action you are simply to add your username and password as a query string into your URL. If the method is POST, then you should setHttpMethod to POST and then send username and password as DATA to service.

      If you have any other questions, feel free to ask. I’m really glad to help you :)

      Regards,
      KEMAL

      • Navneeth Baliga on July 13, 2012 at 5:17 am said:

        Hi,

        So i’m doing this for a software tool called BASECAMP which provides a tool to track projects for various companies. Anwyways BASECAMP uses the REST based web service with JSON. They have API’s for Ruby,PHP and C# but they do not have libraries for Objective C .

        This is what I have done, I have set the URL to “www.xyz.basecamp.hq.com/login and I have set the HTTP Body with the username and password. When I run the app the HTTP should send whatever username and password I have entered, but instead it is just taking me to the login page where I have to login again by entering the details once again. How do I get round to this problem ?

        Thanks
        N.B

        • Hmm Have u set Content-Type and requestMethod as like as below?

          [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
          [request setHttpMethod:@"POST"];

  2. yogesh on July 20, 2012 at 10:48 am said:

    this tutorial is really helped me a lot…. i did with HTTP GET & POST both.i haven’t seen a best tutorial as like this till yet….thanks:)

  3. You are awesome. Seriously, wish I’d seen this before i went through all 500 other pages on stack overflow that were all much harder to understand. SEO this stuff! =]

  4. chandrasekhar on January 21, 2013 at 8:00 am said:

    How to parse the data..I mean in these example without parsing POST and GET the data how it is possible ?I am new to iPhone….how to parse the data ?

  5. khalid on January 29, 2013 at 4:04 am said:

    Clear instructions and clean code. Thanky you :)

  6. Cheers!!

    Great!! Article Mat..

    Tons of Thank you from INDIA :)

  7. Fady Kamal on May 14, 2013 at 8:20 pm said:

    I have a question, what if i want to interface a web application wil login/register. so when i login in IOS i should be logged in in the web so for any further requests what do i need to send, e.g do i need to send my following requests with the cookie i got from the login response the first time, or should it be handled already and the web side will always know it’s me making requests ?

    • If I understand it correctly, you are trying to log in to a web site from your application. If so, you need to keep track of what you are sending and receiving every time you make a request to a web site that you already logged in. Most web sites attach a cookie to your browser once you login and they check your cookie every time you make requests if your cookie is eligible. In this case, once you perform a login operation from your iOS application you need to store your cookie somewhere to be used in the future requests to web server.

  8. Hi Kemal,
    It’s a great tutorial.You explain so well about the get and post method.Thank u for clearing my concept….

  9. gopinath on January 22, 2014 at 2:34 pm said:

    hi, your tutorial is simple and neat. I am getting the concept of get and post, but i couldnt able to get the use of synchronous method, can u clear me the use?

  10. Faisal Ahamed on February 25, 2014 at 12:32 pm said:

    Hello sir,
    I am new to ios.i want to make log in and sing up page. can i make it by the use of this tutorial ?

  11. Pingback: Fetching data with GET,POST methods by using NSURLConnection[forwarded] | zhangbaoma

  12. Rajeev on June 3, 2014 at 7:14 am said:

    Here i need post the data from textfields using http post. help me plz

  13. Rajeev on June 4, 2014 at 4:16 am said:

    With this tutorial i can directly pass the strings to web server. but here i need pass the data from textfields help me to fix it

  14. Pratik on July 14, 2014 at 1:29 pm said:

    Hi Kamal,

    Its nice tutorial and helped me well, thank you.

    i am working on project and its required to get the data from web service but the thing is i really never done it. mostly i parse the data using POST method but this time i have to use PUT method to parse Json data. can you explain me bit of it pls.

    Thanks,
    Pratik

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Post Navigation