• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 批量地理编码 MKLocalSearch 响应

[复制链接]
菜鸟教程小白 发表于 2022-12-13 01:02:15 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我有一个搜索设置,它在 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-推荐答案


在另一个问题中引用的 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方法。但希望这能说明主要观察结果,即在使用 MKLocalSearch 时,您根本不应该使用 CLGeocoder 方法 geocodeAddressString

关于ios - 批量地理编码 MKLocalSearch 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25438928/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap