我启用了位置服务,可以在应用程序处于后台时更新位置,并且当应用程序位于前台时,我还会监听位置更新,并显示地图。在iOS中设计此场景的最佳方法是什么?我考虑过一些选择:
1)拥有一个具有locationManager
成员的类的实例,该成员本身就是其委托。然后,在didUpdateToLocation
委托方法的主体中,类似于:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
if (!background) {
// Perform some processing and notify the view controller which displays the map
// by means of Notification Center
}
else {
appDelegate.bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:appDelegate.bgTask];
appDelegate.bgTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Perform some data processing
// Close background task
if (appDelegate.bgTask != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask:appDelegate.bgTask];
appDelegate.bgTask = UIBackgroundTaskInvalid;
}
});
}
}
(注意:我不确定是否启用了位置服务作为后台服务,需要执行位置处理,就好像它是一个有限的后台任务......)。此类的实例可以是AppDelegate
的成员,并在输入背景或从显示地图的viewModel调用实例时开始侦听位置。因此,AppDelegate
将引用管理locationManager
的实例,地图viewController将引用AppDelegate
,或通过通知中心进行通信。
2)将locationManager
成员直接放在AppDelegate
中,并成为委托人。
将de locations侦听和管理封装在不同的类中,或直接在AppDelegate
处理它会更好吗?考虑到我必须能够在前台和后台监听位置并执行某些任务。
提前致谢
答案 0 :(得分:2)
我认为您最好的策略是让一个类的单例实例成为locationManager
委托。此实例负责过滤从locationManager
返回的任何内容,并最终将位置分配给其中一个属性,我们称之为myLoc
。
这解决了您的集中逻辑问题,即位置在获取后需要进行后处理。
其次,为了在更新位置时获取正确的UIViewControllers
和其他类实例以执行所需操作,我建议您在myLoc
上使用键值观察(KVO)。我假设你知道它是如何工作的。我建议KVO的原因是你需要根据被改变的位置触发代码的多个区域的变化,并且KVO是针对那种模式制作的。
答案 1 :(得分:0)
我想在@Rikkles的答案中添加更多内容,您可以创建一个BaseViewController
,它是UIViewController
的子类,并且还有一个单例locationManager类的实例。
这种方法允许我们移动所有冗余代码,例如,检查可达性,显示活动指示符,获取用户位置等,只有一个地方,并且可供所有其他实现它的类使用。