Ios 未在后台调用CLLocationManager委托方法

Ios 未在后台调用CLLocationManager委托方法,ios,objective-c,iphone,cocoa,cllocationmanager,Ios,Objective C,Iphone,Cocoa,Cllocationmanager,我正在构建一个应用程序,检查用户是否靠近我的客户机存储区,如果靠近,它会向他发送通知 我希望应用程序也能在后台检查它 我已将以下行添加到我的info.plist文件中: 这是我的代码: AppDelegate.m: -(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self configureLocationManager

我正在构建一个应用程序,检查用户是否靠近我的客户机存储区,如果靠近,它会向他发送通知

我希望应用程序也能在后台检查它

我已将以下行添加到我的
info.plist
文件中:

这是我的代码:

AppDelegate.m

-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self configureLocationManager];
[self.locationManager startUpdatingLocation];

return YES;
}
-(void)configureLocationManager
{
    //Initializing locationManager
    self.locationManager=[[CLLocationManager alloc] init];
    //setting "locationManager"'s(CLLocationManager) delegate to "self"
    self.locationManager.delegate=self.monitorLocationVC;
    //Setting "locationManager"'s(CLLocationManager)'s distance filter to none
    //self.locationManager.distanceFilter=kCLDistanceFilterNone;
    //Setting "locationManager"'s(CLLocationManager)'s activityType to navigation
    self.locationManager.activityType=CLActivityTypeAutomotiveNavigation;
    //setting "locationManager"'s(CLLocationManager) desiredAccuracy to "best"
    self.locationManager.desiredAccuracy=kCLLocationAccuracyBestForNavigation;
    //If OS version is 9 or above - setting "allowsBackgroundLocationUpdates" to YES
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
        self.locationManager.allowsBackgroundLocationUpdates = YES;
    }
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    [self checkIfNearStore]; //Not being called in background
}

-(void)checkIfNearStore
{
    for (Store *currentStore in self.allStores) {
        if ([currentStore.circularRegion containsCoordinate:self.locationManager.location.coordinate]&&currentStore.alreadySendNotification==NO) {
            NSLog(@"Entered: %@",[[self storeForRegion:currentStore.circularRegion] address]);
            currentStore.alreadySendNotification=YES;
            [self.storesAlreadySentNotifications addObject:currentStore];
        }
    }

    for (Store *currentStore in self.storesAlreadySentNotifications) {
        if (![currentStore.circularRegion containsCoordinate:self.locationManager.location.coordinate]) {
            currentStore.alreadySendNotification=NO;
        }
    }
}
监视器位置ViewController.m

-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self configureLocationManager];
[self.locationManager startUpdatingLocation];

return YES;
}
-(void)configureLocationManager
{
    //Initializing locationManager
    self.locationManager=[[CLLocationManager alloc] init];
    //setting "locationManager"'s(CLLocationManager) delegate to "self"
    self.locationManager.delegate=self.monitorLocationVC;
    //Setting "locationManager"'s(CLLocationManager)'s distance filter to none
    //self.locationManager.distanceFilter=kCLDistanceFilterNone;
    //Setting "locationManager"'s(CLLocationManager)'s activityType to navigation
    self.locationManager.activityType=CLActivityTypeAutomotiveNavigation;
    //setting "locationManager"'s(CLLocationManager) desiredAccuracy to "best"
    self.locationManager.desiredAccuracy=kCLLocationAccuracyBestForNavigation;
    //If OS version is 9 or above - setting "allowsBackgroundLocationUpdates" to YES
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
        self.locationManager.allowsBackgroundLocationUpdates = YES;
    }
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    [self checkIfNearStore]; //Not being called in background
}

-(void)checkIfNearStore
{
    for (Store *currentStore in self.allStores) {
        if ([currentStore.circularRegion containsCoordinate:self.locationManager.location.coordinate]&&currentStore.alreadySendNotification==NO) {
            NSLog(@"Entered: %@",[[self storeForRegion:currentStore.circularRegion] address]);
            currentStore.alreadySendNotification=YES;
            [self.storesAlreadySentNotifications addObject:currentStore];
        }
    }

    for (Store *currentStore in self.storesAlreadySentNotifications) {
        if (![currentStore.circularRegion containsCoordinate:self.locationManager.location.coordinate]) {
            currentStore.alreadySendNotification=NO;
        }
    }
}
-(无效)位置管理器:(CLLocationManager*)管理器更新位置:(NSArray*)位置
{
[self-checkIfNearStore];//未在后台调用
}
-(作废)checkIfNearStore
{
用于(存储*当前存储在self.allStores中){
if([currentStore.circularRegion containsCoordinate:self.locationManager.location.coordinate]&¤tStore.alreadySendNotification==否){
NSLog(@“输入:%@,[[self-storeForRegion:currentStore.circularRegion]地址]);
currentStore.alreadySendNotification=是;
[self.storesReadySentNotificationsAddObject:currentStore];
}
}
用于(在self.storesReadySentNotifications中存储*当前存储){
if(![currentStore.circularRegion containsCoordinate:self.locationManager.location.coordinate]){
currentStore.alreadySendNotification=否;
}
}
}
有人有主意吗?谢谢

背景位置更新 我建议您仔细阅读与此方法相关的讨论(您必须使用此方法来解决此问题)。请注意,您可以通过调用stopmoningsignificantlocationchanges然后调用start。。。方法。您还需要监视locationManager:didUpdateLocations方法中的时间戳

苹果详细说明了当应用程序处于后台时,获取更新所需的步骤。基本上,您必须在应用程序委托方法中截取密钥。这是一个示例代码

但是,在您开始编写代码之前,请按照建议查看讨论,因为它将使您更清楚地了解如何掌握这种行为。与往常一样,您也总是希望监视讨论中提到的failure delegate方法

苹果

诺塔贝尼酒店 苹果发布了这条非常重要的说明,说明了位置更新发送到设备的频率限制。为了节省电池,他们试图限制更新次数,直到设备移动500米。你的测试应该考虑这些限制。

资源

有关更多补充信息,请注意以下问题的答案:


不幸的是,由于保密协议的原因,我无法发布我用于地理围栏的代码,但本文可以帮助您实现您的目标:

关于什么的想法?您是否获得了用户跟踪其位置的授权?@trojanfoe是的,用户已允许locationManager“始终授权”。您是否在project capabilities中启用了后台模式作为位置?同样在您的info.plist中。@RJVKumar可能没有,您能告诉我怎么做吗?在Xcode中选择您的项目目标(名称)。然后单击“功能”选项卡->后台模式->位置更新..启用此功能。我需要实时位置,而不是每500米一次,因此我无法使用显著的位置更改,我需要定期监控。您可以启用SLC,并且每次在
-(void)locationManager:(CLLocationManager*)manager didUpdateLocations:(NSArray*)中接收到新位置时启用SLC位置
你重新加载区域同样,你可能想对
-(void)locationManager:(CLLocationManager*)manager didExitRegion:(CLRegion*)区域做同样的操作。教程是否涵盖了该区域?顺便说一句,我需要实时位置,不是每500米一次,所以我不能使用显著的位置更改,我需要定期监控,也许我错了?这就是我想告诉你的。你不需要实时监控。SLC足以重新加载区域…如果不是,假设500米半径内有20多个区域,则每次触发一个当前围栏时重新加载区域。