适配ios8.0/7.0定位

现象

假如你用做ios8之前的定位去在ios8.0的机子上跑的话,你会发现 诶?怎么定位功能不能用了,右上角那个定位的小图标不出来。这时你应该去了设置里面看看隐私——定位,看到没有开启,然后改成始终,然后程序重新跑过,然后你又发现还是不能用。。。于是你又去设置那里看看,靠 发现改成的始终怎么给取消了。。(其实这就是我。。)

原因

在以前的IOS版本中当开始使用定位服务时会自动弹出询问授权的对话框,而现在IOS8需要手动调用locationManager requestAlwaysAuthorization手动申请授权,来获取定位权限。
苹果在ios8.0之后给了我们两个东西

- (void)requestWhenInUseAuthorization __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0);

- (void)requestAlwaysAuthorization __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0);

这两个东西呢 就是用来手动获取定位权限的。你可以分别设置 注意看,当你使用上面的 第一次会提示窗口 当你使用可不可以获取你位置,下面这个则会弹出当你未使用可不可以,当然 下面这个更强大。。。

苹果官方是这么说的 大家去看API吧。。

在ios8.0中的方法

假如你用的是百度定位 或者任何第三方定位 都没关系,因为现在的方法仅仅是提供一个把定位功能开启的作用,我们要用到苹果自己的定位参数

        _locationManager = [[CLLocationManager alloc] init];//创建位置管理器
        _locationManager.delegate = (id)self;
        _locationManager.desiredAccuracy=kCLLocationAccuracyBest;
        _locationManager.distanceFilter=100.0f;
        //定位服务是否可用
        _enable=[CLLocationManager locationServicesEnabled];
        //是否具有定位权限
        _status=[CLLocationManager authorizationStatus];
        if(!_enable || _status<3){
            //请求权限
            [_locationManager requestAlwaysAuthorization];
//            [_locationManager requestWhenInUseAuthorization];
        }

记住  locationManager必须是全局变量 ,不可为局部变量,当为局部变量是手动定位 提示AlertView会一闪而过!  我刚开始就一直出现就没了,点都来不及点,所以这样肯定不行的,后面自己试着试着就可以了,原来是无意之中设为全局就行了。


在info.plist里面添加一个key: NSLocationAlwaysUsageDescription,value 好像是可以随便设的。。

或者 NSLocationWhenInUseUsageDescription  BOOL 类型 数值为YES 或者好像是随便设的。。。


这样之后  系统就会提示是否开启了。 当然,上述方法是放在AppDelegate里面的,程序第一次刚启动,就先告诉用户。

但是,假如我们在用到的时候才提醒呢,这时假如你也这样写,在询问之后 

       [_userLocationstartUserLocationService];

这样会发生什么呢,这样会导致第一次显示不出来,因为询问的时候 这个百度的开启定位功能已经执行了,所以第一次不行,你第二次进来才显示正确。

这时就要用到

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status;

这个就是状态改变的时候会做的,但是我发现,刚开始 点了之后会执行一次,当你定位又会执行一次,至于为什么 我也没去多想,总之 我是在里面这样判断

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
    
    _enable=[CLLocationManager locationServicesEnabled];
    _status=[CLLocationManager authorizationStatus];
    if(!_enable || _status<3){
        
    }else{
        [_mapView viewWillAppear];
        [_userLocation startUserLocationService];
        //    _mapView.showsUserLocation = NO;//先关闭显示的定位图层
        _mapView.userTrackingMode = BMKUserTrackingModeNone;//设置定位的状态
        _mapView.showsUserLocation = YES;//显示定位图层
        
        _mapView.delegate = self;
        _geocodesearch.delegate = self;
        _userLocation.delegate = self;
        _walkingRoutePlanOption.delegate = self;
    }
}
这样就搞定了 此时,把要定位的都放这里。但是 你这样写完之后 在ios7上跑就会报错了,因为你用了ios8的方法,此时我们就要适配了。。

适配ios8.0/7.0定位

#define IOSVersion                          [[[UIDevice currentDevice] systemVersion] floatValue]

#define IsIOS7Later                         !(IOSVersion < 7.0)

#define IsIOS8Later                         !(IOSVersion < 8.0)


直接贴上代码

