iOS定位服務編程詳解,ios定位詳解
現在的行動裝置很多都提供定位服務,使用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類是封裝了位置和高度資訊。
在定位服務的應用中,第一次請求獲得位置資訊時候,系統會提示使用者是否允許開啟定位服務。使用者所在的位置是比較私密的資訊,應用擷取這些資訊使用者是有知情權和否定權的。如果應用在使用者不知情的情況下,而獲得使用者的位置資訊,這在某些國家是違法的行為。
選擇“不允許”,定位服務就無法獲得位置資訊了,如果想改變這些設定可以在系統設定應用中開啟或關閉。
我們可以關閉所有的定位服務,只需要把最上面的“定位服務”開關控制項關閉就可以了。下面的具體應用也可以關閉和開啟。
下面我們通過一個案例介紹一下使用定位服務編程,在應用啟動時候啟動,進入畫面時候會獲得位置資訊,並顯示在對應的文字框中,如果裝置位置發送變化,也會重新會的位置資訊,並更新對應的文字框。
首先要實現定位服務的案例,需要為工程引入CoreLocation架構,添加具體步驟是選擇工程中的TARGETS→WhereAmI→Build Phases→Link Binary With Libraries,選擇右下角的“+”按鈕,開啟架構和庫選擇對話方塊
再添加對話方塊中選擇CoreLocation.framework,點擊Add按鈕後添加完成。UI設計部分我們不再介紹。我們直接看看實現代碼,其中主要代碼是視圖控制器ViewController中編寫的,其中ViewController.h代碼如下:
Cpp代碼
- #import <UIKit/UIKit.h>
-
- #import <CoreLocation/CoreLocation.h>
-
- #import <CoreLocation/CLLocationManagerDelegate.h>
-
-
-
-
-
- @interface ViewController : UIViewController <CLLocationManagerDelegate>
-
-
-
- //經度
-
- @property (weak, nonatomic) IBOutlet UITextField *txtLng;
-
- //緯度
-
- @property (weak, nonatomic) IBOutlet UITextField *txtLat;
-
- //高度
-
- @property (weak, nonatomic) IBOutlet UITextField *txtAlt;
-
-
-
- @property(nonatomic, strong) CLLocationManager *locationManager;
-
-
-
- @end
在h檔案中首先需要引入<CoreLocation/CoreLocation.h> 和<CoreLocation/CLLocationManagerDelegate.h>標頭檔。然後在定義ViewController 時需要聲明實現CLLocationManagerDelegate協議。我們還定義了 CLLocationManager *locationManager屬性。
ViewController.m的viewDidLoad代碼如下:
Cpp代碼
- - (void)viewDidLoad
-
- {
-
- [super viewDidLoad];
-
- //定位服務管理對象初始化
-
- _locationManager = [[CLLocationManager alloc] init];
-
- _locationManager.delegate = self;
-
- _locationManager.desiredAccuracy = kCLLocationAccuracyBest; ①
-
- _locationManager.distanceFilter = 1000.0f; ②
-
- }
在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:方法中,代碼如下:
Cpp代碼
- - (void)viewWillAppear:(BOOL)animated
-
- {
-
- [super viewWillAppear:animated];
-
- //開始定位
-
- [_locationManager startUpdatingLocation];
-
- }
調用startUpdatingLocation方法定位服務就會開啟,它根據設定的條件,不斷請求回調新的位置信 息。因此開啟這個方法一定要謹慎,要在最合適的時候開啟,在視圖控制器的聲明周期方法中viewWillAppear:是最合適的。與開啟服務對應的方法 是stopUpdatingLocation方法,它的調用是在視圖控制器的viewWillDisappear:方法中調用的,代碼如下:
Cpp代碼
- - (void)viewWillDisappear:(BOOL)animated
-
- {
-
- [super viewWillDisappear:animated];
-
- //停止定位
-
- [_locationManager stopUpdatingLocation];
-
- }
viewWillDisappear:在視圖消失(應用退到後台)時調用,能夠保證最及時地關閉定位服務,這是負責 任的做法。在iOS 6之後請求有所變化,定位服務應用退入台後可以延遲更新位置資訊,其中 allowDeferredLocationUpdatesUntilTraveled:timeout:方法可以設定延遲更新,從而使得應用在後台不再 更新位置資訊。關閉延遲更新使用disallowDeferredLocationUpdates方法實現。此外,在iOS 6之後新增 pausesLocationUpdatesAutomatically屬性,它能設定自動暫停位置更新,定位服務的開啟和暫停管理權交給系統,這樣會更 加合理和簡單。
一旦定位服務開啟,並設定好了CLLocationManager委託屬性delegate後,當使用者裝置移動到達過濾距離時,就會回調委託方法,與定位服務有關的方法有兩個:
locationManager:didUpdateLocations: 定位成功,是iOS 6新方法,替代之前的locationManager:didUpdateToLocation:fromLocation:方法;
locationManager:didFailWithError: 定位失敗;
實現CLLocationManager委託代碼如下:
Cpp代碼
- #pragma mark Core Location委託方法用於實現位置的更新
-
- - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
-
- {
-
- CLLocation * currLocation = [locations lastObject]; ①
-
- _txtLat.text = [NSString stringWithFormat:@"%3.5f",
-
- currLocation.coordinate.latitude]; ②
-
- _txtLng.text = [NSString stringWithFormat:@"%3.5f",
-
- currLocation.coordinate.longitude]; ③
-
- _txtAlt.text = [NSString stringWithFormat:@"%3.5f",
-
- currLocation.altitude]; ④
-
- }
-
-
-
- - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
-
- {
-
- NSLog(@”error: %@”,error);
-
- }
在locationManager:didUpdateLocations:方法中參數locations是位置變 化的集合,它按照時間變化的順序存放。如果想獲得當前裝置的位置,可以使用第①行的[locations lastObject]語句獲得集合中最後一個 元素,它就是裝置當前位置了。從集合中返回的物件類型是CLLocation,CLLocation封裝了位置、高度等資訊。在上面代碼中我們使用了它的 兩個屬性:altitude和coordinate,altitude屬性是高度值,coordinate是封裝了經度和緯度的結構體 CLLocationCoordinate2D,CLLocationCoordinate2D定義如下:
Cpp代碼
- typedef struct {
-
- CLLocationDegrees latitude; //緯度
-
- CLLocationDegrees longitude; //經度
-
- } CLLocationCoordinate2D;
其中latitude為經度資訊,longitude為緯度資訊,它們都是CLLocationDegrees類型,CLLocationDegrees是使用typedef定義的double類型。
第 ②行代碼中的newLocation.coordinate.latitude運算式是獲得裝置當前的緯度,第③行代碼中的 newLocation.coordinate.longitude運算式是獲得裝置當前的緯度,而獲得高度可以使用第④行 newLocation.altitude運算式直接獲得。
iOS怎實現定位服務?
當然支援了 現在太多的軟體可以做到了。
IOS60定位服務在哪開
在設定裡面的隱私裡面,有定位服務開關,