简体   繁体   中英

JSON call in iOS not receives data but cannot Parse or Log it

I need to make a HTTPRequest to a URL and parse the resulting JSON and I have tried the following code

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"viewdidload");
    self.responseData = [NSMutableData data];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.gcap.eu/omosanya/download.php"]];
    [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"didReceiveResponse");
    [self.responseData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.responseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"didFailWithError");
    NSLog([NSString stringWithFormat:@"Connection failed: %@", [error description]]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSLog(@"connectionDidFinishLoading");
    NSLog(@"Succeeded! Received %lu bytes of data",(unsigned long)[self.responseData length]);

    // convert to JSON
    NSError *myError = nil;
    NSDictionary *res = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingAllowFragments error:&myError];

    // show all values
    for(id key in res) {
        id value = [res objectForKey:key];

        NSString *keyAsString = (NSString *)key;
        NSString *valueAsString = (NSString *)value;

        NSLog(@"key: %@", keyAsString);
        NSLog(@"value: %@", valueAsString);
    }

    // extract specific value...
    NSArray *results = [res objectForKey:@"results"];

    for (NSDictionary *result in results) {
        NSString *icon = [result objectForKey:@"timestamp"];
        NSLog(@"icon: %@", icon);
    }

}

I get the following output in my console:

2015-02-03 17:12:28.201 LSDir[1495:130391] viewdidload
2015-02-03 17:12:28.831 LSDir[1495:130391] didReceiveResponse
2015-02-03 17:12:36.815 LSDir[1495:130391] connectionDidFinishLoading
2015-02-03 17:12:36.815 LSDir[1495:130391] Succeeded! Received 8223702 bytes of data

Note that no JSON is printed? Why is this and how do i fix it? Is there something wrong with my NSJSONSerialization?

Beware that json string can be a dictionary or an array. If you don't sure about which kind the json string is, you have to verify it before take your action. Here is the code to verify json object

id jsonObject = [NSJSONSerialization JSONObjectWithData:_responseData options:NSJSONReadingAllowFragments error:&myError];
if ([jsonObject isKindOfClass:[NSArray class]]) {
    NSLog(@"its an array!");
    NSArray *jsonArray = (NSArray *)jsonObject;
    //do your work with this array
}
else {
    NSLog(@"its probably a dictionary");
    NSDictionary *jsonDictionary = (NSDictionary *)jsonObject;
    //do your work with this dictionary
}

Don't use NSURLConnection - use the block-based NSURLSession API instead. It's the successor to NSURLConnection and is backwards compatible to iOS 7.

Here's the snippet of code that you need to solve your problem (I think):

    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"http://www.gcap.eu/omosanya/download.php"]
                                         completionHandler:^(NSData *data,
                                                             NSURLResponse *response,
                                                             NSError *error) {

                                             NSError *deserializationError = nil;
                                             if (!error) { // HTTP Reqeust Succeeded
                                                 id results = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&deserializationError];

                                                 if (!deserializationError) { // Deserialization Succeeded
                                                     if ([results isKindOfClass:[NSDictionary class]]) { // Dictionary
                                                         NSLog(@"JSON Dictionary Data %@", (NSDictionary *)results);
                                                     } else { // Array
                                                         NSLog(@"JSON Array Data %@", (NSArray *)results);
                                                     }
                                                 } else { // Deserialization Failed
                                                     NSLog(@"Deserializaiton Error: %@", error);
                                                 }
                                             } else { // HTTP Request Failed
                                                 NSLog(@"HTTP Error: %@", error);
                                             }}];
   [task resume];

There's a great (free) tutorial here on NSURLSession : http://www.raywenderlich.com/51127/nsurlsession-tutorial

I tried this:

-(void)viewDidAppear:(BOOL)animated
{             
        dispatch_async(kBgQueue, ^{
                NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.gcap.eu/omosanya/download.php"]];
                [self performSelectorOnMainThread:@selector(receivedCall:)withObject:data waitUntilDone:YES];
        });
}
- (void) receivedCall:(NSData *)response
{
        NSError *error;

        NSArray *parsedResponse = [NSJSONSerialization
                                        JSONObjectWithData:response
                                        options:NSJSONReadingMutableContainers
                                        error:&error];

        if (error) {
                NSLog(@"Error %@", error);
        }
        NSLog(@"Silly Response %@", parsedResponse);

}

Where:

#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

I received the following Error:

Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Badly formed array around character 3482608.) UserInfo=0x16512920 {NSDebugDescription=Badly formed array around character 3482608.}

I suspect the problem is badly formed JSON and the issue can be resolved by investigating how the server forms the JSON.

Also the code above might be worth using - it doesn't block the main thread and implements the same functionality with less code. It's easier to extend as well because if you want to make multiple API calls either in parallel or sequentially this can be achieved easier that the method you employed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM