[iOS] CoreLocation - CLGeocoder
16760 ワード
位置情報権限を許可する場合、許可されたデータでユーザーのアドレスを画面に表示したいのですが...CLLocationで得ることができるのはユーザーマシンの座標だけで、経度と緯度もあります...これを使ってユーザーの住所を調べる方法が分かりません.
だからグーグルゲームを頑張ってやっと見つけた!CLGeocodeを利用すればいい!アップルの公式ファイルもあります!CLGeocoderを使用して座標値をアドレスに変換する方法を示します.
CLGeocoder
だからグーグルゲームを頑張ってやっと見つけた!CLGeocodeを利用すればいい!アップルの公式ファイルもあります!CLGeocoderを使用して座標値をアドレスに変換する方法を示します.
CLGeocoder
領域座標と領域名を変換するインタフェース
はい.これが変換インタフェースだと知っていますが、どうやって変換しますか?
はい、読んでみましたが、geocoderオブジェクトは使い捨てオブジェクトで、ネットワークに関連するサービスを利用して、ある座標位置値を取得して、ユーザーが理解できるアドレスを取得することができます.逆に、アドレスで座標情報を取得することができます.
詳細はConverting Between CoordinatesとUser-friendly Places Nameの記事でご覧いただけます.
Converting a Coordinate into a Placemark
公式ファイルによると、CLLocationオブジェクトを持っている場合は、reverseGeocodeLocation(_:completionHandler:)
メソッドを呼び出して、位置に対応するCLPlacemark
オブジェクトを取得できます.通常、ユーザが選択した地図の位置アドレスを文字列でユーザに表示しようとすると、これらの操作が実行される.これこそ私に必要な情報です!
コード例を親切に書いてあります.func lookUpCurrentLocation(completionHandler: @escaping (CLPlacemark?)
-> Void ) {
// Use the last reported location.
if let lastLocation = self.locationManager.location {
let geocoder = CLGeocoder()
// Look up the location and pass it to the completion handler
geocoder.reverseGeocodeLocation(lastLocation,
completionHandler: { (placemarks, error) in
if error == nil {
let firstLocation = placemarks?[0]
completionHandler(firstLocation)
}
else {
// An error occurred during geocoding.
completionHandler(nil)
}
})
}
else {
// No location was available.
completionHandler(nil)
}
}
ネットワークベースのタスクのためか、completion handlerを利用して非同期タスクを処理しているようです.私はずっとそのplacemarksでプレイヤーの位置情報を得ることができると思っています.さっそく始めましょう.
まずユーザ位置情報モデルクラスを実現しました~!class UserLocationInformation {
var country: String
var administrativeArea: String
var subAdministrativeArea: String?
var locality: String
var thoroughFare: String
var subThoroughFare: String
init(country: String, administrativeArea: String, locality: String, thoroughFare: String, subThoroughFare: String) {
self.country = country
self.administrativeArea = administrativeArea
self.locality = country
self.thoroughFare = thoroughFare
self.subThoroughFare = subThoroughFare
}
}
次に,位置情報を受信してアドレスに変換する方法を実施した.私が考えている方法は、geoCoderオブジェクトを作成し、reverseGeocodeLocation
メソッドで取得したプレースホルダのアドレスをモデル初期化によって取得することです.
この操作は非同期操作であるため、時間的な問題が発生しました.解決策は、@expervation closureを使用してユーザーロcation Informationオブジェクト初期化タスクをポップアップキャビネットに送信することです. private func convertLocationToAddress(with clLocation: CLLocation, localeIdentifier: String, completionHandler: @escaping (UserLocationInformation) -> ()) {
let locale = Locale(identifier: localeIdentifier)
let geoCoder = CLGeocoder()
geoCoder.reverseGeocodeLocation(clLocation, preferredLocale: locale) { placemarks, error in
if error != nil {
NSLog("\(String(describing: error))")
return
}
guard let placemark = placemarks?.first,
let country = placemark.country,
let administrativeArea = placemark.administrativeArea,
let locality = placemark.locality,
let thoroughFare = placemark.locality,
let subThoroughFare = placemark.subThoroughfare
else { return }
completionHandler(UserLocationInformation(country: country, administrativeArea: administrativeArea, locality: locality, thoroughFare: thoroughFare, subThoroughFare: subThoroughFare))
}
}
その後,CLLocationManagerDelegateを用いたViewControlメソッドでは,ユーザが切り替え時に呼び出すメソッドにポップアップキャビネットで送信されたキャビネットを受け取り,UI設定を行った.(UI設定は必ずメインスレッドで設定する部分は忘れてはいけません!!)もちろん、ユーザが位置権限を許可した場合にのみ、位置値が使用可能であることが前提です.func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
if manager.authorizationStatus == .authorizedWhenInUse {
guard let coordinate = manager.location?.coordinate else {
NSLog("Can't locate coordinate")
return
}
let clLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
guard let localeIdentifier = Locale.preferredLanguages.first else { return }
convertLocationToAddress(with: clLocation, localeIdentifier: localeIdentifier) { information in
DispatchQueue.main.async {
self.addLeftBarButtonItems(title: information.thoroughFare)
}
}
}
シミュレータをぐるっと回すと!!
乾杯.私はアドレス情報を受け取って、それがUIに適用することを確認します!
初めて位置情報を勉強したので、今はまだ気まずいですが、もっと簡潔なコードを書くように頑張ります!
[注意]:
Apple Developer Document | CLGeocoder
Apple Developer Document | Converting Between Coordinates and User-Friendly Place Names
Reference
この問題について([iOS] CoreLocation - CLGeocoder), 我々は、より多くの情報をここで見つけました
https://velog.io/@inwoodev/iOS-CoreLocation-CLGeocoder
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
func lookUpCurrentLocation(completionHandler: @escaping (CLPlacemark?)
-> Void ) {
// Use the last reported location.
if let lastLocation = self.locationManager.location {
let geocoder = CLGeocoder()
// Look up the location and pass it to the completion handler
geocoder.reverseGeocodeLocation(lastLocation,
completionHandler: { (placemarks, error) in
if error == nil {
let firstLocation = placemarks?[0]
completionHandler(firstLocation)
}
else {
// An error occurred during geocoding.
completionHandler(nil)
}
})
}
else {
// No location was available.
completionHandler(nil)
}
}
class UserLocationInformation {
var country: String
var administrativeArea: String
var subAdministrativeArea: String?
var locality: String
var thoroughFare: String
var subThoroughFare: String
init(country: String, administrativeArea: String, locality: String, thoroughFare: String, subThoroughFare: String) {
self.country = country
self.administrativeArea = administrativeArea
self.locality = country
self.thoroughFare = thoroughFare
self.subThoroughFare = subThoroughFare
}
}
private func convertLocationToAddress(with clLocation: CLLocation, localeIdentifier: String, completionHandler: @escaping (UserLocationInformation) -> ()) {
let locale = Locale(identifier: localeIdentifier)
let geoCoder = CLGeocoder()
geoCoder.reverseGeocodeLocation(clLocation, preferredLocale: locale) { placemarks, error in
if error != nil {
NSLog("\(String(describing: error))")
return
}
guard let placemark = placemarks?.first,
let country = placemark.country,
let administrativeArea = placemark.administrativeArea,
let locality = placemark.locality,
let thoroughFare = placemark.locality,
let subThoroughFare = placemark.subThoroughfare
else { return }
completionHandler(UserLocationInformation(country: country, administrativeArea: administrativeArea, locality: locality, thoroughFare: thoroughFare, subThoroughFare: subThoroughFare))
}
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
if manager.authorizationStatus == .authorizedWhenInUse {
guard let coordinate = manager.location?.coordinate else {
NSLog("Can't locate coordinate")
return
}
let clLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
guard let localeIdentifier = Locale.preferredLanguages.first else { return }
convertLocationToAddress(with: clLocation, localeIdentifier: localeIdentifier) { information in
DispatchQueue.main.async {
self.addLeftBarButtonItems(title: information.thoroughFare)
}
}
}
Reference
この問題について([iOS] CoreLocation - CLGeocoder), 我々は、より多くの情報をここで見つけました https://velog.io/@inwoodev/iOS-CoreLocation-CLGeocoderテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol