Objective-C的CLLocation學(xué)習(xí)筆記

CLLocation - 位置對(duì)象

CLLocation對(duì)象包含設(shè)備的地理位置和高度,以及指示這些測(cè)量精度和收集時(shí)間的值历涝。在iOS操作系統(tǒng)中,位置對(duì)象還包含航向信息,即設(shè)備移動(dòng)的速度和航向烛缔。

通常不需要自己創(chuàng)建CLLocation對(duì)象馏段。從CLLocationManager對(duì)象請(qǐng)求位置更新后,系統(tǒng)使用板載傳感器收集位置數(shù)據(jù)践瓷,并將數(shù)據(jù)報(bào)告給應(yīng)用程序院喜。一些服務(wù)還會(huì)返回之前收集的位置數(shù)據(jù),可以將這些數(shù)據(jù)作為上下文來改進(jìn)服務(wù)晕翠。始終可以從CLLocationManager對(duì)象的UIApplicationLaunchOptionsLocationKey屬性中檢索最近收集的位置喷舀。如果要緩存自定義位置數(shù)據(jù)或計(jì)算兩個(gè)地理坐標(biāo)之間的距離,可以自己創(chuàng)建location對(duì)象淋肾。需要按原樣使用CLLocation對(duì)象硫麻,不要子類化它們

常用類型定義
typedef double CLLocationDegrees;

類型定義用于表示W(wǎng)GS 84參考坐標(biāo)系下緯度或經(jīng)度坐標(biāo)(以度為單位)的類型樊卓。單位度數(shù)可以是正(北和東)或負(fù)(南和西)拿愧。

例如 :

CLLocationDegrees latitude = 45.148327;
CLLocationDegrees longitude = 124.818265;
typedef double CLLocationAccuracy;

類型定義用于表示以米為單位的位置精度級(jí)別的類型。單位為米的值越低碌尔,位置的物理精度就越高浇辜。負(fù)精度值表示位置無效。

typedef double CLLocationSpeed;

類型定義設(shè)備移動(dòng)的速度(以米每秒為單位的類型)唾戚。

typedef double CLLocationDirection;

類型定義相對(duì)于正北以度數(shù)測(cè)量的方位角奢赂。方向值從正北開始以度為單位測(cè)量,并圍繞指南針順時(shí)針繼續(xù)颈走。因此膳灶,北是0度,東是90度立由,南是180度轧钓,以此類推。負(fù)值表示方向無效锐膜。

struct CLLocationCoordinate2D {
    CLLocationDegrees latitude;
    CLLocationDegrees longitude;
};
typedef struct CLLocationCoordinate2D CLLocationCoordinate2D;

結(jié)構(gòu)體描述使用WGS 84參考坐標(biāo)系指定的與位置相關(guān)聯(lián)的緯度和經(jīng)度毕箍。

CL_EXTERN
CLLocationCoordinate2D CLLocationCoordinate2DMake(CLLocationDegrees latitude, CLLocationDegrees longitude) API_AVAILABLE(ios(4.0), macos(10.7));

函數(shù)描述將緯度和經(jīng)度值格式化為坐標(biāo)數(shù)據(jù)結(jié)構(gòu)格式

參數(shù) :

latitude : 新坐標(biāo)的緯度道盏。

longitude : 新坐標(biāo)的經(jīng)度而柑。

返回值 : 包含緯度和經(jīng)度值的坐標(biāo)結(jié)構(gòu)。

例如:

CLLocationDegrees latitude = 45.148327;
CLLocationDegrees longitude = 124.818265;
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);

CLLocationManager - 位置管理器

CLLocationManager荷逞,用于啟動(dòng)和停止向應(yīng)用程序傳遞位置相關(guān)事件的對(duì)象≈衷叮可以使用該類的實(shí)例來配置涩澡、啟動(dòng)和停止Core Location(核心位置)服務(wù)。位置管理器對(duì)象支持以下與位置相關(guān)的活動(dòng):

  • 以可配置的精確度跟蹤用戶當(dāng)前位置的大小變化坠敷。
  • 報(bào)告來自船上羅盤的航向變化妙同。(iOS)
  • 監(jiān)視感興趣的不同區(qū)域射富,并在用戶進(jìn)入或離開這些區(qū)域時(shí)生成位置事件。
  • 當(dāng)應(yīng)用程序在后臺(tái)時(shí)粥帚,延遲位置更新的交付胰耗。(iOS)
  • 向附近的信標(biāo)報(bào)告范圍。

準(zhǔn)備使用定位服務(wù)時(shí)芒涡,請(qǐng)執(zhí)行以下步驟

  • 1.查看應(yīng)用程序是否被授權(quán)使用位置服務(wù)柴灯,如果您的應(yīng)用程序的授權(quán)狀態(tài)尚未確定,則請(qǐng)求權(quán)限拖陆。
  • 2.檢查是否有適當(dāng)?shù)奈恢梅?wù)可供使用弛槐。
  • 3.創(chuàng)建一個(gè)CLLocationManager類的實(shí)例懊亡,并在應(yīng)用程序的某個(gè)地方存儲(chǔ)對(duì)它的強(qiáng)引用依啰。在所有涉及到該對(duì)象的任務(wù)完成之前,需要保持對(duì)CLLocationManager對(duì)象的強(qiáng)引用店枣。由于大多數(shù)位置管理器任務(wù)是異步運(yùn)行的速警,因此將位置管理器存儲(chǔ)在局部變量中是不夠的。
  • 4.將自定義對(duì)象指定給代理屬性鸯两。此對(duì)象必須符合CLLocationManagerDelegate協(xié)議闷旧。
  • 5.配置與要使用的服務(wù)相關(guān)的屬性。例如钧唐,在獲取位置更新時(shí)忙灼,始終配置distanceFilter和desiredAccuracy屬性。
  • 6.調(diào)用適當(dāng)?shù)姆椒▉韱?dòng)事件的交付钝侠。

對(duì)于使用的服務(wù)该园,請(qǐng)準(zhǔn)確配置與該服務(wù)關(guān)聯(lián)的任何屬性。Core Location(核心位置)通過在不需要時(shí)關(guān)閉硬件來積極地管理電源帅韧。例如里初,將位置事件所需的精度設(shè)置為1公里,可使位置管理器靈活地關(guān)閉GPS硬件忽舟,并僅依賴WiFi或蜂窩無線電双妨,這可顯著節(jié)省電力。

所有與位置和標(biāo)題相關(guān)的更新都將傳遞到關(guān)聯(lián)的代理對(duì)象叮阅,該對(duì)象是您提供的自定義對(duì)象刁品。

CLLocationManager常用屬性
@property(assign, nonatomic) CLLocationDegrees headingFilter API_AVAILABLE(ios(3.0)) API_UNAVAILABLE(watchos, tvos, macOS);

屬性描述生成新航向事件所需的最小角度變化(以度為單位)。角度距離是相對(duì)于上次交付的航向事件測(cè)量的浩姥。使用值kCLHeadingFilterNone通知所有移動(dòng)哑诊。此屬性的默認(rèn)值為1度。

@property(assign, nonatomic) CLLocationDistance distanceFilter;

屬性描述在生成更新事件之前及刻,設(shè)備必須水平移動(dòng)的最小距離(以米為單位)镀裤。此距離是相對(duì)于先前交付的位置測(cè)量的竞阐。使用值kCLDistanceFilterNone通知所有移動(dòng)。此屬性的默認(rèn)值為kCLDistanceFilterNone暑劝。此屬性僅與標(biāo)準(zhǔn)位置服務(wù)一起使用骆莹,在監(jiān)視重要位置更改時(shí)不使用。

@property (readonly, nonatomic) CLLocationDistance maximumRegionMonitoringDistance API_AVAILABLE(ios(4.0), macos(10.8)) API_UNAVAILABLE(watchos, tvOS);

屬性描述可以指定給區(qū)域的最大邊界距離担猛。此屬性定義從區(qū)域中心點(diǎn)允許的最大邊界距離幕垦。嘗試監(jiān)視距離大于此值的區(qū)域?qū)?dǎo)致位置管理器向委托發(fā)送kclerRorrorRegionMonitoringFailure錯(cuò)誤。如果區(qū)域監(jiān)視不可用或不受支持傅联,則此屬性中的值為-1先改。

@property (readonly, nonatomic, copy) NSSet<__kindof CLRegion *> *monitoredRegions API_AVAILABLE(ios(4.0), macos(10.8)) API_UNAVAILABLE(watchos, tvOS);

屬性描述由所有位置管理器對(duì)象(CLLocationManager對(duì)象)監(jiān)視的共享區(qū)域集。不能直接將區(qū)域添加到此屬性蒸走。相反仇奶,必須通過調(diào)用startMonitoringForRegion:方法來注冊(cè)區(qū)域。此屬性中的區(qū)域由應(yīng)用程序中CLLocationManager類的所有實(shí)例共享比驻。

此集合中的對(duì)象不一定與注冊(cè)時(shí)指定的對(duì)象相同该溯。系統(tǒng)只維護(hù)區(qū)域數(shù)據(jù)本身。因此别惦,唯一標(biāo)識(shí)已注冊(cè)區(qū)域的方法是使用其標(biāo)識(shí)符屬性狈茉。

位置管理器在應(yīng)用程序啟動(dòng)之間保存區(qū)域數(shù)據(jù)。如果應(yīng)用程序被終止然后重新啟動(dòng)掸掸,則此屬性的內(nèi)容將重新填充包含先前注冊(cè)數(shù)據(jù)的區(qū)域?qū)ο蟆?/p>

CLLocationManager常用函數(shù)
+ (BOOL)locationServicesEnabled API_AVAILABLE(ios(4.0), macos(10.7));

函數(shù)描述返回一個(gè)布爾值氯庆,指示整個(gè)設(shè)備上是否啟用了位置服務(wù)。在開始位置更新之前扰付,可以檢查此方法的返回值堤撵,以確定設(shè)備是否啟用了位置服務(wù)。如果在禁用位置服務(wù)時(shí)嘗試啟動(dòng)位置更新悯周,則位置管理器將向其代理報(bào)告錯(cuò)誤粒督。用戶通常可以通過切換位置服務(wù)開關(guān)從設(shè)置應(yīng)用程序啟用或禁用位置服務(wù)禽翼。

返回值 : 如果已啟用位置服務(wù)屠橄,則為“YES”;如果未啟用位置服務(wù)闰挡,則為“NO”锐墙。

反應(yīng)了這里的設(shè)置:

截屏2021-07-16上午11.51.58.png
+ (CLAuthorizationStatus)authorizationStatus API_AVAILABLE(ios(4.2), macos(10.7));

函數(shù)描述返回應(yīng)用程序使用位置服務(wù)的授權(quán)狀態(tài)。給定應(yīng)用程序的授權(quán)狀態(tài)由系統(tǒng)管理长酗,并由多個(gè)因素決定溪北。應(yīng)用程序必須由用戶明確授權(quán)使用定位服務(wù),并且定位服務(wù)本身當(dāng)前必須為系統(tǒng)啟用。當(dāng)應(yīng)用程序首次嘗試使用定位服務(wù)時(shí)之拨,將自動(dòng)顯示用戶授權(quán)請(qǐng)求茉继。

返回值 : 指示應(yīng)用程序是否被授權(quán)使用位置服務(wù)的值。

CLAuthorizationStatus提供的枚舉值:

typedef NS_ENUM(int, CLAuthorizationStatus) {
    //用戶尚未選擇應(yīng)用程序是否可以使用位置服務(wù)蚀乔。
       //當(dāng)未確定授權(quán)狀態(tài)時(shí)如果應(yīng)用程序位于前臺(tái)烁竭,請(qǐng)求授權(quán)將導(dǎo)致位置管理器提示用戶獲得權(quán)限。
    kCLAuthorizationStatusNotDetermined = 0,

    //由于某些原因(如家長控制)對(duì)位置服務(wù)的有效限制吉挣,此應(yīng)用程序無權(quán)使用位置服務(wù)派撕。
    //用戶無法更改此狀態(tài)
    kCLAuthorizationStatusRestricted,

    //拒絕對(duì)此應(yīng)用程序的位置授權(quán)
    //用戶已明確拒絕對(duì)此應(yīng)用程序的位置授權(quán),或者在設(shè)置中全局禁用了位置服務(wù)睬魂,或者位置服務(wù)不可用(如飛行模式)疲扎。
    kCLAuthorizationStatusDenied,

    //用戶授權(quán)應(yīng)用程序隨時(shí)啟動(dòng)定位服務(wù)的權(quán)限杠氢。
    //該授權(quán)允許使用所有位置服務(wù)希痴,并接收位置事件躏敢,無應(yīng)用程序是否正在使用。
    //應(yīng)用程序可能會(huì)通過諸如訪問監(jiān)控蛙粘、區(qū)域監(jiān)控和重大位置變化監(jiān)控等監(jiān)控api被在后臺(tái)啟動(dòng)垫卤。
    kCLAuthorizationStatusAuthorizedAlways API_AVAILABLE(macos(10.12), ios(8.0)),

    //用戶已授權(quán)僅在使用應(yīng)用程序時(shí)有訪問位置的權(quán)限
    //此授權(quán)允許僅在應(yīng)用程序正在使用時(shí)使用所有位置服務(wù)和接收位置事件威彰。
    //若要繼續(xù)在后臺(tái)使用位置服務(wù)出牧,需要啟用連續(xù)后臺(tái)位置更新
    //通過allowsBackgroundLocationUpdates可以啟用連續(xù)后臺(tái)位置更新
    kCLAuthorizationStatusAuthorizedWhenInUse API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(macOS),

    //MacOS使用,iOS歇盼、tvOS和watchOS上不推薦或禁止使用此值舔痕。用戶已授權(quán)此應(yīng)用程序使用位置服務(wù)。
    kCLAuthorizationStatusAuthorized API_DEPRECATED("Use kCLAuthorizationStatusAuthorizedAlways", ios(2.0, 8.0)) API_AVAILABLE(macos(10.6)) API_UNAVAILABLE(watchos, tvos) = kCLAuthorizationStatusAuthorizedAlways
};

反應(yīng)了這里的設(shè)置:

截屏2021-07-16上午11.59.42.png
- (void)requestWhenInUseAuthorization API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(macOS);

函數(shù)描述請(qǐng)求在應(yīng)用程序位于前臺(tái)時(shí)使用定位服務(wù)的權(quán)限豹缀。當(dāng)前授權(quán)狀態(tài)為kCLAuthorizationStatusNotDetermined時(shí)伯复,此方法將異步運(yùn)行,并提示用戶授予應(yīng)用程序使用位置服務(wù)的權(quán)限邢笙。用戶提示包含應(yīng)用程序Info.plist文件中NSLocationWhenInUseUsageDescription密鑰的文本啸如,調(diào)用此方法時(shí)需要該密鑰的存在。確定狀態(tài)后氮惯,位置管理器將結(jié)果傳遞給代理的locationManager:didChangeAuthorizationStatus:方法叮雳。如果當(dāng)前授權(quán)狀態(tài)不是kCLAuthorizationStatusNotDetermined,則此方法不執(zhí)行任何操作妇汗,也不調(diào)用locationManager:didChangeAuthorizationStatus:方法帘不。

在使用定位服務(wù)之前,必須調(diào)用此方法或requestAlwaysAuthorization方法杨箭。如果用戶授予應(yīng)用“使用時(shí)”授權(quán)寞焙,你的應(yīng)用可以在前臺(tái)啟動(dòng)大部分(但不是全部)位置服務(wù)(應(yīng)用程序無法自動(dòng)啟動(dòng)例如區(qū)域監(jiān)視或重要位置更改服務(wù)的應(yīng)用程序的服務(wù))。在前臺(tái)啟動(dòng)時(shí),如果應(yīng)用程序已在Xcode項(xiàng)目的“ Capabilities”選項(xiàng)卡中啟用后臺(tái)位置更新捣郊,則服務(wù)將繼續(xù)在后臺(tái)運(yùn)行辽狈。在后臺(tái)運(yùn)行應(yīng)用程序時(shí)嘗試啟動(dòng)定位服務(wù)將失敗。當(dāng)應(yīng)用程序移動(dòng)到具有活動(dòng)位置服務(wù)的后臺(tái)時(shí)呛牲,系統(tǒng)會(huì)在狀態(tài)欄中顯示位置服務(wù)指示器稻艰。

注 :如不設(shè)置 Info.plist文件,控制器會(huì)打印提醒:

This app has attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain both “NSLocationAlwaysAndWhenInUseUsageDescription” and “NSLocationWhenInUseUsageDescription” keys with string values explaining to the user how the app uses this data(此應(yīng)用試圖訪問隱私敏感數(shù)據(jù)侈净,但沒有使用說明尊勿。應(yīng)用程序的Info.plist必須同時(shí)包含“ NSLocationAlwaysAndWhenInUseUsageDescription”和“ NSLocationWhenInUseUsageDescription”鍵,這些鍵的字符串值向用戶解釋應(yīng)用程序如何使用此數(shù)據(jù))

- (void)startUpdatingLocation API_AVAILABLE(watchos(3.0)) API_UNAVAILABLE(tvOS);

函數(shù)描述開始生成報(bào)告用戶當(dāng)前位置的更新畜侦。此方法立即返回元扔。調(diào)用此方法將導(dǎo)致位置管理器獲得初始位置修復(fù)(可能需要幾秒鐘),并通過調(diào)用其locationManager:didUpdateLocations:方法來通知代理旋膳。之后澎语,調(diào)用方主要在超過distanceFilter屬性中的值時(shí)生成更新事件。不過验懊,在其他情況下也可能會(huì)提供更新擅羞,例如硬件收集到更準(zhǔn)確的位置讀數(shù),則調(diào)用方可以發(fā)送另一個(gè)通知义图。

連續(xù)多次調(diào)用此方法不會(huì)自動(dòng)生成新事件减俏。但在中間調(diào)用stopUpdateLocation會(huì)導(dǎo)致下次調(diào)用此方法時(shí)發(fā)送新的初始事件

如果啟動(dòng)此服務(wù)并且應(yīng)用程序掛起碱工,則系統(tǒng)將停止傳遞事件娃承,直到應(yīng)用程序重新開始運(yùn)行(在前臺(tái)或后臺(tái))。如果應(yīng)用程序已終止怕篷,則新位置事件的傳遞將完全停止历筝。因此,如果應(yīng)用需要在后臺(tái)接收位置事件廊谓,它必須在Info.plist文件中包含UIBackgroundModes鍵(帶有位置值)梳猪。

除了實(shí)現(xiàn)locationManager:didUpdateLocations:方法的委托對(duì)象外,還應(yīng)該實(shí)現(xiàn)locationManager:didFailWithError:方法以響應(yīng)潛在的錯(cuò)誤蒸痹。

- (void)stopUpdatingLocation;

函數(shù)描述停止生成位置更新春弥。只要代碼不再需要接收與位置相關(guān)的事件,就調(diào)用此方法电抚。禁用事件傳遞使接收器可以在沒有客戶端需要位置數(shù)據(jù)時(shí)禁用適當(dāng)?shù)挠布?從而節(jié)省電源)惕稻。始終可以通過再次調(diào)用startUpdatingLocation方法重新啟動(dòng)位置更新的生成。

+ (BOOL)headingAvailable API_AVAILABLE(ios(4.0), macos(10.7)) API_UNAVAILABLE(watchos, tvOS);

函數(shù)描述返回一個(gè)布爾值蝙叛,指示位置管理器是否能夠生成與導(dǎo)航方向相關(guān)的事件俺祠。在要求位置管理器傳遞與導(dǎo)航方向相關(guān)的事件之前,應(yīng)檢查此方法返回的值。

返回值 : 如果航向數(shù)據(jù)可用蜘渣,則為“YES”淌铐;如果不可用,則為“NO”蔫缸。

- (void)startUpdatingHeading API_AVAILABLE(ios(3.0)) API_UNAVAILABLE(watchos, tvos, macOS);

函數(shù)描述開始生成報(bào)告用戶當(dāng)前導(dǎo)航方向的更新腿准。此方法立即返回。當(dāng)調(diào)用方已經(jīng)停止導(dǎo)航方向的更新時(shí)拾碌,調(diào)用此方法將導(dǎo)致它獲取初始航向并通知代理吐葱。此外,當(dāng)超過headingFilter屬性中的值時(shí)校翔,調(diào)用方生成更新事件弟跑。

在調(diào)用此方法之前,應(yīng)始終檢查headingAvailable屬性防症,以查看當(dāng)前設(shè)備上是否支持導(dǎo)航方向信息孟辑。如果不支持導(dǎo)航方向信息,則調(diào)用此方法無效蔫敲,并且不會(huì)將事件傳遞給代理饲嗽。

連續(xù)多次調(diào)用此方法不會(huì)自動(dòng)生成新事件。但在中間調(diào)用stopUpdatengHeading會(huì)導(dǎo)致下次調(diào)用此方法時(shí)發(fā)送新的初始事件奈嘿。

如果啟動(dòng)此服務(wù)并且應(yīng)用程序掛起貌虾,則系統(tǒng)將停止傳遞事件,直到應(yīng)用程序重新開始運(yùn)行(在前臺(tái)或后臺(tái))指么。如果應(yīng)用程序已終止酝惧,則新航向事件的傳遞將完全停止榴鼎,并且必須在應(yīng)用程序重新啟動(dòng)時(shí)由代碼重新啟動(dòng)伯诬。

航向事件將傳遞到委托的locationManager:didUpdateHeading:方法。如果出現(xiàn)錯(cuò)誤巫财,位置管理器將改為調(diào)用委托的locationManager:didFailWithError:方法盗似。

- (void)stopUpdatingHeading API_AVAILABLE(ios(3.0)) API_UNAVAILABLE(watchos, tvos, macOS);

函數(shù)描述停止生成航向更新。只要代碼不再需要接收與航向相關(guān)的事件平项,就調(diào)用此方法赫舒。禁用事件傳遞使接收器可以在沒有客戶端需要位置數(shù)據(jù)時(shí)禁用適當(dāng)?shù)挠布?從而節(jié)省電源)。始終可以通過再次調(diào)用startUpdatingHeading方法來重新啟動(dòng)航向更新的生成闽瓢。

+ (BOOL)isMonitoringAvailableForClass:(Class)regionClass API_AVAILABLE(ios(7.0), macos(10.10)) API_UNAVAILABLE(watchos, tvOS);

函數(shù)描述返回一個(gè)布爾值接癌,指示設(shè)備是否支持使用指定類進(jìn)行區(qū)域監(jiān)聽。區(qū)域監(jiān)視支持的可用性取決于設(shè)備上存在的硬件扣讼。此方法不考慮位置服務(wù)的可用性或用戶可能已為應(yīng)用程序或系統(tǒng)禁用這些服務(wù)的事實(shí)缺猛,必須單獨(dú)確定應(yīng)用程序的授權(quán)狀態(tài)。

參數(shù) :

regionClass : MapKit框架中的區(qū)域監(jiān)視類。這個(gè)類必須從CLRegion類派生荔燎。

返回值 : 如果設(shè)備能夠使用指定的類監(jiān)視區(qū)域耻姥,則為“YES”;否則為“NO”有咨。

- (void)requestStateForRegion:(CLRegion *)region API_AVAILABLE(ios(7.0), macos(10.10)) API_UNAVAILABLE(watchos, tvOS);

