从iPhone OS 2开始,CLLocationManager
一直是以Create, delegate, start, wait的方式来运作。
// 导入CoreLocation框架
// 添加<CLLocationManagerDelegate>协议
// 创建一个location manager
self.locationManager = [[CLLocationManager alloc] init];
// 设置一个委托来接受location的回调
self.locationManager.delegate = self;
// 启动location manager
[self.locationManager startUpdatingLocation];
// 等待location回调
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(@"%@", [locations lastObject]);
}
唯一比较大变化是用不同的委托方法来监听更新,而老方法是可以继续工作。有时候当你忘记了设置委托或者打错了委托方法的签名,这种方法总会默默地失败,但这些失误是众所周知的,有据可查的。
Location Manager在iOS8中无法启动
在iOS8中上述代码不仅不会实现它的功能,而且不会提示任何错误。你无法从中得到位置更新并且不知道为什么。你编译的程序甚至不会提示要求允许获取当前位置。我对Core Location比较了解,我花了30分钟的时间来研究新的运行方式。菜鸟们可能会对这些改变更感到有挫败感。
iOS8 需要
在iOS8中你需要干两件事情使得Location发挥作用:在你的Info.plist中添加一个键,然后在location manager发送授权请求允许运行。至少有一个键是需要的,如果没有任何一个存在,你可以调用startUpdatingLocation但是location manager并没有真正启动。也不会给委托发送任何错误信息(既然没法启动,那就也不会失败)。如果添加了键但是忘了明确要求获取权限,那么上述代码也会失败。
所以首先你需要做的是添加以下一个或者两个键到你的Info.plist文件中:
·
NSLocationWhenInUseUsageDescription
·
NSLocationAlwaysUsageDescription
每个键都需要一个字符串来描述你为什么需要位置服务,你可以写“Location is required to find out where you are”,像在iOS7中一样(iOS7是在InfoPlist.strings文件中)。
下一步需要通过对应的Location方法来发起请求,WhenInUse或者Background。可以通过以下任何一个调用:
[self.locationManager requestWhenInUseAuthorization]
[self.locationManager requestAlwaysAuthorization]
这里有一个ViewController的完整实现,有一个local manager请求WhenInUse或者Background授权。这是一个基本的例子,不考虑用户是否已拒绝或限制位置。
#import "ViewController.h"
@import CoreLocation;
@interface ViewController () <CLLocationManagerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// ** 不要忘记在MyApp-Info.plist中添加NSLocationWhenInUseUsageDescription
// 并且给它赋一个字符串
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// 检测iOS8. 如果没有这个保护,在iOS 7上会因为"unknow selector"而崩溃
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])
{
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
}
// Location Manager的委托方法
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(@"%@", [locations lastObject]);
}
@end
备注:
由于在Xcode6中出现了Corelocation的问题,找到了这个解决方法,所以翻译一部分供大家分享下;原文还有关于授权类型的解释,此次并没有翻译,有兴趣的可以点击下面的链接;以后有时间我再来补充。转载请注明谢谢。
http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
http://datacalculation.blogspot.in/2014/11/how-to-fix-cllocationmanager-location.html