美文网首页代码片段iOS常用
iOS在后台锁屏状态下不能持续定位和提交位置信息的解决办法

iOS在后台锁屏状态下不能持续定位和提交位置信息的解决办法

作者: ZYiDa | 来源:发表于2020-08-04 16:59 被阅读0次
    前情提要

    公司一个项目需要用到在登录后,锁屏后台的状态下也能持续性获取定位信息,并且每间隔20S提交到服务端。

    第一步:

    info.plist文件中添加如下内容

    截屏2020-08-04 16.37.59.png
    或者 在TARGET --- Signing&&Capabilities --- Background Mode中勾选Location Updates,如下图
    截屏2020-08-04 16.41.41.png

    第二步:

    由于我用的高德地图来获取位置信息的,那就需要在定位前&&获取定位权限后将AMapLocationManagerpausesLocationUpdatesAutomatically属性设置为NO,allowsBackgroundLocationUpdates属性设置为YES。如下

    - (AMapLocationManager *)locationManager {
        if (!_locationManager) {
            _locationManager = [[AMapLocationManager alloc] init];
            _locationManager.delegate = self;
            [_locationManager setPausesLocationUpdatesAutomatically:NO];
            if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
                _locationManager.allowsBackgroundLocationUpdates = YES;
            }
            _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
            _locationManager.locationTimeout = 2;
            _locationManager.reGeocodeTimeout = 2;
        }
        return _locationManager;
    }
    

    第三部:

    为了方便获取位置信息和提交,我单独写了一个GCD-Timer的管理类,如下

    #import "JTTimerManager.h"
    #import "LocationManager.h"
    static JTTimerManager *jtm = nil;
    
    @interface JTTimerManager ()
    @property (nonatomic, strong) dispatch_source_t reportTimer;
    @end
    
    @implementation JTTimerManager
    
    /*
     创建单利,单利的唯一性
     */
    + (instancetype)share{
    
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            jtm = [[self alloc]init];
        });
        return jtm;
    }
    
    
    /*
     覆盖该方法主要确保 alloc init方法创建对象的唯一性
     */
    + (instancetype)allocWithZone:(struct _NSZone *)zone{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            jtm = [super allocWithZone:zone];
        });
        return jtm;
    }
    
    /*
     确保通过copy产生对象的唯一性
     */
    - (id)copy{
        return self;
    }
    
    /*
     确保通过mutableCopy产生对象的唯一性
     */
    - (id)mutableCopy{
        return self;
    }
    
    #pragma mark - GCD-Timer
    - (dispatch_source_t )timerWithTimeInterval:(NSTimeInterval)timeInterval
                            delay:(NSTimeInterval)delay
                            block:(void (^)(void))block{
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
        dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC));
        uint64_t interval = (uint64_t)(timeInterval * NSEC_PER_SEC);
        dispatch_source_set_timer(timer, start, interval, 0);
        dispatch_source_set_event_handler(timer, ^{
            if(block){
                block();
            }
        });
        return timer;
    }
    
    #pragma mark - 启动定时器
    - (void)startWithTimer:(dispatch_source_t)timer{
        if(timer){
            dispatch_resume(timer);
        }
    }
    
    
    #pragma mark - 取消定时器
    - (void)cancelWithTimer:(dispatch_source_t)timer{
        if(timer){
            dispatch_cancel(timer);
        }
    }
    
    
    #pragma mark - 计时操作
    - (void)commitLocationInfo{
        NSLog(@"** 提交定位信息 **");
        [[LocationManager shared] getLocationInfoWithHandler:^(CLLocation * _Nonnull location, AMapLocationReGeocode * _Nonnull regeocode, NSError * _Nonnull error) {
            
        }];
    }
    
    #pragma mark - 开始定位并提交位置信息
    + (void)startReport{
        JTTimerManager *jtm = [JTTimerManager share];
        @WeakObj(jtm);
        jtm.reportTimer = [jtm timerWithTimeInterval:20 delay:0 block:^(void) {
            [Weakjtm commitLocationInfo];
        }];
        [jtm startWithTimer:jtm.reportTimer];
        
        [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
            [[UIApplication sharedApplication]endBackgroundTask:UIBackgroundTaskInvalid];
        }];
        
    }
    
    #pragma mark - 停止提交
    + (void)stopReport{
        JTTimerManager *jtm = [JTTimerManager share];
        [jtm cancelWithTimer:jtm.reportTimer];
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    @end
    
    

    还有一句全局最重要的话,有了它才能保证后台运行。

    [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
            [[UIApplication sharedApplication]endBackgroundTask:UIBackgroundTaskInvalid];
    }];
    

    相关文章

      网友评论

        本文标题:iOS在后台锁屏状态下不能持续定位和提交位置信息的解决办法

        本文链接:https://www.haomeiwen.com/subject/wxmwrktx.html