Получение данных из блока завершения NSURLResponse
похоже, я еще не полностью понял концепцию блоков...
в моем коде я должен получить данные JSON из asychronous block
для возврата из ''. Я погуглил и обнаружил, что если определить variable with __block
видимость _mutability_ of
эта переменная расширена до block
.
но по какой-то причине возвращаемый объект json равен нулю.Интересно, почему?
- (NSMutableDictionary *)executeRequestUrlString:(NSString *)urlString
{
__block NSMutableDictionary *json = nil;
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPShouldHandleCookies:YES];
[request setHTTPMethod:@"GET"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"];
NSString *cookieString = [self.userDefaults objectForKey:SAVED_COOKIE];
[request addValue:cookieString forHTTPHeaderField:@"Cookie"];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue currentQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]);
NSError *error1;
NSMutableDictionary * innerJson = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error1];
json = innerJson;
}];
return json;
}
3 ответов
во-первых, чтобы ответить на ваш вопрос:
но по какой-то причине возвращается объект json
nil
. Интересно, почему?
переменная, которую вы возвращаете, не была установлена в момент ее возврата. Вы не можете собрать результаты сразу после sendAsynchronousRequest:queue:completionHandler:
метод вернулся: вызов должен закончить туда и обратно перед вызовом вашего блока и установкой json
переменной.
теперь краткое замечание о том, что с этим делать: ваш метод пытается преобразовать асинхронный вызов в синхронный. Постарайтесь сохранить асинхронность, если сможете. Вместо того, чтобы ожидать метод, который возвращает NSMutableDictionary*
, сделайте метод, который принимает собственный блок, и передайте словарь этому блоку, когда sendAsynchronousRequest:
метод завершается:
- (void)executeRequestUrlString:(NSString *)urlString withBlock:(void (^)(NSDictionary *jsonData))block {
// Prepare for the call
...
// Make the call
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue currentQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]);
NSError *error1;
NSMutableDictionary * innerJson = [NSJSONSerialization
JSONObjectWithData:data options:kNilOptions error:&error1
];
block(innerJson); // Call back the block passed into your method
}];
}
когда вы называете sendAsynchronousRequest:queue:completionHandler:
, ты просил асинхронные запрос. Таким образом, он выстраивает запрос и блок в очередь и немедленно возвращается. В какой-то момент в будущем запрос выполняется, а в какой-то момент после этого запускается блок завершения. Но к тому времени ...--1--> уже давно работает.
Если вы хотите иметь возможность синхронно возвращать данные, вы должны сделать синхронный запрос. Это будет висеть этот поток, пока он не завершится, поэтому он не должен быть основным нитка.
Проверьте строку при преобразовании данных, поступающих с сервера, используя код ниже:
NSLog(@"dataAsString %@", [NSString stringWithUTF8String:[data bytes]]);
если строка находится в правильном формате JSON, только тогда ваш объект JSON будет правильным.
надеюсь, это hepls!!