Sunday, February 1, 2015

iOS Tutorial - Part 28 - HttpRequest POST, GET (NSURLConnection) III

HttpRequest POST, GET (NSURLConnection) III


Video Description 
In first and second session of Http request we have learned how to implement NSURLConnection delegate methods and also create Http GET and POST request. In the last session we will learn how to parse JSON format and show it in a tableView.

JSON content Type

If you copy paste the response from our Guardian News into this JSON formatter, and press Process button, you will see the JSON format in better view. If you collapse the first (-) buttons you will see it's a curly brace with something inside. This curly brace means the type of the response is dictionary. You can also say this fact by "key", "value" content. If you expand the response by taping on (+) button, and collapse the content of "response" by tapping on (-) you would see something like this
{  
   "response":{  }
}
It shows that "response" is a key and {} is it's value. Now if you expand the response value content and collapse the value of the "results", you would see something like this:
{  
   "response":{  
      "status":"ok",
      "userTier":"developer",
      "total":1732677,
      "startIndex":1,
      "pageSize":10,
      "currentPage":1,
      "pages":173268,
      "orderBy":"newest",
      "results":[  ]
   }
} 
If you notice the content of "results" is inside of Bracket []. It means that the content type of "results" is Array. The way we read JSON is based on the content type. If it's dictionary we should define NSDictionary but if the type is array we should define NSArray.

Read JSON format step by step

Since the whole response is dictionary we should define an NSDictionary and serialize the received data to make it human readable. We also handle any potential error with NSError.
- (void)getReceivedData:(NSMutableData *)data sender:(RestAPI *)sender
{
    NSError *error = nil;
    NSDictionary *receivedData =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
}
Now in order to get the value of "response" we should define another dictionary like bellow and we initializing it with the key called "response":
- (void)getReceivedData:(NSMutableData *)data sender:(RestAPI *)sender
{
    NSError *error = nil;
    NSDictionary *receivedData =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
    NSDictionary *response = [[NSDictionary alloc] initWithDictionary:[receivedData objectForKey:@"response"]];
}
Then we have a "results" to parse. The type of results is array so we define an array like bellow:
    NSArray *results = [[NSArray alloc] initWithArray:[response objectForKey:@"results"]];
Now we have to iterate through the array items, we do this by for loop like bellow:
for (int i; i < results.count; i++)
    {
        NSDictionary *resultsItems = [results objectAtIndex:i];
        NSString *webTitle = [resultsItems objectForKey:@"webTitle"];
        [self.webTitles addObject:webTitle];
        NSString *sectionName = [resultsItems objectForKey:@"sectionName"];
        [self.sectionNames addObject:sectionName];
    }
Since the content of each item of array is type of dictionary, we defined resultsItems variable. Then inside of this dictionary we are looking for a key "webTitle" and "sectionName". These are the values that we are going to show it in our tableView. We store these inside of two arrays to access them later for filling our tableView.

Fill out the tableView with the fetched response

Now we just have to define a number of sections, which is 1 and then number of rows in each sections, which is equal to the number items in webTitle array. And finally we implement the important tableView delegate, which is for content of each cell.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.webTitles.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    
    cell.textLabel.text = [self.webTitles objectAtIndex:indexPath.row];
    cell.detailTextLabel.text = [self.sectionNames objectAtIndex:indexPath.row];
    
    return cell;
}

Reload tableView

The last thing we have to do is to reload the tableView to show the fetched results, it's very easy to implement and it should be in the getReceivedData method.
[self.tableView reloadData];

Download

Download this App from here

2 comments:

  1. Replies
    1. You're welcome. Thanks for your comment. If you want to make Asynchronous HttpRequest, I uploaded the session yesterday, here is the link: http://huxtek.blogspot.com/2015/02/ios-tutorial-part-29.html

      Delete