最近项目要用到定位的功能,研究了一番百度地图,需要接入很多第三方库,还需要生成密钥等等,个人觉得比较麻烦,虽然百度地图的功能已经相当完善了,最后决定用系统地图定位,系统自带用的是高德地图,AIP很清晰,下面是代码实现。
首先import CoreLocation, 创建 OTTLocationManager类,继承NSObject
// 创建CLLocationManager 对象
let manager = CLLocationManager()
// 保存当前定位:
var currentLocation: CLLocation?
// 检测是否获取到定位
// 反地理编码,保存城市,地区
var subLocality: String?
var locality: String?
创建单例,方便ViewController使用:
//singleton manager
class var defaultManager: OTTLocationManager {
struct Static {
static let locManager = OTTLocationManager()
}
return Static.locManager
}
开启定位服务的初始设定:
func getLatLon() {
if (CLLocationManager.locationServicesEnabled()) {
//使用应用程序期间允许访问位置数据
self.manager.requestWhenInUseAuthorization()
self.manager.delegate = self
self.manager.desiredAccuracy = kCLLocationAccuracyBest
self.manager.distanceFilter = kCLLocationAccuracyHundredMeters
self.manager.startUpdatingLocation()
} else {
CLLocationManager.authorizationStatus()
print("[OTTLocationManager getLatLon] 定位服务未开启")
}
}
实现代理方法,获取定位经纬度及反地理编码:
extension OTTLocationManager: CLLocationManagerDelegate {
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.isLocation = true
//取得locations数组的最后一个:因定位一直在移动,所以取数组最后一个准确经纬度
let location: CLLocation = locations[locations.count - 1]
if location.horizontalAccuracy > 0 {
let lat = Float(location.coordinate.latitude)
let lon = Float(location.coordinate.longitude)
self.currentLocation = location
print("[OTTLocationManager locationManager:didUpdateLocations] lat = \(lat), lon = \(lon)")
//反地理编码:将经纬度转换成城市,地区,街道
CLGeocoder().reverseGeocodeLocation(location) { (placemakes: [CLPlacemark]?, error: NSError?) -> Void in
guard let placemark = placemakes?.first else {
return
}
// 城市
self.locality = placemark.locality
// 地区
self.subLocality = placemark.subLocality
print("[OTTLocationManager locationManager:didUpdateLocations] locality = \(placemark.locality), sublocality = \(placemark.subLocality), subthoroughfare = \(placemark.subThoroughfare), self.subLocality = \(self.subLocality)") //详细街道
}
}
// 停止定位服务
self.manager.stopUpdatingLocation()
}
//MARK:定位错误信息
func locationManager(manager: CLLocationManager, didFinishDeferredUpdatesWithError error: NSError?) {
print("[OTTLocationManager locationManager:didFinishDeferredUpdatesWithError] \(error)\(error?.description)")
}
//检测是否获取到定位
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
//如果未开启定位服务或者获取不到定位,会走此代理方法
self.manager.stopUpdatingLocation()
self.isLocation = false
print("[OTTLocationManager locationManager:didFailWithError] 无法获取到定位")
}
}
啊哈,这样就实现了简单的定位功能.
模拟器运行,要在Debug->Location->CustomLocation 设置经纬度,模拟移动端定位,否则不会执行代理方法。
如果要实现地图定位功能,需要import MapKit,实现 MKMapViewDelegate代理方法,后续介绍,敬请期待。