【发布时间】:2014-05-06 08:27:53
【问题描述】:
我正在尝试制作一个位置应用程序。您可以为特定位置设置警报。当您到达该位置时,警报将启动。 现在,问题是我如何在应用程序处于后台时检查我在所需位置到达的天气? 据我所知,苹果允许任何代码在后台最多运行 10 分钟。 但是有许多应用程序可以在后台持续检查特定位置。
建议任何方式来实现这一点。
【问题讨论】:
标签: ios google-maps core-location
我正在尝试制作一个位置应用程序。您可以为特定位置设置警报。当您到达该位置时,警报将启动。 现在,问题是我如何在应用程序处于后台时检查我在所需位置到达的天气? 据我所知,苹果允许任何代码在后台最多运行 10 分钟。 但是有许多应用程序可以在后台持续检查特定位置。
建议任何方式来实现这一点。
【问题讨论】:
标签: ios google-maps core-location
您可以使用region monitoring capability of the core-location framework
您可以将您的目的地定义为一个区域,然后即使您在后台,您也会收到对您委托的locationManager:didEnterRegion: 方法的调用。
由于您没有主动执行,因此 10 分钟的后台任务限制不适用。
【讨论】:
我 认为 this 文章对你很有帮助
您需要做的第一件事是修改应用的 plist。添加以下设置。
应用程序不在后台运行:否
所需的背景模式:VOIP
并设置应用程序启动时的代码
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(@"Starting app");
self.powerHandler = [[PowerHandler alloc] init];
self.lastBatteryState = UIDeviceBatteryStateUnknown;
UIApplication* app = [UIApplication sharedApplication];
self.expirationHandler = ^{
[app endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
self.bgTask = [app beginBackgroundTaskWithExpirationHandler:expirationHandler];
NSLog(@"Expired");
self.jobExpired = YES;
while(self.jobExpired) {
// spin while we wait for the task to actually end.
[NSThread sleepForTimeInterval:1];
}
// Restart the background task so we can run forever.
[self startBackgroundTask];
};
self.bgTask = [app beginBackgroundTaskWithExpirationHandler:expirationHandler];
// Assume that we're in background at first since we get no notification from device that we're in background when
// app launches immediately into background (i.e. when powering on the device or when the app is killed and restarted)
[self monitorBatteryStateInBackground];
return YES;
}
接下来,我们设置后台作业
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@"Entered background");
[self monitorBatteryStateInBackground];
}
- (void)monitorBatteryStateInBackground
{
NSLog(@"Monitoring battery state");
self.background = YES;
self.lastBatteryState = UIDeviceBatteryStateUnknown;
[self startBackgroundTask];
}
- (void)startBackgroundTask
{
NSLog(@"Restarting task");
// Start the long-running task.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// When the job expires it still keeps running since we never exited it. Thus have the expiration handler
// set a flag that the job expired and use that to exit the while loop and end the task.
while(self.background && !self.jobExpired)
{
[self updateBatteryState:[self.powerHandler checkBatteryState]];
[NSThread sleepForTimeInterval:1];
}
self.jobExpired = NO;
});
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
NSLog(@"App is active");
self.background = NO;
}
【讨论】:
我会使用 regionmonitoring 然后你在委托方法中被调用
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
和
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
【讨论】:
有两种方法。
UIBackgroundModes 和值 location。现在,即使在应用程序进入后台 10 分钟后,它也允许您的应用程序获取位置。因此,在每个新位置上,将其距离与所需位置进行比较。如果在允许范围内,请执行此操作。【讨论】: