Search code examples
iosobjective-cjsonafnetworkingafnetworking-2

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?


Solution

  • 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.