函數(shù)描述異步檢索區(qū)域的狀態(tài)琐簇。 此方法異步執(zhí)行請(qǐng)求,并將結(jié)果傳遞給位置管理器的代理座享。必須在代理中實(shí)現(xiàn)locationManager:dideterminestate:forRegion:方法才能接收結(jié)果婉商。如果region參數(shù)包含未知類型的region對(duì)象,則此方法不執(zhí)行任何操作渣叛。

參數(shù) :

region : 想知道的地區(qū)据某。此對(duì)象必須是MapKit提供的標(biāo)準(zhǔn)區(qū)域子類之一的實(shí)例。不能使用此方法來確定自己定義的自定義區(qū)域的狀態(tài)诗箍。

- (void)startMonitoringForRegion:(CLRegion *)region API_AVAILABLE(ios(5.0), macos(10.8)) API_UNAVAILABLE(watchos, tvOS);

函數(shù)描述開始監(jiān)視指定區(qū)域癣籽。對(duì)于要監(jiān)視的每個(gè)區(qū)域,必須調(diào)用此方法一次滤祖。如果應(yīng)用程序已監(jiān)視具有相同標(biāo)識(shí)符的現(xiàn)有區(qū)域筷狼,則舊區(qū)域?qū)⑻鎿Q為新區(qū)域。使用此方法添加的區(qū)域由應(yīng)用程序中的所有CLLocationManager對(duì)象共享匠童,并存儲(chǔ)在monitoredRegions屬性中埂材。

區(qū)域事件將傳遞到代理的locationManager:didEnterRegion: 和locationManager:didExitRegion: 方法。如果出現(xiàn)錯(cuò)誤汤求,位置管理器將改為調(diào)用代理的locationManager:monitoringDidFailForRegion:withError: 方法俏险。一個(gè)應(yīng)用程序一次最多可以注冊(cè)20個(gè)區(qū)域。為了及時(shí)報(bào)告區(qū)域變化扬绪,區(qū)域監(jiān)視服務(wù)需要網(wǎng)絡(luò)連接竖独。

參數(shù) :

region : 定義要監(jiān)視的邊界的區(qū)域?qū)ο蟆4藚?shù)不能為nil挤牛。

- (void)stopMonitoringForRegion:(CLRegion *)region API_AVAILABLE(ios(4.0), macos(10.8)) API_UNAVAILABLE(watchos, tvOS);

函數(shù)描述停止監(jiān)視指定區(qū)域莹痢。如果指定的區(qū)域?qū)ο螽?dāng)前未被監(jiān)視,則此方法無效墓赴。

參數(shù) :

region : 當(dāng)前正在監(jiān)視的區(qū)域?qū)ο缶荷拧4藚?shù)不能為nil。

CLLocationManager代理函數(shù)

- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray<CLLocation *> *)locations API_AVAILABLE(ios(6.0), macos(10.9));

函數(shù)描述通知代理新的位置數(shù)據(jù)可用诫硕。此方法的實(shí)現(xiàn)是可選的坦辟,但建議使用。

參數(shù) :

manager : 生成更新事件的位置管理器對(duì)象章办。

locations : 包含位置數(shù)據(jù)的CLLocation對(duì)象數(shù)組锉走。該數(shù)組始終包含至少一個(gè)表示當(dāng)前位置的對(duì)象滔吠。如果更新被延遲,或者多個(gè)位置在更新之前到達(dá)挠日,則數(shù)組可能包含其他條目疮绷。數(shù)組中的對(duì)象按照它們發(fā)生的順序組織。因此嚣潜,最近的位置更新位于數(shù)組的末尾冬骚。

- (void)locationManager:(CLLocationManager *)manager
       didUpdateHeading:(CLHeading *)newHeading API_AVAILABLE(ios(3.0)) API_UNAVAILABLE(watchos, tvos, macOS);

函數(shù)描述通知代理位置管理器接收到更新的航向信息。此方法的實(shí)現(xiàn)是可選的懂算,但如果使用startUpdatingHeading方法開始標(biāo)題更新只冻,則此實(shí)現(xiàn)是預(yù)期的。locationManager對(duì)象在您最初啟動(dòng)航向服務(wù)之后調(diào)用這個(gè)方法计技。當(dāng)先前報(bào)告的值更改超過CLLocationManager對(duì)象的headingFilter屬性中指定的值時(shí)喜德,將傳遞后續(xù)事件。

參數(shù) :

manager : 生成更新事件的位置管理器對(duì)象垮媒。

newHeading : 新的航向數(shù)據(jù)舍悯。

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status API_AVAILABLE(ios(4.2), macos(10.7));

函數(shù)描述在應(yīng)用程序創(chuàng)建位置管理器時(shí)以及授權(quán)狀態(tài)更改時(shí)通知代理其授權(quán)狀態(tài)。當(dāng)應(yīng)用程序創(chuàng)建相關(guān)對(duì)象的CLLocationManager實(shí)例時(shí)睡雇,以及當(dāng)應(yīng)用程序的授權(quán)狀態(tài)更改時(shí)萌衬,系統(tǒng)調(diào)用此方法。狀態(tài)將通知應(yīng)用程序是否可以訪問用戶的位置它抱。

使用此代理方法來管理應(yīng)用程序的狀態(tài)更改秕豫,以響應(yīng)其使用位置信息的能力。例如根據(jù)需要啟用或禁用應(yīng)用程序的位置相關(guān)功能观蓄。

Core Location(核心位置)保證會(huì)調(diào)用locationManager:didChangeAuthorizationStatus:方法混移,當(dāng)用戶的操作導(dǎo)致授權(quán)狀態(tài)改變時(shí),以及當(dāng)你的應(yīng)用程序創(chuàng)建一個(gè)CLLocationManager實(shí)例時(shí)侮穿,無論你的應(yīng)用程序是在前臺(tái)還是后臺(tái)運(yùn)行歌径。

如果在調(diào)用requestWhenInUseAuthorization或requestAlwaysAuthorization方法之后,用戶的選擇沒有更改授權(quán)狀態(tài)撮珠,則位置管理器不會(huì)向該方法報(bào)告當(dāng)前的授權(quán)狀態(tài)沮脖,位置管理器只報(bào)告更改。例如芯急,當(dāng)狀態(tài)從kCLAuthorizationStatusNotDetermined更改為kCLAuthorizationStatusAuthorizedWhenInUse時(shí),位置管理器調(diào)用此方法驶俊。

參數(shù) :

manager : 報(bào)告事件的位置管理器對(duì)象娶耍。

status : 應(yīng)用程序的授權(quán)狀態(tài)。

- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager  API_AVAILABLE(ios(3.0)) API_UNAVAILABLE(watchos, tvos, macOS);

函數(shù)描述詢問代理是否應(yīng)顯示航向校準(zhǔn)警報(bào)饼酿。Core Location(核心位置)可調(diào)用此方法榕酒,以校準(zhǔn)用于確定航向值的機(jī)載硬件胚膊。通常,Core Location(核心位置)在以下時(shí)間調(diào)用此方法:

第一次請(qǐng)求航向更新想鹰,當(dāng)磁芯位置觀測(cè)到所觀測(cè)磁場的大小或傾角發(fā)生顯著變化時(shí)紊婉,如果您從該方法返回YES, Core Location(核心位置)將立即在當(dāng)前窗口的頂部顯示標(biāo)題校準(zhǔn)警告。校準(zhǔn)警報(bào)提示用戶以特定的模式移動(dòng)設(shè)備辑舷,以便核心位置能夠區(qū)分地球磁場和任何局部磁場喻犁。在完成校準(zhǔn)或通過調(diào)用dismissHeadingCalibrationDisplay方法顯式地取消警報(bào)之前,警報(bào)都是可見的何缓。在后一種情況下肢础,可以使用此方法設(shè)置計(jì)時(shí)器,并在指定時(shí)間量過后關(guān)閉接口碌廓。

校準(zhǔn)過程只能過濾掉隨設(shè)備移動(dòng)的磁場传轰。若要校準(zhǔn)靠近其他磁干擾源的設(shè)備,用戶必須將設(shè)備從磁干擾源處移開谷婆,或在校準(zhǔn)過程中將磁干擾源與設(shè)備一起移開慨蛙。

如果從此方法返回NO或在代理中沒有為其提供實(shí)現(xiàn),則核心位置不會(huì)顯示標(biāo)題校準(zhǔn)警告纪挎。即使沒有顯示警報(bào)股淡,當(dāng)任何干擾磁場遠(yuǎn)離設(shè)備時(shí),校準(zhǔn)仍然可以自然發(fā)生廷区。然而唯灵,如果設(shè)備由于任何原因無法校準(zhǔn)自身,任何后續(xù)事件的headingAccuracy屬性值將反映未校準(zhǔn)的讀數(shù)隙轻。

參數(shù) :

manager : 協(xié)調(diào)航向校準(zhǔn)警報(bào)顯示的位置管理器對(duì)象埠帕。

返回值 : 如果要允許顯示航向校準(zhǔn)警報(bào),則為“YES”玖绿;如果不允許敛瓷,則為“NO”。

航向校準(zhǔn)警報(bào)頁面大致長成這樣 :

IMG_1316.PNG
- (void)locationManager:(CLLocationManager *)manager
    didFailWithError:(NSError *)error;

函數(shù)描述通知代理位置管理器無法檢索位置值斑匪。位置管理器在嘗試獲取位置或標(biāo)題數(shù)據(jù)時(shí)遇到錯(cuò)誤時(shí)調(diào)用此方法呐籽。如果位置服務(wù)無法立即檢索位置,它將報(bào)告kclerRorrorLocationUnknown錯(cuò)誤并繼續(xù)嘗試蚀瘸。在這種情況下狡蝶,您可以忽略錯(cuò)誤并等待新事件。如果由于附近磁場的強(qiáng)烈干擾而無法確定航向贮勃,則此方法返回kCLErrorHeadingFailure贪惹。

如果用戶拒絕應(yīng)用程序使用位置服務(wù),則此方法將報(bào)告一個(gè)kCLErrorDenied錯(cuò)誤寂嘉。收到此類錯(cuò)誤后奏瞬,應(yīng)停止定位服務(wù)枫绅。

參數(shù) :

manager : 無法檢索位置的位置管理器對(duì)象。

error : 包含無法檢索位置或標(biāo)題的原因的錯(cuò)誤對(duì)象硼端。

- (void)locationManager:(CLLocationManager *)manager
    didEnterRegion:(CLRegion *)region API_AVAILABLE(ios(4.0), macos(10.8)) API_UNAVAILABLE(watchos, tvOS);

函數(shù)描述通知代理用戶已進(jìn)入指定區(qū)域并淋。因?yàn)閰^(qū)域是共享的應(yīng)用程序資源,所以每個(gè)活動(dòng)位置管理器對(duì)象都將此消息傳遞給其關(guān)聯(lián)的代理珍昨。哪個(gè)位置管理器實(shí)際注冊(cè)了指定的區(qū)域并不重要县耽。如果多個(gè)位置管理器共享一個(gè)代理對(duì)象,則該代理將多次接收消息曼尊。所提供的區(qū)域?qū)ο罂赡芘c已注冊(cè)的區(qū)域?qū)ο蟛煌昃鳌R虼耍肋h(yuǎn)不要執(zhí)行對(duì)象指針級(jí)別的比較來確定是否相等骆撇。相反瞒御,使用該區(qū)域的標(biāo)識(shí)符字符串來確定您的代理是否應(yīng)該響應(yīng)。

參數(shù) :

manager : 報(bào)告事件的位置管理器對(duì)象神郊。

region : 包含所輸入?yún)^(qū)域信息的對(duì)象肴裙。

- (void)locationManager:(CLLocationManager *)manager
    didExitRegion:(CLRegion *)region API_AVAILABLE(ios(4.0), macos(10.8)) API_UNAVAILABLE(watchos, tvOS);

