我有一个搜索设置,它在 UITableVIew 中显示 MKLocalSearchRequest 的响应
我想从每次搜索的响应中清理所有响应。到目前为止,这是我在这篇文章 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)startSearchNSString *)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。现在它抛出这个错误
-[MKMapItem length]: unrecognized selector sent to instance 0x7f813c9c6200
Best Answer-推荐答案 strong>
在另一个问题中引用的 CLGeocoder 方法 geocodeAddressString 旨在对地址进行地理编码。
但是您正在特定区域内执行 MKLocalSearch ,它返回已被地理编码的 MKMapItem 对象。因此,您可以从代码示例中完全删除 geocodeAddressString 代码。
事实上,这解释了您的异常的来源,即您正在获取 MKLocalSearch 返回的 MKMapItem ,并尝试将其用作搜索字符串参数CLGeocoder 方法 geocodeAddressString (仅用于查找地址的字符串表示形式)。
最重要的是,进行本地搜索并在 map 应用程序中显示结果比您在上面所设想的要容易得多。您需要做的就是:
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 上显示它,你可以这样做
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];
}
}];
实际上,在后一个示例中,您在自己的 map View 上显示结果,您可以创建自己的自定义注释类,以便更好地控制 viewForAnnotation中注释 View 的呈现 方法。但希望这能说明主要观察结果,即在使用 MKLocalSearch 时,您根本不应该使用 CLGeocoder 方法 geocodeAddressString 。
关于ios - 批量地理编码 MKLocalSearch 响应,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/25438928/
|