使用AFNetworking获取JSON时遇到问题

时间:2014-12-02 10:23:41

标签: objective-c json afnetworking-2 get-request

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

这是NSURLConnection的样子

enter image description here

这就是AFNetworking 的样子 enter image description here

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

这是来自AFNetworking的代码,我使用了来自光线的示例代码

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

}

1 个答案:

答案 0 :(得分:3)

  1. 您正在将acceptableContentTypes设置为text/html。我认为你这样做是因为你的网络服务没有设置正确的Content-Type标题来表明它是application/json。如果您修改了网络服务以提供正确的标头Content-Type,则可以在Objective-C代码中删除此acceptableContentTypes行。

    如果你想知道为什么你不必担心NSURLConnection,那是因为NSURLConnection没有对Content-Type进行任何验证(当然,除非你编写自己的代码,例如,didReceiveResponse,检查了这一点)。

  2. 您建议您无法显示数据。但是,在你的第二个屏幕快照中,它就是它。我个人对内部表示的担心要少于我是否可以访问NSDictionary中的数据。如果你

    NSLog(@"responseObject=%@", responseObject); 
    
    在成功区内的#3处,您看到了什么?我打赌你会看到你的NSDictionary罚款(尽管内部代表的细微差别)。

    我的论点是您正在成功获取数据。是的,您的网络服务应设置正确的Content-Type标头,这样您就不必覆盖acceptableContentTypes值,但看起来AFNetworking正在检索您的数据。

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

    您已更新了问题,告诉我们您正在实例化DataParser并致电sendBackAllGames。您应该将代码放在异步网络请求的完成块中。

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

  4. 的成功区块内

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

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