Я создаю приложение, которое использует CoreLocation для двух целей:
-
Во-первых, мониторинг регионов маяков. В основном мы работаем с определенным аппаратным устройством, которое действует как маяк, и мы отслеживаем с помощью CoreLocation статус этого маякового соединения.
-
Во-вторых, когда приложение обнаруживает отсоединение от маякового устройства, мы хотим начать процесс GPS, чтобы найти место, где произошло разъединение.
В большинстве случаев обратный вызов разъединения маякового устройства происходит, когда приложение находится в фоновом режиме. Поэтому приложение должно начать отслеживание GPS, вызывая -startUpdatingLocation
, находясь в фоновом режиме.
И это проблема. Похоже, что iOS не позволяет обновлять данные о местоположении, если вызов -startUpdatingLocation
произошел, когда приложение было в фоновом режиме.
Очевидно, что я правильно настроил фоновые режимы, NSLocationAlwaysUsageDescription
, установил свойство _locationManager.allowsBackgroundLocationUpdates
на YES
.
Удивительная вещь: если я назову -startUpdatingLocation
, находясь на переднем плане, а затем переключись на фон, обновления местоположения будут отправляться правильно, когда они находятся в фоновом режиме. Однако при вызове -startUpdatingLocation
в фоновом режиме приложение получает 2 или 3 обновления местоположения, а затем останавливается навсегда.. пока я вручную не верну приложение на передний план, когда обновления местоположений возобновятся, а затем продолжайте работать, даже если я переключу приложение к фону снова.
Кто-нибудь знает или понимает, что я должен сделать, чтобы исправить это? или это основное ограничение iOS? Из-за требований моего приложения мне действительно нужно начать поиск обновлений, когда приложение находится в фоновом режиме (внутри обратного вызова маяка была выходная область).
Btw, если вы хотите воспроизвести эту проблему, очень просто. Просто создайте пустой проект в Xcode и добавьте этот код в свой контроллер представления по умолчанию. Не забудьте включить фоновые режимы, добавьте описание в свой ключ info.plist "NSLocationAlwaysUsageDescription".
- (void)viewDidLoad
{
[super viewDidLoad];
_locationManager = [[CLLocationManager alloc] init];
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_8_3)
_locationManager.allowsBackgroundLocationUpdates = YES;
_locationManager.delegate = self;
_locationManager.activityType = CLActivityTypeOther;
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
_locationManager.distanceFilter = kCLDistanceFilterNone;
[_locationManager requestAlwaysAuthorization];
// Creating a background task to delay the start of the startUpdatingLocation
__block UIBackgroundTaskIdentifier taskIdentifier = UIBackgroundTaskInvalid;
taskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:taskIdentifier];
}];
// Delaying the call to startUpdatingLocation 10 seconds, enough time to dismiss the application
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[_locationManager startUpdatingLocation];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] endBackgroundTask:taskIdentifier];
});
});
}
Затем отследите делегат CLLocationManager, выполнив некоторые NSLogs и узнайте, что произойдет.
Спасибо,