如何使用UISearchBarsearchMKMapView?

我有一个应用程序,需要有类似的苹果“地图”应用程序(iPhone,iPod Touch和iPad附带)的searchfunction。

这个function不应该是一件难事,但我真的不知道如何在search栏中input一个街道地址,然后获得该地址的坐标或什么东西,可以帮助我实际移动地图和中心在那个地方。

我的意思是,我有什么要查询,苹果提供了一个“地址searchAPI方法”? 或者我需要直接使用谷歌地图API?

我很想听听应该怎么做。

这也许是最简单的方法。 它使用苹果服务器进行地理编码。 有时苹果服务器比谷歌提供更好的响应。 很快(在IOS 6.1中)谷歌地图将完全脱离IOS。 所以如果应用程序保持在苹果提供的function内,这是好事。

-(void)searchBarSearchButtonClicked:(UISearchBar *)theSearchBar { [theSearchBar resignFirstResponder]; CLGeocoder *geocoder = [[CLGeocoder alloc] init]; [geocoder geocodeAddressString:theSearchBar.text completionHandler:^(NSArray *placemarks, NSError *error) { //Error checking CLPlacemark *placemark = [placemarks objectAtIndex:0]; MKCoordinateRegion region; region.center.latitude = placemark.region.center.latitude; region.center.longitude = placemark.region.center.longitude; MKCoordinateSpan span; double radius = placemark.region.radius / 1000; // convert to km NSLog(@"[searchBarSearchButtonClicked] Radius is %f", radius); span.latitudeDelta = radius / 112.0; region.span = span; [theMapView setRegion:region animated:YES]; }]; } 

好的,回答我自己的问题:

正如之前提到的,最好的办法是使用Google Maps API,它支持很多格式,但是由于几个原因,我select了使用JSON。

因此,下面是对Google地图执行JSON查询并获取查询坐标的步骤。 请注意,并非所有正确的validation都完成,这只是一个概念validation。

1)下载iPhone的JSON框架/库,有几个,我select了这个 ,这是非常好的,似乎是一个活跃的项目,加上几个商业应用程序似乎正在使用它。 所以把它添加到你的项目(说明在这里 )。

2)要查询Google地图的地址,我们需要构build一个请求url,例如: http : //maps.google.com/maps/geo?q=Paris+France

这个URL将返回一个查询“Paris + France”的JSON对象。

3)代码:

 //Method to handle the UISearchBar "Search", - (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar { //Perform the JSON query. [self searchCoordinatesForAddress:[searchBar text]]; //Hide the keyboard. [searchBar resignFirstResponder]; } 

