由于公司SDK需要定位设备位置来做一些操作,所以就用了系统的CLLocation去做了简单的定位和经纬度反编译。但是在反编译的时候遇到一些问题,CLGeocoder报错。
话不多说,贴上代码
@interface TimeAndLocation ()<CLLocationManagerDelegate>
@property (nonatomic,strong)CLLocationManager *locationManager;
@property (nonatomic , strong)CLLocation *location;
@end
@implementation TimeAndLocation
+(TimeAndLocation *)getInstance{
static TimeAndLocation *timeAndLocation = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
timeAndLocation = [[TimeAndLocation alloc]init];
timeAndLocation.locationManager = [[CLLocationManager alloc]init];
timeAndLocation.locationManager.delegate = timeAndLocation;
timeAndLocation.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
timeAndLocation.locationManager.distanceFilter = kCLLocationAccuracyBestForNavigation;
[timeAndLocation.locationManager requestAlwaysAuthorization];
[timeAndLocation.locationManager requestWhenInUseAuthorization];
[timeAndLocation.locationManager startUpdatingLocation];
});
return timeAndLocation;
}
#pragma mark - LocationDelegate
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
CLLocation *location = [locations lastObject];
NSLog(@"地理位置信息%@",location);
CLLocationCoordinate2D coordinate = location.coordinate;
NSLog(@"%f --- %f",coordinate.latitude,coordinate.longitude);
CLGeocoder *clgeocoder = [[CLGeocoder alloc]init];
[clgeocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (placemarks) {
CLPlacemark *placemark = [placemarks firstObject];
NSLog(@"%@",placemark);
}
[self.locationManager stopUpdatingLocation];
}];
}
由于还需要其他逻辑,就简单封装了一个类,方便外部使用。
然后,运行就报错了
有人说是
[clgeocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (placemarks) {
CLPlacemark *placemark = [placemarks firstObject];
NSLog(@"%@",placemark);
}
[self.locationManager stopUpdatingLocation];
}];
中的location的问题,
也有人说是 没有设置info.plist里面的权限(8.0之后需要经过用户同意),
还有人说把xcode中 Edit scheme 里面 run-Options-all location simulation 默认使用模拟器勾选去掉,重新运行模拟器reset content and settings,再勾选上,
然而我的代码里面都有,以上方法都尝试了都不行
【解决过程】
1.关于错误kCLErrorDomain,也找到了官网的解释:
kCLErrorDomain
The domain for Core Location errors.
extern NSString *const kCLErrorDomain;Constants
kCLErrorDomain
The domain for Core Location errors. This value is used in the
NSError
class.Available in iOS 2.0 and later.
Declared in
CLErrorDomain.h
.
但是很明显,没有具体解释原因,所以没法帮助解决问题。
2.最后是从
找到
Location Manager Error : (KCLErrorDomain error 0)
得知Apple的电脑中,有对应的无线(Wi-Fi)管理软件Airport。
而对应的上述的CLGeocoder去执行坐标转换为地理信息,是通过底层的CoreLocation实现的。
而CoreLocation是依赖于当前网络的。
而当前在Xcode中是使用iOS模拟器调试代码的。
所以,此处iOS模拟器,只是使用Ethernet链接网络的话,CoreLocation就无效了。
所以要去开启Airport。
3.结果,由于我的是黑苹果,所以里面没有无线网卡,导致:
系统偏好设置->网络:
里面没有Airport:
所以也就无法开启Airport,无法使用Wifi。
也尝试了通过向导创建Wifi,未成功。
也去试了试搜索Airport,但是还是打开的上述页面。
4.去VirtualBox中看了看,结果也找不到有什么虚拟的无线网卡供选择的:
所以,貌似现在无法解决此问题,无法开启VirtualBox中的Mac的Airport。
【总结】
真机运行OK的
CLGeocoder的reverseGeocodeLocation出现kCLErrorDomain的原因,在于用的是Xcode的iOS模拟器中,没有无线网络,导致CLGeocoder所依赖的底层的CoreLocation出错。
解决办法是:开启Mac的Airport即可。