问题
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:
You are setting the
acceptableContentTypes
totext/html
. I presume you are doing that because your web-service is not setting the correctContent-Type
header to indicate that it'sapplication/json
. If you fixed the web service to provide the correct headerContent-Type
, you could then remove thisacceptableContentTypes
line in your Objective-C code.If you're wondering why you didn't have to worry about that with
NSURLConnection
, that's becauseNSURLConnection
doesn't do any validation ofContent-Type
(unless, of course, you write your own code in, for example,didReceiveResponse
, that checked this).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 youNSLog(@"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 theacceptableContentTypes
value, but it looks like AFNetworking is retrieving your data fine.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 thejsonDict
until the asynchronous request is done.You've updated your question showing us that you're instantiating a
DataParser
and callingsendBackAllGames
. 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 thegetAllGames
method could supply thesendBackAllGames
code in a completion block thatfetchData
calls inside the success block of theAFHTTPRequestOperation
.
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