处理完UISearchBarsearch之后,我们必须向Google Maps发出请求:

 - (void) searchCoordinatesForAddress:(NSString *)inAddress { //Build the string to Query Google Maps. NSMutableString *urlString = [NSMutableString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@?output=json",inAddress]; //Replace Spaces with a '+' character. [urlString setString:[urlString stringByReplacingOccurrencesOfString:@" " withString:@"+"]]; //Create NSURL string from a formate URL string. NSURL *url = [NSURL URLWithString:urlString]; //Setup and start an async download. //Note that we should test for reachability!. NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [connection release]; [request release]; } 

我们当然必须处理GoogleMaps服务器的响应(注意:缺less大量validation)

 //It's called when the results of [[NSURLConnection alloc] initWithRequest:request delegate:self] come back. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { //The string received from google's servers NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; //JSON Framework magic to obtain a dictionary from the jsonString. NSDictionary *results = [jsonString JSONValue]; //Now we need to obtain our coordinates NSArray *placemark = [results objectForKey:@"Placemark"]; NSArray *coordinates = [[placemark objectAtIndex:0] valueForKeyPath:@"Point.coordinates"]; //I put my coordinates in my array. double longitude = [[coordinates objectAtIndex:0] doubleValue]; double latitude = [[coordinates objectAtIndex:1] doubleValue]; //Debug. //NSLog(@"Latitude - Longitude: %f %f", latitude, longitude); //I zoom my map to the area in question. [self zoomMapAndCenterAtLatitude:latitude andLongitude:longitude]; [jsonString release]; } 

最后是放大我的地图的function,现在应该是一件小事。

 - (void) zoomMapAndCenterAtLatitude:(double) latitude andLongitude:(double) longitude { MKCoordinateRegion region; region.center.latitude = latitude; region.center.longitude = longitude; //Set Zoom level using Span MKCoordinateSpan span; span.latitudeDelta = .005; span.longitudeDelta = .005; region.span = span; //Move the map and zoom [mapView setRegion:region animated:YES]; } 

希望这有助于某人,因为JSON部分是一个真正的痛苦找出,我认为图书馆没有很好的logging,仍然是非常好的。

编辑:

由于@Leo问题,修改了一个方法名称为“searchCoordinatesForAddress:”。 我不得不说,这个方法作为一个概念的certificate是好的,但是如果你打算下载大的JSON文件,你将不得不追加到一个NSMutableData对象来保存所有的查询到谷歌服务器。 (请记住,HTTP查询是分段的。)

这个链接可以帮助你,如果你search一个地区。

 NSMutableString *urlString = [NSMutableString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@?output=json",inAddress]; 

如果你想search一条街,这是核心链接

 NSMutableString *urlString = [NSMutableString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=json",inAddress]; 

注意第二个? 应该是&

如果其他人有相同的问题,inheritance人链接: https : //github.com/stig/json-framework/向下滚动到项目改名为SBJson

另外,这里是在您的应用程序使用它之前获取所有数据的代码。 请注意,代理方法“接收数据”,因为它将可变数据对象与下载的数据附加在一起。

我只是使用MR GANDOS searchCoodinates方法,因为它工作的很好

 - (void) searchCoordinatesForAddress:(NSString *)inAddress { //Build the string to Query Google Maps. NSMutableString *urlString = [NSMutableString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?address=%@&sensor=false",inAddress]; //Replace Spaces with a '+' character. [urlString setString:[urlString stringByReplacingOccurrencesOfString:@" " withString:@"+"]]; //Create NSURL string from a formate URL string. NSURL *url = [NSURL URLWithString:urlString]; //Setup and start an async download. //Note that we should test for reachability!. NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [connection release]; [request release]; } 

//第一步//这是一个很重要的事情,因为它创造了可接受的数据对象作为响应被接收

 -(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response { if (receivedGeoData) { [receivedGeoData release]; receivedGeoData = nil; receivedGeoData = [[NSMutableData alloc] init]; } else { receivedGeoData = [[NSMutableData alloc] init]; } } 

///第二步//这个是重要的,因为它用数据来看数据对象

 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [receivedGeoData appendData:data]; } 

//第三步…… //现在你已经拥有了所有的数据

 - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSString *jsonResult = [[NSString alloc] initWithData:receivedGeoData encoding:NSUTF8StringEncoding]; NSError *theError = NULL; dictionary = [NSMutableDictionary dictionaryWithJSONString:jsonResult error:&theError]; NSLog(@"%@",dictionary); int numberOfSites = [[dictionary objectForKey:@"results"] count]; NSLog(@"count is %d ",numberOfSites); } -(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error { // Handle the error properly } 

您可以使用Google的API服务从文本searchstring中获取经纬度坐标。 一定要传递用户的当前位置,以便结果相关。 阅读这个问题的答案: 在MKMapView上search并显示业务位置

Swift版本,适用于iOS 9:

 let geocoder = CLGeocoder() geocoder.geocodeAddressString(addressString) { (placemarks, error) in if let center = (placemarks?.first?.region as? CLCircularRegion)?.center { let region = MKCoordinateRegion(center: center, span: MKCoordinateSpanMake(0.02, 0.02)) self.mapView.setRegion(region, animated: true) } } 

根据user1466453的答案。