Dynamically Controlling Your Application From The Web

September 30th, 2011 Posted by: - posted under:Tutorials

Often times you find yourself in a situation where you might want to control your application remotely. You may want to enable/disable features at a certain time, push messages to all of your users, or do some cross promotion whenever you launch a new application. All of this can easily be done with a little JSON and some simple web interface coding.

 

In this tutorial, I will show you how to use ASIHTTPRequest along with JSONKIT to fetch, parse, and interpret remote JSON that will ultimately change how our application behaves. For this example, we are going to make a simple “nag” popup that will nag the user to download your latest application. When you set a remote flag to true, all users will see the popup every time they launch the application. The popup will also display a dynamic message from the web and link to a location specified in the JSON.

1. The JSON

First, let’s chat a little bit about the JSON we will be using. Here’s what it will look like:

{
    "nag": true,
    "message": "Check out Smart Lockscreen Creator!",
    "url": "http://itunes.apple.com/us/app/smart-lockscreen-creator/id419890996?mt=8"
}

The field names should be pretty self explanatory. We will use JSON kit to parse these fields into an NSDictionary.

2. The Libraries

As mentioned before, we will be using 2 libraries to get the job done.

  • ASIHTTPRequest ASIHTTPRequest is an easy to use wrapper around the CFNetwork API that makes some of the more tedious aspects of communicating with web servers easier.
  • JSONKit – A JSON Parser written in C with an Objective-C wrapper.

Make sure you download their source and follow each of their instructions for setting up your project to use them. JSONKit is pretty much drag in the source and you are good to go. ASI has a few framework dependancies that you are going to have to work out. The instructions for setting it up are here.

3. The Code – Download And Parse

You can add the code to fetch and control your application wherever you see fit, however I have added mine to the application’s delegate method.

    // 1. Fetch out to the web
    NSURL *url = [NSURL URLWithString:@"http://f.cl.ly/items/2y141v3O0G2e2Y2W3P24/alert.json"];
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
 
    // 2. Completion block
    [request setCompletionBlock:^(void) {
        NSString *responseString = [request responseString];
        // 3. parse the response
        NSDictionary *responseDict = [responseString objectFromJSONString];
 
        // 4. pull out data
        BOOL nag = [[responseDict objectForKey:@"nag"] boolValue];
        NSString *message = [responseDict objectForKey:@"message"];
        self.nagURL = [NSURL URLWithString:[responseDict objectForKey:@"url"]];
 
        // 5. If nag is true, then show the alert
        if(nag) {
            UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Message" 
                                                             message:message 
                                                            delegate:self 
                                                   cancelButtonTitle:@"Cancel" 
                                                   otherButtonTitles:@"Go",nil] autorelease];
            [alert show];
        }
    }];
    // 6. Start the request
    [request startAsynchronous];

In #1, we fetch out to the web and pull down the json string that contains our configuration settings. #2 sets the completion block for the request. If you are unfamiliar with this pattern, the request fires off in a new thread and the block gets executed AFTER the request completes. That way, we can keep all of our code in line rather than messing around with target and selector callbacks.

For #3, we are using JSONKit’s category on NSString that returns an NSDictionary representation of the JSON string. It couldn’t be easier.

Line #4 is where we extract the info from the dictionary and assign it to local variables. We set the nagURL global property here as well. The reason we must create a property for nagURL is we need to use it again in the delegate method for the UIAlertView in order to send the user to the url specified from the web.

Line #5 is where we check if nag is true and then show the alert. Make sure to set the delegate to our calling class so that we can respond accordingly.

Finally, in #6, we start the request asynchronously.

The last thing to do is implement the delegate method for the alert view. It’s pretty straight forward:

- (void) alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
    if(buttonIndex == 1) {
        [[UIApplication sharedApplication] openURL:self.nagURL];
    }
}

We simply check to see if the user pressed the “Go” button, if so, we send them to the URL specified by the nagURL property.

Conclusion

And there you have it. A very simple example of how you can control some portion of your applicaiton’s functionality based on remote web data. You could expand upon this in a number of ways including:

  • Enabling/Disabling parts of the app
  • Loading “News” in some sort of ticker
  • Daily promotions
  • Promote new apps
  • Daily content (jokes, words, inspiration, scripture, etc…)

If you have any questions or comments, you can leave the here or write me on Twitter.

The source project for this post is available here.

Happy iCoding!