所以我最近想从使用NSUrlConnection改为AFNetworking。我可以使用两种方法接收JSON数据,但在使用AFNetworking时会发生奇怪的事情。
这是NSURLConnection的样子
这就是AFNetworking 的样子
我不知道那是什么(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];
}
答案 0 :(得分:3)
您正在将acceptableContentTypes
设置为text/html
。我认为你这样做是因为你的网络服务没有设置正确的Content-Type
标题来表明它是application/json
。如果您修改了网络服务以提供正确的标头Content-Type
,则可以在Objective-C代码中删除此acceptableContentTypes
行。
如果你想知道为什么你不必担心NSURLConnection
,那是因为NSURLConnection
没有对Content-Type
进行任何验证(当然,除非你编写自己的代码,例如,didReceiveResponse
,检查了这一点)。
您建议您无法显示数据。但是,在你的第二个屏幕快照中,它就是它。我个人对内部表示的担心要少于我是否可以访问NSDictionary
中的数据。如果你
NSLog(@"responseObject=%@", responseObject);
在成功区内的#3处,您看到了什么?我打赌你会看到你的NSDictionary
罚款(尽管内部代表的细微差别)。
我的论点是您正在成功获取数据。是的,您的网络服务应设置正确的Content-Type
标头,这样您就不必覆盖acceptableContentTypes
值,但看起来AFNetworking正在检索您的数据。
可能的问题是您的主线程在异步网络请求完成之前尝试使用jsonDict
。因此,诀窍是推迟使用jsonDict
,直到异步请求完成。
您已更新了问题,告诉我们您正在实例化DataParser
并致电sendBackAllGames
。您应该将代码放在异步网络请求的完成块中。
或者,您可以在fetchData
方法中使用完成块模式,然后getAllGames
方法可以在sendBackAllGames
调用的完成块中提供fetchData
代码在AFHTTPRequestOperation
。
如果使用完成块模式,它看起来像
-(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
的方法需要返回数据,那么您也要为此方法重复此完成块模式。