函數(shù)描述通知代理用戶已離開指定區(qū)域。因?yàn)閰^(qū)域是共享的應(yīng)用程序資源涌乳,所以每個(gè)活動(dòng)位置管理器對(duì)象都將此消息傳遞給其關(guān)聯(lián)的代理蜻懦。哪個(gè)位置管理器實(shí)際注冊(cè)了指定的區(qū)域并不重要。如果多個(gè)位置管理器共享一個(gè)代理對(duì)象夕晓,則該代理將多次接收消息宛乃。所提供的區(qū)域?qū)ο罂赡芘c已注冊(cè)的區(qū)域?qū)ο蟛煌R虼苏袅荆肋h(yuǎn)不要執(zhí)行對(duì)象指針級(jí)別的比較來確定是否相等征炼。相反,使用該區(qū)域的標(biāo)識(shí)符字符串來確定您的代理是否應(yīng)該響應(yīng)躬贡。

參數(shù) :

manager : 報(bào)告事件的位置管理器對(duì)象谆奥。

region : 包含有關(guān)已離開區(qū)域的信息的對(duì)象。

- (void)locationManager:(CLLocationManager *)manager
    didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region API_AVAILABLE(ios(7.0), macos(10.10)) API_UNAVAILABLE(watchos, tvOS);

函數(shù)描述通知代理指定區(qū)域的狀態(tài)拂玻。每當(dāng)區(qū)域有邊界轉(zhuǎn)換時(shí)酸些,位置管理器都會(huì)調(diào)用此方法。除了調(diào)用locationManager:didEnterRegion:和locationManager:didextregion:方法之外檐蚜,它還調(diào)用此方法魄懂。位置管理器還調(diào)用此方法以響應(yīng)對(duì)其requestStateForRegion:方法的調(diào)用,該方法異步運(yùn)行熬甚。

參數(shù) :

manager : 報(bào)告事件的位置管理器對(duì)象逢渔。

state : 指定區(qū)域的狀態(tài)。

region : 國家確定的地區(qū)乡括。

- (void)locationManager:(CLLocationManager *)manager
    monitoringDidFailForRegion:(nullable CLRegion *)region
    withError:(NSError *)error API_AVAILABLE(ios(4.0), macos(10.8)) API_UNAVAILABLE(watchos, tvOS);

函數(shù)描述通知代理發(fā)生區(qū)域監(jiān)視錯(cuò)誤肃廓。如果嘗試監(jiān)視給定區(qū)域時(shí)出錯(cuò),位置管理器會(huì)將此消息發(fā)送給其代理诲泌。區(qū)域監(jiān)視可能會(huì)失敗盲赊,因?yàn)闊o法監(jiān)視該區(qū)域本身,或者是因?yàn)樵谂渲脜^(qū)域監(jiān)視服務(wù)時(shí)出現(xiàn)了更常見的故障敷扫。
盡管此方法的實(shí)現(xiàn)是可選的哀蘑,但如果在應(yīng)用程序中使用區(qū)域監(jiān)視,建議實(shí)現(xiàn)它葵第。

參數(shù) :

manager : 報(bào)告事件的位置管理器對(duì)象绘迁。

region : 發(fā)生錯(cuò)誤的區(qū)域。

error : 一個(gè)錯(cuò)誤對(duì)象卒密,包含指示區(qū)域監(jiān)視失敗原因的錯(cuò)誤代碼缀台。

- (void)locationManager:(CLLocationManager *)manager
    didStartMonitoringForRegion:(CLRegion *)region API_AVAILABLE(ios(5.0), macos(10.8)) API_UNAVAILABLE(watchos, tvOS);

函數(shù)描述通知代理正在監(jiān)視新區(qū)域

參數(shù) :

manager : 報(bào)告事件的位置管理器對(duì)象哮奇。

region : 正在監(jiān)視的區(qū)域膛腐。

- (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager API_AVAILABLE(ios(6.0)) API_UNAVAILABLE(watchos, tvos, macOS);

函數(shù)描述通知代理位置更新已暫停。當(dāng)位置管理器檢測(cè)到設(shè)備的位置沒有改變時(shí)鼎俘,它可以暫停更新的傳遞哲身,以便關(guān)閉相應(yīng)的硬件并節(jié)省電源。當(dāng)它這樣做時(shí)贸伐,它會(huì)調(diào)用此方法以讓應(yīng)用程序知道發(fā)生了這種情況勘天。

暫停發(fā)生后,必須在適當(dāng)?shù)臅r(shí)間重新啟動(dòng)位置服務(wù)捉邢「浚可以使用此方法的實(shí)現(xiàn)在用戶的當(dāng)前位置啟動(dòng)區(qū)域監(jiān)視,或啟用“訪問位置”服務(wù)來確定用戶何時(shí)開始再次移動(dòng)歌逢。另一種選擇是立即以較低的精度重新啟動(dòng)定位服務(wù)(這可以節(jié)省能源)巾钉,然后只有在用戶再次開始移動(dòng)后才能恢復(fù)較高的精度。

參數(shù) :

manager : 暫停事件傳遞的位置管理器對(duì)象秘案。

- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager API_AVAILABLE(ios(6.0)) API_UNAVAILABLE(watchos, tvos, macOS);

函數(shù)描述通知代理位置更新的傳遞已恢復(fù)砰苍。當(dāng)在自動(dòng)暫停后重啟定位服務(wù)時(shí)哈雏,Core location會(huì)調(diào)用這個(gè)方法來通知你的應(yīng)用服務(wù)已經(jīng)恢復(fù)第焰。Core location不會(huì)在暫停更新后自動(dòng)恢復(fù)更新论矾,程序要負(fù)責(zé)重新啟動(dòng)你的應(yīng)用程序中的定位服務(wù)献酗。

參數(shù) :

manager : 恢復(fù)事件傳遞的位置管理器笔咽。

- (void)locationManager:(CLLocationManager *)manager
    didFinishDeferredUpdatesWithError:(nullable NSError *)error API_AVAILABLE(ios(6.0), macos(10.9)) API_UNAVAILABLE(watchos, tvOS);

函數(shù)描述通知代理不再延遲更新长已。CLLocationManager對(duì)象調(diào)用此方法以讓應(yīng)用程序知道它已停止延遲位置事件的傳遞郎嫁。管理器可能出于多種原因調(diào)用此方法堕花。例如未舟,當(dāng)您完全停止位置更新圈暗、要求位置管理器禁止延遲更新或滿足延遲更新的條件(例如超過超時(shí)或距離參數(shù))時(shí)掂为,它將調(diào)用此函數(shù)。

參數(shù) :

manager : 生成更新事件的位置管理器對(duì)象员串。

error : 包含無法傳遞延遲位置更新原因的錯(cuò)誤對(duì)象勇哗。

CLGeocoder - 地理編碼

用于在地理坐標(biāo)和地名之間轉(zhuǎn)換的接口。提供在坐標(biāo)(指定為經(jīng)緯度)和該坐標(biāo)的地名之間進(jìn)行轉(zhuǎn)換的服務(wù)寸齐。坐標(biāo)的地名表示通常由與給定位置相對(duì)應(yīng)的街道欲诺、城市、州和國家信息組成渺鹦,但也可以包含相關(guān)的興趣點(diǎn)扰法、地標(biāo)或其他識(shí)別信息。geocoder對(duì)象是一個(gè)單一對(duì)象毅厚,它與基于網(wǎng)絡(luò)的服務(wù)一起查找指定坐標(biāo)值的地標(biāo)信息塞颁。

若要使用地理編碼器對(duì)象,請(qǐng)創(chuàng)建該對(duì)象并調(diào)用其正向或反向地理編碼方法之一以開始請(qǐng)求卧斟。反向地理編碼請(qǐng)求采用緯度和經(jīng)度值殴边,查找到用戶可讀的地址。正向地理編碼請(qǐng)求采用用戶可讀的地址珍语,并找到相應(yīng)的緯度和經(jīng)度值锤岸。正向地理編碼請(qǐng)求還可以返回有關(guān)指定位置的附加信息,例如該位置的興趣點(diǎn)或建筑物板乙。對(duì)于這兩種類型的請(qǐng)求是偷,使用CLPlacemark對(duì)象返回結(jié)果。在正向地理編碼請(qǐng)求的情況下募逞,如果提供的信息產(chǎn)生多個(gè)可能的位置蛋铆,則可以返回多個(gè)placemark對(duì)象。為了明智地決定返回什么類型的信息放接,geocoder服務(wù)器在處理請(qǐng)求時(shí)使用提供給它的所有信息刺啦。例如,如果用戶在高速公路上快速移動(dòng)纠脾,它可能返回整個(gè)區(qū)域的名稱玛瘸,而不是用戶經(jīng)過的小公園的名稱。

CLGeocoder常用函數(shù)
- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;

函數(shù)描述為指定的位置提交反向地理編碼請(qǐng)求苟蹈,此方法將指定的位置數(shù)據(jù)異步提交給地理編碼服務(wù)器并返回糊渊。當(dāng)請(qǐng)求完成時(shí),geocoder在主線程上執(zhí)行提供的完成處理程序慧脱。

啟動(dòng)反向地理編碼請(qǐng)求后渺绒,不要嘗試啟動(dòng)另一個(gè)反向或正向地理編碼請(qǐng)求。地理編碼請(qǐng)求對(duì)每個(gè)應(yīng)用程序都有速率限制,因此在短時(shí)間內(nèi)發(fā)出太多請(qǐng)求可能會(huì)導(dǎo)致某些請(qǐng)求失敗宗兼。當(dāng)超過最大速率時(shí)躏鱼,geocoder會(huì)將值為kCLErrorNetwork的錯(cuò)誤對(duì)象傳遞給完成處理程序。

參數(shù) :

location : 包含要查找的坐標(biāo)數(shù)據(jù)的位置對(duì)象针炉。

completionHandler : 要與結(jié)果一起執(zhí)行的處理程序塊挠他。無論請(qǐng)求是成功還是失敗扳抽,geocoder都會(huì)執(zhí)行此處理程序篡帕。

- (void)reverseGeocodeLocation:(CLLocation *)location preferredLocale:(nullable NSLocale *)locale completionHandler:(CLGeocodeCompletionHandler)completionHandler API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

函數(shù)描述提交指定位置和區(qū)域設(shè)置的反向地理編碼請(qǐng)求。此方法將指定的位置數(shù)據(jù)異步提交給地理編碼服務(wù)器并返回贸呢。當(dāng)請(qǐng)求完成時(shí)镰烧,geocoder在主線程上執(zhí)行提供的完成處理程序。

啟動(dòng)反向地理編碼請(qǐng)求后楞陷,不要嘗試啟動(dòng)另一個(gè)反向或正向地理編碼請(qǐng)求怔鳖。地理編碼請(qǐng)求對(duì)每個(gè)應(yīng)用程序都有速率限制,因此在短時(shí)間內(nèi)發(fā)出太多請(qǐng)求可能會(huì)導(dǎo)致某些請(qǐng)求失敗固蛾。當(dāng)超過最大速率時(shí)结执,geocoder會(huì)將帶有值network的錯(cuò)誤對(duì)象傳遞給完成處理程序。

參數(shù) :

location : 包含要查找的坐標(biāo)數(shù)據(jù)的位置對(duì)象艾凯。

locale : 返回地址信息時(shí)要使用的區(qū)域設(shè)置献幔。如果希望在不同于用戶當(dāng)前語言設(shè)置的區(qū)域設(shè)置中返回地址,可以為此參數(shù)指定一個(gè)值趾诗。指定nil以使用用戶的默認(rèn)區(qū)域設(shè)置信息蜡感。

