iOS學(xué)習(xí)筆記19-地圖(一)定位CoreLocation

一巴席、定位介紹

現(xiàn)在很多社交历涝、電商、團(tuán)購應(yīng)用都引入了地圖和定位功能情妖,似乎地圖功能不再是地圖應(yīng)用和導(dǎo)航應(yīng)用所特有的睬关。的確,有了地圖和定位功能確實讓我們的生活更加豐富多彩毡证,極大的改變了我們的生活方式电爹。要實現(xiàn)地圖、導(dǎo)航功能料睛,往往需要先熟悉定位功能丐箩。

在iOS中通過CoreLocation框架進(jìn)行定位操作。

CoreLocation自身可以單獨使用恤煞,和地圖開發(fā)框架MapKit完全是獨立的屎勘,但是往往地圖開發(fā)要配合定位框架使用。

CoreLocation可以實現(xiàn)的功能:
  1. 定位功能
  1. 地理編碼與逆地理編碼

二居扒、定位核心類

定位是一個很常用的功能概漱,如一些地圖軟件打開之后如果用戶允許軟件定位的話,那么打開軟件后就會自動鎖定到當(dāng)前位置喜喂,如果用戶手機(jī)移動那么當(dāng)前位置也會跟隨著變化瓤摧。要實現(xiàn)這個功能需要使用CoreLoactionCLLocationManager類竿裂,下面是這個類的使用說明:

1. 類方法:
+ (BOOL)locationServicesEnabled;/* 返回用戶是否啟用定位服務(wù) */
+ (CLAuthorizationStatus)authorizationStatus;/* 定位服務(wù)授權(quán)狀態(tài),返回枚舉類型 */

typedef NS_ENUM(int, CLAuthorizationStatus){
    kCLAuthorizationStatusNotDetermined = 0, /* 用戶尚未決定是否啟用定位服務(wù) */
    kCLAuthorizationStatusRestricted, /* 沒有獲得用戶授權(quán) */
    kCLAuthorizationStatusDenied, /* 用戶禁止使用定位或者定位服務(wù)處于關(guān)閉狀態(tài) */
    kCLAuthorizationStatusAuthorizedAlways, /* 前臺照弥、后臺定位授權(quán) */
    kCLAuthorizationStatusAuthorizedWhenInUse, /* 前臺定位授權(quán) */
};
2. 對象屬性:
  • 定位精度desiredAccuracy
    枚舉類型:
  • 位置信息更新最小距離distanceFilter
    浮點數(shù)腻异,默認(rèn)為kCLDistanceFilterNone,表示不進(jìn)行距離限制
3. 對象方法:
#pragma mark - 定位追蹤
-(void)startUpdatingLocation;/* 開始定位追蹤 */
-(void)stopUpdatingLocation;/* 停止定位追蹤 */
#pragma mark - 導(dǎo)航追蹤
-(void)startUpdatingHeading;/* 開始導(dǎo)航方向追蹤 */
-(void)stopUpdatingHeading;/* 停止導(dǎo)航方向追蹤 */
#pragma mark - 區(qū)域定位追蹤
-(void)startMonitoringForRegion:(CLRegion *)region;/* 開始對某個區(qū)域進(jìn)行定位追蹤 */
-(void)stopMonitoringForRegion:(CLRegion *)region;/* 停止對某個區(qū)域進(jìn)行定位追蹤 */
#pragma mark - 授權(quán)請求
-(void)requestWhenInUseAuthorization;/* 請求獲得應(yīng)用前臺定位授權(quán) */
-(void)requestAlwaysAuthorization;/* 請求獲得應(yīng)用前后臺定位授權(quán) */
4. 常用代理方法CLLocationManagerDelegate
/* 位置發(fā)生改變后調(diào)用这揣,第一次定位也會調(diào)用 */
-(void)locationManager:(CLLocationManager *)manager 
    didUpdateLocations:(NSArray *)locations;
/* 導(dǎo)航方向發(fā)生變化后調(diào)用 */
-(void)locationManager:(CLLocationManager *)manager 
      didUpdateHeading:(CLHeading *)newHeading;
/* 進(jìn)入某個區(qū)域后調(diào)用 */
-(void)locationManager:(CLLocationManager *)manager 
        didEnterRegion:(CLRegion *)region;
/* 走出某個區(qū)域后調(diào)用 */
-(void)locationManager:(CLLocationManager *)manager 
         didExitRegion:(CLRegion *)region;
