didUpdateLocations не вызывается в фоновом режиме (obj-c) - PullRequest
0 голосов
/ 28 ноября 2018

Я пишу плагин IOS для нашего существующего приложения Unity, чтобы проверять и отправлять обновления местоположения на наш сервер как на переднем, так и на заднем плане.Мне удалось получить обновления местоположения, когда приложение находится на переднем плане, но по какой-то причине оно не будет вызывать didUpdateLocations, когда приложение находится в фоновом режиме.Вот мой код для настройки служб определения местоположения:

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <UIKit/UIKit.h>

@interface IOSPlugin :NSObject <CLLocationManagerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@end

@implementation IOSPlugin
@synthesize locationManager;

static IOSPlugin *_sharedInstance;
static NSString * token;

+(IOSPlugin *) sharedInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"Creating IOSPlugin shared instance");
        _sharedInstance = [[IOSPlugin alloc] init];
    });
    return _sharedInstance;
}

-(id)init
{
    self = [super init];
    if(self)
        [self setup];
    return self;
}

-(void)setup
{
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.distanceFilter = kCLDistanceFilterNone;
    locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    locationManager.allowsBackgroundLocationUpdates = YES;

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

    NSLog(@"LocationManager initalised..");

}

-(void)locationManager:(CLLocationManager *)manager 
didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    NSLog(@"%f", locations.lastObject.coordinate.latitude);
    NSLog(@"%f", locations.lastObject.coordinate.longitude);

    CLLocation* loc = locations.lastObject;

    //show a toast just to see if this gets called
    [_sharedInstance showMessage];
    //send location to server
    [_sharedInstance sendToApi:loc];
}

У меня есть 2 метода, которые переключаются между передним и фоновым службами определения местоположения (токен, который передается только для нашего сервера):

-(void)startForegroundLocationService:(NSString *)_token
{
    token = _token;

    [locationManager stopMonitoringSignificantLocationChanges];
    NSLog(@"Stopped background location service");

    [locationManager startUpdatingLocation];
    NSLog(@"Started foreground location service");
}

-(void)startBackgroundLocationService:(NSString *)_token
{
    token = _token;

    [locationManager stopUpdatingLocation];
    NSLog(@"Stopped foreground location service");

    [locationManager startMonitoringSignificantLocationChanges];
    NSLog(@"Started background location service");
}

Они вызываются из единицы в скрипте C #, когда приложение становится фоновым, оно вызывает startBackgroundLocationService и наоборот.

У меня также есть скрипт C # после сборки, который редактирует plist-файл для добавления вследующие ключи:

NSLocationAlwaysAndWhenInUseUsageDescription - "Uses background location"
NSLocationWhenInUseUsageDescription - "Uses foreground location"
UIBackgroundModes - "location"

Эта реализация прекрасно работает, когда приложение открыто, в симуляторе или на устройстве, если я меняю местоположение, оно отправляет его на наш сервер, и это здорово.Когда приложение становится фоновым, я не вижу никаких обратных вызовов, полученных методом didUpdateLocations, и оно ничего не отправляет на наш сервер.Я просмотрел все, что мог найти об этом в obj-c, и не могу найти решение этой проблемы - любая помощь будет принята с благодарностью!

1 Ответ

0 голосов
/ 29 ноября 2018

Я публикую это как ответ, а не комментарий, так как форматирование лучше в ответах.Извините, если это расстроило повелителей переполнения стека.

Я вижу, что у вас работают фоновые обновления местоположения, но вы не можете получить обновления местоположения, когда приложение завершается.

Из Apple Docs :

Если вы запустите эту службу и ваше приложение будет впоследствии остановлено, система автоматически перезапустит приложение в фоновом режиме, если новыйсобытие прибывает.В таком случае словарь параметров, передаваемый приложению: willFinishLaunchingWithOptions: и application: didFinishLaunchingWithOptions: методы вашего делегата приложения, содержит ключ UIApplicationLaunchOptionsLocationKey, указывающий, что ваше приложение было запущено из-за события местоположения.После повторного запуска вы все равно должны сконфигурировать объект диспетчера местоположений и вызвать этот метод, чтобы продолжить получать события местоположения.Когда вы перезапускаете службы определения местоположения, текущее событие немедленно доставляется вашему делегату.Кроме того, свойство location вашего объекта менеджера местоположений заполняется самым последним объектом location даже до запуска служб определения местоположения.

Итак, в вашем делегате приложения обязательно создайте заново и настройте менеджер местоположений в методе application:didFinishLaunchingWithOptions:, если присутствует ключ UIApplicationLaunchOptionsLocationKey.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...