completionHandler : 要與結(jié)果一起執(zhí)行的處理程序塊。無論請(qǐng)求是成功還是失敗恃泪,geocoder都會(huì)執(zhí)行此處理程序郑兴。

- (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;

函數(shù)描述使用指定的字符串提交正向地理編碼請(qǐng)求。此方法將指定的位置數(shù)據(jù)異步提交給地理編碼服務(wù)器并返回贝乎。完成處理程序塊將在主線程上執(zhí)行情连。

啟動(dòng)前向地理編碼請(qǐng)求后,不要嘗試啟動(dòng)另一個(gè)前向或反向地理編碼請(qǐng)求览效。地理編碼請(qǐng)求對(duì)每個(gè)應(yīng)用程序都有速率限制却舀,因此在短時(shí)間內(nèi)發(fā)出太多請(qǐng)求可能會(huì)導(dǎo)致某些請(qǐng)求失敗。當(dāng)超過最大速率時(shí)朽肥,geocoder會(huì)將值為kCLErrorNetwork的錯(cuò)誤對(duì)象傳遞給完成處理程序禁筏。

參數(shù) :

addressString : 描述要查找的位置的字符串。

completionHandler : 要與結(jié)果一起執(zhí)行的處理程序塊衡招。無論請(qǐng)求是成功還是失敗篱昔,geocoder都會(huì)執(zhí)行此處理程序。

- (void)geocodeAddressString:(NSString *)addressString inRegion:(nullable CLRegion *)region completionHandler:(CLGeocodeCompletionHandler)completionHandler;

函數(shù)描述使用指定的字符串和區(qū)域信息提交正向地理編碼請(qǐng)求。此方法將指定的位置數(shù)據(jù)異步提交給地理編碼服務(wù)器并返回州刽。完成處理程序塊將在主線程上執(zhí)行空执。

啟動(dòng)前向地理編碼請(qǐng)求后,不要嘗試啟動(dòng)另一個(gè)前向或反向地理編碼請(qǐng)求穗椅。地理編碼請(qǐng)求對(duì)每個(gè)應(yīng)用程序都有速率限制辨绊,因此在短時(shí)間內(nèi)發(fā)出太多請(qǐng)求可能會(huì)導(dǎo)致某些請(qǐng)求失敗。當(dāng)超過最大速率時(shí)匹表,geocoder會(huì)將值為kCLErrorNetwork的錯(cuò)誤對(duì)象傳遞給完成處理程序门坷。

參數(shù) :

addressString : 描述要查找的位置的字符串。

region : 查找指定地址時(shí)用作提示的地理區(qū)域袍镀。通過指定一個(gè)區(qū)域默蚌,可以將返回的結(jié)果集的優(yōu)先級(jí)設(shè)置為靠近某個(gè)特定地理區(qū)域(通常是用戶的當(dāng)前位置)的位置。如果應(yīng)用程序被授權(quán)提供位置服務(wù)苇羡,并且您為此參數(shù)指定了nil绸吸,則結(jié)果集將根據(jù)用戶的大致位置進(jìn)行優(yōu)先級(jí)排序。調(diào)用此方法不會(huì)觸發(fā)位置服務(wù)授權(quán)請(qǐng)求设江。

completionHandler : 要與結(jié)果一起執(zhí)行的處理程序塊锦茁。無論請(qǐng)求是成功還是失敗,geocoder都會(huì)執(zhí)行此處理程序叉存。

- (void)geocodeAddressString:(NSString *)addressString inRegion:(nullable CLRegion *)region preferredLocale:(nullable NSLocale *)locale completionHandler:(CLGeocodeCompletionHandler)completionHandler API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

函數(shù)描述使用指定的地址字符串和區(qū)域設(shè)置信息提交正向地理編碼請(qǐng)求码俩。此方法將指定的位置數(shù)據(jù)異步提交給地理編碼服務(wù)器并返回。當(dāng)請(qǐng)求完成時(shí)鹉胖,geocoder在主線程上執(zhí)行提供的完成處理程序握玛。

啟動(dòng)正向地理編碼請(qǐng)求后,不要嘗試啟動(dòng)另一個(gè)反向或正向地理編碼請(qǐng)求甫菠。地理編碼請(qǐng)求對(duì)每個(gè)應(yīng)用程序都有速率限制挠铲,因此在短時(shí)間內(nèi)發(fā)出太多請(qǐng)求可能會(huì)導(dǎo)致某些請(qǐng)求失敗。當(dāng)超過最大速率時(shí)寂诱,geocoder會(huì)將帶有值network的錯(cuò)誤對(duì)象傳遞給完成處理程序拂苹。

參數(shù) :

addressString : 描述要查找的位置的字符串。

region : 查找指定地址時(shí)用作提示的地理區(qū)域痰洒。通過指定一個(gè)區(qū)域瓢棒,可以將返回的結(jié)果集的優(yōu)先級(jí)設(shè)置為靠近某個(gè)特定地理區(qū)域(通常是用戶的當(dāng)前位置)的位置。如果應(yīng)用程序被授權(quán)提供位置服務(wù)丘喻,并且您為此參數(shù)指定了nil脯宿,則結(jié)果集將根據(jù)用戶的大致位置進(jìn)行優(yōu)先級(jí)排序。調(diào)用此方法不會(huì)觸發(fā)位置服務(wù)授權(quán)請(qǐng)求泉粉。

locale : 地址字符串的區(qū)域設(shè)置连霉。指定nil以使用用戶的當(dāng)前區(qū)域設(shè)置榴芳。

completionHandler : 要與結(jié)果一起執(zhí)行的處理程序塊。無論請(qǐng)求是成功還是失敗跺撼,geocoder都會(huì)執(zhí)行此處理程序窟感。

- (void)cancelGeocode;

函數(shù)描述取消掛起的地理編碼請(qǐng)求∏妇可以使用此方法取消掛起的請(qǐng)求并釋放與該請(qǐng)求關(guān)聯(lián)的資源柿祈。取消掛起的請(qǐng)求將導(dǎo)致調(diào)用完成處理程序塊。如果請(qǐng)求未掛起哩至,因?yàn)樗逊祷鼗蛏形撮_始躏嚎,則此方法不執(zhí)行任何操作。

\color{red}{練習(xí)代碼片段:}

//
//  CLLocation+YCLocation.h
//  YCMapViewDemo
//
//  Created by gongliang on 13-9-16.
//  Copyright (c) 2013年 gongliang. All rights reserved.
//  火星坐標(biāo)系轉(zhuǎn)換擴(kuò)展
/*
 從 CLLocationManager 取出來的經(jīng)緯度放到 mapView 上顯示憨募,是錯(cuò)誤的!
 從 CLLocationManager 取出來的經(jīng)緯度去 Google Maps API 做逆地址解析紧索,當(dāng)然是錯(cuò)的!
 從 MKMapView 取出來的經(jīng)緯度去 Google Maps API 做逆地址解析終于對(duì)了菜谣。去百度地圖API做逆地址解析,依舊是錯(cuò)的晚缩!
 從上面兩處取的經(jīng)緯度放到百度地圖上顯示都是錯(cuò)的尾膊!錯(cuò)的!的荞彼!
 
 分為 地球坐標(biāo)冈敛,火星坐標(biāo)(iOS mapView 高德 , 國內(nèi)google, 搜搜鸣皂、阿里云 都是火星坐標(biāo))抓谴,百度坐標(biāo)(百度地圖數(shù)據(jù)主要都是四維圖新提供的)
 
 火星坐標(biāo): MKMapView
 地球坐標(biāo): CLLocationManager
 
 當(dāng)用到CLLocationManager 得到的數(shù)據(jù)轉(zhuǎn)化為火星坐標(biāo), MKMapView不用處理
 
 
 API                坐標(biāo)系
 百度地圖API         百度坐標(biāo)
 騰訊搜搜地圖API      火星坐標(biāo)
 搜狐搜狗地圖API      搜狗坐標(biāo)
 阿里云地圖API       火星坐標(biāo)
 圖吧MapBar地圖API   圖吧坐標(biāo)
 高德MapABC地圖API   火星坐標(biāo)
 靈圖51ditu地圖API   火星坐標(biāo)
 
 */

#import <CoreLocation/CoreLocation.h>

@interface CLLocation (YCLocation)

///從地圖坐標(biāo)轉(zhuǎn)化到火星坐標(biāo)
- (CLLocation*)locationMarsFromEarth;

///從火星坐標(biāo)轉(zhuǎn)化到百度坐標(biāo)
- (CLLocation*)locationBaiduFromMars;

///從百度坐標(biāo)到火星坐標(biāo)
- (CLLocation*)locationMarsFromBaidu;

@end

//
//  CLLocation+YCLocation.m
//  YCMapViewDemo
//
//  Created by gongliang on 13-9-16.
//  Copyright (c) 2013年 gongliang. All rights reserved.
//

#import "CLLocation+YCLocation.h"

void transform_earth_from_mars(double lat, double lng, double* tarLat, double* tarLng);
void transform_mars_from_baidu(double lat, double lng, double* tarLat, double* tarLng);
void transform_baidu_from_mars(double lat, double lng, double* tarLat, double* tarLng);

@implementation CLLocation (YCLocation)

///從地圖坐標(biāo)轉(zhuǎn)化到火星坐標(biāo)
- (CLLocation*)locationMarsFromEarth
{
    double lat = 0.0;
    double lng = 0.0;
    transform_earth_from_mars(self.coordinate.latitude, self.coordinate.longitude, &lat, &lng);
    return [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(lat, lng)
                                         altitude:self.altitude
                               horizontalAccuracy:self.horizontalAccuracy
                                 verticalAccuracy:self.verticalAccuracy
                                           course:self.course
                                            speed:self.speed
                                        timestamp:self.timestamp];
    
}

///從火星坐標(biāo)轉(zhuǎn)化到百度坐標(biāo)
- (CLLocation*)locationBaiduFromMars
{
    double lat = 0.0;
    double lng = 0.0;
    transform_mars_from_baidu(self.coordinate.latitude, self.coordinate.longitude, &lat, &lng);
    return [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(lat, lng)
                                         altitude:self.altitude
                               horizontalAccuracy:self.horizontalAccuracy
                                 verticalAccuracy:self.verticalAccuracy
                                           course:self.course
                                            speed:self.speed
                                        timestamp:self.timestamp];
}

///從百度坐標(biāo)到火星坐標(biāo)
- (CLLocation*)locationMarsFromBaidu
{
    double lat = 0.0;
    double lng = 0.0;
    transform_baidu_from_mars(self.coordinate.latitude, self.coordinate.longitude, &lat, &lng);
    return [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(lat, lng)
                                         altitude:self.altitude
                               horizontalAccuracy:self.horizontalAccuracy
                                 verticalAccuracy:self.verticalAccuracy
                                           course:self.course
                                            speed:self.speed
                                        timestamp:self.timestamp];
}


- (CLLocation*)locationEarthFromMars
{
    // 二分法查糾偏文件
    // http://xcodev.com/131.html
    return nil;
}

@end



// --- transform_earth_from_mars ---
// 參考來源:https://on4wp7.codeplex.com/SourceControl/changeset/view/21483#353936
// Krasovsky 1940
//
// a = 6378245.0, 1/f = 298.3
// b = a * (1 - f)
// ee = (a^2 - b^2) / a^2;

const double a = 6378245.0;
const double ee = 0.00669342162296594323;

bool transform_sino_out_china(double lat, double lon)
{
    if (lon < 72.004 || lon > 137.8347)
        return true;
    if (lat < 0.8293 || lat > 55.8271)
        return true;
    return false;
}

