ios - iOS 9背景位置更新和使用Web服务在服务器上更新

标签 ios iphone cllocationmanager background-process location-services

我已经开发了一个应用程序,该应用程序具有在后台和前台同时更新服务器上位置的功能。我使用了Timer,它以1分钟的时间间隔连续更新位置,因为如果间隔超过1分钟,iOS会在后台暂停应用程序。

问题出在iOS 9上,当应用程序在后台运行时,它会停止位置更新,而在一段时间后,它将再次启动。

这些是我从设备日志中找到的崩溃日志。

Exception Type:  00000020
    Exception Codes: 0x000000008badf00d
    Exception Note:  SIMULATED (this is NOT a crash)
    Highlighted by Thread:  2

    Application Specific Information:
    <BKNewProcess: 0x15646220; com.com.com; pid: 1168; hostpid: -1> has active assertions beyond permitted time: 
    {(
        <BKProcessAssertion: 0x15537b80> id: 1168-1B744B09-0EB7-4B01-A6FE-F167669E4439 name: Called by UIKit, from <redacted> process: <BKNewProcess: 0x15646220; com.com.com; pid: 1168; hostpid: -1> permittedBackgroundDuration: 180.000000 reason: finishTask owner pid:1168 preventSuspend  preventIdleSleep  preventSuspendOnSleep ,
        <BKProcessAssertion: 0x15643480> id: 1168-59515322-D982-46F8-94A5-0DD259406664 name: Called by UIKit, from <redacted> process: <BKNewProcess: 0x15646220; com.com.com; pid: 1168; hostpid: -1> permittedBackgroundDuration: 180.000000 reason: finishTask owner pid:1168 preventSuspend  preventIdleSleep  preventSuspendOnSleep 
    )}
    Elapsed total CPU time (seconds): 6.880 (user 6.880, system 0.000), 9% CPU 
    Elapsed application CPU time (seconds): 0.081, 0% CPU

注意:在iOS 7和iOS 8中,一切工作都很好。

我已经尝试了一些可用于stackoverflow的解决方案,但是我无法找出可以解决该问题的确切解决方案。

我还发现,如果我不锁定设备,则位置更新和Web服务调用可以正常工作,但是如果设备被锁定,它将停止更新位置并调用Web服务。

任何帮助将不胜感激。

先感谢您。

更新
AppDelegate.h
@property (nonatomic, retain) CLLocation *currentLocation;
@property (nonatomic, strong) NSTimer* locationUpdateTimer;
-(void)updateUsersLocation;
-(void)distroyTimer;
AppDelegate.m
-(void)callLocationManager
{
    @autoreleasepool
    {
        UIAlertView * alert;
        //We have to make sure that the Background App Refresh is enable for the Location updates to work in the background.
        if([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusDenied)
        {
            alert = [[UIAlertView alloc]initWithTitle:ALERTTITLE
                                              message:@"The app doesn't work without the Background App Refresh enabled. To turn it on, go to Settings > General > Background App Refresh"
                                             delegate:nil
                                    cancelButtonTitle:@"Ok"
                                    otherButtonTitles:nil, nil];
            [alert show];
            return;
        }
        else if([[UIApplication sharedApplication] backgroundRefreshStatus] == UIBackgroundRefreshStatusRestricted)
        {
            alert = [[UIAlertView alloc]initWithTitle:ALERTTITLE
                                              message:@"The functions of this app are limited because the Background App Refresh is disable."
                                             delegate:nil
                                    cancelButtonTitle:@"Ok"
                                    otherButtonTitles:nil, nil];
            [alert show];
            return;
        }
        else if(![CLLocationManager locationServicesEnabled])
        {
            UIAlertView *alert = [[UIAlertView alloc]
                                  initWithTitle:@""
                                  message:@"Please enable GPS service for HiHo Mobile From settings"
                                  delegate:nil
                                  cancelButtonTitle:@"OK"
                                  otherButtonTitles:nil];
            [alert show];
            return;
        }
        else
        {
            if (!self.locationManager)
            {
                self.locationManager = [[CLLocationManager alloc] init];
            }
            self.locationManager.delegate = self;
            // self.locationManager.distanceFilter = kCLDistanceFilterNone;
            self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
            self.locationManager.distanceFilter = 10.0f;
            self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;

            if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
            {
                [self.locationManager requestAlwaysAuthorization];
            }

            if ([self.locationManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)])
            {
                self.locationManager.allowsBackgroundLocationUpdates  = YES;
            }
            if ([self.locationManager respondsToSelector:@selector(pausesLocationUpdatesAutomatically)])
            {
                self.locationManager.pausesLocationUpdatesAutomatically= NO;
            }
            if([self.locationManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)])
            {
                [self.locationManager setAllowsBackgroundLocationUpdates:YES];
            }
            [self.locationManager stopMonitoringSignificantLocationChanges];
            [self.locationManager startUpdatingLocation];

            if ([USERDEFAULTS boolForKey:@"someFlag"]==YES)
            {
                [self distroyTimer];
                self.locationUpdateTimer =
                [NSTimer scheduledTimerWithTimeInterval:180
                                                 target:self
                                               selector:@selector(updateUsersLocation)
                                               userInfo:nil
                                                repeats:YES];
                [[NSRunLoop mainRunLoop]addTimer:self.locationUpdateTimer forMode:NSRunLoopCommonModes];
            }
            else
            {
                [self.locationManager stopUpdatingLocation];
                [self.locationManager startMonitoringSignificantLocationChanges];
            }
        }
    }
}

-(void)distroyTimer
{
    if ([self.locationUpdateTimer isValid])
    {
        [self.locationUpdateTimer invalidate];
        self.locationUpdateTimer = nil;
    }
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    NSLog(@"latitude: %f, longitude: %f",newLocation.coordinate.latitude, newLocation.coordinate.longitude);
    self.currentLocation = newLocation;
}

//编写代码以更新服务器上的位置
-(void)updateUsersLocation
{
    // Your code goes here.
}

注意:位置服务的持续更新将极大地消耗iOS设备的电池。因此,只要您不使用更新的位置,就可以使用significant locations

最佳答案

您应该使用“位置更新后台”模式在后台获取位置更新,然后在调用didupdalocation时,应用将从后台唤醒。请参阅docs以获得更好的理解。

关于ios - iOS 9背景位置更新和使用Web服务在服务器上更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32903850/

相关文章:

ios - 尝试播放录制的文件时文件路径不正确

ios - 是否应该为每个场景/屏幕创建单独的 ViewController.Swift?

iphone - 我的 Phonegap 项目中没有 PhoneGap.plist

swift - OS X 保存位置权限

iphone - 将 CLLocationCoordinate2D 存储到 NSUserDefaults

iphone - CLLocationManager 警报被自己解除

ios - 调用中的额外参数 "method"。阿拉莫菲尔

ios - 在 UIWebView 中检测键盘按下

iphone - 如何实现像把球扔进桶里的效果?

iphone - 加载前显示 View ?加载时运行指示器?