【问题标题】:CLLocationManager delegate methods not being called on backgroundCLLocationManager 委托方法未在后台调用
【发布时间】:2016-05-12 08:15:55
【问题描述】:

我正在构建一个应用程序来检查用户是否在我客户的商店附近,如果是,它会向他发送通知。

我也希望应用在后台检查它。

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

image

这是我的代码:

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;
    }
}

MonitorLocationViewController.m

-(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;
        }
    }
}

有人有想法吗?谢谢!

【问题讨论】:

  • 关于什么的想法?您是否获得了用户的授权来跟踪他们的位置?
  • @trojanfoe 是的,用户已允许 locationManager 的“始终授权”。
  • 您是否启用了项目功能中的后台模式作为位置?以及在您的 info.plist 中。
  • @RJVKumar 也许不行,请问我该怎么做?
  • 在 Xcode 中选择您的项目目标(名称)。然后单击功能选项卡->后台模式->位置更新..启用此功能。

标签: ios objective-c iphone cocoa cllocationmanager


【解决方案1】:

后台位置更新

我建议您仔细阅读与startMonitoringSignificantLocationChanges 方法相关的讨论(您必须使用此方法来解决问题)。请注意,您可以通过调用 stopMonitoringSignificantLocationChanges 然后再次调用 start... 方法来强制进行新更新。您还需要在 locationManager:didUpdateLocations 方法中监控时间戳。

Apple 详细说明了当应用处于后台时获取更新所需的步骤。基本上你必须在你的应用委托方法中截取一个键。这个SO question 有示例代码。

但是在您跳到代码之前,请按照建议查看讨论,因为它会让您更清楚地了解如何掌握这种行为。与往常一样,您也总是希望监控讨论中提到的失败委托方法。

苹果Documentation

Nota Bene

Apple 已发布此非常重要的说明,说明位置更新发送到设备的频率限制。为了节省电池,他们尝试限制更新次数,直到设备移动 500 米。您的测试应考虑这些限制。

资源

有关更多补充信息,请注意以下对这些 SO 问题的回答:

#1 #2

【讨论】:

  • 我需要实时位置,不是每 500m 所以我不能使用显着的LocationChanges,我需要定期监控。
【解决方案2】:

很遗憾,由于保密协议,我无法发布我用于地理围栏的代码,但这篇文章可以帮助您实现您想要的:https://corgitoergosum.net/2013/01/12/geo-fencing-in-timetraveler-v2-part-i-of-3/

【讨论】:

  • 您启用 SLC 并且每次在 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 中收到新位置时,您都会重新加载区域
  • 另外,你可能想为-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region做同样的事情
  • 教程涵盖了吗?
  • 顺便说一句,我需要实时位置,而不是每 500m,所以我不能使用显着的LocationChanges,我需要定期监控,或者我错了?
  • 这就是我想告诉你的。您不需要实时监控。 SLC 足以重新加载区域...如果不是,假设您在 500m 半径内有超过 20 个区域,则每次触发当前围栏之一时重新加载区域。
猜你喜欢
  • 2013-12-03
  • 2011-03-12
  • 2011-11-29
  • 1970-01-01
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-07
相关资源
最近更新 更多