double transform_earth_from_mars_lat(double x, double y)
{
    double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(fabs(x));
    ret += (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0;
    ret += (20.0 * sin(y * M_PI) + 40.0 * sin(y / 3.0 * M_PI)) * 2.0 / 3.0;
    ret += (160.0 * sin(y / 12.0 * M_PI) + 320 * sin(y * M_PI / 30.0)) * 2.0 / 3.0;
    return ret;
}

double transform_earth_from_mars_lng(double x, double y)
{
    double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(fabs(x));
    ret += (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 / 3.0;
    ret += (20.0 * sin(x * M_PI) + 40.0 * sin(x / 3.0 * M_PI)) * 2.0 / 3.0;
    ret += (150.0 * sin(x / 12.0 * M_PI) + 300.0 * sin(x / 30.0 * M_PI)) * 2.0 / 3.0;
    return ret;
}

void transform_earth_from_mars(double lat, double lng, double* tarLat, double* tarLng)
{
    if (transform_sino_out_china(lat, lng))
    {
        *tarLat = lat;
        *tarLng = lng;
        return;
    }
    double dLat = transform_earth_from_mars_lat(lng - 105.0, lat - 35.0);
    double dLon = transform_earth_from_mars_lng(lng - 105.0, lat - 35.0);
    double radLat = lat / 180.0 * M_PI;
    double magic = sin(radLat);
    magic = 1 - ee * magic * magic;
    double sqrtMagic = sqrt(magic);
    dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * M_PI);
    dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * M_PI);
    *tarLat = lat + dLat;
    *tarLng = lng + dLon;
}

// --- transform_earth_from_mars end ---
// --- transform_mars_vs_bear_paw ---
// 參考來源:http://blog.woodbunny.com/post-68.html
const double x_pi = M_PI * 3000.0 / 180.0;

void transform_mars_from_baidu(double gg_lat, double gg_lon, double *bd_lat, double *bd_lon)
{
    double x = gg_lon, y = gg_lat;
    double z = sqrt(x * x + y * y) + 0.00002 * sin(y * x_pi);
    double theta = atan2(y, x) + 0.000003 * cos(x * x_pi);
    *bd_lon = z * cos(theta) + 0.0065;
    *bd_lat = z * sin(theta) + 0.006;
}

void transform_baidu_from_mars(double bd_lat, double bd_lon, double *gg_lat, double *gg_lon)
{
    double x = bd_lon - 0.0065, y = bd_lat - 0.006;
    double z = sqrt(x * x + y * y) - 0.00002 * sin(y * x_pi);
    double theta = atan2(y, x) - 0.000003 * cos(x * x_pi);
    *gg_lon = z * cos(theta);
    *gg_lat = z * sin(theta);
}

//
//  TestCLLocationController.h
//  FrameworksTest

#import <UIKit/UIKit.h>

@interface TestCLLocationController : UIViewController

@end
//
//  TestCLLocationController.m
//  FrameworksTest

#import "TestCLLocationController.h"
#import "CLLocation+YCLocation.h"

@interface TestCLLocationController ()<CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;//位置管理對(duì)象
@property (nonatomic, strong) CLLocation *location;//位置對(duì)象
@property (nonatomic, strong) UIImageView *headingRelatedImageView;//航向指示視圖
@property (nonatomic, strong) UITextField *addressTextField;//地址文本輸入框
@property (nonatomic, strong) UILabel *longitudeLabel;//經(jīng)度值標(biāo)簽
@property (nonatomic, strong) UILabel *latitudeLabel;//緯度值標(biāo)簽
@property (nonatomic, strong) UITextField *longitudeTextField;//經(jīng)度文本輸入框
@property (nonatomic, strong) UITextField *latitudeTextField;//緯度文本輸入框
@property (nonatomic, strong) UILabel *addressLabel;//具體地址標(biāo)簽
@property (nonatomic, strong) UILabel *regionMonitorLabel;//區(qū)域監(jiān)視標(biāo)簽
@property (nonatomic, strong) UILabel *monitoringLabel;//正在區(qū)域監(jiān)視標(biāo)簽
@property (nonatomic, strong) UILabel *locationUpdateLabel;//位置更新標(biāo)簽

@end

@implementation TestCLLocationController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    [self createNavigationTitleView:@"CLLocation"];
    //請(qǐng)求定位權(quán)限
    [self requestLocationJurisdiction];
    //設(shè)置航向指示視圖
    [self setHeadingRelatedView];
    //設(shè)置區(qū)域監(jiān)聽
    [self setAreaMonitoring];
    //設(shè)置視圖
    [self createView];
    
}

///請(qǐng)求定位權(quán)限
- (void)requestLocationJurisdiction{
    //判斷設(shè)備在設(shè)置中是否啟用了位置服務(wù)
    if([CLLocationManager locationServicesEnabled]){
        //設(shè)備啟用了位置服務(wù)癌压,判斷應(yīng)用程序的位置權(quán)限
        switch ([CLLocationManager authorizationStatus]) {
            //用戶尚未選擇應(yīng)用程序是否可以使用位置服務(wù)
            case kCLAuthorizationStatusNotDetermined:
                //啟用定位
                [self enablePositioning];
                //請(qǐng)求在應(yīng)用程序位于前臺(tái)時(shí)使用定位服務(wù)的權(quán)限
                [self.locationManager requestWhenInUseAuthorization];
                break;
            //用戶授權(quán)應(yīng)用程序隨時(shí)啟動(dòng)定位服務(wù)的權(quán)限
            //用戶已授權(quán)僅在使用應(yīng)用程序時(shí)有訪問位置的權(quán)限
            case kCLAuthorizationStatusAuthorizedAlways:
            case kCLAuthorizationStatusAuthorizedWhenInUse:
                //啟用定位
                [self enablePositioning];
                break;
            //拒絕對(duì)此應(yīng)用程序的位置授權(quán)
            case kCLAuthorizationStatusDenied:
                //設(shè)備未啟用位置服務(wù),展示提示
                [self showPermissionSettingAlert:@"無法定位" withMessage:@"當(dāng)前應(yīng)用程序設(shè)置不支持定位"];
                break;
            default:
                break;
        }
        
    }else{
        //設(shè)備未啟用位置服務(wù)稚新,展示提示
        [self showPermissionSettingAlert:@"無法定位" withMessage:@"當(dāng)前設(shè)備設(shè)置不支持定位"];
    }
}

///啟用定位
- (void)enablePositioning{
    //初始化位置管理對(duì)象
    if(self.locationManager == nil){
        self.locationManager = [[CLLocationManager alloc]init];
    }
    //設(shè)置代理
    self.locationManager.delegate = self;
    //請(qǐng)求在應(yīng)用程序位于前臺(tái)時(shí)使用定位服務(wù)的權(quán)限
    [self.locationManager requestAlwaysAuthorization];
    //開始生成報(bào)告用戶當(dāng)前位置的更新
    [self.locationManager startUpdatingLocation];
    //判斷位置管理器是否能夠生成與導(dǎo)航方向相關(guān)的事件
    if ([CLLocationManager headingAvailable]) {
        //生成新航向事件所需的最小角度變化
        self.locationManager.headingFilter = kCLHeadingFilterNone;
        [self.locationManager startUpdatingHeading];
    }
}

///顯示權(quán)限設(shè)置提示框
- (void)showPermissionSettingAlert:(NSString *)title withMessage:(NSString *)message{
    //初始化提示框
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    //YES操作項(xiàng)
    UIAlertAction *yesAction = [UIAlertAction actionWithTitle:@"YES" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
        //打開設(shè)置頁面
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]options:@{}completionHandler:nil];
    }];
    //NO操作項(xiàng)
    UIAlertAction *noAction = [UIAlertAction actionWithTitle:@"NO" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
    }];
    [alertController addAction:yesAction];
    [alertController addAction:noAction];
    [self presentViewController:alertController animated:true completion:nil];
}

///設(shè)置航向指示視圖
- (void)setHeadingRelatedView{
    //航向指示視圖
    self.headingRelatedImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"btn_navigation"]];
    self.headingRelatedImageView.contentMode = UIViewContentModeScaleToFill;
    [self.view addSubview:self.headingRelatedImageView];
    //Masonry布局
    [self.headingRelatedImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_top).offset(HEAD_BAR_HEIGHT);
        make.centerX.equalTo(self.view);
        make.size.mas_equalTo(CGSizeMake(20, 30));
    }];
}

///設(shè)置區(qū)域監(jiān)聽
- (void)setAreaMonitoring{
    //判斷設(shè)備是否支持區(qū)域監(jiān)聽
    if (![CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]]) {
        return;
    }
    //指定區(qū)域類型,一般是圓形區(qū)域
    //區(qū)域的中點(diǎn)坐標(biāo)
    CLLocationCoordinate2D center = CLLocationCoordinate2DMake(39.909502, 119.511151);
    //區(qū)域半徑(米)
    CLLocationDistance distance = 170.0;
    //半徑限制
    if (distance > self.locationManager.maximumRegionMonitoringDistance) {
        distance = self.locationManager.maximumRegionMonitoringDistance;
    }
    //初始化圓形地理區(qū)域,指定為中心點(diǎn)和半徑决记。
    CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center radius:distance identifier:@"MyLocation"];
    //開始監(jiān)視指定區(qū)域往枷,對(duì)于要監(jiān)視的每個(gè)區(qū)域忱叭,必須調(diào)用此方法一次
    [self.locationManager startMonitoringForRegion:region];
    //延遲2秒執(zhí)行今艺,以防止概率出現(xiàn)的Domain=kCLErrorDomain Code=5錯(cuò)誤
    dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC));
    dispatch_after(delayTime, dispatch_get_main_queue(), ^{
        //異步檢索區(qū)域的狀態(tài)
        [self.locationManager requestStateForRegion:region];
    });
    
}

