在IOS和OS X设备上都可以使用定位服务,它们共享同一套框架,即Core Location。使用这个框架来获得设备的位置是非常方便的,你不需要关心设备使用什么硬件方式去获取位置,蜂窝基站,Wi-Fi,GPS。框架会根据你设备的硬件情况和你对定位精度的设置来自动选择定位方式。
获取权限
位置是用户的隐私,所以对设备位置的请求必须获得用户的许可。在OS X上,你不需要额外的配置,只要系统发现你在获取设备的位置,就回询问用户是否同意。在IOS上,这个过程会稍微复杂一些,有两种权限,一种是允许应用在前台活动时获取位置信息,一种是在后台也可以获取位置信息。这两种都需要在info.plist中配置,对应的键分别是:NSLocationWhenInUseUsageDescription,NSLocationAlwaysUsageDescription它们的值可以随便填,不过这个值会在弹出的询问用户的弹窗里显示。
配置CLLocationManager对象
//对应两种获取的权限:只在前台获取位置信息requestWhenInUseAuthorization
//在后台也获取requestAlwaysAuthorization
//这个if判断是为了兼容IOS8以下,没有这个方法
if locationManager.respondsToSelector("requestWhenInUseAuthorization") {
locationManager.requestWhenInUseAuthorization()
}
//设置定位精度
locationManager.desiredAccuracy = kCLLocationAccuracyBest
//设置设备移动多长的距离才调用位置更新方法
locationManager.distanceFilter = 1000
locationManager.startUpdatingLocation()
locationManager.delegate = self
实现代理方法
//获取用户位置成功
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let newLocation = locations.last{
myGPSs.append(myGPS(coorX: newLocation.coordinate.latitude, coorY: newLocation.coordinate.longitude, initTitle: "你的位置", initSubtitle: "你在这里",url: NSURL(string: "http://img3.douban.com/view/photo/photo/public/p1864484723.jpg"),initName: "Fixed"))
//如果获得到的精度大于0则停止获取位置信息,否则很费电,这个值为-1则定位不可信
if newLocation.horizontalAccuracy>0 {
locationManager.stopUpdatingLocation()
}
//在获得的位置周围生成一个以精度为半径的覆盖物,这个必须实现一个mapView的代理方法才会生效,这个代理方法决定了如何渲染这个覆盖物
let overlay = MKCircle(centerCoordinate: newLocation.coordinate, radius: newLocation.horizontalAccuracy)
mapView.addOverlay(overlay)
mapView.addAnnotations(myGPSs)
mapView.showAnnotations(myGPSs, animated: true)
} else {
print("No location found")
}
}
//获得用户位置失败
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
}
地理编码
Core Location提供了将地址转换为经纬度和经纬度转换为地址的方法,当让这个功能需要访问苹果的服务器。使用CLGeocoder类
geocoder.reverseGeocodeLocation(newLocation)
{ (placemarks:[CLPlacemark]?, error:NSError?) -> Void in
if error == nil {
//对于一个坐标,可能会返回多个地址
let placemark = placemarks![0] as CLPlacemark
let address = NSString(format: "%@ %@, %@, %@ %@",
placemark.country!,
placemark.administrativeArea!,
placemark.locality!,
placemark.thoroughfare!,
placemark.subThoroughfare!)
self.addressLabel.stringValue = address as String
} else {
self.addressLabel.stringValue = "Fail to Find an Address"
}
}
监测用户出入区域
首先注册一个区域
//监测用户出入该区域
let location = CLLocationCoordinate2DMake(39.96, 116.35)
let region = CLCircularRegion(center: location, radius: 1000, identifier: "BUPT")
locationManager.startMonitoringForRegion(region)
实现代理方法
//用户进入监测区域
func locationManager(manager: CLLocationManager, didEnterRegion region: CLRegion) {
print("enter \(region.identifier)")
}
//用户离开监测区域
func locationManager(manager: CLLocationManager, didExitRegion region: CLRegion) {
print("leave \(region.identifier)")
}