(0081)iOS开发之无限后台定位并上传数据到服务器

关键词:ios 后台持续定位

iOS 后台的理解

// http://blog.csdn.net/u013773524/article/details/52153917

// http://blog.csdn.net/pz0605/article/details/49719207


需求场景:

每隔一段时间,反复执行同一个任务,去调服务端的接口。

成熟的第三方SDK: (介绍地址:http://blog.csdn.net/ioscircleandcircle/article/details/75426009)

后台长时间定时定位-Location实践经验.它是一个Github上的第三方库,叫Location,不仅能在后台定时采集位置数据,还优化了定位方式,减少耗电。


相似需求一:

由于公司一款产品的需求,最近一直在研究iOS设备的后台定位。主要的难点就是,当系统进入后台之后,程序会被挂起,届时定时器、以及代码都不会Run~ 所以一旦用户将我的App先换到了后台,我的定位功能将无法继续。

http://www.cnblogs.com/oshushu/articles/4569252.html


相似需求二:

最近做一个考勤APP,功能很简单,就是一直在后台运行,每隔固定时间向服务器上传一次位置信息。持续运行24小时测试,功能实现。http://blog.csdn.net/dolacmeng/article/details/45064939/

相似需求三:

iOS开发:后台定位并上传数据到服务器 http://blog.csdn.net/jijiji000111/article/details/53149971


第一种方式:

当程序处于运行状态,每隔几秒给服务器发送一次请求。这时我们可以这样处理:

UILocalNotification *localNotification = [[UILocalNotification alloc] init];

// 可以用该语句查看当前线程
NSLog(@"当前线程--%@", [NSThread currentThread]);    

// 此处需要写一个异步任务,是因为需要开辟一个新的线程去反复执行你的代码块,否则会阻塞主线程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

        while (TRUE) {

            // 每隔5秒执行一次(当前线程阻塞5秒)
            [NSThread sleepForTimeInterval:5];  
            
            [[UIApplication sharedApplication] cancelAllLocalNotifications];
           
            // 这里写你要反复处理的代码,如网络请求
            NSLog(@"***每5秒输出一次这段文字***");            

            [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
        };
    });
链接:https://www.jianshu.com/p/af0e87d63069

第二种方式:

也是今天想着重提到的,就是通过定位获取更多的后台使用的时间,这种适合于需要在后台收集用户的定位的场景,例如滴滴打车此类应用。重要的是这个思路很好!

1.需要在info.plist 设置

2.其实这种后台刷新是很暴力的,导航仪不断在定位,你才可以获取后台活跃的时间,去执行你的一些想要的操作,但是不断的定位会导致,电量消耗过快,我测试一个小时奖金跑去了10%的电量,那么有没有一些更优的方案,减少定位的次数,然后又能让后台活跃呢?下面来讲解下思路


这个优化面临的问题,就是当程序进入了后台,如果让定位停止了,那么程序就后台就无法活跃了,就是把程序进入后台的问题解决了,那就好办了,看了上图,也可以看出,思路主要是在当前正在定位的时候,10秒后关闭当前的定位,然后此时开启后台任务backgroundtask,那么只要就会有3分钟的活跃时间,那么在这个后台任务有效时间内再次开启定位的话,程序在后台便依旧可以活跃,那么只要开启和关闭循环进行,就可以实现常驻后台了,那么这个时间间隔可以自定义,在自己需要的范围内即可,但是不能超过3分钟,那么接下来在看看主要代码实现

//定位回调里执行重启定位和关闭定位

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{   

 NSLog(@"定位收集");//正在手机定位不执行任何操作    

if (isCollect) { 

       return;   

 }    

      [self performSelector:@selector(restartLocation) withObject:nil afterDelay:120]; 

      [self performSelector:@selector(stopLocation) withObject:nil afterDelay:10]; 

      isCollect = YES;

}

-(void)restartLocation{    NSLog(@"重新启动定位");  

          CLLocationManager *locationManager = [BGLogation shareBGLocation];   

          locationManager.delegate = self;    

          locationManager.distanceFilter = kCLDistanceFilterNone; // 不移动也可以后台刷新回调  

  if ([[UIDevice currentDevice].systemVersion floatValue]>= 8.0) {     

          [locationManager requestAlwaysAuthorization];    

}   

        [locationManager startUpdatingLocation]; 

         [self.bgTask beginNewBackgroundTask];

}//停止后台定位

-(void)stopLocation{    

         NSLog(@"停止定位");   

         isCollect = NO;   

         CLLocationManager *locationManager = [BGLogation shareBGLocation];  

         [locationManager stopUpdatingLocation];

}

接下来是demo 的地址

https://github.com/heysunnyboy/locationdemo.git

可以看到下面的代码 ,在delegate 里设置的定时器一直都在跑没有停止就知道这个后台常驻是有效的

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    // Override point for customization after application launch.  

           _task = [BGTask shareBGTask]; 

           UIAlertView *alert; 

   //判断定位权限    

if([UIApplication sharedApplication].backgroundRefreshStatus ==       UIBackgroundRefreshStatusDenied) { 

       alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"应用没有不可以定位,需要在在设置/通用/后台应用刷新开启" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; 

          [alert show];  

}elseif([UIApplication sharedApplication].backgroundRefreshStatus == UIBackgroundRefreshStatusRestricted)    {       

              alert = [[UIAlertView alloc]initWithTitle:@"提示" message:@"设备不可以定位" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; 

       [alert show];   

 }  else  {    

              self.bgLocation = [[BGLogation alloc]init];    

              [self.bgLocation startLocation];     

              [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(log) userInfo:nil repeats:YES];    

}    return YES;

}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值