didUpdateLocations不在后台调用(obj-c)

时间:2018-11-28 15:30:55

标签: ios objective-c unity3d

我正在为我们现有的Unity应用程序编写一个IOS插件,以在前台和后台检查位置更新并将其发送到我们的服务器。当应用程序在前台时,我设法获得了位置更新,但是由于某种原因,当应用程序在后台时,它不会调用“ 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 :(得分:0)

我将其发布为答案而不是评论,因为格式对答案更好。抱歉,这会使堆栈溢出霸主不高兴。

我看到您的后台位置更新正常运行,但是在终止该应用程序后您无法正常运行位置更新。

From the Apple Docs

  

如果您启动此服务而您的应用随后被终止,则   新的系统会自动将应用重新启动到后台   事件到了。在这种情况下,选项字典将传递给   application:willFinishLaunchingWithOptions:和   application:didFinishLaunchingWithOptions:您应用程序的方法   委托包含键UIApplicationLaunchOptionsLocationKey   表示您的应用是由于位置事件而启动的。在   重新启动,您仍然必须配置位置管理器对象并调用   此方法继续接收位置事件。重新启动时   定位服务,当前事件已发送给您的代表   立即。此外,您所在位置的location属性   经理对象中甚至填充了最新的位置对象   在开始定位服务之前。

因此,如果存在application:didFinishLaunchingWithOptions:键,请确保在您的应用程序委托中使用UIApplicationLaunchOptionsLocationKey方法重新创建和配置您的位置管理器。