0

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?

Community
  • 1
  • 1
Faiz Mokhtar
  • 938
  • 1
  • 10
  • 24
  • That doesn't appear to be HTML. Did you mean that server returns a response with Content-Type text/html? – Jon Shier Sep 30 '14 at 14:54
  • The Content-Type returned by the server is a lie. It is a defect on the server end. If possible work with the web service provider to get them to fix this defect. If you can't get this defect fixed, then you should be able to treat the response as XML. **Warning**: blindly treating the response as XML could be fragile because of the server defect. Be careful with the data. – Jeffery Thomas Sep 30 '14 at 14:58
  • @jshier Okay, that confirms it, since that is no way an html tag. And yes, the server returns Content-Type text/html. – Faiz Mokhtar Oct 01 '14 at 01:11
  • You could use an `AFXMLParserResponseSerializer` and set it's `acceptableContentTypes` to an `NSSet` including `text/html`, `application/xml` and `text/xml`. See [AFHTTPResponseSerializer doc](http://cocoadocs.org/docsets/AFNetworking/2.0.0/Classes/AFHTTPResponseSerializer.html#//api/name/acceptableContentTypes) – fluidsonic Oct 01 '14 at 02:41

2 Answers2

0

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.

Faiz Mokhtar
  • 938
  • 1
  • 10
  • 24
0

Please try the following code:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager new];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html", nil];
vasylus
  • 13
  • 6