Все еще трудно определить причину, но есть некоторые проблемы с кодом, который вы выложили.
Во-первых, в didReceiveData
эта строка, вероятно, не та, которую вы хотите:
if ( connection = theConnection ) //theConnection is created before
Одиночный =
выполняет присваивание вместо проверки на равенство (что составляет ==
).
Однако исправление этого не является решением (другая проблема в connectionDidFinishLoading
).
Метод didReceiveData
не подходит для обработки результатов геокодирования JSON.Метод didReceiveData
может быть вызван несколько раз для одного запроса URL.Таким образом, возможно, что результаты геокодирования (так же, как файл kml) могут быть доставлены в несколько кусков, которые не могут быть обработаны по отдельности в этом методе.data
в этом методе может быть частичным потоком полного результата, который не имеет смысла обрабатывать.Вам следует только добавлять данные в объект NSMutableData или, как предполагает ответ на связанный вопрос, записывать данные в файл.
Данные могут обрабатываться / анализироваться только методом connectionDidFinishLoading
.
Поскольку вы используете один и тот же делегат соединения для загрузки файла kml и геокодирования, они оба вызывают один и тот же метод connectionDidFinishLoading
.В этом методе вы не проверяете, к какому соединению оно вызывается.
Когда запрос URL геокодирования завершается и вызывает connectionDidFinishLoading
, этот метод принимает все, что находится в webData
(возможно, результаты геокодирования или пустыеданные) и записывает его в файл kmlStr
.Вероятно, именно из-за этого данные kml показывают «ничего».
Необходимо переместить обработку результатов геокодирования на connectionDidFinishLoading
и проверить, какое соединение вызывает его.
Дляпример:
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[webData appendData:data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
if ( connection == theConnection ) //"theConnection" is for kml file download
{
NSString *fileName = [[[NSURL URLWithString:kmlStr] path] lastPathComponent];
NSArray *pathArr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *folder = [pathArr objectAtIndex:0];
NSString *filePath = [folder stringByAppendingPathComponent:fileName];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
NSError *writeError = nil;
[webData writeToURL: fileURL options:0 error:&writeError];
if( writeError) {
NSLog(@" Error in writing file %@' : \n %@ ", filePath , writeError );
return;
}
NSLog(@"%@",fileURL);
}
else //it's a geocoding result
{
NSString *jsonString = [[NSString alloc] initWithData:webData encoding:NSUTF8StringEncoding];
NSDictionary *results = [jsonString JSONValue];
//check the Google geocode error code before looking for coordinates...
NSDictionary *statusDict = [results objectForKey:@"Status"];
NSNumber *errorCode = [statusDict objectForKey:@"code"];
if ([errorCode intValue] == 200) //200 is "success"
{
NSArray *placemark = [results objectForKey:@"Placemark"];
NSArray *coordinates = [[placemark objectAtIndex:0] valueForKeyPath:@"Point.coordinates"];
double longitude = [[coordinates objectAtIndex:0] doubleValue];
double latitude = [[coordinates objectAtIndex:1] doubleValue];
NSLog(@"Latitude - Longitude: %f %f", latitude, longitude);
[self zoomMapAndCenterAtLatitude:latitude andLongitude:longitude];
}
else
{
NSLog(@"geocoding error %@", errorCode);
}
[jsonString release];
}
}
(Вероятно, лучше избегать использования одного и того же делегата для нескольких соединений. Было бы удобнее перенести геокодирование в другой класс с собственным объектом соединения и методами делегата. Кстати,В iOS5 встроено геокодирование, поэтому вам не нужно делать это самостоятельно. См. класс CLGeocoder .
Я добавил проверку для кода ошибки Google.Возможно, что запрашиваемый адрес не даст результатов, в этом случае не будет координат метки, и в этом случае широта и долгота будут установлены на ноль.Это еще одна возможная причина появления карты 0,0.
Похоже, вы используете устаревший геокодер Google v2 . Это самая последняя версия , но вы можете переключиться на использование CLGeocoder
, если вам не требуется поддержка iOS4 или более ранней версии.