天天看點

iOS6定位服務程式設計詳解

現在的移動裝置很多都提供定位服務,使用ios系統的iphone、ipod touch和ipad都可以提供位置服務,ios裝置能提供3種不同途徑進行定位:wifi, 蜂窩式行動電話基站, gps衛星

ios不像android系統在定位服務程式設計時,可以指定采用哪種途徑進行定位。ios的api把底層這些細節屏蔽掉了,開發人員和使用者并不知道現在裝置是采用哪種方式進行定位的,ios系統會根據裝置的情況和周圍的環境,采用一套最佳的解決方案。這個方案是這樣的,如果能夠接收gps資訊,那麼裝置優先采用gps定位,否則采用wifi或蜂窩基站定位,在wifi和蜂窩基站之間優先使用wifi,如果無法連接配接wifi才使用蜂窩基站定位。

總體來說gps定位優點是準确、覆寫面廣闊,缺點是不能被遮擋(例如:在建築物裡面收不到gps衛星信号)、gps開啟後比較費電。蜂窩基站不僅誤差比較大,而且會耗費使用者流量費。而wifi定位是最經濟實惠的。

定位服務程式設計

定位服務在ios 6之後api沒有太大的變化,主要使用corelocation架構,定位時候主要使用cllocationmanager、cllocationmanagerdelegate和cllocation。cllocationmanager是定位服務管理類它能夠給我們提供獲得裝置的位置資訊和高度資訊,也可以監控裝置進入或離開某個區域,它還可以幫助獲得裝置的運作方向等。cllocationmanagerdelegate是cllocationmanager類委托協定。cllocation類是封裝了位置和高度資訊。

在定位服務的應用中,第一次請求獲得位置資訊時候,系統會提示使用者是否允許開啟定位服務。使用者所在的位置是比較私密的資訊,應用擷取這些資訊使用者是有知情權和否定權的。如果應用在使用者不知情的情況下,而獲得使用者的位置資訊,這在某些國家是違法的行為。

iOS6定位服務程式設計詳解

選擇“不允許”,定位服務就無法獲得位置資訊了,如果想改變這些設定可以在系統設定應用中開啟或關閉。

iOS6定位服務程式設計詳解

我們可以關閉所有的定位服務,隻需要把最上面的“定位服務”開關控件關閉就可以了。下面的具體應用也可以關閉和開啟。

下面我們通過一個案例介紹一下使用定位服務程式設計,在應用啟動時候啟動,進入畫面時候會獲得位置資訊,并顯示在對應的文本框中,如果裝置位置發送變化,也會重新會的位置資訊,并更新對應的文本框。

iOS6定位服務程式設計詳解

首先要實作定位服務的案例,需要為工程引入corelocation架構,添加具體步驟是選擇工程中的targets→whereami→build phases→link binary with libraries,選擇右下角的“+”按鈕,打開架構和庫選擇對話框

iOS6定位服務程式設計詳解

再添加對話框中選擇corelocation.framework,點選add按鈕後添加完成。ui設計部分我們不再介紹。我們直接看看實作代碼,其中主要代碼是視圖控制器viewcontroller中編寫的,其中viewcontroller.h代碼如下:

在h檔案中首先需要引入<corelocation/corelocation.h>和<corelocation/cllocationmanagerdelegate.h>頭檔案。然後在定義viewcontroller時需要聲明實作cllocationmanagerdelegate協定。我們還定義了cllocationmanager *locationmanager屬性。

viewcontroller.m的viewdidload代碼如下:

在viewdidload方法中,主要對cllocationmanager的成員變量_locationmanager進行初始化。首先使用[[cllocationmanager alloc] init]語句執行個體化cllocationmanager對象。然後_locationmanager.delegate = self語句設定定位服務委托為self。第①行代碼設定desiredaccuracy屬性,它是一個非常重要的屬性,它的取值有6個常量:kcllocationaccuracynearesttenmeters。精度10米;kcllocationaccuracyhundredmeters 。精度100米;kcllocationaccuracykilometer 。精度1000米;kcllocationaccuracythreekilometers。精度3000米;kcllocationaccuracybest 。裝置使用電池供電時候,最高的精度;kcllocationaccuracybestfornavigation。導航情況下最高精度,一般要有外接電源時才能使用;

精度越高請求獲得位置資訊的時間就越短,這就意味着裝置越耗電。是以一個應用應該選擇适合它的精度,如果你的應用是一個車載導航應用,kcllocationaccuracybestfornavigation是比較好的選擇,你可以使用汽車上的電瓶為裝置供電。如果你的應用為徒步旅行者提供的導航應用,kcllocationaccuracyhundredmeters是一個不錯的選擇。

第②行代碼設定distancefilter屬性,它是距離過濾器,它定義了裝置移動更新位置資訊的最小距離,它的機關是米,本例設定了1000米。

初始化cllocationmanager完成之後,需要使用startupdatinglocation方法開始定位服務。它是在viewcontroller.m的viewwillappear:方法中,代碼如下:

調用startupdatinglocation方法定位服務就會開啟,它根據設定的條件,不斷請求回調新的位置資訊。是以開啟這個方法一定要慎重,要在最合适的時候開啟,在視圖控制器的聲明周期方法中viewwillappear:是最合适的。與開啟服務對應的方法是stopupdatinglocation方法,它的調用是在視圖控制器的viewwilldisappear:方法中調用的,代碼如下:

viewwilldisappear:在視圖消失(應用退到背景)時調用,能夠保證最及時地關閉定位服務,這是負責任的做法。在ios 6之後請求有所變化,定位服務應用退入台後可以延遲更新位置資訊,其中allowdeferredlocationupdatesuntiltraveled:timeout:方法可以設定延遲更新,進而使得應用在背景不再更新位置資訊。關閉延遲更新使用disallowdeferredlocationupdates方法實作。此外,在ios 6之後新增pauseslocationupdatesautomatically屬性,它能設定自動暫停位置更新,定位服務的開啟和暫停管理權交給系統,這樣會更加合理和簡單。

一旦定位服務開啟,并設定好了cllocationmanager委托屬性delegate後,當使用者裝置移動到達過濾距離時,就會回調委托方法,與定位服務有關的方法有兩個:

locationmanager:didupdatelocations: 定位成功,是ios 6新方法,替代之前的locationmanager:didupdatetolocation:fromlocation:方法;

locationmanager:didfailwitherror: 定位失敗;

實作cllocationmanager委托代碼如下:

在locationmanager:didupdatelocations:方法中參數locations是位置變化的集合,它按照時間變化的順序存放。如果想獲得目前裝置的位置,可以使用第①行的[locations lastobject]語句獲得集合中最後一個元素,它就是裝置目前位置了。從集合中傳回的對象類型是cllocation,cllocation封裝了位置、高度等資訊。在上面代碼中我們使用了它的兩個屬性:altitude和coordinate,altitude屬性是高度值,coordinate是封裝了經度和緯度的結構體cllocationcoordinate2d,cllocationcoordinate2d定義如下:

其中latitude為經度資訊,longitude為緯度資訊,它們都是cllocationdegrees類型,cllocationdegrees是使用typedef定義的double類型。

第②行代碼中的newlocation.coordinate.latitude表達式是獲得裝置目前的緯度,第③行代碼中的newlocation.coordinate.longitude表達式是獲得裝置目前的緯度,而獲得高度可以使用第④行newlocation.altitude表達式直接獲得。

繼續閱讀