批次地址解析MKLocalSearchResponse [英] Batch Geocode MKLocalSearchResponse
问题描述
我有一个搜索设置,可在UITableVIew中显示MKLocalSearchRequest的响应
I have a search setup that displays the response of a MKLocalSearchRequest in UITableVIew
我想从每次搜索的响应中清除 all 个响应.到目前为止,这是我为实现这一目标而付出的努力,受到这篇文章的启发
I want to clean up all the responses from the response of each search. Here is my shot at accomplishing this so far, inspired by this post Multiple Locations on Map (using MKMapItem and CLGeocoder)
这是我的代码.
@interface ViewController () <UISearchBarDelegate,UISearchDisplayDelegate,UITextFieldDelegate>
@property (nonatomic, strong) UISearchDisplayController *searchController;
@property (nonatomic, strong) UISearchBar *searchBar;
@property (nonatomic, strong) MKLocalSearch *localSearch;
@property (nonatomic, strong) MKLocalSearchResponse *localSearchResponse;
@property (nonatomic, strong) NSArray *dirtyResponseArray;
@property (nonatomic, strong) NSMutableArray *geocodedResultsArray;
@end
@implementation ViewController
-(void)startSearch:(NSString *)searchString
{
if (self.localSearch.searching)
[self.localSearch cancel];
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = searchString;
request.region = MKCoordinateRegionMake(self.currentLocation.coordinate, self.mapView.region.span);
MKLocalSearchCompletionHandler completionHandler = ^(MKLocalSearchResponse *response, NSError *error){
if (error != nil) return;
else {
self.dirtyResponseArray = response.mapItems;
[self operation];
[self.searchController.searchResultsTableView reloadData];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
[self.searchDisplayController.searchResultsTableView reloadData];
};
if (self.localSearch != nil)
self.localSearch = nil;
self.localSearch = [[MKLocalSearch alloc] initWithRequest:request];
[self.localSearch startWithCompletionHandler:completionHandler];
}
-(void)operation
{
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSOperation *finalCompletionOperation = [NSBlockOperation blockOperationWithBlock:^{
[MKMapItem openMapsWithItems:self.geocodedResultsArray launchOptions:nil];
NSLog(@"Local Search Response To use in tableview =================== %@", self.geocodedResultsArray);
}];
NSOperation *previousCompletionHandler = nil;
//Issue is probably right here. How should I handle the MKMapItem in the array?
//NSString *address = [self.dirtyResponseArray valueForKey:@"address"][@"formattedAddress"]; ??
for (NSString *address in self.dirtyResponseArray) {
NSBlockOperation *geocodeRequest = [[NSBlockOperation alloc] init];
if (previousCompletionHandler) [geocodeRequest addDependency:previousCompletionHandler];
NSBlockOperation *geocodeCompletionHandler = [[NSBlockOperation alloc] init];
[finalCompletionOperation addDependency:geocodeCompletionHandler];
[geocodeRequest addExecutionBlock:^{ [geocoder geocodeAddressString:address
completionHandler:^(NSArray *placemarks, NSError *error)
{
[geocodeCompletionHandler addExecutionBlock:^{
if (error) NSLog(@"%@", error);
else if ([placemarks count] > 0)
{
CLPlacemark *geocodedPlacemark = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:geocodedPlacemark.location.coordinate
addressDictionary:geocodedPlacemark.addressDictionary];
MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
[mapItem setName:geocodedPlacemark.name];
[self.geocodedResultsArray addObject:mapItem];
}
}];
[queue addOperation:geocodeCompletionHandler];
}];
}];
[queue addOperation:geocodeRequest];
previousCompletionHandler = geocodeCompletionHandler;
}
[queue addOperation:finalCompletionOperation];
}
@end
我不确定如何处理每个MKMapItem.现在它抛出这个错误
I'm not sure how to handle each MKMapItem. Right now its throwing this error
-[MKMapItem length]: unrecognized selector sent to instance 0x7f813c9c6200
推荐答案
在另一个问题中引用的CLGeocoder
方法geocodeAddressString
旨在对地址进行地理编码.
The CLGeocoder
method, geocodeAddressString
, which is referenced in that other question, is designed for geocoding an address.
但是您要在特定区域内执行MKLocalSearch
,这将返回已进行地理编码的MKMapItem
对象.结果,您可以从代码示例中完全删除geocodeAddressString
代码.
But you're performing a MKLocalSearch
within a particular region, which returns MKMapItem
objects which are already geocoded. As a result, you can entirely remove the geocodeAddressString
code from your code sample.
实际上,这解释了您的异常的来源,即您采用了MKLocalSearch
返回的MKMapItem
,并试图将其用作CLGeocoder
方法geocodeAddressString
的搜索字符串参数(仅用于查找地址的字符串表示形式.
In fact, this explains the source of your exception, that you're taking the MKMapItem
returned by MKLocalSearch
, and trying to use it as the search string parameter of CLGeocoder
method geocodeAddressString
(which is only used for looking up string representations of addresses).
最重要的是,进行本地搜索并在地图"应用中显示结果要比上面设想的要容易得多.您需要做的只是:
Bottom line, to do a local search and show the results in the Maps app is far easier than what you've contemplated above. All you need to do is:
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = searchString;
request.region = region;
MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request];
[search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
[MKMapItem openMapsWithItems:response.mapItems launchOptions:nil];
}];
或者,如果您想将其显示在自己的MKMapView
上,则可以执行类似的操作
Or, if you wanted to show it on your own MKMapView
, you could do something like
MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = searchString;
request.region = region;
MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request];
[search startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error) {
for (MKMapItem *item in response.mapItems) {
[self.mapView addAnnotation:item.placemark];
}
}];
在实践中,在后一个示例中,您将在自己的地图视图上显示结果,您可以创建自己的自定义注释类,以便更好地控制viewForAnnotation
方法中注释视图的呈现.但是希望这可以说明主要的观察结果,即使用MKLocalSearch
时,您根本不应该使用CLGeocoder
方法geocodeAddressString
.
In practice, in this latter example where you're showing results on your own map view, you might create your own custom annotation class so that you have greater control over your rendering of the annotation view in viewForAnnotation
method. But hopefully this illustrates the main observation, that when using MKLocalSearch
, you should not be using CLGeocoder
method geocodeAddressString
at all.
这篇关于批次地址解析MKLocalSearchResponse的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!