///設(shè)置視圖
- (void)createView{
    //初始化地址提示標(biāo)簽
    UILabel *addressTipsLabel = [[UILabel alloc]initWithFrame:CGRectZero];
    addressTipsLabel.text = @"地址:";
    addressTipsLabel.font = [UIFont systemFontOfSize:15];
    [self.view addSubview:addressTipsLabel];
    //Masonry布局
    [addressTipsLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.headingRelatedImageView.mas_bottom).offset(20);
        make.left.equalTo(self.view.mas_left).offset(20);
    }];
    
    //初始化地址文本輸入框
    self.addressTextField = [[UITextField alloc]initWithFrame:CGRectZero];
    self.addressTextField.placeholder = @" 請(qǐng)輸入地址";
    self.addressTextField.layer.borderColor = [UIColor blackColor].CGColor;
    self.addressTextField.layer.borderWidth = 0.5;
    [self.view addSubview:self.addressTextField];
    //Masonry布局
    [self.addressTextField mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(addressTipsLabel);
        make.left.equalTo(addressTipsLabel.mas_right).offset(10);
        make.size.mas_equalTo(CGSizeMake(200, 35));
    }];
    
    //初始化查詢按鈕
    UIButton *queryButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [queryButton setTitle:@"查詢" forState:UIControlStateNormal];
    [queryButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [queryButton setBackgroundColor:[UIColor blueColor]];
    [queryButton setTag:1000];
    [self.view addSubview:queryButton];
    [queryButton addTarget:self action:@selector(queryButtonClick:) forControlEvents:UIControlEventTouchUpInside];
    //Masonry布局
    [queryButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.addressTextField);
        make.left.equalTo(self.addressTextField.mas_right).offset(10);
        make.size.mas_equalTo(CGSizeMake(60, 35));
    }];
    
    //初始化經(jīng)度值標(biāo)簽
    self.longitudeLabel = [[UILabel alloc]initWithFrame:CGRectZero];
    self.longitudeLabel.font = [UIFont systemFontOfSize:15];
    self.longitudeLabel.textColor = [UIColor redColor];
    self.longitudeLabel.textAlignment = NSTextAlignmentCenter;
    self.longitudeLabel.text = @"當(dāng)前經(jīng)度";
    self.longitudeLabel.layer.borderWidth = 0.5;
    self.longitudeLabel.layer.borderColor = [UIColor redColor].CGColor;
    [self.view addSubview:self.longitudeLabel];
    [self.longitudeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(addressTipsLabel.mas_bottom).offset(30);
        make.left.equalTo(self.view.mas_left).offset(20);
        make.size.mas_equalTo(CGSizeMake(150, 30));
    }];
    
    //初始化緯度值標(biāo)簽
    self.latitudeLabel = [[UILabel alloc]initWithFrame:CGRectZero];
    self.latitudeLabel.font = [UIFont systemFontOfSize:15];
    self.latitudeLabel.textColor = [UIColor greenColor];
    self.latitudeLabel.text = @"當(dāng)前緯度";
    self.latitudeLabel.textAlignment = NSTextAlignmentCenter;
    self.latitudeLabel.layer.borderWidth = 0.5;
    self.latitudeLabel.layer.borderColor = [UIColor greenColor].CGColor;
    [self.view addSubview:self.latitudeLabel];
    [self.latitudeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.longitudeLabel);
        make.right.equalTo(queryButton.mas_right).offset(10);
        make.size.mas_equalTo(CGSizeMake(150, 30));
    }];
    
    //初始化經(jīng)度提示標(biāo)簽
    UILabel *longitudeTipsLabel = [[UILabel alloc]initWithFrame:CGRectZero];
    longitudeTipsLabel.text = @"經(jīng)度:";
    longitudeTipsLabel.font = [UIFont systemFontOfSize:15];
    [self.view addSubview:longitudeTipsLabel];
    //Masonry布局
    [longitudeTipsLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.longitudeLabel.mas_bottom).offset(50);
        make.left.equalTo(self.view.mas_left).offset(20);
    }];
    
    //初始化經(jīng)度文本輸入框
    self.longitudeTextField = [[UITextField alloc]initWithFrame:CGRectZero];
    self.longitudeTextField.placeholder = @" 請(qǐng)輸入經(jīng)度";
    self.longitudeTextField.layer.borderColor = [UIColor blackColor].CGColor;
    self.longitudeTextField.layer.borderWidth = 0.5;
    [self.view addSubview:self.longitudeTextField];
    //Masonry布局
    [self.longitudeTextField mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(longitudeTipsLabel);
        make.left.equalTo(addressTipsLabel.mas_right).offset(10);
        make.size.mas_equalTo(CGSizeMake(105, 35));
    }];
    
    //初始化緯度提示標(biāo)簽
    UILabel *latitudeTipsLabel = [[UILabel alloc]initWithFrame:CGRectZero];
    latitudeTipsLabel.text = @"緯度:";
    latitudeTipsLabel.font = [UIFont systemFontOfSize:15];
    [self.view addSubview:latitudeTipsLabel];
    //Masonry布局
    [latitudeTipsLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(longitudeTipsLabel);
        make.left.equalTo(self.latitudeLabel.mas_left);
    }];
    
    //初始化經(jīng)度文本輸入框
    self.latitudeTextField = [[UITextField alloc]initWithFrame:CGRectZero];
    self.latitudeTextField.placeholder = @" 請(qǐng)輸入緯度";
    self.latitudeTextField.layer.borderColor = [UIColor blackColor].CGColor;
    self.latitudeTextField.layer.borderWidth = 0.5;
    [self.view addSubview:self.latitudeTextField];
    //Masonry布局
    [self.latitudeTextField mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(latitudeTipsLabel);
        make.left.equalTo(latitudeTipsLabel.mas_right).offset(10);
        make.size.mas_equalTo(CGSizeMake(105, 35));
    }];
    
    //初始化查詢按鈕
    UIButton *queryButton2 = [UIButton buttonWithType:UIButtonTypeCustom];
    [queryButton2 setTitle:@"查詢" forState:UIControlStateNormal];
    [queryButton2 setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [queryButton2 setBackgroundColor:[UIColor blueColor]];
    [queryButton2 setTag:1001];
    [self.view addSubview:queryButton2];
    [queryButton2 addTarget:self action:@selector(queryButtonClick:) forControlEvents:UIControlEventTouchUpInside];
    //Masonry布局
    [queryButton2 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.longitudeTextField.mas_bottom).offset(20);
        make.centerX.equalTo(self.view);
        make.size.mas_equalTo(CGSizeMake(120, 35));
    }];
    
    //初始化具體地址標(biāo)簽
    self.addressLabel = [[UILabel alloc]initWithFrame:CGRectZero];
    self.addressLabel.font = [UIFont systemFontOfSize:15];
    self.addressLabel.textColor = [UIColor redColor];
    self.addressLabel.textAlignment = NSTextAlignmentCenter;
    self.addressLabel.text = @"當(dāng)前位置:";
    self.addressLabel.layer.borderWidth = 0.5;
    self.addressLabel.layer.borderColor = [UIColor redColor].CGColor;
    [self.view addSubview:self.addressLabel];
    //Masonry布局
    [self.addressLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(queryButton2.mas_bottom).offset(20);
        make.left.equalTo(self.longitudeLabel.mas_left);
        make.right.equalTo(self.latitudeLabel.mas_right);
        make.height.mas_equalTo(30);
    }];
    
    //初始化區(qū)域監(jiān)視標(biāo)簽
    self.regionMonitorLabel = [[UILabel alloc]initWithFrame:CGRectZero];
    self.regionMonitorLabel.font = [UIFont systemFontOfSize:15];
    self.regionMonitorLabel.textColor = [UIColor blackColor];
    self.regionMonitorLabel.textAlignment = NSTextAlignmentCenter;
    self.regionMonitorLabel.numberOfLines = 0;
    self.regionMonitorLabel.layer.borderWidth = 0.5;
    self.regionMonitorLabel.layer.borderColor = [UIColor blackColor].CGColor;
    [self.view addSubview:self.regionMonitorLabel];
    //Masonry布局
    [self.regionMonitorLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.addressLabel.mas_bottom).offset(30);
        make.left.equalTo(self.longitudeLabel.mas_left);
        make.right.equalTo(self.view.mas_right).offset(- 20);
    }];
    
    //初始化正在區(qū)域監(jiān)視標(biāo)簽
    self.monitoringLabel = [[UILabel alloc]initWithFrame:CGRectZero];
    self.monitoringLabel.font = [UIFont systemFontOfSize:15];
    self.monitoringLabel.textColor = [UIColor blackColor];
    self.monitoringLabel.textAlignment = NSTextAlignmentCenter;
    self.monitoringLabel.numberOfLines = 0;
    self.monitoringLabel.layer.borderWidth = 0.5;
    self.monitoringLabel.layer.borderColor = [UIColor blackColor].CGColor;
    [self.view addSubview:self.monitoringLabel];
    //Masonry布局
    [self.monitoringLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.regionMonitorLabel.mas_bottom).offset(30);
        make.left.equalTo(self.longitudeLabel.mas_left);
        make.right.equalTo(self.view.mas_right).offset(- 20);
    }];
    
    //初始化位置更新標(biāo)簽
    self.locationUpdateLabel = [[UILabel alloc]initWithFrame:CGRectZero];
    self.locationUpdateLabel.font = [UIFont systemFontOfSize:15];
    self.locationUpdateLabel.textColor = [UIColor blackColor];
    self.locationUpdateLabel.textAlignment = NSTextAlignmentCenter;
    self.locationUpdateLabel.numberOfLines = 0;
    self.locationUpdateLabel.layer.borderWidth = 0.5;
    self.locationUpdateLabel.layer.borderColor = [UIColor blackColor].CGColor;
    [self.view addSubview:self.locationUpdateLabel];
    //Masonry布局
    [self.locationUpdateLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.monitoringLabel.mas_bottom).offset(30);
        make.left.equalTo(self.longitudeLabel.mas_left);
        make.right.equalTo(self.view.mas_right).offset(- 20);
    }];
}

///查詢按鈕點(diǎn)擊事件
- (void)queryButtonClick:(UIButton *)sender{
    
    if(sender.tag == 1000 ){
        
        //初始化地理編碼器對(duì)象
        CLGeocoder *geoCoder = [[CLGeocoder alloc]init];
        //提交指定位置的正向地理編碼請(qǐng)求
        [geoCoder geocodeAddressString:self.addressTextField.text completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
            
            if (placemarks.count >0) {
                
                CLPlacemark *placeMark = placemarks[0];
                CLLocation *location = placeMark.location;
                //設(shè)置經(jīng)度值標(biāo)簽的經(jīng)度
                self.longitudeLabel.text = [NSString stringWithFormat:@"當(dāng)前經(jīng)度:%f",location.coordinate.longitude];
                //設(shè)置維度值標(biāo)簽的緯度
                self.latitudeLabel.text = [NSString stringWithFormat:@"當(dāng)前緯度:%f",location.coordinate.latitude];
                
            }else if(error == nil && placemarks.count){
                
                NSLog(@"無位置和錯(cuò)誤返回");
                self.longitudeLabel.text = @"未找到";
                self.latitudeLabel.text = @"未找到";
                
            }else if(error){
                
                NSLog(@"loction error:%@",error);
                self.longitudeLabel.text = @"未找到";
                self.latitudeLabel.text = @"未找到";
                
            }
        }];

        
    }else if(sender.tag == 1001){
        
        if(IS_NOT_EMPTY(self.longitudeTextField.text) && IS_NOT_EMPTY(self.latitudeTextField.text)){
            CLLocationDegrees latitude = self.latitudeTextField.text.doubleValue;
            CLLocationDegrees longitude = self.longitudeTextField.text.doubleValue;
            self.location = [[CLLocation alloc]initWithLatitude:latitude longitude:longitude];
        }
        //初始化地理編碼器對(duì)象
        CLGeocoder *geoCoder = [[CLGeocoder alloc]init];
        //提交指定位置的反向地理編碼請(qǐng)求
        [geoCoder reverseGeocodeLocation:self.location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
            if (placemarks.count >0) {

                CLPlacemark *placeMark = placemarks[0];
                NSLog(@"當(dāng)前國家 - %@",placeMark.country);//當(dāng)前國家
                NSLog(@"當(dāng)前城市 - %@",placeMark.locality);//當(dāng)前城市
                NSLog(@"當(dāng)前位置 - %@",placeMark.subLocality);//當(dāng)前位置
                NSLog(@"當(dāng)前街道 - %@",placeMark.thoroughfare);//當(dāng)前街道
                NSLog(@"具體地址 - %@",placeMark.name);//具體地址
                self.addressLabel.text = [NSString stringWithFormat:@"%@%@%@,%@",IS_NOT_EMPTY(placeMark.locality)? placeMark.locality : @"",IS_NOT_EMPTY(placeMark.subLocality)? placeMark.subLocality : @"" ,IS_NOT_EMPTY(placeMark.thoroughfare)? placeMark.thoroughfare : @"",IS_NOT_EMPTY(placeMark.name)? placeMark.name : @""];

            }else if(error == nil && placemarks.count){

                NSLog(@"無位置和錯(cuò)誤返回");

            }else if(error){

                NSLog(@"loction error:%@",error);

            }

        }];
    }
    
}

#pragma mark - CLLocationManagerDelegate

///通知代理新的位置數(shù)據(jù)可用
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    self.location = [locations lastObject];
    if (self.location.coordinate.latitude <= 0 || self.location.coordinate.longitude <= 0) {
        return;
    }
    CLLocationCoordinate2D locationCoordinate = self.location.coordinate;
    //設(shè)置經(jīng)度值標(biāo)簽的經(jīng)度
    self.longitudeLabel.text = [NSString stringWithFormat:@"當(dāng)前經(jīng)度:%f",locationCoordinate.longitude];
    //設(shè)置維度值標(biāo)簽的緯度
    self.latitudeLabel.text = [NSString stringWithFormat:@"當(dāng)前緯度:%f",locationCoordinate.latitude];
    //停止生成位置更新
    [manager stopUpdatingLocation];
    
}

