CoreLocation框架可用於定位設備當前經緯度,通過該框架,應用程序可通過附近的蜂窩基站,WIFI信號或者GPS等信息計算用戶位置。
iOS定位支持的3種模式。
(1)GPS衛星定位
(2)基站定位
(3)WiFi
iOS開發者使用CoreLocation.framework框架進行定位非常簡單,CoreLocation框架的常用API主要有如下幾個。
(1)CLLocationManger:定位管理器類。
(2)CLLocationManagerDelegate:該協議代表定位管理器的delegate協議。實現該協議的對象可負責處理CLLocationManager的定位事件。
(3)CLLocation:該對象代表位置。該對象包含了當前設備的經度、緯度、高度、速度、路線等信息,還包含了該定位信息的水平精確度,垂直精確度以及時間戳信息。
(4)CLHeading:該對象代表設備的移動方向。
(5)CLRegion:該對象代表一個區域。一般程序不會直接使用該類,而是使用它的兩個子類,即CLCircularRegion(圓形區域)和CLBeaconRegion(藍牙信號區)。
1.獲取位置信息
(1)創建CLLocationManager對象,該對象負責獲取定位相關信息。並為該對象設置一些必要的屬性。
(2)為CLLocationManager指定delegate屬性,該屬性值必須是一個實現CLLocationManagerDelegate協議的對象。實現CLLocationManagerDelegate協議時可根據需要實現協議中特定的方法。
(3)調用CLLocationManager的startUpdatingLocation方法獲取定位信息。定位結束時,可調用stopUpdatingLocation方法結束獲取定位信息。
案例:
第一步:在CoreLocation.framework添加到項目中去
第二步:在iOS8中需要在info.plist中添加兩個字段。
代碼如下:
#import "ViewController.h" #import <CoreLocation/CoreLocation.h> @interface ViewController ()<CLLocationManagerDelegate> @property (weak, nonatomic) IBOutlet UITextField *longitude; @property (weak, nonatomic) IBOutlet UITextField *latitude; @property (weak, nonatomic) IBOutlet UITextField *height; @property (weak, nonatomic) IBOutlet UITextField *speed; @property (weak, nonatomic) IBOutlet UITextField *direction; @property(strong,nonatomic)CLLocationManager *locationManager; @end @implementation ViewController - (IBAction)beginLocation:(UIButton *)sender { if ([CLLocationManager locationServicesEnabled]) { NSLog(@"開始執行定位服務"); //設定定位精度:最佳精度 self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; //設置距離過濾器為50米,表示每移動50米更新一次位置 self.locationManager.distanceFilter = 50; //將視圖控制器自身設置為CLLocationManager的delegate //因此該視圖控制器需要實現CLLocationManagerDelegate協議 self.locationManager.delegate = self; } else { NSLog(@"無法使用定位服務"); } } -(void) viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; //開啟定位 [_locationManager startUpdatingLocation]; } -(void) viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; //結束定位 [_locationManager stopUpdatingLocation]; } #pragma mark - CLLocationDelegate代理協議 //成功獲取定位數據后將會激發該方法 -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { //獲取最后一個定位數據 CLLocation *location = [locations lastObject]; //依次獲取CLLocation中封裝的經度、緯度、高度、速度、方向等信息 self.longitude.text = [NSString stringWithFormat:@"%g",location.coordinate.longitude];//緯度 NSLog(@"%f",location.coordinate.longitude); self.latitude.text = [NSString stringWithFormat:@"%g",location.coordinate.latitude];//經度 self.height.text = [NSString stringWithFormat:@"%g",location.altitude]; self.speed.text = [NSString stringWithFormat:@"%g",location.speed]; self.direction.text = [NSString stringWithFormat:@"%g",location.course]; } //定位失敗執行的操作 -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"定位失敗:%@",error); } - (void)viewDidLoad { [super viewDidLoad]; //創建CLLocationManager對象 self.locationManager = [[CLLocationManager alloc]init]; } @end
運行效果圖,如下:

