本文介绍了使用AFNetworking提取JSON时遇到问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我最近想从使用NSUrlConnection更改为AFNetworking。我可以同时使用这两种方法接收JSON数据,但是当与AFNetworking一起使用时,会发生一些奇怪的事情。

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.

这就是NSURLConnection的样子

这就是AFNetworking的样子

我不知道那是什么(结构__lidb_autoregen_nspair),我不知道这是否是阻止我显示数据

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

这是AFNetworking的代码,我使用ray的示例代码

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. 您正在将 acceptableContentTypes 设置为 text / html 。我认为您正在这样做是因为您的网络服务未设置正确的 Content-Type 标头来表明它是 application / json 。如果您修复了Web服务以提供正确的标头 Content-Type ,则可以在您的行中删除此 acceptableContentTypes 行Objective-C代码。

  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.

如果您想知道为什么不必使用 NSURLConnection 来担心这一点,这是因为 NSURLConnection 不会对 Content-Type 进行任何验证(当然,除非您编写自己的代码,例如 didReceiveResponse 中的代码)。

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).

您建议您无法显示数据。但是,在第二个屏幕快照中已经存在。我个人对内部表示的担心要比我是否可以从 NSDictionary 访问数据少。如果您

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);

您究竟看到了什么?我打赌,您会看到您的 NSDictionary 罚款(尽管内部表示形式存在细微差异)。

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).

我的争辩是您正在成功恢复数据。是的,您的Web服务应设置正确的 Content-Type 标头,这样您就不必覆盖 acceptableContentTypes 值,但看起来AFNetworking可以正常检索您的数据。

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.

可能的问题是您的主线程尝试使用 jsonDict 完成异步网络请求之前。因此,诀窍是将 jsonDict 的使用推迟到异步请求完成后再使用。

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.

您已更新问题,向我们显示您正在实例化 DataParser 并调用 sendBackAllGames 。您应该将代码放入异步网络请求的完成块中。

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.

或者,您可以在<$中使用完成块模式c $ c> fetchData 方法,然后 getAllGames 方法可以提供 sendBackAllGames 代码在 fetchData AFHTTPRequestOperation 成功块内调用的完成块中。

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];
}

您会这样称呼它:

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

        NSMutableDictionary *results = [dataParserObjec sendBackAllGames:jsonDict];

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

如果调用 getAllGames 的方法需要要返回的数据,您也将为此方法重复此完成块模式。

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

这篇关于使用AFNetworking提取JSON时遇到问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-18 20:07