Having problems using AFNetworking fetching JSON

痞子三分冷 提交于 2020-01-16 01:56:08

问题


So i recently wanted to change from using NSUrlConnection to AFNetworking. I can receive the JSON data with both methods buts when using with AFNetworking something weird happens.

This is how it looks like with NSURLConnection

and this is how it looks like with AFNetworking

I have no idea what that (struct __lidb_autoregen_nspair) is and i dont know if that is the thing that is preventing me from displaying the data

This is the code from AFNetworking, i use the sample code from ray

-(void) fetchData{

// 1

NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];

// 2
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

    // 3
    jsonDict = (NSMutableDictionary *)responseObject;



} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    // 4
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Weather"
                                                        message:[error localizedDescription]
                                                       delegate:nil
                                              cancelButtonTitle:@"Ok"
                                              otherButtonTitles:nil];
    [alertView show];
}];

// 5
[operation start];

}

----------------------------------------------------------------------------------------- Edit

-(NSMutableDictionary *) getAllGames{

[self fetchData];

DataParser *dataParserObjec = [[DataParser alloc] init];

return [dataParserObjec sendBackAllGames:jsonDict];

}

回答1:


  1. You are setting the acceptableContentTypes to text/html. I presume you are doing that because your web-service is not setting the correct Content-Type header to indicate that it's application/json. If you fixed the web service to provide the correct header Content-Type, you could then remove this acceptableContentTypes line in your Objective-C code.

    If you're wondering why you didn't have to worry about that with NSURLConnection, that's because NSURLConnection doesn't do any validation of Content-Type (unless, of course, you write your own code in, for example, didReceiveResponse, that checked this).

  2. You suggest that you are unable to display the data. But yet there it is, in your second screen snapshot. I personally would be less worried about internal representation than whether I could access the data from the NSDictionary. If you

    NSLog(@"responseObject=%@", responseObject); 
    

    at #3, inside the success block, what precisely do you see? I'd wager you'll see your NSDictionary fine (despite the subtle differences in the internal representation).

    My contention is that you are getting the data back successfully. Yes, your web service should set the correct Content-Type header so you don't have to overwrite the acceptableContentTypes value, but it looks like AFNetworking is retrieving your data fine.

  3. The likely issue is that your main thread is trying to use jsonDict before the asynchronous network request is done. So the trick is to defer the use of the jsonDict until the asynchronous request is done.

    You've updated your question showing us that you're instantiating a DataParser and calling sendBackAllGames. You should put that code inside the completion block of your asynchronous network request.

    Alternatively, you could use a completion block pattern in your fetchData method, and then the getAllGames method could supply the sendBackAllGames code in a completion block that fetchData calls inside the success block of the AFHTTPRequestOperation.


If you used the completion block pattern, it would look like

-(void) fetchDataWithCompletionHandler:(void (^)(id responseObject, NSError *error))completionHandler {

    NSURL *url = [NSURL URLWithString:string];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.responseSerializer = [AFJSONResponseSerializer serializer];

    // removed once we fixed the `Content-Type` header on server
    //
    // operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        if (completionHandler) {
            completionHandler(responseObject, nil);
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        [[[UIAlertView alloc] initWithTitle:@"Error Retrieving Weather"
                                    message:[error localizedDescription]
                                   delegate:nil
                          cancelButtonTitle:@"OK"
                          otherButtonTitles:nil] show];

        if (completionHandler) {
            completionHandler(nil, error);
        }
    }];

    [operation start];
}

And you'd call it like so:

[self fetchDataWithCompletionHandler:^(id responseObject, NSError *error) {
    if (responseObject) {
        DataParser *dataParserObjec = [[DataParser alloc] init];

        NSMutableDictionary *results = [dataParserObjec sendBackAllGames:jsonDict];

        // do whatever you want with results
    }
}];

If the method that called getAllGames needed the data to be returned, you'd repeat this completion block pattern for this method, too.



来源:https://stackoverflow.com/questions/27246989/having-problems-using-afnetworking-fetching-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!