A common need of mobile applications is to communicate with a central web server. Here is how I approach it using the PHP framework CodeIgniter server-side and iOS on the device-side. Our goal is to pull an array of beer names into our iPhone / iPad simulator asynchronously.
Prerequisites
- Local PHP web server.
- Download and configure a CodeIgniter application to run on your local web server.
- XCode iOS app — If you don’t have one, try downloading Ray Wenderlich’s “simple iPhone app”.
- Download and import the ASIHTTPRequest library into your Xcode solution.
CodeIgniter
First, we’ll look at how to set up the web server api endpoint. The basic steps I’m going to implement are:
- Build a new controller in the app/controllers folder
- Add our JSON view file to your app/views folder
Controller (i.e. api.php)
class Api extends CI_Controller { public function listBeers() { // Array of beers // This typically would be a call to your Model class to return a collection of objects $beers = array( 'New Belgium Ranger IPA', 'Odell Brewing St. Lupulin', 'Upslope Pale Ale', 'Ska Brewing Modus Hoperandi', 'Great Divide Titan IPA' ); // Build our view's data object $data = array('response' => $beers); // Load the JSON view $this->load->view('json', $data); } }
The “listBeers” function above simply builds an array of beers and send them to the JSON view for rendering. A typical MVC-style application would usually pull a list of objects from a model and return those, but this refined example should do for our purposes.
JSON View (i.e. json.php)
// RFC4627-compliant header header('Content-type: application/json'); // Encode data if(isset($response)) { echo json_encode($response); } else echo json_encode(array('error' => true));
The above code encodes PHP arrays and objects into JSON and outputs them in the response.
Test the API
After you add both the controller code and the new view file, try testing your new action method. You should see the following JSON-encoded array:
[“New Belgium Ranger IPA”,”Odell Brewing St. Lupulin”,”Upslope Pale Ale”,”Ska Brewing Modus Hoperandi”,”Great Divide Titan IPA”]
iOS
On to our iOS code, here’s what we plan on doing:
- Build a new Objective-C Class (subclass of NSObject) called “APIService”.
- Call the APIService static method “requestBeerList” from a view controller.
APIService.h
#import@interface APIService : NSObject // our asynchronous api service method +(void)requestBeerList; @end
APIService.m
#import "APIService.h" #import "ASIHTTPRequest.h" #import "JSONKit.h" @implementation APIService // Build an asynchronous request and completion blocks +(void)requestBeerList { NSURL* URL = [NSURL URLWithString:@"http://yourlocalhostpath/api/listbeers"]; __weak ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:URL]; [request setTimeOutSeconds:20]; // Ah, success, parse the returned JSON data into a NSDictionary [request setCompletionBlock:^{ NSData *data = [request responseData]; NSDictionary *serializedData = [data objectFromJSONData]; NSLog(@"Data returned: %@", serializedData); }]; // Oops, failed, let's see why [request setFailedBlock:^{ NSError *error = [request error]; NSLog(@"Error downloading beers: %@", error.localizedDescription); }]; [request startAsynchronous]; } @end
The “requestBeerList” method will build an asynchronous HTTP request and also handle both successful and failed responses. Normally, I would persist the returned information with CoreData and let the main thread know that the call completed via NSNotificationCenter.
Wire the service call to your view controller
In one of your view controller’s “ViewDidLoad” method try calling our service with the following code and also don’t forget to add an import statement at the top of your file for APIService.h:
[APIService requestBeerList];
Build and simulate your iOS app
Alright, try building and running the test in your simulator. Your console should output the serialized JSON beer list once you trigger the API call.
Please let me know if you have any questions, especially if you’re having compiling issues.