方向監測
擁有GPS硬件的設備可以生成設備的當前方向(course屬性)和速度信息。iPhone設備攜帶的定位管理器可以返回一個已經計算好的course值,通過這個值我們可以獲得當前前進的方向,course值是0~360之間的浮點數,0°值表示正北方向,90°表示正東方向,180°值表示正南方向,270°值表示正西方向,程序可以通過course值來檢測用戶位置的移動方向。除此之外,還可以通過磁力計來獲取設備的真實方向。
使用CLLocationManager獲取設備方向的步驟如下。
1.創建CLLocationManager對象,該對象負責獲取定位相關信息,並為該對象設置一些必要的屬性。
2.為CLLocationManager指定delegate屬性,該屬性值必須是一個實現CLLocationManagerDelegate協議的對象。實現CLLocationManagerDelegate協議時可根據需要實現協議中特定的方法。
3.調用CLLocationManager的startUpdatingHeading方法獲取方向信息。獲取方向結束時,可調用stopUpdatingHeading方法結束時獲取方向信息。
當設備的方向改變時,iOS系統就會自動激發CLLocationManager的delegate對象的locationManager:didUpdateHeading:方法,而程序可通過重寫該方法來獲取設備方向。
iOS允許為檢測方向改變設置如下屬性。
1)CLLocationDegress headingFilter:設置只有當設備方向的改變值超過該屬性值時才激發delegate的方法。
2)CLDeviceOrientation headingOrientation:設置設備當前方向。
監聽方向時返回的是一個CLHeading對象,該對象包含以下屬性。
1)magnticHeading:該屬性返回設備與磁北的相對方向。
2)trueHeading:該屬性返回設備與真北的相對方向。
3)headingAccuracy:該屬性返回方向值的誤差范圍。
4)timestamp:該屬性返回方向值的生成時間。
#import "ViewController.h" #import <CoreLocation/CoreLocation.h> @interface ViewController ()<CLLocationManagerDelegate> { CALayer *znzLayer; } @property(strong,nonatomic)CLLocationManager *locationManager; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //如果磁力計可用,則開始監聽方向改變 if ([CLLocationManager headingAvailable]) { //創建顯示方向的指南針圖片Layer; znzLayer = [[CALayer alloc]init]; NSInteger screenHeight = [UIScreen mainScreen].bounds.size.height; NSInteger y = (screenHeight - 320)/2; znzLayer.frame = CGRectMake(0, y, 320, 320); //設置znzLayer顯示的圖片 znzLayer.contents = (id)[[UIImage imageNamed:@"1.png"]CGImage]; //將znzLayer添加到系統的UIView中 [self.view.layer addSublayer:znzLayer]; //創建CLLocationManager對象 self.locationManager = [[CLLocationManager alloc]init]; self.locationManager.delegate = self; [self.locationManager startUpdatingHeading]; } else { [[[UIAlertView alloc]initWithTitle:@"提醒" message:@"您的設備不支持磁力計" delegate:self cancelButtonTitle:@"確定" otherButtonTitles: nil]show]; } } #pragma mark - CLLocationManagerDelegate代理方法 -(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { //將設備的方向換算成弧度 CGFloat headings = -1.0f *M_PI * newHeading.magneticHeading / 180.0f; //創建不斷改變CALayer的transform屬性的屬性動畫 CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"]; CATransform3D fromValue = znzLayer.transform; //設置動畫開始的屬性值 anim.fromValue = [NSValue valueWithCATransform3D:fromValue]; //繞Z軸旋轉heading弧度的變換矩陣 CATransform3D toValue = CATransform3DMakeRotation(headings, 0, 0, 1); //設置動畫結束時的屬性 anim.toValue = [NSValue valueWithCATransform3D:toValue]; anim.duration = 0.5; anim.removedOnCompletion = YES; //設置動畫結束后znzLayer的變換矩陣 znzLayer.transform = toValue; //為znzLayer添加動畫 [znzLayer addAnimation:anim forKey:nil]; } -(BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager { return YES; } @end
區域監測
如果希望iOS設備進入某個區域發出通知,那么這種區域監測的功能也被稱為臨近警告。所謂臨近警告的示意圖如下:
用戶設備不斷地臨近指定固定點,當與該固定點的距離小於指定范圍時,系統可以觸發相應的處理。用戶設備離開指定固定點,當與該固定點的距離大於指定范圍時,系統也可以觸發相應的處理。
iOS的區域監測同樣可以使用CLLocationManager來實現,監聽設備是否進入/離開某個區域的步驟如下:
1)創建CLLocationManager對象,該對象負責獲取定位相關信息,並未該對象設置一些必要的屬性。對於區域監測而言,CLLocationManager對象需要設置monitoredRegions屬性,該屬性值用於設置該設備監聽的多個區域。
2)為CLLocationManager指定delegate屬性,該屬性值必須是一個實現CLLocationManagerDelegate協議的對象。實現CLLocationManagerDelegate協議時可根據需要實現協議中特定的方法。
3)調用CLLocationManager的startMonitoringForRegion:方法進行區域監測。區域監測結束時,可調用stopMonitoringForRegion:方法結束區域監測。
#import "ViewController.h" #import <CoreLocation/CoreLocation.h> @interface ViewController ()<CLLocationManagerDelegate> @property(strong,nonatomic)CLLocationManager *locationManager; @end @implementation ViewController -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.locationManager startUpdatingLocation]; } - (void)viewDidLoad { [super viewDidLoad]; //判斷是否開啟定位服務 if ([CLLocationManager locationServicesEnabled]) { self.locationManager = [[CLLocationManager alloc]init]; //定義一個CLLocationCoordinate2D作為區域的圓心 CLLocationCoordinate2D companyCenter; companyCenter.latitude = 23.126272; companyCenter.longitude = 113.395568; //使用CLCircularRegion創建一個圓形區域,半徑為500米 CLRegion *fkit = [[CLCircularRegion alloc]initWithCenter:companyCenter radius:500 identifier:@"fkit"]; //開始監聽fkit區域 [self.locationManager startMonitoringForRegion:fkit]; self.locationManager.delegate = self; [self.locationManager requestAlwaysAuthorization]; } else { [[[UIAlertView alloc]initWithTitle:@"提醒" message:@"您的設備不支持定位" delegate:self cancelButtonTitle:@"確定" otherButtonTitles: nil]show]; } [self.locationManager startUpdatingLocation]; } #pragma mark - CLLocationManagerDelegate代理方法 //進入指定區域以后彈出提示框提示用戶 -(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region { [[[UIAlertView alloc]initWithTitle:@"區域檢測提示" message:@"您已經【進入】中關園區域" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]show]; } //離開指定區域以后將彈出提示框提示用戶 -(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region { [[[UIAlertView alloc]initWithTitle:@"區域檢測提示" message:@"您已經【離開】中關園區域" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]show]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. }