///通知代理位置管理器接收到更新的航向信息
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
    
    CGAffineTransform transform =CGAffineTransformMakeRotation((newHeading.magneticHeading) * M_PI / 180.f );
    self.headingRelatedImageView.transform = transform;
}

///當(dāng)此應(yīng)用程序的授權(quán)狀態(tài)更改時(shí)調(diào)用
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status API_AVAILABLE(ios(4.2), macos(10.7)){
    NSLog(@"當(dāng)此應(yīng)用程序的授權(quán)狀態(tài)更改時(shí)調(diào)用");
    switch (status) {
        //用戶授權(quán)應(yīng)用程序隨時(shí)啟動(dòng)定位服務(wù)的權(quán)限
        //用戶已授權(quán)僅在使用應(yīng)用程序時(shí)有訪問位置的權(quán)限
        case kCLAuthorizationStatusAuthorizedAlways:
        case kCLAuthorizationStatusAuthorizedWhenInUse:
            //啟用定位
            [self enablePositioning];
            break;
        default:
            break;
    }
}

///詢問代理是否應(yīng)顯示航向校準(zhǔn)警報(bào)
- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager{
    return YES;
}

///通知代理位置管理器無法檢索位置值
- (void)locationManager:(CLLocationManager *)manager
       didFailWithError:(NSError *)error{
    NSLog(@"發(fā)生異常了");
    if(error.code == kCLErrorLocationUnknown) {
        NSLog(@"無法檢索位置");
    }
    else if(error.code == kCLErrorNetwork) {
        NSLog(@"網(wǎng)絡(luò)問題");
    }
    else if(error.code == kCLErrorDenied) {
        NSLog(@"定位權(quán)限的問題");
    }
}

///通知代理用戶已進(jìn)入指定區(qū)域
- (void)locationManager:(CLLocationManager *)manager
         didEnterRegion:(CLRegion *)region API_AVAILABLE(ios(4.0), macos(10.8)) API_UNAVAILABLE(watchos, tvOS){
    //異步檢索區(qū)域的狀態(tài)
    [self.locationManager requestStateForRegion:region];
    NSLog(@"以進(jìn)入指定區(qū)域");
    self.regionMonitorLabel.text = @"以進(jìn)入指定區(qū)域";
}

///通知代理用戶已離開指定區(qū)域
- (void)locationManager:(CLLocationManager *)manager
          didExitRegion:(CLRegion *)region API_AVAILABLE(ios(4.0), macos(10.8)) API_UNAVAILABLE(watchos, tvOS){
    //異步檢索區(qū)域的狀態(tài)
    [self.locationManager requestStateForRegion:region];
    NSLog(@"以離開指定區(qū)域");
    self.regionMonitorLabel.text = @"以離開指定區(qū)域";
}

///通知代理指定區(qū)域的狀態(tài)
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
    
    if (state == CLRegionStateInside) {
        NSLog(@"以進(jìn)入指定區(qū)域");
        self.regionMonitorLabel.text = @"以進(jìn)入指定區(qū)域";
    } else if (state == CLRegionStateOutside) {
        NSLog(@"以離開指定區(qū)域");
        self.regionMonitorLabel.text = @"以離開指定區(qū)域";
    } else {
        NSLog(@"未知狀態(tài)");
        self.regionMonitorLabel.text = @"未知狀態(tài)";
    }
    
}

///通知代理發(fā)生區(qū)域監(jiān)視錯(cuò)誤
- (void)locationManager:(CLLocationManager *)manager
    monitoringDidFailForRegion:(nullable CLRegion *)region
              withError:(NSError *)error API_AVAILABLE(ios(4.0), macos(10.8)) API_UNAVAILABLE(watchos, tvOS){
    //停止區(qū)域監(jiān)視
    [self.locationManager stopMonitoringForRegion:region];
    //CLCircularRegion類定義圓形地理區(qū)域的位置和邊界
    CLCircularRegion  *circularRegion = (CLCircularRegion *)region;
    CLLocation *location = [[CLLocation alloc]initWithLatitude:circularRegion.center.latitude longitude:circularRegion.center.longitude];
    
    //初始化地理編碼器對(duì)象
    CLGeocoder *geocoder = [[CLGeocoder alloc]init];
    //提交指定位置的反向地理編碼請(qǐng)求
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        
        if (placemarks.count >0) {

                CLPlacemark *placeMark = placemarks[0];
                NSLog(@"當(dāng)前國家 - %@",placeMark.country);//當(dāng)前國家
                NSLog(@"當(dāng)前城市 - %@",placeMark.locality);//當(dāng)前城市
                NSLog(@"當(dāng)前位置 - %@",placeMark.subLocality);//當(dāng)前位置
                NSLog(@"當(dāng)前街道 - %@",placeMark.thoroughfare);//當(dāng)前街道
                NSLog(@"具體地址 - %@",placeMark.name);//具體地址
                NSString *errorGeocoder = [NSString stringWithFormat:@"%@%@%@,%@",IS_NOT_EMPTY(placeMark.locality)? placeMark.locality : @"",IS_NOT_EMPTY(placeMark.subLocality)? placeMark.subLocality : @"" ,IS_NOT_EMPTY(placeMark.thoroughfare)? placeMark.thoroughfare : @"",IS_NOT_EMPTY(placeMark.name)? placeMark.name : @""];
            
                NSLog(@"%@區(qū)域監(jiān)聽發(fā)生錯(cuò)誤",errorGeocoder);

            }else if(error == nil && placemarks.count){

                NSLog(@"無位置和錯(cuò)誤返回");

            }else if(error){

                NSLog(@"loction error:%@",error);

            }

        }];
    //輸出包含錯(cuò)誤的本地化描述的字符串
    NSLog(@"區(qū)域監(jiān)控失敗 %@ %@",region, error.localizedDescription);
    self.regionMonitorLabel.text = error.localizedDescription;
    
    for (CLRegion *monitoredRegion in manager.monitoredRegions) {
        NSLog(@"monitoredRegion: %@", monitoredRegion);
    }
    if ((error.domain != kCLErrorDomain || error.code != 5) &&
        [manager.monitoredRegions containsObject:region]) {
        NSString *message = [NSString stringWithFormat:@"%@ %@",
            region, error.localizedDescription];
        NSLog(@"%@",message);
    }
}

///通知代理正在監(jiān)視新區(qū)域
- (void)locationManager:(CLLocationManager *)manager
didStartMonitoringForRegion:(CLRegion *)region API_AVAILABLE(ios(5.0), macos(10.8)) API_UNAVAILABLE(watchos, tvOS){
    
    //CLCircularRegion類定義圓形地理區(qū)域的位置和邊界
    CLCircularRegion  *circularRegion = (CLCircularRegion *)region;
    CLLocation *location = [[CLLocation alloc]initWithLatitude:circularRegion.center.latitude longitude:circularRegion.center.longitude];
    
    //初始化地理編碼器對(duì)象
    CLGeocoder *geocoder = [[CLGeocoder alloc]init];
    //提交指定位置的反向地理編碼請(qǐng)求
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        
        if (placemarks.count >0) {

                CLPlacemark *placeMark = placemarks[0];
                NSLog(@"當(dāng)前國家 - %@",placeMark.country);//當(dāng)前國家
                NSLog(@"當(dāng)前城市 - %@",placeMark.locality);//當(dāng)前城市
                NSLog(@"當(dāng)前位置 - %@",placeMark.subLocality);//當(dāng)前位置
                NSLog(@"當(dāng)前街道 - %@",placeMark.thoroughfare);//當(dāng)前街道
                NSLog(@"具體地址 - %@",placeMark.name);//具體地址
                NSString *errorGeocoder = [NSString stringWithFormat:@"%@%@%@,%@",IS_NOT_EMPTY(placeMark.locality)? placeMark.locality : @"",IS_NOT_EMPTY(placeMark.subLocality)? placeMark.subLocality : @"" ,IS_NOT_EMPTY(placeMark.thoroughfare)? placeMark.thoroughfare : @"",IS_NOT_EMPTY(placeMark.name)? placeMark.name : @""];
            
                self.monitoringLabel.text = [NSString stringWithFormat:@"在監(jiān)視新區(qū)域:%@",errorGeocoder];

            }else if(error == nil && placemarks.count){

                NSLog(@"無位置和錯(cuò)誤返回");

            }else if(error){

                NSLog(@"loction error:%@",error);

            }

        }];
}

///通知代理位置更新已暫停
- (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager API_AVAILABLE(ios(6.0)) API_UNAVAILABLE(watchos, tvos, macOS){
    self.locationUpdateLabel.text = @"位置更新已暫停";
}

///通知代理位置更新的傳遞已恢復(fù)
- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager API_AVAILABLE(ios(6.0)) API_UNAVAILABLE(watchos, tvos, macOS){
    self.locationUpdateLabel.text = @"位置更新的傳遞已恢復(fù)";
}

///通知代理不再延遲更新
- (void)locationManager:(CLLocationManager *)manager
didFinishDeferredUpdatesWithError:(nullable NSError *)error API_AVAILABLE(ios(6.0), macos(10.9)) API_UNAVAILABLE(watchos, tvOS){
    self.locationUpdateLabel.text = @"不再延遲更新";
}

///通知代理一個(gè)或多個(gè)信標(biāo)在范圍內(nèi)韵丑。
- (void)locationManager:(CLLocationManager *)manager
didRangeBeacons:(NSArray<CLBeacon *> *)beacons
               inRegion:(CLBeaconRegion *)region{
    
}

///通知代理檢測(cè)到滿足約束的信標(biāo)。
- (void)locationManager:(CLLocationManager *)manager
        didRangeBeacons:(NSArray<CLBeacon *> *)beacons
   satisfyingConstraint:(CLBeaconIdentityConstraint *)beaconConstraint API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos, macOS){
    
}

///通知代理未檢測(cè)到滿足約束的信標(biāo)虚缎。
- (void)locationManager:(CLLocationManager *)manager
didFailRangingBeaconsForConstraint:(CLBeaconIdentityConstraint *)beaconConstraint
                  error:(NSError *)error API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos, macOS){
    
}

///通知代理收到了新的與訪問相關(guān)的事件
- (void)locationManager:(CLLocationManager *)manager didVisit:(CLVisit *)visit API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(watchos, tvos, macOS){
    
}
@end

樣式如圖 :

IMG_1317.PNG
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末撵彻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子实牡,更是在濱河造成了極大的恐慌陌僵,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件创坞,死亡現(xiàn)場離奇詭異碗短,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)题涨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門偎谁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人携栋,你說我怎么就攤上這事搭盾。” “怎么了婉支?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長澜建。 經(jīng)常有香客問我向挖,道長,這世上最難降的妖魔是什么炕舵? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任何之,我火速辦了婚禮,結(jié)果婚禮上咽筋,老公的妹妹穿的比我還像新娘溶推。我一直安慰自己,他們只是感情好奸攻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布蒜危。 她就那樣靜靜地躺著,像睡著了一般睹耐。 火紅的嫁衣襯著肌膚如雪辐赞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天硝训,我揣著相機(jī)與錄音响委,去河邊找鬼新思。 笑死,一個(gè)胖子當(dāng)著我的面吹牛赘风,可吹牛的內(nèi)容都是我干的夹囚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼邀窃,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼荸哟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蛔翅,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤敲茄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后山析,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體堰燎,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年笋轨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了秆剪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡爵政,死狀恐怖仅讽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情钾挟,我是刑警寧澤洁灵,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站掺出,受9級(jí)特大地震影響徽千,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜汤锨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一双抽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧闲礼,春花似錦牍汹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至聂抢,卻和暖如春钧嘶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背琳疏。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國打工有决, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留闸拿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓书幕,卻偏偏與公主長得像新荤,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子台汇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354