Getting xml data from a web service (Part 1 – AFNetworking 101)

Lets say that we are in a situation that an external source offer as web service a useful xml feed.

Our iOS app can use this feed in order to present various data or calculate new values based on that data.

I want to get the xml data, usually we have to visit a specific URL that contains the name of the service and parameters like

http://services.test.com/<name of the web service>?<parameters>

Hmm…starting to sound familiar to your situation? Great!

The process can be splitter in two sections:

1. The network communication with the web service

2. The parsing of the fetched data of the 1st step

In iOS we are lucky because for these tasks we have two powerful libraries. For the network communication we have the AFNetworking and and for the parsing the RaptureXML.

Lets get started with AFNetworking.

Unlimited features, high ratings and good reviews. I haven’t dug it deep but let me show the simple first steps to get the xml date from a web service.

First we have to install it in our Xcode project.  Following the official guide

1. Download it from GitHub AFNetworking Repository

2. We add the AFNetworking required files to our project.  Specifically, in Project Navigator, we right click the our project name in the left column, we select “Add Files…” from the pop menu and we choose the AFNetworking folder to add to our project.

In the “add files…” window be cautious to have the following options checked:

Destination: Copy items into destination group’s folder [Checked], Folders: Create Groups for any added folders [Top Item Selected] and Add To Targets:(Project Name) [All Targets Selected]

At the point it’s supposed that the project can be built without errors. Try it…

If it is true you are in the correct direction.  In addition you will get two annoying warnings. No problem.

AFNetworking has optional dependencies of the SystemConfiguration and CoreServices / MobileCoreServices frameworks.

To include these frameworks in your project, and silence these warnings, do the following two things:

  1. Go to the “Build Phases” tab for your project target
  2. Under “Link Binary with Libraries”, click the + button and add SystemConfiguration as well as MobileCoreServices on iOS.
  3. In your precompiled headers file, Prefix.pch, add the following lines under#import <Foundation/Foundation.h>:
    #import <SystemConfiguration/SystemConfiguration.h>
    #import <MobileCoreServices/MobileCoreServices.h>

Now if you built the project everything will be working fine.

As the official documentation refer, if our app talk to a server backend, we’ll love AFHTTPClient.

The AFHTTPClient has everything we need for talking to the web API. We can store the base URL and request relative paths to that, we can store a common set of header for things like authentication and automatically figure out how to parse our server response, so JSON requests give us JSON objects, XML requests give us parser objects, etc.

The few theoretical steps that we have follow are:

– Create a subclass for each service endpoint you hit.

-In HTTP client subclasses, create a class method that returns a shared singleton instance. This way, you can configure and use a single client to use throughout the entire app.

In practise we create a new objective-C class, e.g. AFmyAPIClient.h and AFmyAPIClient.m subclasses of AFHTTPClient.

//  AFmyAPIClient.h

#import &amp;quot;AFmyAPIClient.h&amp;quot;

@interface AFepricesClient : AFHTTPClient
+ (AFepricesClient *)sharedClient;
@end

and

//  AFmyAPIClient.h

#import &amp;quot;AFmyAPIClient.h&amp;quot;

static NSString * const kAFApiBaseURLString = @&amp;quot;http://services.testwebservice.gr/&amp;quot;;

@implementation AFmyAPIClient

+ (AFmyAPIClient *)sharedClient
{
static AFmyAPIClient *_sharedClient = nil;
static dispatch_once_t onceToken;

dispatch_once(&amp;amp;onceToken, ^{
_sharedClient = [[AFmyAPIClient alloc] initWithBaseURL:[NSURL URLWithString:kAFApiBaseURLString]];
});

return _sharedClient;
}

- (id)initWithBaseURL:(NSURL *)url
{
self = [super initWithBaseURL:url];
if (!self) {
return nil;
}

[self registerHTTPOperationClass:[AFHTTPRequestOperation class]];
// Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1

return self;
}
@end

Then in the viewDidLoad method in your view controller add

#import &amp;quot;AFmyAPIClient.h&amp;quot;
...

- (void)viewDidLoad
{
 [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a nib.

 AFmyAPIClient *myClient = [AFmyAPIClient sharedClient];

 [myClient getPath:@&amp;quot;getCategories?ui=123456&amp;quot; //it's an example path
 parameters:nil
 success:^(AFHTTPRequestOperation *operation, id responseObject) {

 NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
 NSLog(@&amp;quot;%@&amp;quot;, responseString);
 }
 failure:^(AFHTTPRequestOperation *operation, NSError *error) {
 NSLog(@&amp;quot;There was an error logging into Reader - %@&amp;quot;, [error localizedDescription]);
 }];

}

If you build and run it… you will get raw xml output in you terminal like this (consider that our xml document is in Greek so we need utf8 encoding for proper presentation of the text)

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;categorylist&gt;&lt;category&gt;&lt;categoryid&gt;5&lt;/categoryid&gt;&lt;name&gt;ΡΥΖΙ ΜΑΚΡΟΣΠΕΡΜΟ (ΤΥΠΟΥ ΚΑΡΟΛΙΝΑ)&lt;/name&gt;&lt;/category&gt;&lt;category&gt;&lt;categoryid&gt;6&lt;/categoryid&gt;&lt;name&gt;ΡΥΖΙ ΜΑΚΡΟΣΠΕΡΜΟ (ΤΥΠΟΥ ΜΠΑΡΜΠΑ - ΜΠΕΝ)&lt;/name&gt;&lt;/category&gt;&lt;category&gt;&lt;categoryid&gt;7&lt;/categoryid&gt;&lt;name&gt;ΡΥΖΙ ΣΤΡΟΓΓΥΛΟΣΠΕΡΜΟ (ΤΥΠΟΥ ΓΛΑΣΕ)&lt;/name&gt;&lt;/category&gt;.....&lt;/categorylist&gt;

of the original xml of this form:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;categorylist&gt;
      &lt;category&gt;
         &lt;categoryid&gt;5&lt;/categoryidt&gt;
         &lt;name&gt;ΡΥΖΙ ΜΑΚΡΟΣΠΕΡΜΟ (ΤΥΠΟΥ ΚΑΡΟΛΙΝΑ)&lt;/name&gt;
      &lt;/category&gt;
      &lt;category&gt;
         &lt;categoryid&gt;6&lt;/categoryid&gt;
         &lt;name&gt;ΡΥΖΙ ΜΑΚΡΟΣΠΕΡΜΟ (ΤΥΠΟΥ ΜΠΑΡΜΠΑ - ΜΠΕΝ)&lt;/name&gt;
      &lt;/category&gt;
      &lt;category&gt; 
         &lt;categoryid&gt;7&lt;/categoryid&gt;
         &lt;name&gt;ΡΥΖΙ ΣΤΡΟΓΓΥΛΟΣΠΕΡΜΟ (ΤΥΠΟΥ ΓΛΑΣΕ)&lt;/name&gt;
      &lt;/category&gt;
.......
&lt;/categorylist&gt;

2 thoughts on “Getting xml data from a web service (Part 1 – AFNetworking 101)

Leave a Reply

Your email address will not be published. Required fields are marked *