iOS 周期性的后台位置更新不仅取决于重大的位置变化
iOS periodic background location updates which depends not only on significant location change
我有一个应用程序必须报告用户位置,即使它在后台运行甚至被杀死(终止)也是如此。问题是应用程序应该报告位置不少于 1 小时的间隔。
我正在使用显着位置更改 (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 完成后台执行。
关于如何强制后台提取更频繁地工作(或证明不再可能的链接),您有什么建议吗?
也欢迎任何满足我要求的替代解决方案!
我从事过类似的项目。在尝试了各种解决方案之后,我发现的唯一方法是此处提出的解决方案:
https://github.com/voyage11/Location
这里是git对应的教程:
http://mobileoop.com/getting-location-updates-for-ios-7-and-8-when-the-app-is-killedterminatedsuspended
所有学分到https://whosebug.com/users/1995940/ricky
它为我节省了很多时间!
事实证明,iOS 中的后台获取在很大程度上取决于您在处理程序中所做的事情,尤其是网络 activity。这里是您应该考虑的依赖项列表,试图了解 iOS 是否以及多久执行一次您的提取:
- 您花在处理程序上的时间
- 结果(NoData,NewData)
- 错误处理(如果您的代码崩溃,您将不太可能启动
- 超时(您的代码执行可能会被 iOS 中断)
- 用电量
- 网络 activity 与结果相关(当你说你有 NewData 时你必须做一个网络请求,否则你的抓取可能会在一天之内下次执行。
Apps that download small amounts of content quickly, and accurately
reflect when they had content available to download, are more likely
to receive execution time in the future than apps that take a long
time to download their content or that claim content was available
but then do not download anything.
最后一项对我来说很重要,因为出于测试目的,我声明了提取并且从未尝试下载任何东西。一旦我开始在处理程序中使用网络,后台提取将继续按预期每 15-30 分钟工作一次。
我有一个应用程序必须报告用户位置,即使它在后台运行甚至被杀死(终止)也是如此。问题是应用程序应该报告位置不少于 1 小时的间隔。
我正在使用显着位置更改 (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 完成后台执行。
关于如何强制后台提取更频繁地工作(或证明不再可能的链接),您有什么建议吗? 也欢迎任何满足我要求的替代解决方案!
我从事过类似的项目。在尝试了各种解决方案之后,我发现的唯一方法是此处提出的解决方案: https://github.com/voyage11/Location
这里是git对应的教程: http://mobileoop.com/getting-location-updates-for-ios-7-and-8-when-the-app-is-killedterminatedsuspended
所有学分到https://whosebug.com/users/1995940/ricky
它为我节省了很多时间!
事实证明,iOS 中的后台获取在很大程度上取决于您在处理程序中所做的事情,尤其是网络 activity。这里是您应该考虑的依赖项列表,试图了解 iOS 是否以及多久执行一次您的提取:
- 您花在处理程序上的时间
- 结果(NoData,NewData)
- 错误处理(如果您的代码崩溃,您将不太可能启动
- 超时(您的代码执行可能会被 iOS 中断)
- 用电量
- 网络 activity 与结果相关(当你说你有 NewData 时你必须做一个网络请求,否则你的抓取可能会在一天之内下次执行。
Apps that download small amounts of content quickly, and accurately reflect when they had content available to download, are more likely to receive execution time in the future than apps that take a long time to download their content or that claim content was available but then do not download anything.
最后一项对我来说很重要,因为出于测试目的,我声明了提取并且从未尝试下载任何东西。一旦我开始在处理程序中使用网络,后台提取将继续按预期每 15-30 分钟工作一次。