Я разработал приложение, которое имеет возможность обновлять местоположение на сервере, когда приложение находится в фоновом режиме, а также на переднем плане. Я использовал таймер, который постоянно обновляет местоположение с интервалом в 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, но я не могу найти точные решения, которые могут решить проблему.
Также я обнаружил, что если я не заблокирую устройство, то обновление местоположения и вызов веб-службы будут работать нормально, но если устройство заблокировано, оно перестанет обновлять местоположение и вызывать веб-службу.
Любая помощь будет высоко ценится.
Заранее спасибо.
ОБНОВЛЕНИЕ
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
.
NSLog()
. - person Vatsal K   schedule 19.10.2015- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
, используя временную температуру, и получать разницу каждые 20 секунд. - person Vatsal K   schedule 29.04.2016