If you are developing an iPhone or iPad application, which communicates to a web server, you are most probably going to use JSON to send data back and forth.
In this short tutorial I’m going to show you step by step how to use couple of modern day iOS libraries to fetch JSON from a web service and use it in your app.
Disclaimer: This post teaches you how to work with JSON the right way, for the quick and dirty way – keep googling
It’s easy – let’s get started!
Setup the Xcode project
Create a new iOS Xcode project and use the master-detail template for it.
Name the new project “JSON_HelloWorld” and make sure you are using Storyboards and Automatic Reference Counting (as shown on the image below).
Now head to GitHub as you are going to download couple of very handy libraries to help you create your app.
First open up: https://github.com/icanzilb/HUD and press the “ZIP” button to download the library. Unarchive the .zip file and copy the “HUD” subfolder into your XCode project.
When you copy the files make sure to check the “Copy items into …” checkbox.
The HUD library makes using MBProgressHUD a bit easier, and you will use it show loading progress message in your app, while fetching data from the web.
Then open up: https://github.com/icanzilb/JSONModel and press the “ZIP” button to download the library. JSONModel will help you download your JSON data asynchroniously, validate and parse the JSON and make using the data much safer and easier.
Unarchive the .zip file and copy the “JSONModel” sub-folder into your XCode project.
When you copy the files make sure to check the “Copy items into …” checkbox.
You’re all set – let’s start coding!
The Kiva JSON web service
In this tutorial you are going to fetch and read a JSON feed from the Kiva.org web-site. Kiva.org helps entrepreneurs from developing countries get crowd-sourced loans. The JSON you are going to fetch shows the latest created in the system loans.
You can have a look at the row feed here: http://api.kivaws.org/v1/loans/search.json?status=fundraising
Tip: If you are serious about developing a web-powered app I highly recommend using the Charles Web Proxy. It’s a software which tracks the web traffic on your mac and helps you debug everything going through the network.
The first thing you need to do when you want to read JSON is to inspect its structure, let have a look at the Kiva feed:
As you see there are two top level keys “paging” (which you won’t be interested in right now) and “loans” – a list of loan objects. Each loan object has keys called “id“, “name“, “use” and so forth, containing information about the particular loan.
Let’s see how to fetch the “name“, “use“, “country” and “country_code” values and use them in your app.
Writing JSON data models
First you need to create your data models to load from the JSON feed.
Create a new Objective-C File and name the new class “LoanModel” – make it inherit “JSONModel”. Open up “LoanModel.h” and add properties to match the JSON values coming from the Kiva API:
@property (strong, nonatomic) NSString* name;@property (strong, nonatomic) NSString* status;@property (strong, nonatomic) NSString* use;
Thanks to JSONModel, you don’t need to do anything besides just declaring the properties to read the values from the JSON feed.
Awesome! Let’s go on with defining a LocationModel to read the location of the person applying for the particular model.
Now you are going to write a data model class to read this part of the loan:
You will want to read only the “country” and “country_code” keys and ignore the rest. Create a new Objective-C file and call the new class “LocationModel” and make it again inherit “JSONModel”. Add the following properties in “LocationModel.h“:
@property (strong, nonatomic) NSString* country_code;@property (strong, nonatomic) NSString* country;
Again, this is all the code you need to create the fully working location model. Now let’s add the location model as a sub-model to the loan model.
Since “location” is a key of the “loan” JSON object, you just need to declare a new property in the LoanModel class and everything will work out pretty much automatically.
Open up “LoanModel.h” and at the top add this include:
#import "LocationModel.h"
Then at the bottom of your interface declaration add a new property:
@property (strong, nonatomic) LocationModel* location;
Now the LoanModel will know that the “location” key in the JSON feed is actually a sub-model and will make an instance of LocationModel. Cool!
Almost done with defining the model map! You only need a top-model – the one that matches the root of the Kiva JSON feed. Remember there were two keys “paging” and “loans”? You only gonna need the latter – you need a model with a single property. Let’s do it!
Create a new Objective-C class and call it “KivaFeed“, make it inherit “JSONModel”. Open up “KivaFeed.h” and define a property to match the “loans” key, which is a list of loan objects; also import “LoanModel.h” – your header should look like this:
#import "JSONModel.h"#import "LoanModel.h"@interface KivaFeed : JSONModel@property (strong, nonatomic) NSArray<LoanModel>* loans;@end
By adding the “LoanModel” protocol to a NSArray property, you tell the model that this property contains a list of objects of the class with the same name – “LoanModel”.
At this point you have an error, because the LoanModel protocol is not defined. Let’s add it to wrap up with model creation. Open up “LoanModel.h” and just above the @interface line, add the new protocol:
@protocol LoanModel @end
OK, now you pretty much know how to create data models for any JSON feed. Let’s look into how to actually load the JSON from web and use the models in your app!
Fetch JSON from the web
If you run your project right now, nothing much will happen. Let’s change that! First you are going to load the JSON data from Kiva’s web site.
Open up “MasterViewController.m” and delete ALL code inside the file (too much boilerplate for what you’re going to do). Now paste in just the bare bones for a table view controller:
#import "MasterViewController.h"@interface MasterViewController () {}@end@implementation MasterViewController@end
Phew!
Now at the top of the file, just under the import statements include the JSONModel umbrella header and your Kiva feed model class (also the HUD helper class, which you gonna use in a second):
#import "JSONModelLib.h"#import "KivaFeed.h"#import "HUD.h"
Alright, now inside the @interface declaration (just between the curly brackets) add a new ivar to your class:
KivaFeed* _feed;
Now to add the method to fetch the data from Kiva.org, inside your @implementation add a viewWillAppear: method:
-(void)viewDidAppear:(BOOL)animated{ //show loader view [HUD showUIBlockingIndicatorWithText:@"Fetching JSON"]; //fetch the feed _feed = [[KivaFeed alloc] initFromURLWithString:@"http://api.kivaws.org/v1/loans/search.json?status=fundraising" completion:^(JSONModel *model, JSONModelError *err) { //hide the loader view [HUD hideUIBlockingIndicator]; //json fetched NSLog(@"loans: %@", _feed.loans); }];}
You are using the custom asynchronous init method of JSONModel “initFromURLWithString:completion:“. The initialiser method fetches the JSON at the provided URL, and when done, updates the model object and invokes the provided block.
The two calls to the HUD class show and hide a spinner on the screen – so that the user knows that there’s some activity going on in the background.
As you see in the completion block there’s an NSLog statement, which prints out the loans property of the feed model. Let’s see what’s going to happen.
Run the project right now!
First you will notice the modal spinner popping up while the Simulator fetches the JSON from the web:
Then have a look the Xcode’s output console to check if your NSLog statement printed anything. If everything went well you should see something like this:
Sweet, the loan models are loaded with data and all that’s left is to write the standard UITableViewDelegate methods to show the info on the screen!
First just below your NSLog(…) line force a reload of the on screen table view:
NSLog(@"loans: %@", _feed.loans);//reload the table view[self.tableView reloadData];
And now add these methods, that fetch data from _feed.loans in the standard table delegate template:
#pragma mark - table methods-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1;}-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return _feed.loans.count;}-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ LoanModel* loan = _feed.loans[indexPath.row]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; cell.textLabel.text = [NSString stringWithFormat:@"%@ from %@", loan.name, loan.location.country ]; return cell;}
You can run the project again and this time you should see the table showing the latest loans from Kiva.org!
An alternative way
Here’s the place for a very short discussion – if you are working on your own app, you won’t necessarily want to match with model classes all the structure of your JSON feed as I showed you in this post.
You can be more flexible by fetching the JSON feed separately from initializing your data model. Use the built-in JSONHTTPClient class to do your networking and then init your model when the data is downloaded from the web. Like so:
[JSONHTTPClient getJSONFromURLWithString:@"url..." completion:^(NSDictionary *json, JSONModelError *err) { NSError* error = nil; _feed = [[KivaFeed alloc] initWithDictionary:json error:&error]; [self.tableView reloadData]; }];
Great! And that’s a wrap!
You’ve learned how to inspect JSON feeds (give a try to Charles, it’s the ultimate tool for the purpose), you’ve learned how to use JSONModel to create rapidly JSON data model classes, and how to initialise a JSON model straight from the web.
More about JSONModel you can read here: www.jsonmodel.com or at GitHub (don’t forget to star the repository): https://github.com/icanzilb/JSONModel
If you are eager to play more with the project you can:
- Download the complete JSON_HelloWorld project from this tutorial from Github: https://github.com/JSONModel/KivaFeedDemo
- Add a tableView:didSelectRowAtIndexPath: method to MasterViewController and show more details about the loan
- Extend the data models to fetch additional details about each loan
Don’t forget to drop me a line or leave a comment!
Cheers Marin!
·
Source : touch-code-magazine[dot]com
0 comments:
Post a Comment