从 reverseGeocodeLocation 获取位置名称

Posted

技术标签:

【中文标题】从 reverseGeocodeLocation 获取位置名称【英文标题】:Get Location name from reverseGeocodeLocation 【发布时间】:2016-12-19 06:58:02 【问题描述】:

我想使用 reverseGeocodeLocation 找出照片位置。我使用下面的函数

@interface GalleryPhotosViewController ()

CLPlacemark *placemark;

@end

-(NSString *)getLocation:(CLLocation *)locations
CLGeocoder *geocoder = [CLGeocoder new];
[geocoder reverseGeocodeLocation:locations completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) 
    placemark = [placemarks lastObject];
];
return placemark.name;

调用该函数时我无法获得该名称,但在执行其他代码部分后我得到了该名称。我知道 reverseGeocodeLocation 有一个完成块,当执行到达它时它被移交给另一个线程。但是我需要在调用函数时获取该名称。我经历了很多解决方案,但无法解决我的问题。 我想在 currentLocation 中接收位置名称。

CLLocation *loc = asset.location;
NSString *currentLocation = [self getLocation:loc];

我应该在哪里更改我的代码。请帮忙。

【问题讨论】:

lacemark = [placemarks lastObject]; 行下方打印placemark.name(在完成处理程序中)并告诉我它是否会给出任何值! NSLog(@"addressDictionary %@", placemark.addressDictionary);你的坐标的打印地址。在 [geocoder reverseGeocodeLocation:locations completionHandler:^(NSArray * _Nullable placemarks, NSError * _Nullable error) placemark = [placemarks lastObject]; ]; 对,但我想在每次调用方法时都使用块外的值。 @狮子 【参考方案1】:

这是因为在 reverseGeocodeLocation 的完成处理程序中获取值之前,您正在返回值。现在,您无法从任何 completion block 返回值,因此您需要创建自己的 completionblock 并在获得类似结果时调用它,

 -(void)getLocation:(CLLocation *)locations withcompletionHandler : (void(^)(NSString *name))completionHandler


CLGeocoder *geocoder = [CLGeocoder new];
[geocoder reverseGeocodeLocation:locations completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) 
    placemark = [placemarks lastObject];

    completionHandler(placemark.name);

];


然后这样称呼它,

   [self  getLocation:location withcompletionHandler:^(NSString *name) 

    NSLog(@"your name : %@",name);  // or do whatever you want with name!
];

更新:

如果您想要在完成处理程序中使用整个数组,就像您在评论中提到的那样,那么您的方法应该是这样的,

 -(void)getLocation:(CLLocation *)locations withcompletionHandler : (void(^)(NSArray *arr))completionHandler



CLGeocoder *geocoder = [CLGeocoder new];
[geocoder reverseGeocodeLocation:locations completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks,
                                                               NSError * _Nullable error) 
   // placemark = [placemarks lastObject];

    completionHandler(placemarks);

];


你可以这样称呼它,

 [self getLocation:location withcompletionHandler:^(NSArray *arr) 

    // you will get whole array here in `arr`, now you can manipulate it according to requirement
    NSLog(@"your response array : %@",arr);

    CLPlacemark *placemark = [arr lastObject];

];

【讨论】:

同样的问题,我只在 [self getLocation:location withcompletionHandler:^(NSString *name) ]; 块内得到了名称,但我需要更新 currentLocation。 @狮子 那你想要什么?如果您还想要其他东西,您可以向方法添加更多参数。我没有让你清楚!你到底想达到什么目标? 好的,让我说清楚。 currentLocation 在块 [self getLocation:location withcompletionHandler:^(NSString *name) ]; 之外声明。结果,我无法在[self getLocation:location withcompletionHandler:^(NSString *name) ]; 块之外获得name,也无法更新我的currentLocation。但我需要更新currentLocation 以进行进一步操作。 但是getLocation 方法将如何给出当前位置?您正在传递位置并且它正在返回地址(反向地理编码!),那么您如何期望它的当前位置???? 其实我说的是那个地址。我只想通过currentLocation 使用该地址。现在我的问题是我可以在区块之外使用该地址吗?【参考方案2】:

CLGeocoder 类的方法reverseGeocodeLocation 异步运行,因此您不会从被调用函数获取位置数据作为返回值。它使用返回位置数据的完成处理程序,您可以使用该完成处理程序块来更新 UI 或进一步处理您的位置数据。

【讨论】:

没错。我在街区内获得价值,但在街区外却没有。你能告诉我如何用完成处理程序中照片的位置数据更新我的currentLocation。我试过了,但更新失败。 @Gurdev 您应该将getLocation() 更改为返回void,并且当您的完成处理程序块被执行时,placemark 对象将具有使用reverseGeocodeLocation() 找到的位置值。在那里你可以访问它的值。如果需要更多帮助,请告诉我。【参考方案3】:

获取您必须通过纬度和经度的城市,州和地址, 所以传递纬度和经度将传递给地理编码器块和 在块内,您将放置标记数组。

CLGeocoder *geocoder = [[CLGeocoder alloc] init];

    CLLocation *myLocation = [[CLLocation alloc]initWithLatitude:23.0225
                                                        longitude:72.5714];



    [geocoder reverseGeocodeLocation:myLocation
                   completionHandler:^(NSArray *placemarks, NSError *error) 

                       if (error) 
                           NSLog(@"Geocode failed with error: %@", error);
                           return;
                       

                       if (placemarks && placemarks.count > 0)
                       
                           CLPlacemark *placemark = placemarks[0];

                           NSDictionary *addressDictionary =
                           placemark.addressDictionary;

                           NSLog(@"%@ ", addressDictionary);
                           NSString *address = [addressDictionary
                                                objectForKey:(NSString *)kABPersonAddressStreetKey];
                           NSString *city = [addressDictionary
                                             objectForKey:(NSString *)kABPersonAddressCityKey];
                           NSString *state = [addressDictionary
                                              objectForKey:(NSString *)kABPersonAddressStateKey];


                           NSLog(@"%@ %@ %@ %@", address,city, state);
                       

                   ];

【讨论】:

不要只发布代码。请说明问题所在并说明您的回答如何解决问题。

以上是关于从 reverseGeocodeLocation 获取位置名称的主要内容,如果未能解决你的问题,请参考以下文章

使用 reverseGeocodeLocation: 设置地址字符串并从方法返回

无法从 CLGeocoder reverseGeocodeLocation 返回字符串

reverseGeocodeLocation 存储为 NSString 产生错误

reverseGeocodeLocation(_ location: CLLocation) 方法是不是在离线模式下工作?

使用 reverseGeocodeLocation 将用户的状态作为 NSString 返回

如何本地化来自 reverseGeocodeLocation 的地址结果?