在AppDelegate中可以这么写

    if (IsIOS8Later) {
        _locationManager = [[CLLocationManager alloc] init];//创建位置管理器
        _locationManager.delegate = (id)self;
        _locationManager.desiredAccuracy=kCLLocationAccuracyBest;
        _locationManager.distanceFilter=100.0f;
        //定位服务是否可用
        _enable=[CLLocationManager locationServicesEnabled];
        //是否具有定位权限
        _status=[CLLocationManager authorizationStatus];
        if(!_enable || _status<3){
            //请求权限
            [_locationManager requestAlwaysAuthorization];
//            [_locationManager requestWhenInUseAuthorization];
        }
    }
    return YES;

假如你是在控制器中的话

- (void)viewDidLoad

   if(IsIOS8Later){
        _locationManager = [[CLLocationManager alloc] init];//创建位置管理器
        _locationManager.delegate = (id)self;
        _locationManager.desiredAccuracy=kCLLocationAccuracyBest;
        _locationManager.distanceFilter=100.0f;
        //定位服务是否可用
        _enable=[CLLocationManager locationServicesEnabled];
        //是否具有定位权限
        _status=[CLLocationManager authorizationStatus];
        if(!_enable || _status<3){
            //请求权限
            [_locationManager requestAlwaysAuthorization];
            [_locationManager requestWhenInUseAuthorization];
        }
    }else{
        [_userLocation startUserLocationService];
        _mapView.showsUserLocation = NO;//先关闭显示的定位图层
        _mapView.userTrackingMode = BMKUserTrackingModeNone;//设置定位的状态
        _mapView.showsUserLocation = YES;//显示定位图层
        
    }

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
    
    _enable=[CLLocationManager locationServicesEnabled];
    _status=[CLLocationManager authorizationStatus];
    if(!_enable || _status<3){
        
    }else{
        [_mapView viewWillAppear];
        [_userLocation startUserLocationService];
        //    _mapView.showsUserLocation = NO;//先关闭显示的定位图层
        _mapView.userTrackingMode = BMKUserTrackingModeNone;//设置定位的状态
        _mapView.showsUserLocation = YES;//显示定位图层
        
        _mapView.delegate = self;
        _geocodesearch.delegate = self;
        _userLocation.delegate = self;
        _walkingRoutePlanOption.delegate = self;
    }
}

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    if(IsIOS8Later){
        if(!_enable || _status<3){
            //请求权限
            [_locationManager requestAlwaysAuthorization];
            [_locationManager requestWhenInUseAuthorization];
        }
    }else{
        [_mapView viewWillAppear];
        [_userLocation startUserLocationService];
        _mapView.showsUserLocation = NO;//先关闭显示的定位图层
        _mapView.userTrackingMode = BMKUserTrackingModeNone;//设置定位的状态
        _mapView.showsUserLocation = YES;//显示定位图层
        
        _mapView.delegate = self;
        _geocodesearch.delegate = self;
        _userLocation.delegate = self;
        _walkingRoutePlanOption.delegate = self;
    }
}

当然 可以继续优化,定位部分是我刚刚学ios的时候做的,写的不太好,就不多说了,大体思路就是这样



==================11月19日更新==========================

由于我的定位 在该界面一些特定的条件下已经停止定位了。但是退出界面后会 右上角又会有个定位图标。
觉得非常奇怪。我明明已经stop定位了。于是去下了最新百度地图的SDK看。发现我以上说的关于适配ios7.0,8.0定位现在没什么必要了。。。
现在假如你用百度定位,将变的非常简单,只需在

 *需要在info.plist文件中添加(以下二选一,两个都添加默认使用NSLocationWhenInUseUsageDescription)

 *NSLocationWhenInUseUsageDescription 允许在前台使用时获取GPS的描述

 *NSLocationAlwaysUsageDescription 允许永远可获取GPS的描述



即可。

还有就是注意几点 直接上官方demo里的方法。
1、
-(void)viewWillDisappear:(BOOL)animated {
    [_mapView viewWillDisappear];
    _mapView.delegate = nil; // 不用时,置nil
    _locService.delegate = nil;
}
无需调用   [ super viewWillDisAppear :animated];

2、
不要有多余的 

[_userLocation stopUserLocationService];

[_userLocation starUserLocationService];

实例化百度地图相关参数。

这3点非常重要,否则你会发现你的定位莫名其妙就不能用了。


3、19号前的 判断是否是ios8的方法已经不需要了,现在可以直接和ios7一样写方法了。只是plist文件要写东西,记住。


还有就是要提醒大家一点。百度地图的.a文件是分为两种的。一个是模拟器的.a,一个真机.a,你可以选择合并或者跑哪个放哪个。


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值