Absolute Ripple
  • Absolute Ripple
  • Contact

Using AFNetworking

28/1/2013

2 Comments

 
In the past I have been using ASIHTTPRequest networking library for my apps. It was simple to use which is a good thing for someone who was new to iOS programming. I only needed it for simple GET/POST requests, returning the occasional JSON. A few simple example codes that I found at that time also make picking up ASIHTTPRequest nice and easy. Unfortunately, I soon I realized that the developer is no longer updating the library. I resisted changing to another networking library for a long while, because I don't feel like learning another library and because there don't seen to be much simple example codes around. Codes that were available (or at least those that I can find) are either too brief or dealt with things I don't need, and the codes also look rather complex when compared to those in the ASIHTTPRequest library. In short, it seems complicated and takes a lot of time to learn - and I don't have the time.

Recently, I have found time to look into AFNetworking a bit more and it is also time to change to another networking library as it would be most unwise to keep using a library that has ceased to be developed since mid 2011. ASIHTTPRequest still seems to work fine for the occasional, light networking uses that I need it for.

AFNetworking turns out to be much simpler than I had initially expected. It is also much more powerful, flexible and maintainable going forward. The main reason for this is that it is built on top of NSURLConnection and NSOperation, and it uses blocks which is also the reason that it looks much more complex when I first looked at it (at which time my understanding of blocks is next to nil and hardly know anything about NSURLConnection or NSOperation).

AFNetworking has good documentation, but there there seems very little example around. And I prefer to learn by going through an example, especially short codes that illustrate the basic principle or approach. In particular, I was puzzled by how to make a simple HTTP GET or POST request using AFNetworking. Here are some simple codes snippet and notes.

Set Up your Project to Use AFNetworking

The Getting Started guide on AFNetworking github page is most useful for this purpose.

HTTP GET Request

You need to use the AFHTTPClient and AFHTTPRequestOperation, so import them as follows :

#import "AFHTTPClient.h"
#import "AFHTTPRequestOperation.h"


The codes:
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://yourServerAddress.com/"]];
    [httpClient setParameterEncoding:AFFormURLParameterEncoding];
    NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET"
                                                            path:@"
http://yourServerAddress.com/example?name=foo"
                                                      parameters:nil];

[httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
    AFHTTPRequestOperation *operation = [httpClient HTTPRequestOperationWithRequest:request
                                        success:^(AFHTTPRequestOperation *operation, id responseObject) {
                                           
//-- This block gets invoked when the operation is successful
                                            //-- Here it simply print out the responseObject as text in the log
                                            NSLog(@"Response: %@", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
                                        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                                            //-- This block gets invoked when the operation fails
                                            NSLog(@"Error: %@", error.localizedDescription);
                                        }];

//-- The following codes allow you to track the download progress (if required)
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
        //-- This block gets invoked periodically as the download progress
        NSLog(@"bytesRead: %i; totalBytesRead: %lld; totalexpected: %lld", bytesRead, totalBytesRead, totalBytesExpectedToRead);
    }];

//-- end of the download progress tracking code

[httpClient enqueueHTTPRequestOperation:operation];


Alternative codes:
(using the getPath: method in AFHTTPClient)
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://yourServerAddress.com/"]];
NSString *pathStr = @"/example?name=foo";
[httpClient getPath:pathStr parameters:paramaters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSString *responseStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        NSLog(@"Request Successful, response '%@'", responseStr);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error.localizedDescription);
    }];

The alternative is shorter, but the first version is more customisable. In particular, it allows you to get a reference to the relevant AFHTTPRequestOperation.

HTTP POST Request

Likewise, you need to use the AFHTTPClient and AFHTTPRequestOperation, so import them as noted above.

The codes:
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://yourServerAddress.com/"]];
//-- the content of the POST request is passed in as an NSDictionary
//-- in this example, there are two keys with an object each
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:
                                  
object1, @"KEY_NAME_1",
                                  
object2, @"KEY_NAME_2",
                                   nil];

[httpClient postPath:@"/postExample/" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSString *responseStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        NSLog(@"Request Successful, response '%@'", responseStr);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error.localizedDescription);
    }];

Subclassing AFHTTPClient
The above codes use an instance of the AFHTTPClient class. The documentation for AFNetworking, however, suggests that we should sub-class it for each website or web application that the app communicates with. 

2 Comments

