我有一系列地址需要使用Google的Geocode api转换为Lat / Long。我正在将地址和城市输入Google Geocode URL,从而形成正确的连接URL。
基本上我希望能够使用for循环来创建多个NSURLConnection请求,并返回多个响应。
-(void)setString{
for (int i = 0; i < [businessArray count]; i ++)
{
NSString *address = [addressArray objectAtIndex:0];
NSString *city = [locationDict valueForKey:@"city"];
NSString *geocodeURL = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?address=%@,+%@,&sensor=true", address, city];
geocodeURL = [geocodeURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:geocodeURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10];
NSLog(@"%@", request);
geoCodeConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
if (geoCodeConnection)
{
responseData = [NSMutableData data];
connectionIsActive = YES;
NSLog(@"connection active");
} else {
NSLog(@"connection failed");
connectionIsActive = NO;
}
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSError *jsonError = nil;
SBJsonParser *json = [[SBJsonParser alloc] init];
NSDictionary *parsedJSON = [json objectWithString:responseString error:&jsonError];
NSString *lat= [[[[parsedJSON valueForKey:@"results"] valueForKey:@"geometry"] valueForKey:@"location"] valueForKey:@"lat"];
NSString *lng= [[[[parsedJSON valueForKey:@"results"] valueForKey:@"geometry"] valueForKey:@"location"] valueForKey:@"lng"];
NSLog(@"lat = %@ long= %@", lat, lng);
connectionIsActive = NO;
[geoCodeLatArray addObject:lat];
[geoCodeLngArray addObject:lng];
NSLog(@"geoCodeArrayLat: %@", geoCodeLatArray);
}
现在代码只返回最后一个地址'lat和long。如何发送乘法请求并使用JSON返回乘法响应?
答案 0 :(得分:1)
试试这个我正在使用它,
for(int i=0;i< businessArray.count;i++)
{
NSString *address = [addressArray objectAtIndex:i];
NSString *city = [locationDict valueForKey:@"city"];
NSString *address = [NSString stringWithFormat:@"%@,%@", address, city];
CLLocationCoordinate2D location = [self geoCodeUsingAddress:address];
// then here store the location.latitude in lat array and location.longitude in long array.
}
- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address
{
NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:@"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%@", esc_addr];
NSDictionary *googleResponse = [[NSString stringWithContentsOfURL: [NSURL URLWithString: req] encoding: NSUTF8StringEncoding error: NULL] JSONValue];
NSDictionary *resultsDict = [googleResponse valueForKey: @"results"];
NSDictionary *geometryDict = [resultsDict valueForKey: @"geometry"];
NSDictionary *locationDict = [geometryDict valueForKey: @"location"];
NSArray *latArray = [locationDict valueForKey: @"lat"];
NSString *latString = [latArray lastObject];
NSArray *lngArray = [locationDict valueForKey: @"lng"];
NSString *lngString = [lngArray lastObject];
CLLocationCoordinate2D location;
location.latitude = [latString doubleValue];
location.longitude = [lngString doubleValue];
return location;
}
更新到上述功能:
- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address
{
double latitude = 0, longitude = 0;
NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:@"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%@", esc_addr];
NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
if (result) {
NSScanner *scanner = [NSScanner scannerWithString:result];
if ([scanner scanUpToString:@"\"lat\" :" intoString:nil] && [scanner scanString:@"\"lat\" :" intoString:nil]) {
[scanner scanDouble:&latitude];
if ([scanner scanUpToString:@"\"lng\" :" intoString:nil] && [scanner scanString:@"\"lng\" :" intoString:nil]) {
[scanner scanDouble:&longitude];
}
}
}
CLLocationCoordinate2D location;
location.latitude = latitude;
location.longitude = longitude;
return location;
}
这对我有用。
答案 1 :(得分:1)
您可能使用执行请求的异步方法来解决问题,并且具有将在结果可用时调用的完成块。此完成块提供参数 result ,这是连接请求的结果。
此方法可声明如下:
typedef void (^completion_block_t) (id result);
- (void) fetchGeoCoordinateForAddress:(NSString*)address
completionHandler:(completion_block_t)completionHandler;
假设,如果请求成功,则块中的参数 result 是响应数据的JSON表示。否则, result 是一个NSError对象,表示错误。但具体细节取决于您如何实施方法fetchGeoCoordinateForAddress:completionHandler:
。
现在您可以按如下方式设置循环:
for (NSString* address in addresses)
{
[self fetchGeoCoordinateForAddress:address completionHandler:^(id result) {
if (![result isKindOfError:[NSError class]]) // check if result is an error
{
// Note: result is not nil and is a NSDictionary representation of JSON.
// Retrieve the "location" from the response:
NSDictionary* location = result[@"results"][@"geometry"][@"location"];
// Multiple request can occur at the same time! Thus, we need to
// synchronize access to the result array "myLocations" through
// accessing it *exclusively and everywhere* on the main thread:
dispatch_async(dispatch_get_main_queue(), ^{
[self.myLocations addObject:location];
});
}
else {
// got error
DebugLog(@"ERROR: %@", result);
}
}
}
注意:根据实际的JSON和其他详细信息,您的实际代码可能略有不同。
关于方法fetchGeoCoordinateForAddress:completionHandler:
的实施,您有几个选择:
使用第三方库并实施简单的便利包装fetchGeoCoordinateForAddress:completionHandler:
。
创建您自己的“MyHTTPConnectionOperation”类,该类将NSURLConnection
和响应数据以及其他有用的状态信息封装在专用类中。此类通过start
方法异步执行请求,并具有完成处理程序。基本上,所有第三方网络库都将使用此方法。然后实现包装器。
如果NSURLConnection足够且在您的上下文中工作,请使用NSURLConnection的异步方便方法。这是最快的实施方式,但是最不灵活的方法可能并不适用于所有情况,也可能只是次优。
编辑:
一些提示:
如果可能,请使用NSJSONSerialization
解析JSON并创建Foundation表示。如果您有特殊要求,其他第三方图书馆仅提供轻微优势,例如:你需要“使用NSData对象进行分块解析” - 这在你想同时下载和解析时非常有用。或者您需要创建除Foundation之外的其他表示 - 比如C ++容器,或者您希望直接创建具有SAX样式解析的Model。或者,您需要更好的性能和更低的内存食物打印,因为您要接收要保存到磁盘的超大字符串。 NSJSONSerialization
最近变得非常快,所以单凭“表现”不应成为今天的论据。
请求的超时时间不应低至10秒。在蜂窝连接中,这太少了。保留默认值。
如果您打算实施自己的“HTTPConnectionOperation”课程,我会在gist here上添加一个非常有限的示例,这可以帮助您快速启动。
答案 2 :(得分:0)