这个内容涉及到CoreLocation框架里面两个类,CLLocation和CLLocationManager
CLLocation类
CLLocation类里面有一个最重要的属性:
open var coordinate: CLLocationCoordinate2D { get } //坐标
CLLocationCoordinate2D是个结构体,里面就两个属性,经度和纬度
public var latitude: CLLocationDegrees //纬度
public var longitude: CLLocationDegrees // 经度
CLLocation类其它一些属性:
open var altitude: CLLocationDistance { get } //海拔高度
open var speed: CLLocationSpeed { get } // 速度
了解了CLLocation类之后,现在实现定位,实现定位之前要请求用户授权
用户授权
每种授权方式都要在plist文件里面添加键值对
- 使用应用期间授权:应用程序退到后台之后,一般不能获取用户位置了。添加Privacy - Location When In Use Usage Description键。还要调用CLLocationManager的实例方法requestWhenInUseAuthorization()
- 始终:应用程序退到后台之后,还可以获取用户位置。添加Privacy - Location Always and When In Use Usage Description键。还要调用CLLocationManager的实例方法requestAlwaysAuthorization()
两个键不用记,请求用户授权的时候,如果没有在plist文件里面添加键值对,会在控制台输出提示信息
This app has attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain both NSLocationAlwaysAndWhenInUseUsageDescription and NSLocationWhenInUseUsageDescription keys with string values explaining to the user how the app uses this data
把NSLocationAlwaysAndWhenInUseUsageDescription或NSLocationWhenInUseUsageDescription复制到plist文件就可以了
如果用使用应用期间授权方式,应用程序退出后台后,还想获取用户位置,可以把下面属性设置为true
open var allowsBackgroundLocationUpdates: Bool
定位
一次定位
var manager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// 请求用户授权
manager.requestWhenInUseAuthorization()
manager.delegate = self
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// 开始更新位置信息
manager.startUpdatingLocation()
}
// 位置更新完成代理方法
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
// 停止更新位置信息
manager.stopUpdatingLocation()
}
输出结果:
[<+40.00000000,+116.00000000> +/- 5.00m (speed -1.00 mps / course -1.00) @ 4/7/18, 4:58:08 PM China Standard Time]
注意:如果是在模拟器上面跑可以设置模拟器的Debug->Location->Custom Location...选项,设置指定的经纬度
持续定位
问题:不调用manager.stopUpdatingLocation(),会频繁获取用户位置会比较耗电
有两种方法解决方法
方法一:
override func viewDidLoad() {
super.viewDidLoad()
manager.requestWhenInUseAuthorization()
manager.delegate = self
// 距离筛选器: 单位是米, 当位置发生超过10米变化时才调用代理方法
manager.distanceFilter = 10
}
// 位置更新完成代理方法
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
}
方法二:
override func viewDidLoad() {
super.viewDidLoad()
manager.requestWhenInUseAuthorization()
manager.delegate = self
// 期望的精准度
manager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
/**
public let kCLLocationAccuracyBestForNavigation: CLLocationAccuracy 精准度最高的
public let kCLLocationAccuracyBest: CLLocationAccuracy 高
public let kCLLocationAccuracyNearestTenMeters: CLLocationAccuracy 十米
public let kCLLocationAccuracyHundredMeters: CLLocationAccuracy 百米
public let kCLLocationAccuracyKilometer: CLLocationAccuracy 千米
public let kCLLocationAccuracyThreeKilometers: CLLocationAccuracy 三千米
*/
}
// 位置更新完成代理方法
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print(locations)
}
结尾提示:如果敲不出CLLocation对象或CLLocationManager对象,因为没有引入CoreLocation框架