专栏首页ios 技术积累iOS 后台持续定位

iOS 后台持续定位

在日常的工作开发中,有时会遇到需要在后台持续运行的需求。对于这个需求,安卓实现起来比较简单,而iOS来说就比较复杂了。我们公司就有后台持续定位并且上传上传地理坐标的需求, 现在总结一下

实现方式一

因为项目用的百度定位SDK,而百度定位就自带后台定位功能所以可以直接用。

这里说明一下为什么要用百度SDK,因为项目要用定位获取的经纬度、城市信息请接口,而CLLocationManager返回的经纬度和百度是有差别的需要转换,有可能同一位置百度和苹果定位返回的定位信息有差别。为了统一iOS和Android都统一使用百度。

百度SDK后台定位

1.引入头文件

在调用定位功能的类中引入 BMKLocationComponent.h 这个头文件。

#import <BMKLocationkit/BMKLocationComponent.h>
2.配置AK

在调用定位时,需要添加AK,需要注意的是请在 SDK 任何类的初始化以及方法调用之前设置正确的 AK。设置AK的方式如下:

[[BMKLocationAuth sharedInstance] checkPermisionWithKey:@"输入AK" authDelegate:self];
3.设置期望定位精度

由于苹果系统的首次定位结果为粗定位,其可能无法满足需要高精度定位的场景。 百度提供了 kCLLocationAccuracyBest 参数,设置该参数可以获取到精度在10m左右的定位结果,但是相应的需要付出比较长的时间(10s左右),越高的精度需要持续定位时间越长。

推荐使用kCLLocationAccuracyHundredMeters,一次还不错的定位,偏差在百米左右,超时时间设置在2s-3s左右即可。

//初始化实例
_locationManager = [[BMKLocationManager alloc] init];
//设置delegate
_locationManager.delegate = self;
//设置返回位置的坐标系类型
_locationManager.coordinateType = BMKLocationCoordinateTypeBMK09LL;
//设置距离过滤参数
_locationManager.distanceFilter = kCLDistanceFilterNone;
//设置预期精度参数
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//设置应用位置类型
_locationManager.activityType = CLActivityTypeAutomotiveNavigation;
//设置是否自动停止位置更新
_locationManager.pausesLocationUpdatesAutomatically = NO;
//设置是否允许后台定位
_locationManager.allowsBackgroundLocationUpdates = YES;
//设置位置获取超时时间
_locationManager.locationTimeout = 10;
//设置获取地址信息超时时间
_locationManager.reGeocodeTimeout = 10;

更多详细介绍及其余精度阈值说明,请查看参考手册。

4.开启持续定位

调用BMKLocationManager提供的startUpdatingLocation方法实现。代码如下:

[self.locationManager startUpdatingLocation];

如果需要持续定位返回地址信息(需要联网),请设置如下:

[self.locationManager setLocatingWithReGeocode:YES];
[self.locationManager startUpdatingLocation];
5.接收位置更新

实现BMKLocationManagerDelegate代理的BMKLocationManager: didUpdateLocation: orError:方法,处理位置更新。代码如下:

- (void)BMKLocationManager:(BMKLocationManager * _Nonnull)manager didUpdateLocation:(BMKLocation * _Nullable)location orError:(NSError * _Nullable)error

{
    if (error)
    {
        NSLog(@"locError:{%ld - %@};", (long)error.code, error.localizedDescription);  
    } if (location) {//得到定位信息,添加annotation
        if (location.location) {
            NSLog(@"LOC = %@",location.location);
        }
        if (location.rgcData) {
            NSLog(@"rgc = %@",[location.rgcData description]);
        }   
    }
}
6.停止持续定位

当不再需要定位时,调用BMKLocationManager提供的stopUpdatingLocation方法停止定位。代码如下:

[self.locationManager stopUpdatingLocation];
7.更改info.plist

将info.plist的字段改成NSLocationWhenInUseUsageDescription,NSLocationAlwaysUsageDescription,NSLocationAlwaysAndWhenInUseUsageDescription三项。

在左侧目录中选中工程名,开启 TARGETS->Capabilities->Background Modes 在Background Modes中勾选 Location updates,如下图所示:

屏幕快照 2018-11-30 09.21.59.png

实现方式二

使用CLLocationManager 定位

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    [self keepBackgroundTask];
}
- (void)keepBackgroundTask
{
     [self startBgTask];
    
    if (!self.locationManager) {
        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
        [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
        [self.locationManager requestAlwaysAuthorization];
        self.locationManager.allowsBackgroundLocationUpdates = YES;
        self.locationManager.pausesLocationUpdatesAutomatically = NO;
    }
    
     [self.locationManager startUpdatingLocation];  
}

- (void)startBgTask
{
    UIApplication *application = [UIApplication sharedApplication];
    __block UIBackgroundTaskIdentifier bgTask;
    bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
        
    }];
    
}

屏幕快照 2018-11-30 09.21.59.png

开启后台定位审核被拒参考: IOS开启后台定位之审核被拒

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • iOS 事件传递与视图响应链

    当你点击了屏幕上的某个view,这个动作由硬件层传导到操作系统,UIKit 就会打包出一个 UIEvent 对象,然后会把这个Event分发给当前正在活跃的 A...

    赵哥窟
  • iOS UITextField 限制输入

    但是如果很多页面的TextField控件需要验证这样写就很麻烦,为了不重复造轮子。写了一个Category。只实现了输入长度限制,输入数字,输入字母,如果不能满...

    赵哥窟
  • ios Charts MarkerView遇到的一个问题

    两个问题 问题1:最大值的的时候 MarkerView 坐标有问题 ,原因就是最大值的时候,曲线已经在View的顶部了,所以MarkerView 的Y坐标还要...

    赵哥窟
  • 超30亿中文数据首发!首个专为中文NLP打造的GLUE基准发布

    10 月 18 日,2019 中关村论坛平行论坛 ——AI WORLD 2019 世界人工智能峰会在北京启幕。新智元杨静、科大讯飞胡郁、微软王永东、华为王成录、...

    新智元
  • PHP函数之日期时间函数date()详解

    format 必需。规定时间戳的格式。 timestamp 可选。规定时间戳。默认是当前的日期和时间。

    华创信息技术
  • 既得利益者的灭顶之灾:当数字货币结合证券...

    区块链大本营
  • 游戏AI小试牛刀(1)

    现在大家在各种领域使用机器人的事情是越来越多,包括在家政领域和教学领域等等这些在我们身边每天都能接触到的领域。而游戏中使用AI也是一件非常有趣的事情。 为此,我...

    刀刀老高
  • 图穷匕见:K近邻算法与手写数字识别

    机器学习算法是从数据中产生模型,也就是进行学习的算法。我们把经验提供给算法,它就能够根据经验数据产生模型。在面对新的情况时,模型就会为我们提供判断(预测)结果。...

    用户1682855
  • LeetCode 1487. 保证文件名唯一(哈希map)

    给你一个长度为 n 的字符串数组 names 。你将会在文件系统中创建 n 个文件夹:在第 i 分钟,新建名为 names[i] 的文件夹。

    Michael阿明
  • python---列表、元组

    列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储、修改等操作。

    py3study

扫码关注云+社区

领取腾讯云代金券