在日常应用中,经常有需要使用到定位功能,用来判断用户的位置,并且做个性化的设定,或者获取用户位置,做数据分析等其他功能。
定位功能位于iOS的CoreLocation中,无论使用原生还是第三方定位,都需要手动或者第三方自动引入该定位框架。使用原生定位功能可以参考下面的文章,这是链接。
这里我们使用github上的一个第三方定位,可以持续定位并上传用户位置信息到服务器。
1、原始Location定位github地址
2、从上面的地址中下载代码,然后使用xcode打开,运行项目,就可以看到定位的效果,项目每隔60秒会上传定位信息到服务器,每隔10秒停止定位服务,每隔60秒会重启定位服务,上面的时间都是从0开始计时,也就是第一次开启定位后,过10秒会停止定位服务,获取的定位信息会通过精度(accuracy)比较获取最佳的定位信息,如果没有获取,就选择上一次定位的,10秒后停止定位服务,再过50秒会去重启定位服务,同时将获取的最佳定位信息上传到服务器。
![](https://img.haomeiwen.com/i1083100/b2c1a8c0b7e37894.png)
上面的第三方库主要有下面几个问题:
1)上传服务器的代码需要写在这个第三方库中,侵入性比较强。
2)获取到的只有经纬度和定位精度信息,(图中看到的地址信息是改进的版本)
3)可以配置的属性比较少,比如上传服务器的时间间隔,定位的时间间隔,
改进后的Location的地址:github地址
1、改进后主要使用block的方式用来上传定位信息,现在可以更加方便的定制需要上传的服务器的信息,如用户信息
2、使用方法,将文件复制在项目中,在你需要持续定位的位置使用下面的代码, 一般是appdelegate的didFinish代理方法中,也就是程序启动后开启定位。
// 获取位置信息后,隔10秒会关闭位置服务,50秒会重启定位服务(这个期间定位服务不会重启),同时会上传位置信息
self.locationTracker = [[LocationTracker alloc] init];
self.locationTracker.uploadLocationTimeInterval = 60.0; // 这个要大于50秒,不然会有失效的情况
[self.locationTracker startLocationTracking];
self.locationTracker.upLoadBlock = ^(CLPlacemark *placemark){
// 城市名称
NSString *city = placemark.locality;
// 街道名称
NSString *street = placemark.thoroughfare;
// 全称
NSString *name = placemark.name;
NSLog(@"city:%@, street:%@, name:%@", city, street, name);
};
3、除了上面的代码,还需要在项目中加入一下配置和一些注意事项
- 在项目的Capabilities中Background Modes中开启Location updates和Background fetch
![](https://img.haomeiwen.com/i1083100/dd2bec4464dfeda8.png)
- 自iOS8起,系统定位功能进行了升级,开发者在使用定位功能之前,需要在info.plist里添加(以下二选一,两个都添加默认使用NSLocationWhenInUseUsageDescription):
NSLocationWhenInUseUsageDescription ,允许在前台使用时获取GPS的描述
NSLocationAlwaysUsageDescription ,允许永久使用GPS的描述
![](https://img.haomeiwen.com/i1083100/0338207b437cd2eb.png)
3)模拟器中的debug-->Location中选择定位的位置,可以自己定义
![](https://img.haomeiwen.com/i1083100/f30cce983d8045f7.png)
这个改进版还在进行中,可能会存在一些问题,持续改善中。
网友评论
我之前研究地图的时候也是看的这个原始Demo,它没法做到前后台依次切换.
此外,对于高德API和百度API,有相关的持续后台操作的功能么?好像都和iOS系统自带的API一样.
此外,关于定位精准度的 问题:
由于:iOS系统的定位采用的是混合定位的方式,通过GPS、Wifi、手机基站信号共同定位的方式来提高定位精度,虽说如此,但偶尔出现某个点的定位误差依然是难以避免的,当出现较大偏差时,会导致路径上有某个明显凸出的点,或整条路径毛刺现象严重,即使长时间在一个位置不动,也会出现定位点在附近导出乱飘的情况。这些问题只能通过算法分析来修正。
需要用到 卡尔曼滤波 算法修正,卡尔曼滤波算法,您有相关的iOS代码么?
我的每次回调的方法的location 是保存在一个数组里,要是不符合我设置的阈值,那我是不是还要检索当前数组的下标?
你这个思路 挺好,但是好像对数组处理这一块有点难办.
还有关于这个阈值怎么设置?accurary 这个值一般的从室内到室外,波动范围是:5 ~ 700之间,数值越小说明越不准确,我目前自己做一个跑步软件demo做着玩,其中就遇到了这个问题的处理方式.
有机会可以交流一下
self.shareModel.timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self
selector:@selector(restartLocationUpdates)
userInfo:nil
repeats:NO];
可以先invalidate,然后再重新建立一个NSTimer赋给他。
if (self.shareModel.timer) {
[self.shareModel.timer invalidate];
self.shareModel.timer = nil;
}
self.shareModel.timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self
selector:@selector(restartLocationUpdates)
userInfo:nil
repeats:NO];
上面的这些操作,可以直接在LocationTracker中完成,对照
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
的写法。
2、使用百度和高德api,由于我没有做过相应的尝试,所以不好回答,但是有关于他们持续后台定位的文章,http://lbsyun.baidu.com/index.php?title=iossdk/guide/location 他们都是对原生的api进行了封装,所以只要找到对应的后台持续定位的属性,开启就可以。(可能会有坑)
3、定位精准度的问题,其实在提供的代码中已经对定位进行了筛选,是通过accurary选定的,你说的那个问题确实存在,用图形图像中的方法确实可以很好的解决,可以用下面简单的方法:将路径上已经通过精度比较的点保存在一个数组中,然后对于超出自己设定阈值的点,使用邻近的5~10个点的中值,然后去替代,这其实就是一种平均值滤波,你说的那种应该是最优的线性滤波方法,我这边木有相关代码。