How to Write an iOS App That Uses a Web Service

A tutorial on how to write an iOS App that uses a web service. Comes with a companion tutorial showing you how to make the web service itself! By Ray Wenderlich.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 3 of this article. Click here to view the first page.

Communicating with the Web Service

If you’ve grabbed the starter project and skipped ahead, here’s where you should pick back up! Otherwise, good progress so far DIYer! :]

To redeem the promo code, we need to to send a POST to our web service’s with three parameters: the app id, the code to redeem, and the device ID.

The good news is sending a POST is extremely easy with ASIHTTPRequest. You simply:

  • Create a new instance of ASIFormDataRequest and specify the URL
  • Use the setPostValue method to specify each parameter
  • Set the view controller as the delegate of the request, and then call startAsynchronous to start the request in the background
  • When it’s done, either requestFinished or requestFailed will be called on the view controller
  • requestFinished will be called even if the web server responds with an error code. So there you need to check for success or failure…
  • And if success, parse the response string as JSON!

Let’s see what this looks like. First add the following imports to the top of the file:

#import "ASIHTTPRequest.h"
#import "ASIFormDataRequest.h"
#import "JSON.h"

Then replace textFieldShouldReturn with the following:

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    NSLog(@"Want to redeem: %@", textField.text);
    
    // Get device unique ID
    UIDevice *device = [UIDevice currentDevice];
    NSString *uniqueIdentifier = [device uniqueIdentifier];
    
    // Start request
    NSString *code = textField.text;
    NSURL *url = [NSURL URLWithString:@"http://www.wildfables.com/promos/"];
    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
    [request setPostValue:@"1" forKey:@"rw_app_id"];
    [request setPostValue:code forKey:@"code"];
    [request setPostValue:uniqueIdentifier forKey:@"device_id"];
    [request setDelegate:self];
    [request startAsynchronous];
        
    // Hide keyword
    [textField resignFirstResponder];

    // Clear text field
    textView.text = @"";    

    return TRUE;
}

If you’ve set up your own web service following the previous tutorial, you should replace the URL with wherever you put your web service.

As you can see – very simple, following the steps outlined above. Finally, implement the requestFinished and requestFailed callbacks to log out the results:

- (void)requestFinished:(ASIHTTPRequest *)request
{    
    
    if (request.responseStatusCode == 400) {
        textView.text = @"Invalid code";        
    } else if (request.responseStatusCode == 403) {
        textView.text = @"Code already used";
    } else if (request.responseStatusCode == 200) {
        NSString *responseString = [request responseString];
        NSDictionary *responseDict = [responseString JSONValue];
        NSString *unlockCode = [responseDict objectForKey:@"unlock_code"];
        
        if ([unlockCode compare:@"com.razeware.test.unlock.cake"] == NSOrderedSame) {
            textView.text = @"The cake is a lie!";
        } else {        
            textView.text = [NSString stringWithFormat:@"Received unexpected unlock code: %@", unlockCode];
        }
        
    } else {
        textView.text = @"Unexpected error";
    }
    
}

- (void)requestFailed:(ASIHTTPRequest *)request
{    
    NSError *error = [request error];
    textView.text = error.localizedDescription;
}

This simply checks for the error codes that we expect from our web service, and prints a message for each. Or if it’s succcessful, parses the JSON with the JSON framework, and checks the unlock code. Here is where you could grant the user with whatever special content you might want to give them in your app.

Compile and run your project, and you should see something like the following:

The cake is a lie!

Adding a Progress HUD

The app works so far, but when you’re running a task in the background like this it’s often nice to let the user know what’s going on. This is nice and easy with MBProgressHUD, so let’s quickly add it in:

// Add at the top of the file
#import "MBProgressHUD.h"

// Add right before return TRUE in textFieldShouldReturn
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = @"Redeeming code...";

// Add at start of requestFinished AND requestFailed
[MBProgressHUD hideHUDForView:self.view animated:YES];

Compile and run your code, and this time a nice progress indicator should appear while the request is running!

Promo Code System: My Experience

Now as promised, I’d like to share my experience using this promo code system in Wild Fables with you guys!

I set up two codes for Wild Fables – one to unlock a single fable (of the user’s choice), and one to unlock all fables. I set up the first one so I could give out codes to friends & family to give them a little extra taste of Wild Fables, and I set up the second one so I’d have a way to give out full access to Wild Fables to professional app reviewers.

One of my favorite things about this system is it allows for unlimited codes. Which was great as 100 people used a code I gave out on Twitter alone (thanks again for checking it out and all the RTs guys, you rule!)!

I also put some codes in some threads on some various iOS forums, our mailing list for Razeware, our Facebook pages, etc. I made a separate code for each place I gave out the code, which is nice because it let me track where people actually cared about the post & used codes, and where people were more like the picture earlier in this tutorial ;]

People redeemed the codes most often on Twitter or the Cocos2D forums (which makes sense, as my friends such as yourself hang out there), then on the Razeware mailing list (which also makes sense, since if people subscribe to that they must be interested in our products). Forum-wise, Reddit came up on top, then the iPad Forums, MobileRead, MacRumors, and TouchArcade were the best in that order.

Another amusing thing was sometimes I’d get emails from “reviewers” asking for a promo code to redeem my app, so of course I’d send them a custom code. But these “reviewers” would also include a pitch to try to get me to advertise on my site. Looking at the redemption table, I can see that several of them didn’t even bother to redeem the code, so I guess their real reason to email me was to get ad revenue, so beware! :]

As far as drawbacks go, as some people noticed the “unlock” is implemented basically by saving data to the file system, so it doesn’t work across all devices like in-app purchases do. You can implement this by creating a login system or such, but that was overkill for what I wanted to do.

So that’s it for my experience! Let me know if you have any further questions.

Contributors

Over 300 content creators. Join our team.