/* 當(dāng)用戶授權(quán)狀態(tài)發(fā)生變化時調(diào)用 */
-(void)locationManager:(CLLocationManager *)manager 
       didChangeAuthorizationStatus:(CLAuthorizationStatus)status;

三悔常、定位簡單使用

先要在項目導(dǎo)入CoreLocation框架,然后再導(dǎo)入頭文件:
#import <CoreLocation/CoreLocation.h>
iOS版本不同给赞,使用也有一些區(qū)別机打,主要區(qū)分為:
  1. iOS8.0之前的定位使用
  1. iOS8.0之后的定位使用
1. iOS8.0之前的定位使用:
1.1 前臺定位:
- (void)viewDidLoad{
    [super viewDidLoad];
    if (![CLLocationManager locationServicesEnabled]) {
        NSLog(@"定位服務(wù)當(dāng)前可能尚未打開,請設(shè)置打開片迅!");
        return;
    }
    [self initLocationManager];
    //調(diào)用方法,開始更新用戶位置信息
    [self.locationM startUpdatingLocation];
}
//創(chuàng)建CLLocationManager并啟動定位
- (void)initLocationManager{
    //創(chuàng)建CLLocationManager對象并設(shè)置代理
    self.locationM = [[CLLocationManager alloc] init];
    self.locationM.delegate = self;
    //設(shè)置定位精度和位置更新最小距離
    self.locationM.distanceFilter = 100;
    self.locationM.desiredAccuracy = kCLLocationAccuracyBest;
}
//在對應(yīng)的代理方法中獲取位置信息
- (void)locationManager:(CLLocationManager *)manager 
     didUpdateLocations:(NSArray<CLLocation*> *)locations
{
    CLLocation *location = [locations firstObject];//取出第一個位置
    /* 
        使用位置前, 務(wù)必判斷當(dāng)前獲取的位置是否有效
        如果水平精確度小于零, 代表雖然可以獲取位置對象, 但是數(shù)據(jù)錯誤, 不可用
     */
    if (location.horizontalAccuracy < 0)
        return;
    CLLocationCoordinate2D coordinate = location.coordinate;//位置坐標(biāo) 
    CGFloat longitude = coordinate.longitude;//經(jīng)度
    CGFloat latitude = coordinate.latitude;//緯度
    CGFloat altitude = location.altitude;//海拔
    CGFloat course = location.course;//方向
    CGFloat speed = location.speed;//速度
    NSLog(@"經(jīng)度:%f,緯度:%f",longitude,latitude);   
    NSLog(@"海拔:%f,方向:%f,速度:%f",altitude,course,speed);
    //如果不需要實時定位姐帚,使用完即使關(guān)閉定位服務(wù)
    [self.locationM stopUpdatingLocation];   
}
  1. 定位頻率和定位精度并不是越精確越好,需要視實際情況而定障涯,因為越精確越耗性能罐旗,也就越費電。
  1. 定位成功后會根據(jù)設(shè)置情況頻繁調(diào)用locationManager:didUpdateLocations:方法
  2. 每個元素一個CLLocation代表地理位置信息唯蝶,之所以返回數(shù)組是因為有些時候一個位置點可能包含多個位置九秀。
  3. 使用完定位服務(wù)后,如果不需要實時監(jiān)控應(yīng)該立即關(guān)閉定位服務(wù)粘我,以節(jié)省資源鼓蜒。
  4. 除了提供定位功能,還可以調(diào)用startMonitoringForRegion:方法對指定區(qū)域進(jìn)行監(jiān)控征字。
1.2 后臺定位:

在前臺的基礎(chǔ)上都弹,勾選后臺模式Location updates

2. iOS8之后的定位使用
iOS8開始,需要請求定位授權(quán):
  • 前臺授權(quán):
    在Info.plist文件中配置 NSLocationWhenInUseUsageDescriptionYES
  • 前后臺授權(quán):
    在Info.plist文件中配置NSLocationAlwaysUsageDescriptionYES
- (void)viewDidLoad{
    [super viewDidLoad];
    if (![CLLocationManager locationServicesEnabled]) {
        NSLog(@"定位服務(wù)當(dāng)前可能尚未打開匙姜,請設(shè)置打開畅厢!");
        return;
    }
    [self initLocationManager];
    //如果沒有授權(quán),則請求用戶授權(quán)
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
    if (status == kCLAuthorizationStatusNotDetermined){
        //請求前臺定位授權(quán)
        //[self.locationM requestWhenInUseAuthorization];
        //請求前后臺定位授權(quán)
        [self.locationM requestAlwaysAuthorization];
    }
}

