user3773060 user3773060 - 1 month ago 9
Objective-C Question

How to test if Json response includes error or proper json

Explanation: Throughout app, we use a web request method located in AppDelegate.m to fetch data from server. I use a token in all these requests. Sometimes the response from server is the json : {error = "token_not_provided"} or {error = "token_expired"}. I need a way to test if the json includes these errors or the proper json data. If the data sent back is either of these errors, we need to go back to login screen to get a new token upon login. Right now, I have no way to detect these errors in the request method so if they occur, the app will forever crash because there is no way to take you back to login. Here is the request method in App Delegate:

-(void)makeRequest:(NSString*)urlString method:(NSString*)method params:(NSMutableDictionary*)params onComplete:(RequestBlock)callback {

// create the url
NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", BASE_URL, urlString]];
NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:url];


KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];

NSString *token = [keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];

if(!token){

token = @"NO_TOKEN";



}


// set the method (GET/POST/PUT/UPDATE/DELETE)
[request setHTTPMethod:method];
[request addValue:[@"Bearer " stringByAppendingString:token] forHTTPHeaderField:@"Authorization"];


// if we have params pull out the key/value and add to header
if(params != nil) {
NSMutableString * body = [[NSMutableString alloc] init];
for (NSString * key in params.allKeys) {
NSString * value = [params objectForKey:key];
[body appendFormat:@"%@=%@&", key, value];
}
[request setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];
}

// submit the request
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data, NSError *connectionError) {

// do we have data?
if(data && data.length > 0) {

NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];

// if we have a block lets pass it
if(callback) {
callback(json);


}

HERE IS WHERE I WANT TO TEST IF WE HAVE ERROR JSON or PROPER JSON


}


}];


}

Answer Source

If you can modify the interface on your server you could send a bool to identify if the request was successful. Something like "success" = 1 or 0.

To check on the error-message is dangerous, if the message changes your app will crash. If you want to do it anyway you need to check if the key "error" exists and then what it contains.

// Check if key is available.
if ([json.keys containsObject:@"error"]) {
    if ([json[@"error"] isEqualToString:@"token_not_privided"] || [json[@"error"] isEqualToString:@"token_expired"]) {
        // Token is invalid
    } else {
        // Something different went wrong.
    }
}
// Nothing is wrong, lets inform the caller. 
else {
    if (callback) {
        callback(json);
    }
}

You should check on the json and not on the data.