首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iOS 9使用web服务在服务器上进行后台位置更新和更新

iOS 9使用web服务在服务器上进行后台位置更新和更新
EN

Stack Overflow用户
提问于 2015-10-02 09:04:22
回答 3查看 1.4K关注 0票数 1

我已经开发了一个应用程序,它能够在应用程序处于后台和前台时更新服务器上的位置。我使用了计时器,它用1分钟的时间间隔连续更新位置,因为如果间隔超过1分钟,iOS会在后台挂起应用程序。

问题在于iOS 9,当应用程序处于后台时,它会在某个时间停止位置更新,并在一些随机时间持续之后再次启动。

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

代码语言:javascript
复制
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中,一切都很好。

我尝试了两种可以在堆栈溢出上使用的解决方案,但是我无法找到能够解决这个问题的确切解决方案。

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

任何帮助都将不胜感激。

提前谢谢你。

更新

AppDelegate.h

代码语言:javascript
复制
@property (nonatomic, retain) CLLocation *currentLocation;
@property (nonatomic, strong) NSTimer* locationUpdateTimer;
-(void)updateUsersLocation;
-(void)distroyTimer;

AppDelegate.m

代码语言:javascript
复制
-(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;
}

//编写代码以更新服务器上的位置

代码语言:javascript
复制
-(void)updateUsersLocation
{
    // Your code goes here.
}

注意:位置服务的持续更新将极大地耗尽iOS设备的电池。因此,一旦您没有使用更新的位置,您就可以使用significant locations

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-11-26 11:15:43

我为启动和停止位置管理器保留了一个计时器,因为我已经向苹果开发人员发布了一个相同的问题,他们建议我为应用程序保留一个位置管理器,并且删除在应用程序在后台工作期间可能会在线程中受到影响的定时器,所以最后我已经删除了定时器逻辑,现在位置管理器不断更新这个位置,直到用户注销为止。这可能耗尽电池,但这是我找到的唯一解决方案,并正在为我们的应用程序工作。

票数 1
EN

Stack Overflow用户

发布于 2015-10-02 09:17:40

您应该使用位置更新后台模式,以获得位置更新在后台,然后您的应用程序将唤醒从背景时,didupdalocation被称为请参阅文档,以更好的理解。

票数 1
EN

Stack Overflow用户

发布于 2015-10-02 14:44:24

我也有过同样的问题。

新的allowsBackgroundLocationUpdates不能停留在plist中,您必须将其放入代码中。

代码语言:javascript
复制
myLM = [[CLLocationManager alloc] init];
if([myLM respondsToSelector:@selector(allowsBackgroundLocationUpdates)]) {
   [myLM setAllowsBackgroundLocationUpdates: YES];
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32903850

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档