iOS定期后台位置更新,不仅取决于显著位置更改

8
我有一个应用程序,即使在后台或终止(被杀掉),也必须报告用户位置。问题在于,该应用程序应该不少于每小时报告一次位置。
我正在使用重大位置更改(SLC)来跟踪所有移动,当用户在行进时这已经足够了,但是一旦用户停止,就不会再更新,并且应用程序没有机会提交新位置(当用户停留在同一区域但没有SLC时)。
为了解决这个问题,我开始使用后台获取以定期发送后台更新位置(即使没有SLC)。问题在于,后台获取之前经常工作(自从我在另一个iOS 7.x应用程序中使用它以来,每20-30分钟),但现在在iOS8 / iOS9上,我只能得到一天左右的时间,这在我的情况下是不可接受的。我执行了大量测试,开发了一个简单的后台获取应用程序,在获取时添加本地通知。无法强制其更频繁地工作。
以下是我的AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
    [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
    return YES;
}

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{    
    [[UIApplication sharedApplication] cancelAllLocalNotifications];
    UILocalNotification *localNotification = [[UILocalNotification alloc] init];
    NSDate *now = [NSDate date];
    localNotification.fireDate = now;
    localNotification.alertBody = [NSString stringWithFormat:@"Background fetch!"];
    localNotification.soundName = UILocalNotificationDefaultSoundName;
    NSInteger number = [UIApplication sharedApplication].applicationIconBadgeNumber;
    number++;
    localNotification.applicationIconBadgeNumber = number;
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];

    completionHandler(UIBackgroundFetchResultNewData);
}

这里所做的一切就是在每个后台抓取中添加本地通知。我总是用UIBackgroundFetchResultNewData来最终执行后台操作。

你有关于如何强制后台抓取更频繁工作(或证明现在不再可能)的建议吗?欢迎任何满足我的要求的替代方案!


1
后台获取从来没有保证执行时间。我建议您向设备发送静默推送,以便给它报告位置的机会,但如果应用程序被终止,这将无法工作。 - Paulw11
从来没有保证过,但至少以前它的工作频率更高。自iOS 7以来,与后台获取相关的一些重大变化吗? - Mando
1
你返回什么值给完成处理程序?新数据还是没有新数据?根据我的经验,即使在iOS8上,它也不会每20-30分钟调用一次。 - Paulw11
我总是使用UIBackgroundFetchResultNewData来完成后台执行。我刚刚更新了问题并提供了示例代码。这是一个非常简短和简单的应用程序,可以在不同的设备和不同的iOS(iOS8/9)上重现该问题。你有多频繁地调用它?@Paulw11 - Mando
2
如果您只需要SLC,并且手机在过去的一小时内没有显着移动,那么您不能假设它根本没有移动吗?虽然这不一定是情况,但一旦它发生了显着的移动,您将再次收到通知。 - HAS
1
手机可能已经没电并移动,但后端确信用户位置错误。 - Mando
2个回答

4
原来在iOS中,后台获取功能很大程度上取决于处理程序中所做的操作,特别是网络活动。以下是您应该考虑了解的依赖项列表,以确定iOS将如何执行并且执行多少次您的获取:
- 处理程序所用时间 - 结果(NoData、NewData) - 错误处理(如果您的代码崩溃,则会较少地启动您) - 超时(iOS可能会中断您的代码执行) - 电源使用情况 - 与结果相关的网络活动(如果您说有NewData,则必须执行网络请求,否则您的获取可能在下一天或更久的时间内执行)

下载少量内容的应用程序,并准确反映可下载内容的可用性, 将比需要长时间下载其内容或者声称有可用内容却未下载任何东西的应用程序更容易在未来获得执行时间。

在我的案例中,最后一个项目非常关键,因为出于测试目的,我声明了获取,但从未尝试过下载任何内容。一旦我开始在处理程序中使用网络,后台获取就按预期工作,并且每15-30分钟执行一次。
Apple文档: https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接