2

我有一个搜索设置,它在 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)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。现在它抛出这个错误

 -[MKMapItem length]: unrecognized selector sent to instance 0x7f813c9c6200
4

1 回答 1

1

在另一个问题中引用的CLGeocoder方法是为对地址进行地理编码而设计的。geocodeAddressString

但是您在MKLocalSearch特定区域内执行 a ,该区域返回MKMapItem已被地理编码的对象。因此,您可以geocodeAddressString从代码示例中完全删除代码。

实际上,这解释了您的异常的来源,即您正在获取MKMapItem返回的 by MKLocalSearch,并尝试将其用作CLGeocoder方法的搜索字符串参数geocodeAddressString(仅用于查找地址的字符串表示形式)。

最重要的是,进行本地搜索并在地图应用程序中显示结果比您上面所设想的要容易得多。您需要做的就是:

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];
    }
}];

实际上,在后一个示例中,您在自己的地图视图上显示结果,您可能会创建自己的自定义注释类,以便您可以更好地控制viewForAnnotation方法中注释视图的呈现。但希望这能说明主要观察结果,即在使用时MKLocalSearch,您根本不应该使用CLGeocoder方法geocodeAddressString

于 2014-08-22T05:15:34.727 回答