Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSURLConnection getting JSON File

My iOS app is getting the code inside (ex. 101), and by that code it reads JSON file (ex. 101.json) on server and read the data inside. Everything is working good, but how to do that if there's no file (for that code) on server (now it's just showing no data if file not found) and if there's no internet connection just to get data from JSON file inside the app? Here's my code:

NSString *baseURLStr = @"http://myserverurl/";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL
                                                      URLWithString:[baseURLStr stringByAppendingFormat:@"%d/%d.json", int1, int2]]];
NSData *data = [NSURLConnection sendSynchronousRequest:request
                                     returningResponse:nil error:nil];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];  

I found out how to read the file inside the app if there's no internet connection.

if (data == nil){

    NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"FAILED" ofType:@"json"]];
    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
    self.members = json[@"data"];

}
else {

    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
    self.members = json[@"data"];

}  
like image 556
sphynx Avatar asked Dec 15 '22 02:12

sphynx


2 Answers

There are three types of issues you might want to check for:

  • Connection errors: Check to make sure the connection didn't fail; if it did fail, the data will be nil and the NSError object would be populated; typical causes would be an invalid server name in the URL, server was down, or no internet connection at all);

  • HTTP errors: If doing a HTTP request, you want to check that the web server reported success retrieving the page/resource, namely that you received HTTP status code of 200; an example of an error condition might be a 404 - not found error (see the HTTP Status Code Definitions for more complete list); and

  • Server code errors: Check to make sure the server responded with valid JSON, i.e. check to see if the response received can be parsed as JSON successfully (you want to make sure there was no problem in the server code that generated the JSON, e.g. a mistake in your server code).

Thus:

NSURLRequest *request = nil;
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request
                                     returningResponse:&response
                                                 error:&error];
if (!data) {
    NSLog(@"%s: sendSynchronousRequest error: %@", __FUNCTION__, error);
    return;
} else if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
    NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
    if (statusCode != 200) {
        NSLog(@"%s: sendSynchronousRequest status code != 200: response = %@", __FUNCTION__, response);
        return;
    }
}

NSError *parseError = nil;
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (!dictionary) {
    NSLog(@"%s: JSONObjectWithData error: %@; data = %@", __FUNCTION__, parseError, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    return;
}

// now you can use your `dictionary` object

Obviously, if it was NSArray, change that above JSONObjectWithData line to return array, but the concept is the same.

Or, better, use asynchronous connection (as you should never use synchronous connections on the main queue):

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    if (!data) {
        NSLog(@"%s: sendAynchronousRequest error: %@", __FUNCTION__, connectionError);
        return;
    } else if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
        NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
        if (statusCode != 200) {
            NSLog(@"%s: sendAsynchronousRequest status code != 200: response = %@", __FUNCTION__, response);
            return;
        }
    }

    NSError *parseError = nil;
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
    if (!dictionary) {
        NSLog(@"%s: JSONObjectWithData error: %@; data = %@", __FUNCTION__, parseError, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        return
    }

    // now you can use your `dictionary` object
}];

// Note, with asynchronous connection, do not try to use `data` 
// or the object you parsed from theJSON after the block, here.
// Use it above, inside the block.
like image 90
Rob Avatar answered Dec 17 '22 16:12

Rob


For checking the Internet Connection available or Not, There are many of resources you will get for this. I usually use the reachebility

if(reachable){

  //  **Checking the file exist are not** 

    NSURLRequest *request;
    NSURLResponse *response = nil;
    NSError **error=nil; 
    NSData *data=[[NSData alloc] initWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:error]];
    NSString* retVal = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    // you can use retVal , ignore if you don't need.
    NSInteger httpStatus = [((NSHTTPURLResponse *)response) statusCode];
    NSLog(@"responsecode:%d", httpStatus);
    // there will be various HTTP response code (status)

    if(httpStatus == 404)
    {
       // Url Not Exist
    }else{
       // do your stuff
    }
}
like image 31
Kumar KL Avatar answered Dec 17 '22 15:12

Kumar KL