简体   繁体   English

iOS 9后台使用Web服务更新和更新服务器上的位置

[英]iOS 9 Background Location update and Update on server using web-service

I have developed an application that has the capability to update the location on server while application is in background as well as foreground. 我开发了一个应用程序,它能够在应用程序处于后台和前台时更新服务器上的位置。 I have used Timer which continuously updates location with 1 minute time interval, because if the interval is more than 1 minute , iOS suspends the application in background. 我使用了Timer,它以1分钟的时间间隔不断更新位置,因为如果间隔超过1分钟, iOS在后台暂停应用程序。

The problem is with iOS 9, when application is in background, some time it stops the location update and after some random time duration it again starts. 问题出在iOS 9上,当应用程序处于后台时,有时它会停止位置更新,并且在一些随机持续时间后它会再次启动。

These are the crash logs which I found from device logs. 这些是我从设备日志中找到的崩溃日志。

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

Note: Everything is working completely fine in iOS 7 and iOS 8. 注意:在iOS 7和iOS 8中,一切都运行良好。

I have tried couple of solutions available on stackoverflow but I am not able to figure out the exact solutions which can solve the problem. 我已经在stackoverflow上尝试了几种解决方案,但我无法找出可以解决问题的确切解决方案。

Also I found that if I don't lock the device then the location update and web-service calling works fine but if the device is locked, it stops updating location and calling up web-service. 另外我发现,如果我没有锁定设备,那么位置更新和网络服务调用工作正常,但如果设备被锁定,它会停止更新位置并调用网络服务。

Any help would be highly appreciated. 任何帮助将受到高度赞赏。

Thank you in advance. 先感谢您。

UPDATE UPDATE

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;
}

// Write your code to update location on server //编写代码以更新服务器上的位置

-(void)updateUsersLocation
{
    // Your code goes here.
}

Note: Continuous update of location services will dramatically drain your iOS device's battery. 注意:持续更新位置服务将极大地耗尽iOS设备的电池电量。 So as soon as you have no use of updated location you can use significant locations . 因此,只要您不使用更新的位置,就可以使用significant locations

您应该使用位置更新后台模式在后台获取位置更新,然后当调用didupdalocation时,您的应用程序将从后台唤醒请参阅文档以便更好地理解。

I had the same issue. 我遇到过同样的问题。

The new allowsBackgroundLocationUpdates can't stay at plist, you must put it in code. 新的allowBackgroundLocationUpdates不能保留plist,你必须把它放在代码中。

myLM = [[CLLocationManager alloc] init];
if([myLM respondsToSelector:@selector(allowsBackgroundLocationUpdates)]) {
   [myLM setAllowsBackgroundLocationUpdates: YES];
}

I have kept a timer for starting and stopping the location manager, as I have posted a same question to apple developers and they suggest me to keep a single location manager for application and remove the timers which might gets affected during threads while application works in background , so finally I have removed the timers logic , and now location manager continuously updates the location until the user gets logged out. 我已经保留了启动和停止位置管理器的计时器,因为我向苹果开发人员发布了同样的问题,他们建议我为应用程序保留一个位置管理器并删除可能在应用程序在后台运行时在线程中受影响 的计时器 ,最后我删除了定时器逻辑 ,现在位置管理器不断更新位置,直到用户退出。 This might drain the battery but this one is the only solutions that I found and which is working for our application. 这可能会耗尽电池,但这是我找到的唯一解决方案,也适用于我们的应用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM