2016-04-07 6 views
1

Я использую API открытой погоды для получения живой погоды в зависимости от местоположения пользователей. Я сначала сделать переменную urllink и установите его равным запрос HTTP:NSString имеет значение null при преобразовании из NSURL

NSString *urllink = [NSString stringWithFormat:@"api.openweathermap.org/data/2.5/weather?lat=%f&lon=%f&appid=%@", lat, lng, WEATHERAPIKEY]; 

Затем преобразовать эту строку в URL. Преобразование URL обратно в строку, потому что мне нужно изменить его NSData объекта:

NSURL *jsonURL = [NSURL URLWithString:[self urlEncodeValue:urllink]]; 
NSString *jsonDataString = [[NSString alloc]initWithContentsOfURL:jsonURL]; // error on this line 
NSLog(@"This is jsonDataString:%@", jsonDataString); 
NSData *jsonData = [jsonDataString dataUsingEncoding:NSUTF8StringEncoding]; 

Переменная urllink отлично превращается в NSURL. Но когда я пытаюсь преобразовать NSURL в NSString, я получаю nil. Что в свою очередь дает мне nil за NSData.

Так почему линия:

NSString *jsonDataString = [[NSString alloc]initWithContentsOfURL:jsonURL]; 

дает мне nil для jsonDataString?

+0

вы наклеить, что URL в ваш браузер и тестирование? Каков был результат? –

+0

Да, да. Это дало мне правильную строку json. Так что все сработало хорошо. –

ответ

4

Вы пропускаете схему (https:// или http://) в вашей URL. Таким образом, запрос не удастся. Кроме того, вы должны просто использовать URLWithString непосредственно:

NSString *urllink = [NSString stringWithFormat:@"http://api.openweathermap.org/data/2.5/weather?lat=%f&lon=%f&appid=%@", lat, lng, WEATHERAPIKEY]; 

NSURL *jsonURL = [NSURL URLWithString:urllink]; 

Проблема заключается в том, что вы используете initWithContentsOfURL, что (а) синхронные; и (b) не сообщает об ошибках.

Вы должны использовать NSURLSession, который является асинхронным и сообщает об ошибках:

NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:jsonURL completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
    if (data == nil || error != nil) { 
     NSLog(@"error: %@", error); 
     return; 
    } 

    NSError *parseError; 
    NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError]; 
    if (responseObject) { 
     NSLog(@"responseObject = %@", responseObject); 
    } else { 
     NSLog(@"parseError: %@", parseError); 
     NSLog(@"responseString: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); 
    } 
}]; 
[task resume]; 
+0

Благодарим сообщение об ошибке. Что-то не так с моим url, и это должно быть http :, на их веб-сайте они не используют http; и он работает, не знаю почему. Но спасибо. –

+0

Да, предполагается 'http: //'. Фактически, если вы посмотрите на свои ссылки в своих примерах, они покажут вам это без этой схемы, но если вы посмотрите на эту ссылку, она включает в себя 'http: //'. – Rob

0

вы, вероятно, потребуются асинхрами, данные еще не могут присутствовать

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    // The code runs in background 

    do Some Long Operation 

}); 
+0

Я никогда не пользовался асинксом. Можете ли вы показать пример того, как его использовать? Также это происходит в viewDidLoad только для вашей информации. –

+0

Вызов 'initWithContentsOfURL:' с внешним URL-адресом делает синхронный сетевой запрос, что означает, что он будет блокироваться до завершения. Так что это не проблема. Хотя @ Harsh.C, как правило, следует избегать синхронных сетевых запросов, таких как использование этого метода. – Gavin

+0

Какой еще вариант. Это единственный способ, которым я могу думать, от получения nsurl до nsdata. –

Смежные вопросы