先上一段熟悉的程式碼提提神:)
import CoreLocation
let locationManager = CLLocationManager()
locationManager.delegate = self
...
locationManager.requestLocation()
複製程式碼
比如說在做一款天氣App的時候,我們首先需要請求使用者的位置(locationManager.requestLocation()
),然後系統就自動呼叫func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {...}
delegate方法,然後我們在這個方法的locations
引數裡面獲取到使用者的位置資訊。
那大家就在想啊,在requestLocation()
的時候是不是先要判斷一下之前使用者是不是已經同意過了呢?要不要加個if else
判斷什麼的呢?
按正常邏輯是這樣的,沒錯!
但在iOS的世界裡(別的語言也是),對於使用者同不同意有個專屬名詞--授權
。
蘋果一直很重視使用者隱私,所以我們開發的任何一款App一旦想要窺探使用者隱私(比如這裡的定位)的時候,都需要向使用者發起明確請求,並獲得授權
才行。
那對啊,不應該就是在上面的requestLocation()
的時候判斷一下嘛?
error!
其實這裡有個小小的障眼誤解,就是這個requestLocation()
的作用---他並不是請求使用者授權
的意思。
---問題就出在這裡。
他的真正作用是:
官方的說法是:只請求一次使用者的位置。
翻譯成人話就是說只呼叫一次func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {...}
方法,和授不授權沒有半毛錢關係,(令人震驚的英文名稱)。
這個requestLocation()
還有個同宗兄弟,叫startUpdatingLocation()
官方解釋---我們呼叫幾次,他就呼叫幾次func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {...}
方法,也就是說可以按需使用(比如電商和外賣App讓我們填收貨地址的時候)。
搞了半天,那真正的請求使用者授權的方法是哪個?
就兩個:
requestWhenInUseAuthorization()
requestAlwaysAuthorization()
他們都是用例項化後的CLLocationManager
進行呼叫,從字面上就能知道是什麼意思了,根據專案需求使用就行,官方不推薦使用第二個除非特殊情況(也就是說上架稽核的時候會很嚴)。
那就是說我們重點討論第一個就行了。
進入正題:
我們首先用CLLocationManager
下面的一個常量屬性CLAuthorizationStatus
來判斷當前使用者是否已授權(有沒有同意被定位):
因為是常量屬性,所以直接用CLLocationManager.authorizationStatus()
就可以(呼叫authorizationStatus()函式才能返回這個常量屬性CLAuthorizationStatus
),不需要例項化CLLocationManager
。
一共有五種狀態來判斷使用者的授權情況:
//在合適的地方使用以下程式碼
switch CLLocationManager.authorizationStatus() {
case .notDetermined://使用者第一次開啟App的時候
//請求使用者大人同意我定位
locationManager.requestWhenInUseAuthorization()
break//跳出switch
// .restricted--這臺iPhone或iPad被開啟了父母限制
// .denied--使用者拒絕+使用者在設定裡關閉了定位服務(或飛航模式)
// (接上)可以用CLLocationManager.locationServicesEnabled()來判斷是哪種拒絕
case .restricted, .denied:
//既然被拒絕了,那就不給你用一些需要定位才能實現的功能啦
//或根據不同情況給使用者良好的提示,引導使用者去同意被定位
disableMyLocationBasedFeatures()
break
//使用者已授權(已同意被定位)
case .authorizedWhenInUse, .authorizedAlways:
//開啟美妙功能
enableMyWhenInUseFeatures()
break
}
複製程式碼
熟悉iOS的人都知道,只要一有個動作發生(比如我們這裡的授權請求),一定會有個人在下面接著(delegate方法)。
比如說: 1.用上面的程式碼進行判斷之後,我們彈出了請求使用者授權的彈框,使用者呢,或被你說動了同意了定位服務,或被你的醜陋介面氣到拒絕被定位等等等的時候,我們該做出什麼樣的應對呢? 2.使用者或手動設定隱私或切換飛航模式,導致iPhone或iPad設定中的定位服務由無到有,有有到無的時候,我們該怎麼辦呢?
一旦使用者怎麼怎麼樣我們要怎麼怎麼樣--delegate!
一旦使用者的CLAuthorizationStatus
改變就會呼叫didChangeAuthorization方法:
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .restricted, .denied:
//可照上面一樣再進行細分判斷
disableMyLocationBasedFeatures()
break
case .authorizedWhenInUse:
//皆大歡喜
enableMyWhenInUseFeatures()
break
case .notDetermined, .authorizedAlways:
//不在本話題範圍內就先不管了
break
}
}
複製程式碼
以上。
想學習更多關於iOS的定位功能,可以去看一下我的視訊教程 :)
感謝APPLE官方對本文的大力支援。