《2022年2022年后台定位上传的代码实践》由会员分享,可在线阅读,更多相关《2022年2022年后台定位上传的代码实践(8页珍藏版)》请在金锄头文库上搜索。
1、后台定位上传的代码实践前言之前的文章 说过我现在做的是LBS定位的社交APP 其中主要的一个功能就是能够实时定位社交圈中各个成员的位置后台实时上传位置则是非常重要的一个技术点接下来就来说说我关于这方面的实践经验需求先来看看实现这个功能的具体需求是什么由于我们是实时定位的生活类社交APP 所以我们需要做到一下几点1. 如果用户的位置在持续变化则隔一段时间上报一次由于我们希望能够实时的将用户的位置变化反馈在APP里 所以定时的上报是刚需2. 如果用户的移动速度很慢则隔一段距离上报一次如果用户是低速率的状态(比如步行的移动速度大概就是1m/s 左右 ) 这个时候如果还按(1)中的方式来上报的话由于变
2、化太小地图上的点会非常的密集这种数据的意义不大(而且如果要做轨迹服务的话这些密集点都是必须有花掉的) 所以这时候我们按照距离间隔来上报3. 如果用户的位置在到达某处后没有变化则不继续上报我们只关心位置的变化如果用户的位置没有变化或者变化很小其实是不需要上报其位置的(比如进入的公司或者等一个很长时间的红灯) 这时候我们就不上报(以达到省电的目的) 4. 切换到后台也要能定位上报后台上报是必须的用户不可能一直运行着我们的APP (iOS4开始就支持了) 5. APP因各种原因终止运行后(用户主动关闭 , 系统杀掉 ) 也要能定位上报用户主动关闭APP 的几率不大但是因系统调度被杀掉的情况是很普遍的
3、这个时候我们也要能够上报(iOS7开始已支持被杀掉后唤醒) 分析完需求接下来就开始介绍如何实现准备首先做一些准备工作在target的Capabilities选 项 中 打 开Background Modes 并 勾 选Location updates然后在 plist 中添加 NSLocationAlawaysUsageDescription 的键在 value 中随便键入任何内容名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 8 页 - - - - - - - - -
4、完成这两步我们的前期工作就完成了 Background Modes 是iOS7 带入的新功能而NSLocationAlawaysUsageDescription 为了增强权限机制引入的提示描述不添加这个的话定位功能可是使用不了的代码定位肯定要跟CLLocationManager 打交道所以我们先定义一个CLLocationManager 的子类并根据需求中的几点定义三个变量interface MMLocationManager : CLLocationManager + (instancetype)sharedManager; property (nonatomic, assign) CGFl
5、oat minSpeed; / 最小速度property (nonatomic, assign) CGFloat minFilter; / 最小范围property (nonatomic, assign) CGFloat minInteval; / 更新间隔end这里解释一下这几个参数minSpeed 如果当前运动速度大于此值则满足需求 (1) 以时间为更新依据(minFilter) 如果当前运动速度小于此值则满足需求 (2) 以范围为更新依据(minInteval) minFilter 最小的触发范围用于需求 (1) minInteval 更新间隔用于需求 (2) 接下来是初始化函数- (i
6、nstancetype)init self = super init; if ( self ) self.minSpeed = 3; self.minFilter = 50 ; self.minInteval = 10 ; self.delegate = self; self.distanceFilter = self.minFilter; self.desiredAccuracy = kCLLocationAccuracyBest; return self; 这里的默认值可以根据需求来调整然后是位置更新后的处理逻辑其实也非常的简单、- (void)locationManager:(CLLoc
7、ationManager *)manager didUpdateLocations:(NSArray *)locations 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 8 页 - - - - - - - - - CLLocation *location = locations0; NSLog(%,location); / 根据实际情况来调整触发范围 self adjustDistanceFilter:location; / 上传数据 self uploadLocat
8、ion:location; 而这个adjustDistanceFilter函数就是整个代码的核心会根据当前速度来动态的调整distanceFilter 这个参数以满足我们的需求/* 规则 : 如果速度小于minSpeed m/s 则把触发范围设定为50m* 否则将触发范围设定为minSpeed*minInteval* 此时若速度变化超过10% 则更新当前的触发范围( 这里限制是因为不能不停的设置distanceFilter,* 否则 uploadLocation会不停被触发 )*/- (void)adjustDistanceFilter:(CLLocation*)location / NSLo
9、g(adjust:%f,location.speed);if ( location.speed 0.1f ) self.distanceFilter = self.minFilter; else CGFloat lastSpeed = self.distanceFilter/self.minInteval; if ( (fabs(lastSpeed-location.speed)/lastSpeed 0.1f) | (lastSpeed Location-Freeway Drive) 结果如下名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - -
10、- - - 名师精心整理 - - - - - - - 第 4 页,共 8 页 - - - - - - - - - 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 8 页 - - - - - - - - - 接下来我们会讨论一下相关的几个问题名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 8 页 - - - - - - - - - 讨论为什么不用定时器
11、来控制定位间隔网上有很多教程是用NSTimer 来实现的但是其实这样不是很好虽然定位的间隔是固定的但是耗电的问题无法解决后台会持续的更新定位无论当前的位置是否在更新当然如果你的使用场景就是要每隔一段时间来上传就可以使用定时器来处理使用 distanceFilter 来处理会有些什么问题由于 distanceFilter=currentSpeed*minInteval 那么间隔的时间因为速度的变化而会有波动但是这个波动是在可接受范围的如果速度加快或者变慢那么下一次的更新时间则会相应的缩短或者变长但是因为我们是在真实生活环境中速度的变化不可能那么快所以这个误差是可以接受的另外我们对distance
12、Filter 针对速度进行矫正因而总体来说间隔还是会保持在我们与其的范围内的为什么不使用allowDeferredLocationUpdatesUntilTraveled:timeout: allowDeferredLocationUpdatesUntilTraveled是 iOS6推出的一个新的API 看名字我们可以知道这个函数的作用是延迟位置更新直到移动了xx 米或者时间超过了xx 秒 那么这个函数不正好满足了我们的所有要求么? 可是万万没想到事情并不是这样的这个函数并不好用接下来是吐槽时间? (? ) 为什么说这个函数不好用呢? 首先这个函数的要求很多我们来看看要这个函数起作用要满足哪些
13、条件必须 iPhone5 以及之后的硬件设备才支持desiredAccuracy必须设置为kCLLocationAccuracyBest或者kCLLocationAccuracyBestForNavigation distanceFilter 必须设置为kCLDistanceFilterNone 只在 APP运行在后台时生效前台运行时是不会进行延迟处理的只有系统在低功耗(Low Power State)的时候才有可能生效关于 Low Power State 在 iOS中的描述我只在苹果官网的文档中找到部分定义iOS is very good at getting a device into a
14、 low power state when its not being used. At idle, very little power is drawn and energy impact is low. When tasks are actively occurring, system resources are being used and those resources require energy. However, sporadic tasks can cause the device to enter an intermediate state neither idle nor
15、active when the device isn t doing anything. There may not be enough time during these intermediate states for the device to reach absolute idle before the next task executes. When this occurs, energy is wasted and the users battery drains faster. 据我简单的了解这个 *Low Power State”只有在黑屏的状态下(不只是锁屏 )才有可能触发只要
16、有任何电量屏幕的操作(就连推送也算 ) 都会使APP 退出这个状态同时如果在充电状态下也是无法进入的我尝试在真机和模拟器上使用这个API 但结果APP 还是以1HZ 的频率在定位(设置了kCLDistanceFilterNone 的原因 ) 虽然locationManager:didFinishDeferredUpdatesWithError:在指定的时间后成功的回调了但是结果还是没有deffer 于是我查了一下原来这个函数无法直接进行调试的因为 : 不支持模拟器 deferredLocationUpdatesAvailable用于检测设备是否支持模拟器会返回NO 不支持真机调试因为调试时Xc
17、ode 会阻止程序休眠导致程序无法进入低功耗状态结论就是这个东西连调试都没办法所以我也没有那么多时间跑到外面去测试这个东西名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 8 页 - - - - - - - - - 况且使用我上述的方法已经基本可以满足需求所以我已放弃继续研究这个API 了 因为就算使用了这个东西也仅仅是锦上添花而已如果有哪些同学知道如何正确的使用这个东西请留言告诉我万分感谢 ! 【编辑推荐】1.值得收藏!神级代码编辑器 Sublime Text 全程指南2.问题记录: iOS用户行为统计代码的剥离3.微信 死亡代码 如今成其手中的敲诈工具4.3 年代码总结分享5.关于烂代码的那些事名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 8 页 - - - - - - - - -