//創(chuàng)建CLLocationManager并啟動定位
- (void)initLocationManager{
    //創(chuàng)建CLLocationManager對象并設(shè)置代理
    self.locationM = [[CLLocationManager alloc] init];
    self.locationM.delegate = self;
    //設(shè)置定位精度和位置更新最小距離
    self.locationM.distanceFilter = 100;
    self.locationM.desiredAccuracy = kCLLocationAccuracyBest;
}
// 當(dāng)用戶授權(quán)狀態(tài)發(fā)生變化時調(diào)用
- (void)locationManager:(CLLocationManager *)manager 
        didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch (status) {
        case kCLAuthorizationStatusNotDetermined://用戶還未決定
        {
            NSLog(@"用戶還未決定");
            break;
        }
        case kCLAuthorizationStatusRestricted://訪問受限
        {
            NSLog(@"訪問受限");
            break;
        }
        case kCLAuthorizationStatusDenied://定位關(guān)閉時或用戶APP授權(quán)為永不授權(quán)時調(diào)用
        {
            NSLog(@"定位關(guān)閉或者用戶未授權(quán)");
            break;
        }
        case kCLAuthorizationStatusAuthorizedAlways://獲取前后臺定位授權(quán)
        {
            NSLog(@"獲取前后臺定位授權(quán)");
            [self.locationM startUpdatingLocation];
            break;
        }
        case kCLAuthorizationStatusAuthorizedWhenInUse://獲得前臺定位授權(quán)
        {
            NSLog(@"獲得前臺定位授權(quán)");
            [self.locationM startUpdatingLocation];
            break;
        }
        default:break;
    }
}
//在對應(yīng)的代理方法中獲取位置信息
- (void)locationManager:(CLLocationManager *)manager 
     didUpdateLocations:(NSArray<CLLocation*> *)locations
{
    CLLocation *location = [locations firstObject];//取出第一個位置
    /* 
        使用位置前, 務(wù)必判斷當(dāng)前獲取的位置是否有效
        如果水平精確度小于零, 代表雖然可以獲取位置對象, 但是數(shù)據(jù)錯誤, 不可用
     */
    if (location.horizontalAccuracy < 0)
        return;
    CLLocationCoordinate2D coordinate = location.coordinate;//位置坐標(biāo)
    CGFloat longitude = coordinate.longitude;//經(jīng)度
    CGFloat latitude = coordinate.latitude;//緯度
    CGFloat altitude = location.altitude;//海拔
    CGFloat course = location.course;//方向
    CGFloat speed = location.speed;//速度
    NSLog(@"經(jīng)度:%f,緯度:%f",longitude,latitude);
    NSLog(@"海拔:%f,方向:%f,速度:%f",altitude,course,speed);
    //如果不需要實時定位氮昧,使用完即使關(guān)閉定位服務(wù)
    [self.locationM stopUpdatingLocation];
}
控制臺打印

四框杜、地理編碼

定位服務(wù)中還包含CLGeocoder類,用于處理地理編碼和逆地理編碼功能袖肥。

  • 地理編碼:根據(jù)給定的位置(通常是地名)確定地理坐標(biāo)(經(jīng)咪辱、緯度)。
    【位置 -> 地理坐標(biāo)】
  • 逆地理編碼:可以根據(jù)地理坐標(biāo)(經(jīng)椎组、緯度)確定位置信息(街道油狂、門牌等)。
    【地理坐標(biāo) -> 位置】
- (void)viewDidLoad {
    [super viewDidLoad];
    self.geocoder = [[CLGeocoder alloc] init];
    [self getCoordinateByAddress:@"北京"];
    [self getAddressByLatitude:39.54 longitude:116.28];
}

