1

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

这就是 NSURLConnection 的样子

在此处输入图像描述

这就是 AFNetworking 的样子 在此处输入图像描述

我不知道 (struct __lidb_autoregen_nspair) 是什么,我不知道这是否是阻止我显示数据的原因

这是来自 AFNetworking 的代码,我使用来自 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];

}

-------------------------------------------------- - - - - - - - - - - - - - - - - - - - - 编辑

-(NSMutableDictionary *) getAllGames{

[self fetchData];

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

return [dataParserObjec sendBackAllGames:jsonDict];

}
4

1 回答 1

3
  1. 您正在acceptableContentTypestext/html. 我想你这样做是因为你的网络服务没有设置正确的Content-Type标题来表明它是application/json. 如果您修复了 Web 服务以提供正确的 header ,那么您可以在您的 Objective-C 代码中Content-Type删除这一行。acceptableContentTypes

    如果你想知道为什么你不必担心这个问题NSURLConnection,那是因为NSURLConnection它不会做任何验证Content-Type(当然,除非你编写自己的代码,例如,didReceiveResponse检查这个)。

  2. 您建议您无法显示数据。但它仍然存在,在您的第二个屏幕快照中。我个人不太担心内部表示,而是我是否可以从NSDictionary. 如果你

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

    在#3,在成功块内,您到底看到了什么?我打赌你会看到你的NSDictionary罚款(尽管内部表示存在细微差别)。

    我的论点是您成功地取回了数据。是的,您的 Web 服务应该设置正确的Content-Type标头,这样您就不必覆盖该acceptableContentTypes值,但看起来 AFNetworking 可以正常检索您的数据。

  3. 可能的问题是您的主线程jsonDict在异步网络请求完成之前尝试使用。所以诀窍是推迟使用,jsonDict直到异步请求完成。

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

    或者,您可以在fetchData方法中使用完成块模式,然后该getAllGames方法可以sendBackAllGames在完成块中提供代码,该完成块fetchDataAFHTTPRequestOperation.


如果您使用完成块模式,它看起来像

-(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需要返回数据,您也可以为此方法重复此完成块模式。

于 2014-12-02T13:00:53.483 回答