一直以来,定位的实现都非常的简单和一致:
Objective-C的实现:
#import "ViewController.h"
@import CoreLocation; //引入库文件
@interface ViewController () <CLLocationManagerDelegate> //遵守协议
@property (strong, nonatomic) CLLocationManager *locationManager; //定义Location Manager
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//初始化Manager并开始定位
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
}
//Delegate的协议方法
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(@"%@", [locations lastObject]);
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"error = %@",[error description]);
}
@end
Swift的实现:
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
let locationManager:CLLocationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.startUpdatingLocation();
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
println("new Location = \(locations.last)")
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("error = \(error.description)")
}
}
但是在iOS8的情况下,任何代理方法都是沉默的---既不能得到失败的原因或者警告,也不能得到位置信息.App也不会有请求允许使用位置信息的许可.非常的和谐.
在iOS8的系统中需要做两件事情才能让定位能够生效:
1. 在Info.plist添加一对关键字来许可位置服务.NSLocationAlwaysUsageDescription和NSLocationWhenInUseUsageDescription,两个关键字对应的字符串可以是随意的,一般只要添加一个关键字即可,因为有AlwaysUsage那么WhenInUse情况下也能定位,反之则不能适用.
2. 在代码中请求许可.
Objective-C的实现:
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
//或者
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
Swift的实现:
//iOS8中的方法,不然是无法定位的
if locationManager.respondsToSelector(Selector("requestWhenInUseAuthorization")) {
locationManager.requestWhenInUseAuthorization()
}
//或者
if locationManager.respondsToSelector(Selector("requestAlwaysAuthorization")) {
locationManager.requestAlwaysAuthorization()
}
更改地理位置的认证状态
如果最开始的时候设置的是WhenInUse, 而后需要使用Always,那么就需要在Plist和代码中更改状态
Objective-C的实现:
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[self requestAlwaysAuthorization];
}
- (void)requestAlwaysAuthorization
{
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
//如果状态是没有获准就弹出一个Alert
if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status == kCLAuthorizationStatusDenied) {
NSString *title;
title = (status == kCLAuthorizationStatusDenied) ? @"定位是关闭状态" : @"后台定位没有开启";
NSString *message = @"需要开启Alway的定位服务";
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:self
cancelButtonTitle:@"取消"
otherButtonTitles:@"设置", nil];
[alertView show];
}
else if (status == kCLAuthorizationStatusNotDetermined) {
[self.locationManager requestAlwaysAuthorization];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1) {
// 跳到设置界面
NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:settingsURL];
}
}
Swift的实现: if locationManager.respondsToSelector(Selector("requestAlwaysAuthorization")) {
requestAlwaysAuthorization()
}
func requestAlwaysAuthorization() {
let status = CLLocationManager.authorizationStatus()
if status == .Denied || status == .AuthorizedWhenInUse {
let title = (status == .Denied) ? "定位是关闭状态" : "后台定位没有开启"
let message = "需要开启Alway的定位服务"
UIAlertView(title: title, message: message, delegate:self, cancelButtonTitle: "取消", otherButtonTitles: "设置")
} else {
locationManager.requestAlwaysAuthorization()
}
}
func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int) {
if buttonIndex == 1 {
UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)
}
}