<p class="p1"><span class="s1">ios 5.1之前 </span></p><p class="p1"><span class="s1">NSURL *url = [NSURL URLWithString:</span><span class="s2">@"prefs:root=LOCATION_SERVICES"</span><span class="s1">];</span></p><p class="p1"><span class="s1">[[UIApplication sharedApplication] openURL:url];</span></p>
一些其他可用的參數:
List of currently known URLs in the Settings app:
- prefs:root=General&path=About
- prefs:root=General&path=ACCESSIBILITY
- prefs:root=AIRPLANE_MODE
- prefs:root=General&path=AUTOLOCK
- prefs:root=General&path=USAGE/CELLULAR_USAGE
- prefs:root=Brightness
- prefs:root=General&path=Bluetooth
- prefs:root=General&path=DATE_AND_TIME
- prefs:root=FACETIME
- prefs:root=General
- prefs:root=General&path=Keyboard
- prefs:root=CASTLE
- prefs:root=CASTLE&path=STORAGE_AND_BACKUP
- prefs:root=General&path=INTERNATIONAL
- prefs:root=LOCATION_SERVICES
- prefs:root=ACCOUNT_SETTINGS
- prefs:root=MUSIC
- prefs:root=MUSIC&path=EQ
- prefs:root=MUSIC&path=VolumeLimit
- prefs:root=General&path=Network
- prefs:root=NIKE_PLUS_IPOD
- prefs:root=NOTES
- prefs:root=NOTIFICATIONS_ID
- prefs:root=Phone
- prefs:root=Photos
- prefs:root=General&path=ManagedConfigurationList
- prefs:root=General&path=Reset
- prefs:root=Sounds&path=Ringtone
- prefs:root=Safari
- prefs:root=General&path=Assistant
- prefs:root=Sounds
- prefs:root=General&path=SOFTWARE_UPDATE_LINK
- prefs:root=STORE
- prefs:root=TWITTER
- prefs:root=General&path=USAGE
- prefs:root=VIDEO
- prefs:root=General&path=Network/VPN
- prefs:root=Wallpaper
- prefs:root=WIFI
- prefs:root=INTERNET_TETHERING
APP有多種原因像你獲取地址信息授權。(此處省略各種原因舉栗子)
iOS8以前,定位服務授權是二進制的:給或者不給。設置的應用選項會展示那些是你授權後臺定位服務的APP,但是你除了完全授權使用定位服務外不能再做其他處理了(短暫使用)。
iOS8對這方面做了修正,有以下兩種授權方式。
- 在APP在使用的時候授權
- 一直授權
這毫無疑問對用戶隱私來說是一個利好,但是對於開發來說呵呵。。
請求授權
在早先的iOS,定位服務的授權請求是很隱式的。創建一個CLLocationManager
實例,如果用戶還沒有顯示的同意或者拒絕一個APP的定位服務授權下面得代碼會在觸發探測用戶授權定位服務。
import Foundation
import CoreLocation
let manager = CLLocationManager()
if CLLocationManager.locationServicesEnabled() {
manager.startUpdatingLocation()
}
爲了讓事情簡單點,假設上述代碼中我們已經聲明瞭
manager
實例作爲成員變量,並且也設置了它的代理。
每次讓CLLocationManager
獲取最新地址信息的動作都會彈出定位服務授權框。
在iOS8,請求授權與開始使用定位服務是兩個不同的動作。特別地,這裏有兩個不同的方法你可以用來顯式的請求授權requestWhenInUseAuthorization
和requestAlwaysAuthorization
。前者只是允許你在應用打開得時候獲取地位位置信息。後者則允許一直在後臺獲取地理位置信息。
if CLLocationManager.authorizationStatus() == .NotDetermined {
manager.requestWhenInUseAuthorization()
}
或
if CLLocationManager.authorizationStatus() == .NotDetermined {
manager.requestAlwaysAuthorization()
}
因爲授權動作是異步的,所以應用不能馬上開始使用定位服務。相反,應用中必須實現locationManager:didChangeAuthorizationStatus
的代理方法,這個代理方法當用戶改變當前的授權權限的時候將會被髮送。
如果用戶上一次授予用戶定位服務的權限,這個代理方法將會在定位管理者被初始化之後並且它的代理被設置成正確的授權狀態後被調用。這樣將便於代碼進行定位服務。
func locationManager(manager: CLLocationManager!,
didChangeAuthorizationStatus status: CLAuthorizationStatus)
{
if status == .AuthorizedAlways || status == .AuthorizedWhenInUse {
manager.startUpdatingLocation()
// ...
}
}
描述性字符串
另外一個變化是iOS8中要求使用定位服務。在過去,info.plist
中選擇性包含一個NSLocationUsageDescription
的Key.這個值是在向用戶申請定位服務的時候展示給用戶看的一段字符串。現在被分割爲了兩個Keys(NSLocationWhenInUseUsageDescription
and NSLocationAlwaysUsageDescription
),並且現在更加強制了;如果你調用了requestWhenInUseAuthorization
or requestAlwaysAuthorization
而沒有使用相對應得Key,那麼這段提示不會展示給用戶。
請求多次授權
另外一個值得注意的地方是授權彈出將只給用戶展示一次。若CLLocationManager.authorizationStatus()
返回值不爲NotDetermined
,此時調用requestWhenInUseAuthorization()
or requestAlwaysAuthorization()
將不會給用戶展示告警欄。在用戶最初選擇之後,唯一改變授權設置的方式是到設置裏的用戶隱私條款設置裏面進行對應APP相關設置。
儘管在舊操作系統上有諸多不便,在一個應用的生命週期內最顯著麻煩的事情主要是“使用權限”跟“永久權限”的請求。大蘋果爲了緩和這個狀況,提出了字符串常量,UIApplicationOpenSettingsURLString
,提供了一個URL用來打開機器的設置界面。
這裏是一個實例代碼教你讓APP打開設置界面獲取永久權限:
switch CLLocationManager.authorizationStatus() {
case .Authorized:
// ...
case .NotDetermined:
manager.requestWhenAlwaysAuthorization()
case .AuthorizedWhenInUse, .Restricted, .Denied:
let alertController = UIAlertController(
title: "Background Location Access Disabled",
message: "In order to be notified about adorable kittens near you, please open this app's settings and set location access to 'Always'.",
preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
alertController.addAction(cancelAction)
let openAction = UIAlertAction(title: "Open Settings", style: .Default) { (action) in
if let url = NSURL(string:UIApplicationOpenSettingsURLString) {
UIApplication.sharedApplication().openURL(url)
}
}
alertController.addAction(openAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
往後兼容
所有新的API都已iOS8作爲根本。對於仍然需要支持iOS7或更早版本,我們必須維護兩個平行代碼-一個是iOS8顯示的索取權限和另外一個僅僅是要求獲取地理位置信息更新。一個簡單得實現如下:
func triggerLocationServices() {
if CLLocationManager.locationServicesEnabled() {
if self.manager.respondsToSelector("requestWhenInUseAuthorization") {
manager.requestWhenInUseAuthorization()
} else {
startUpdatingLocation()
}
}
}
func startUpdatingLocation() {
manager.startUpdatingLocation()
}
// MARK: - CLLocationManagerDelegate
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if status == .AuthorizedWhenInUse || status == .Authorized {
startUpdatingLocation()
}
}
建立用戶信任
在iOS8所有得改變上跑着共同的一條線索:那就是它們(改變)容易地獲取用戶的信任。
顯式請求授權鼓勵應用不要等到用戶準備做某些事情需要授權的時候纔去請求用戶授權。(略)
大蘋果尊重用戶的個人選擇。。。(略)
室內個人定位
當你細讀CL框架的時候可能會對CLFloor對象產生疑惑,這個新對象有如下簡單得接口:
class CLFloor : NSObject {
var level: Int { get }
}
就這麼簡單,一個簡單屬性,告訴你你現在在一個建築的幾樓。
歐洲人說底層是0樓不是1樓。。
一個CLLocationManager
返回的CLLocation
對象可能帶有一個floor
屬性,但是你若寫一個使用定位服務的栗子APP你會發現你的CLLocation
對象中的floor
屬性爲nil
。
這是因爲API改變是冰山的尖端以此來爲iOS8帶來一套新特徵從而便利室內定位跟蹤(我暈菜了)。對於開發者爲大空間建築物設計應用的時候,比如博物館或者大型商場,大蘋果提供了支持IPS的工具通過使用內置CL APIs和WiFi,GPS,蜂窩式網絡,還有iBeacon數據混用的方式。
大概說了這個技術現狀是商用上嚴格控制。。。
CLVisit
在很多應用,使用位置定位來判斷用戶是不是在某個期望的地理位置。概念上說,你會將這個行爲想成名詞“現場”或者是“訪問”而不是原生的GPS定位。
略一段。。
在iOS8中,大蘋果爲我們解決此類問題提供了CLVisit
,一個新的後臺定位監測類型。一個但一個的CLVisit
表示用戶花了一段時間在一個單一的地方,包含了同一地理座標以及起始/結束時間戳。
理論上來說,使用訪問監控不會比其他的後臺定位做更多的活兒。簡單得調用manager.startMonitoringVisits()
可以啓動後臺訪問定位,假設用戶已經永久授權。一旦啓動,你的APP將會被後臺激活當有新的更新到來的時候(讓我想到了樂動力這個APP)。與基礎的定位不同,如果系統有一些的訪問更新隊列,你的代理方法locationManager:didReceiveUpdates:
將會調用多次,每次都只調用一個訪問,而不是一個CLLocation
對象數組。調用manager.stopMonitoringVisits()
將會停止定位跟蹤。
訪問處理句柄
每個CLVisit
對象包含着一些基礎屬性:平均座標,水平精度,以及數據到達與離開得時間戳。
每次訪問被記錄,CLLocationManagerDelegate
會被通知兩次:一旦用戶剛到達一個新地點,一個用戶剛準備離開這個地點。你可以通過departureDate
屬性計算出它們哪個是哪個;如果離開時間是NSDate.distantFuture()
意味着用戶還在那兒。
func locationManager(manager: CLLocationManager!, didVisit visit: CLVisit!) {
if visit.departureDate.isEqualToDate(NSDate.distantFuture()) {
// User has arrived, but not left, the location
} else {
// The visit is complete
}
}
告警實現
略。。。。