Apple In-App Purchase: Creating App Store Hosted Content

2/1/2013

2 Comments

 
Following the introduction of iOS 6 it is possible to host the content of your in-app purchase on Apple's server, rather than having to host the contents on your own server under previous iOS versions. This makes it simpler (and perhaps less expensive) to implement in-app purchase for your app as you no longer need to develop and maintain your own server to host the purchased contents.
The steps in filling out the online forms in iTunes Connect when setting up each product that you want to sell via in-app purchase appears simple enough until you come to the point where you need to upload the content to the Apple server. How do you upload the content? What format should the content be in? There is a scarcity of documentation or guides around regarding this. Some guides simply said that your need to put all your contents in a 'package' and that is what you upload to Apple. This raises another question: what is this 'package' thing? How do you create it?
After putting together information from many sources, here are the steps to create the Apple App Store hosted content and also how to upload the same to Apple.
What is the Package?
The package is simply a structured folder, which contains a ContentInfo.plist in the root level and a sub-folder called 'Contents'. The ContentInfo.plist contains two keys:
  • ContentVersion - This is the version number of the content.
  • IAPProductionIdentifier - This is the product identifier of the product with which the content is associated. i.e. the identifier you defined in iTunes Connect.
The Contents folder contains the actual files associated with the in-app purchase. e.g. in an app that sell music score, it would be the actual music score file or files. Note that the content must not contain executable codes, otherwise the package would not be valid.
How to create the Package
Even though the package is structured folder, you cannot just create a folder on the Finder with the above contents. The best way to create the package that meets Apple's requiremetns it seems at the moment is to use Xcode. (The following steps are based on Xcode 4.6.)

Creating the Package
Step 1: Create a New Project in Xcode
File > New > Project
Select "Other" under iOS heading on the left hand panel of the template screen.
Select 'In-App Purchase Content" on the right hand side.
Then click "Next".
Picture
Step 2: Enter the info for this project
For Product Name, enter the product identifier as defined by you in iTunes Connect. The two must be the same. Fill in the Organization Name and Company identifier as you normally would. In this example, the identifier is "p02050".
Then click "Next".
Picture
Step 3: Update the ContentInfo.plist
Unfold the Supporting Files section of the project navigator panel and select the ContentInfo.plist file. Update the two keys in this file.
ContentVersion - the default version is 1.0, update this as required
IAPProductIdentifier - change this so that it matches the Product Identifier your defined in iTunes Connect.
Picture
Step 4: Add in the Actual Contents
Locate all the relevant content files on your computer in the Finder.
Drag and drop the files onto the Supporting Files section of the project navigator panel.
Complete the panel as shown below and then clicked "Finish".
Picture
Step 5: Archive the Project
Select Project > Archive from the menu.
Picture
Step 6: Validate the Package
Click the "Validate" button.
Fill in the panel that appear as you normally would when validating and submitting an app. Make sure the correct app content is selected in the In-App Purchase Content drop down menu.
Step 7: Export the Package
Click the "Distribute" button.
Select the "Export Package" radio button and click "Next".
Enter a name and Select a location on your computer to save the resulting package.
Then clicked "Save".
This step is option as you can upload the content at this point using Xcode. See below.
Picture
How to Upload the Package?
You have two options:
a. use Xcode; or
b. use Application Loader - This is a free tool provided by Apple. After you have logged in to iTunes Connect, clicked the "Managed Your Applications" link. The link to this Applciation Loader is located towards the bottom of the screen.
Using Xcode to Upload
This is same as what you normally do when submitting an app for review. That is, instead of choosing the "Export Package" option in the above panel, choose "Submit in-app purchase content". After clicking Next, put in your developer program credentials and select the correct application and product identifier, then click "Submit"



2 Comments

    Archives

    August 2013
    July 2013
    June 2013
    May 2013
    January 2013
    October 2012
    September 2012
    March 2012
    February 2012

    Categories

    All
    Apple Policy
    In App Purchase
    Ios Programming
    Our Apps

    RSS Feed

    Disclaimers

    Here are some resources that I find useful in writing iOS apps. These are not necessarily unique as they are based on various sources online.
    This is mainly to provide a source of reference to myself and my associates but if it can be of use to someone else, that is good.
    Note that information is provided here as is. Use at your own risk. There is no guarantee that it is accurate. We will update the information as time and resources permit.

    Powered by Create your own unique website with customizable templates.