Faiz Mokhtar Faiz Mokhtar - 15 days ago 9
iOS Question

Parsing Content-Type text/html with AFNetworking

I have to implement a version checker in my app. The app will check the version (which was manually set) from the server. Thing is, the server return the response in neither

JSON
or
XML
. It returns in plain
text/html
, which I'm not familiar with.

eg. If the app need to be updated, it will return response as below.

<checkversion>
<update>TRUE</update>
<status>MINOR</status>
<alert></alert>
<version>1.0.0</version>
<ituneslink>0</ituneslink>
</checkversion>


Else, it will return response as below.

<checkversion>
<update>FALSE</update>
</checkversion>


After looking at some similar SO posts such as this and this, I manage to get the response in format of
string
. Below is the snippets of my code.

- (void)slurpVersionChecker
{
NSString *versionURL = @"api";
NSDictionary *params = @{@"api_key":@"key"};

AFHTTPRequestOperationManager *requestManager = [AFHTTPRequestOperationManager manager];
[requestManager setResponseSerializer:[AFHTTPResponseSerializer serializer]];
[requestManager POST:versionURL parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *string = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(@"version: %@", string);

}failure:^(AFHTTPRequestOperation *operation, NSError *error){
NSLog(@"failed to check version: %@", error);
}];

}


Question is, how do I parse each of the responses? and is it there any way where I can parse the response through
responseObject
directly without converting it to
String
?

Answer

Okay. I already managed to solve this so I might as well post the solution here for others.

Here's what I basically do.

I use XMLReader to parse the response into NSDictionary. So, add the library to my project and import XMLReader.h in the header. Then, I only need to call the dictionaryForXMLDAta method to use it which returns:

checkversion = {
version: {
    alert =     {
        text = "";
    };
    ituneslink =     {
        text = 0;
    };
    status =     {
        text = MINOR;
    };
    text = "";
    update =     {
        text = TRUE;
    };
    version =     {
        text = "1.0.0";
    };
}

The NSDictionary return is not that pretty though. So, I had to use objectForKey a few times to retrieve the value.

[requestManager POST:versionURL parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSData * data = (NSData *)responseObject;
        NSError *error = nil;
        NSDictionary *dict = [XMLReader dictionaryForXMLData:data
                                                     options:XMLReaderOptionsProcessNamespaces
                                                       error:&error];
        NSDictionary *version = [dict objectForKey:@"checkversion"];
        update = [[version objectForKey:@"update"] objectForKey:@"text"];
        ...
    }

Bonus: I want to notify the user if there's a new update available. So, I check if the update variable is equal to TRUE and if it's TRUE, it will link the user to the app store.

if([update isEqualToString:@"TRUE"]) {
            number = [[version objectForKey:@"version"] objectForKey:@"text"];
            itunesURL = [[version objectForKey:@"ituneslink"] objectForKey:@"text"];

            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"New Version Available" message:nil delegate:self cancelButtonTitle:@"Not Now" otherButtonTitles:@"Download", nil];
            [alert show];

        }

And that's pretty much how I solved it.