#pragma mark 根據(jù)地名確定地理坐標(biāo)
-(void)getCoordinateByAddress:(NSString *)address{
    //地理編碼
    [self.geocoder geocodeAddressString:address 
                      completionHandler:^(NSArray *placemarks, NSError *error) {
        //取得第一個地標(biāo),地標(biāo)中存儲了詳細(xì)的地址信息专筷,注意:一個地名可能搜索出多個地址
        CLPlacemark *placemark = [placemarks firstObject];
        CLLocation *location = placemark.location;//位置
        CLRegion *region = placemark.region;//區(qū)域
        NSDictionary *addressDic = placemark.addressDictionary;//詳細(xì)地址信息字典
        NSLog(@"位置:%@,區(qū)域:%@,詳細(xì)信息:%@",location,region,addressDic);
    }];
}
#pragma mark 根據(jù)坐標(biāo)取得地名
-(void)getAddressByLatitude:(CLLocationDegrees)latitude 
                  longitude:(CLLocationDegrees)longitude
{
    //反地理編碼
    CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude 
                                                      longitude:longitude];
    [self.geocoder reverseGeocodeLocation:location 
                        completionHandler:^(NSArray *placemarks, NSError *error) {
        CLPlacemark *placemark = [placemarks firstObject];
        NSLog(@"詳細(xì)信息:%@",placemark.addressDictionary);
    }];
}
地標(biāo)類CLPlacemark還包含以下信息:
NSString *name = placemark.name;//地名
NSString *thoroughfare = placemark.thoroughfare;//街道
NSString *subThoroughfare = placemark.subThoroughfare; //街道相關(guān)信息夹供,例如門牌等
NSString *locality = placemark.locality; // 城市
NSString *subLocality = placemark.subLocality; // 城市相關(guān)信息,例如標(biāo)志性建筑
NSString *administrativeArea = placemark.administrativeArea; // 州
NSString *subAdministrativeArea = placemark.subAdministrativeArea; //其他行政區(qū)域信息
NSString *postalCode = placemark.postalCode; //郵編
NSString *ISOcountryCode = placemark.ISOcountryCode; //國家編碼
NSString *country = placemark.country; //國家
NSString *inlandWater = placemark.inlandWater; //水源仁堪、湖泊
NSString *ocean = placemark.ocean; // 海洋
NSArray *areasOfInterest = placemark.areasOfInterest; //關(guān)聯(lián)的或利益相關(guān)的地標(biāo)
下一節(jié)我會寫地圖類MapKit的相關(guān)筆記,敬請期待吧填渠!有什么問題可以在下方評論區(qū)提出弦聂,O(∩_∩)O哈!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末氛什,一起剝皮案震驚了整個濱河市莺葫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌枪眉,老刑警劉巖捺檬,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異贸铜,居然都是意外死亡堡纬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進(jìn)店門蒿秦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烤镐,“玉大人,你說我怎么就攤上這事棍鳖∨谝叮” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵渡处,是天一觀的道長镜悉。 經(jīng)常有香客問我,道長医瘫,這世上最難降的妖魔是什么侣肄? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮醇份,結(jié)果婚禮上茫孔,老公的妹妹穿的比我還像新娘。我一直安慰自己被芳,他們只是感情好缰贝,可當(dāng)我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著畔濒,像睡著了一般剩晴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天赞弥,我揣著相機(jī)與錄音毅整,去河邊找鬼。 笑死绽左,一個胖子當(dāng)著我的面吹牛悼嫉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拼窥,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼戏蔑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鲁纠?” 一聲冷哼從身側(cè)響起总棵,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎改含,沒想到半個月后情龄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡捍壤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年骤视,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹃觉。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡尚胞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出帜慢,到底是詐尸還是另有隱情笼裳,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布粱玲,位于F島的核電站躬柬,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏抽减。R本人自食惡果不足惜允青,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望卵沉。 院中可真熱鬧颠锉,春花似錦、人聲如沸史汗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽停撞。三九已至瓷蛙,卻和暖如春悼瓮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背艰猬。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工横堡, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人冠桃。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓命贴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親食听。 傳聞我的和親對象是個殘疾皇子胸蛛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內(nèi)容

  • http://www.cnblogs.com/kenshincui/p/4125570.html 摘要: 現(xiàn)在很多...
    大崔老師閱讀 3,300評論 1 2
  • 出自http://my.oschina.net/are1OfBlog/blog/420034 摘要 現(xiàn)在很多社交、...
    JJO閱讀 4,142評論 4 19
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫碳蛋、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,121評論 4 61
  • 感恩這幾日的天氣省咨,雖然已進(jìn)入深秋肃弟,但是氣溫卻異常的溫暖,讓人感覺非常舒適零蓉。 感恩門口賣手工水餃的老板笤受,我說自己帶回...
    武丹yoyo閱讀 261評論 0 1
  • 寫在前面 在iOS開發(fā)中,NSError的使用非常常見敌蜂,使用也比較簡單箩兽,也正因為簡單,所以對這一部分知識不甚注重章喉。...
    sadjason閱讀 10,615評論 1 12