在iOS開發中,定位是不少App都須要使用的功能。本文主要對iOS中的定位知識點進行介紹。本文代碼環境爲:Xcode 10.1 + Swift 4.2
。bash
CoreLocation
模塊中,因此必須導入import CoreLocation
CLLocation
:表示某個位置的地理信息,好比經緯度、海拔等CLLocationManager
:定位管理器,能夠理解爲定位不能本身工做,須要有個管理者對它進行全過程監督。CLGeocoder
:地理編碼,分爲兩種
CLPlacemark
:位置信息,包含的信息如國家、城市、街道等CLLocationManagerDelegate
:定位代理,不論是定位成功與失敗,都會有相應的代理方法回調CLLocationManager
發起定位,定位成功或者失敗都會回調CLLocationManagerDelegate
中相應的代理方法 (2)在成功的代理方法中獲取 CLLocation
對象,進而獲取經緯度 (3)經過 CLGeocoder
獲取經緯度對應的位置信息CLPlacemark
(4)經過CLPlacemark
獲取具體的位置信息在iOS中,隱私保護特別好,凡事須要定位的時候,第一次必須彈出對話框給用戶選擇,一共有兩種權限ide
requestWhenInUseAuthorization
(2)在info.plist
對應的位置寫明申請權限的具體緣由requestAlwaysAuthorization
(2)在info.plist
對應的位置寫明申請權限的具體緣由Privacy - Location Usage Description
Privacy - Location Always Usage Description
Privacy - Location When In Use Usage Description
Privacy - Location Always and When In Use Usage Description
,因此iOS11以後必須配置的是 Privacy - Location When In Use Usage Description
和Privacy - Location Always and When In Use Usage Description
注意:上架的App這個緣由必須寫明確測試
因爲定位須要GPS,因此通常狀況下,都須要真機進行測試,筆者在教學過程當中,常用的是一種模擬定位,這種定位須要準備一個gpx
的文件,能夠取名 XXX.gpx
,裏面的內容以下:ui
<?xml version="1.0" encoding="UTF-8" ?>
<gpx version="1.1"
creator="GMapToGPX 6.4j - http://www.elsewhere.org/GMapToGPX/"
xmlns="http://www.topografix.com/GPX/1/1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<!--安徽商貿職業技術學院 谷歌地球:31.2906511800,118.3623587000-->
<wpt lat="31.2906511800" lon="118.3623587000">
<name>安徽商貿職業技術學院</name>
<cmt>中國安徽省蕪湖市弋江區文昌西路24號 郵政編碼: 241002</cmt>
<desc>中國安徽省蕪湖市弋江區文昌西路24號 郵政編碼: 241002</desc>
</wpt>
</gpx>
複製代碼
將本身的定位信息填寫進xml對應的位置便可,而後選擇Edit Scheme
,在Options
中選擇本身的gpx
的文件,這樣模擬器運行的時候就會讀取該文件的位置信息。 編碼
若是你的App須要後臺定位,能夠這樣作,首先在Capabilities
中打開後臺模式 spa
使用時才定位權限
須要加上locationManager.allowsBackgroundLocationUpdates = true
開啓後臺定位,而一直能夠定位權限
不須要寫任何額外代碼使用時才定位權限
退出後,手機頂部會有藍條提示,而一直能夠定位權限
則沒有CoreLocation
模塊CLLcationManager
對象,設置參數和代理,請求定位受權並配置info.plist
CLLcationManager
對象的startUpdatingLocation
方法進行定位import UIKit
import CoreLocation
class ViewController: UIViewController {
//定位須要一個CLLocationManager
lazy var locationManager:CLLocationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
setupManager()
}
func setupManager(){
//默認狀況是這樣的,每當位置改變時LocationManager就調用一次代理。經過設置distanceFilter能夠實現當位置改變超出必定範圍時LocationManager才調用相應的代理方法。這樣能夠達到省電的目的。
locationManager.distanceFilter = 300
//精度 好比爲10 就會盡可能達到10米之內的精度
locationManager.desiredAccuracy = kCLLocationAccuracyBest
//代理
locationManager.delegate = self
//第一種:能後臺定位可是會在頂部出現大藍條(打開後臺定位的開關)
//容許後臺定位
locationManager.allowsBackgroundLocationUpdates = true
locationManager.requestWhenInUseAuthorization()
//第二種:能後臺定位而且不會出現大藍條
//locationManager.requestAlwaysAuthorization()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//發起位置更新(定位)會一直輪詢,耗電
self.locationManager.startUpdatingLocation()
}
}
extension ViewController : CLLocationManagerDelegate{
//定位成功
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
//地理編碼的類
let gecoder = CLGeocoder()
if let location = location {
//反地理編碼 轉換成 具體的地址
gecoder.reverseGeocodeLocation(location) { (placeMarks, error) in
//CLPlacemark -- 國家 城市 街道
let placeMark = placeMarks?.first
if let placeMark = placeMark{
print("\(placeMark.country!) -- \(placeMark.name!) -- \(placeMark.locality!)")
}
}
}
self.locationManager.stopUpdatingLocation()
}
//定位失敗
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
}
複製代碼