前回の続き↓
iOSアプリで位置情報を取得するときに配慮する点をまとめてみた②
#はじめに
iOSアプリで位置情報を取得するときに配慮する点をまとめた内容となっています。
#前回までのあらすじ
前回、アプリの位置情報サービスの有無
をバックグラウンド状態
から戻った時も
チェックをしなければいけないと書きました。
アプリがバックグラウンド状態
から戻った時にある処理をするにはAppDelegate
のapplicationWillEnterForeground(_ application: UIApplication)
で処理するんでしたね。
そして、アラートを表示したいのでViewController内で処理するためにNotificationCenter
を使いました。
#バックグラウンド状態から戻ったときにチェックする(アプリ)
では、実際にコードを書いてみます。
※長くなるので前回のソースコードから一部抜粋
今回も、アラートの表示はこの方法を用います↓
UIAlertControllerをファイルを分けて実装してみる
import UIKit
import CoreLocation
final class ViewController: UIViewController {
private var locationManager: CLLocationManager = {
var locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
locationManager.distanceFilter = 5
return locationManager
}()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
}
// バックグラウンド状態から戻ってきた時に呼ばれるメソッド(自分で作る)
@objc private func willEnterForeground() {
// 端末の位置情報サービスがオンの場合
if CLLocationManager.locationServicesEnabled() {
// 位置情報サービスの認証ステータスを取得
let status = CLLocationManager.authorizationStatus()
switch status {
// 許可しない場合
case .denied:
// アラート表示
Alert.okAlert(vc: self, title: "アプリの位置情報サービスを\nオンにして下さい", message: "OKをタップすると設定アプリに移動します") { (_) in
// 設定アプリに画面遷移する
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
}
default:
break
}
}
// 端末の位置情報サービスがオフの場合
}else {
// アラート表示
Alert.okAlert(vc: self, title: "位置情報サービスを\nオンにして下さい", message: "「設定」アプリ ⇒「プライバシー」⇒「位置情報サービス」からオンにできます")
}
}
端末の位置情報サービスがオンかオフかを分岐して
オン
の場合にアプリの位置情報サービスの有無
をチェックしています。
ビルドしてみると、ちゃんとチェックされてますね↓
※バグ?のせいなのか、たまに位置情報サービスの認証ステータスが次回確認
になっていますが
本来はなし
になります。
因みに、この部分は.denied
だけのケースのみでOKです。
理由は認証ステータスが変更されればデリゲートメソッド
が呼ばれますし、設定アプリ
に画面遷移するのは.denied
の場合のみで、その時に何もしないで戻った場合をチェックしたいので他の認証ステータスの記述は必要ないです。
ここで、一旦、全体のソースコードを見てみましょう。
import UIKit
import CoreLocation
final class ViewController: UIViewController {
private var locationManager: CLLocationManager = {
var locationManager = CLLocationManager()
locationManager.distanceFilter = 5
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
return locationManager
}()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.requestWhenInUseAuthorization()
locationManager.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
}
@objc private func willEnterForeground() {
if CLLocationManager.locationServicesEnabled() {
let status = CLLocationManager.authorizationStatus()
switch status {
case .denied:
Alert.okAlert(vc: self, title: "アプリの位置情報サービスを\nオンにして下さい", message: "OKをタップすると設定アプリに移動します") { (_) in
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
}
default:
break
}
}else {
Alert.okAlert(vc: self, title: "位置情報サービスを\nオンにして下さい", message: "「設定」アプリ ⇒「プライバシー」⇒「位置情報サービス」からオンにできます")
}
}
}
extension ViewController: CLLocationManagerDelegate {
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
if CLLocationManager.locationServicesEnabled() {
let status = manager.authorizationStatus
switch status {
case .authorizedAlways, .authorizedWhenInUse:
manager.startUpdatingLocation()
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .denied:
Alert.okAlert(vc: self, title: "アプリの位置情報サービスを\nオンにして下さい", message: "OKをタップすると設定アプリに移動します") { (_) in
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
}
case .restricted:
break
default:
break
}
}else {
Alert.okAlert(vc: self, title: "位置情報サービスを\nオンにして下さい", message: "「設定」アプリ ⇒「プライバシー」⇒「位置情報サービス」からオンにできます")
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let gps = manager.location?.coordinate else {
return
}
manager.stopUpdatingLocation()
let lat = gps.latitude
let lng = gps.longitude
print("経度:\(String(describing: lat)), 緯度:\(String(describing: lng))")
}
}
import UIKit
final class Alert {
static func okAlert(vc: UIViewController,title: String, message: String, handler: ((UIAlertAction) -> Void)? = nil) {
let okAlertVC = UIAlertController(title: title, message: message, preferredStyle: .alert)
okAlertVC.addAction(UIAlertAction(title: "OK", style: .default, handler: handler))
vc.present(okAlertVC, animated: true, completion: nil)
}
}
端末・アプリの位置情報サービスの有無
や、変更された認証ステータスの処理
等ここまで
色んな所に配慮してきました。
後は、お気づきの方がいらっしゃると思いますが
認証ステータスが.restricted
の場合は何もしていませんね。
ここは、Appleのドキュメントを見てみるとペアレンタルコントロール
などの何らかの制限があるために
ユーザーが認証ステータスを変更できない状態
に呼ばれる認証ステータスとなっています↓
CLAuthorization Status .restricted
ずっとbreak
にしていましたが、アラートなどでユーザーに伝えたほうがいいので改修しときましょう。
case .restricted:
Alert.okAlert(vc: self, title: "位置情報サービスの使用を\n許可されていません", message: "何らかの制限が掛かっています")
#iOS14以外のバージョン対応
現状、iOS14
以降を想定して位置情報の取得をしてきましたが
iOS14以外のバージョンでも位置情報を取得したい場合が開発していると出てくると思います。
その場合、使用するメソッドが違ったり、Appleが非推奨にしているコード等も登場して
多少、複雑になってきます。
では、実際にアプリのバージョンを下げてみて実装していきましょう。
私はこちらの記事を拝見して、iOSのバージョンを下げましたので参考にしてみて下さい↓
世界一詳細に全部日本語でXcode11で作った新規プロジェクトをiOS12以前で実行できるところまで解説する
#推奨・非推奨コード
では、これでiOS11 ~ iOS14に対応するアプリとなりました。
実装する前にAppleが推奨・非推奨しているコード
を紹介していきます。
※私の記事に関係があるコードだけを紹介しますのでご了承ください。
// CLLocationManagerクラスのインスタンス初期化および、認証ステータスが変更されたら呼ばれるデリゲートメソッド
// 推奨していない iOS 4.2–14.0
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus)
// 推奨している iOS14-
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager)
// 位置情報の認証ステータス取得
// 推奨していない iOS 4.2–14.0
func authorizationStatus() -> CLAuthorizationStatus
// 推奨している iOS14-
var authorizationStatus: CLAuthorizationStatus
こんな感じに変更されています。
後は、iOS14から正確な位置精度
という項目が新たに追加されました。
簡単に言うと、位置情報の精度を正確にするか曖昧にするかを自分で選択できるようになったんですね。
下記のコードのように、選択肢によって分岐することができます↓
switch locationManager.accuracyAuthorization {
// 正確な位置情報を取得した場合
case .fullAccuracy:
// 曖昧な位置情報を取得した場合
case .reducedAccuracy:
default:
break
}
ここは開発するアプリによって変わってきますので、よく吟味した方が良い部分ですね。
こちらの記事が詳しく書いていますので参考にしてみて下さい↓
iOS14でのCore Location変更点
iOS 14 でさらに強化された位置情報まわりのプライバシー
※今回は、位置情報の取得で配慮する点をまとめた記事なので
あまり正確かどうかは関係ないので紹介だけに留めておきます。
注目してほしい部分は、最初の方で説明した推奨・非推奨のコードです。
iOS14以前のバージョンに対応させるには非推奨のコード
も使用しなければいけません。
では早速、実装していきます。
#iOS14以前のバージョンに対応した場合の実装
※長いので一部抜粋
import UIKit
import CoreLocation
final class ViewController: UIViewController {
private var locationManager: CLLocationManager = {
var locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
locationManager.distanceFilter = 5
return locationManager
}()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.requestWhenInUseAuthorization()
locationManager.delegate = self
}
}
// 推奨しているデリゲートメソッド
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
// iOS14以降の場合
if #available(iOS 14.0, *) {
if CLLocationManager.locationServicesEnabled() {
let status = manager.authorizationStatus
switch status {
case .authorizedAlways, .authorizedWhenInUse:
manager.startUpdatingLocation()
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .denied:
Alert.okAlert(vc: self, title: "アプリの位置情報サービスを\nオンにして下さい", message: "OKをタップすると設定アプリに移動します") { (_) in
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
}
case .restricted:
Alert.okAlert(vc: self, title: "位置情報サービスの使用を\n許可されていません", message: "何らかの制限が掛かっています")
default:
break
}
}else {
Alert.okAlert(vc: self, title: "位置情報サービスを\nオンにして下さい", message: "「設定」アプリ ⇒「プライバシー」⇒「位置情報サービス」からオンにできます")
}
}
}
// 非推奨のデリゲートメソッド
//iOS14以前の場合
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if CLLocationManager.locationServicesEnabled() {
switch status {
case .authorizedAlways, .authorizedWhenInUse:
manager.startUpdatingLocation()
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .denied:
Alert.okAlert(vc: self, title: "アプリの位置情報サービスを\nオンにして下さい", message: "OKをタップすると設定アプリに移動します") { (_) in
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
}
case .restricted:
Alert.okAlert(vc: self, title: "位置情報サービスの使用を\n許可されていません", message: "")
default:
break
}
}else {
Alert.okAlert(vc: self, title: "位置情報サービスを\nオンにして下さい", message: "「設定」アプリ ⇒「プライバシー」⇒「位置情報サービス」からオンにできます")
}
}
こんな感じの実装となり、どちらも記述します。
メソッド内は、バージョンの指定以外、ほぼ変わらないですね。
これでiOS14以前のバージョン
に対応できました。
#エラー処理
どの場面でも大体、エラー処理というものは存在しますが、もちろんCLLocationManagerでも存在します。
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error)
では、どのようにViewController内で記述するのかというと、こんな感じです↓
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
//本来なら、アラートで画面にエラー内容を表示したりする
print("\((error as NSError).domain)")
}
このデリゲートメソッドはCLLocationManagerが位置情報を取得できなかった時
に呼ばれます。
このメソッドを実装していない場合、エラーをスルーしてしまうので要注意
です。
様々なエラーがあるので、見てみて下さい↓
CLError
そして、ここからは自分が苦戦した所を紹介します。
#苦戦した部分~認証ステータスの取得~
認証ステータスの取得も、先ほど紹介しましたが推奨・非推奨のコード
がありましたね。
ここが、かなり厄介?で現在進行形で悩んでいます...。
// 位置情報の認証ステータス取得
// 推奨していない iOS 4.2–14.0
func authorizationStatus() -> CLAuthorizationStatus
// 推奨している iOS14-
var authorizationStatus: CLAuthorizationStatus
まず、この2つのコードを比較すると
推奨していない方はメソッド
、推奨している方はプロパティ
となっています。
ここがまず、大きな違いですね。
そして、推奨していないfunc authorizationStatus()
メソッドは
アプリがバックグラウンド・フォアグラウンド状態
関係なく認証ステータスを返してくれますが
今回、iOS14で新しく登場したauthorizationStatus
プロパティの方は
フォアグラウンド状態
の時の認証ステータスしか返してくれません。
つまり、authorizationStatus
プロパティの方はバックグラウンド状態
で認証ステータスを変更した場合
フォアグラウンド状態
の時の認証ステータスを返すんですね。
じゃあ、この部分の一体どこで苦戦したのかというと
バックグラウンド状態
から戻ってきた時にアプリの位置情報サービスの有無
をチェックする部分です。
実際に分かりやすいようにコードで説明しますね。
認証ステータス
を取得する場合、今までだと下記の実装でした↓
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
}
// バックグラウンド状態から戻った時に呼ばれるメソッド
@objc private func willEnterForeground() {
if CLLocationManager.locationServicesEnabled() {
// 認証ステータスの取得(非推奨)
let status = CLLocationManager.authorizationStatus()
switch status {
// 許可しない場合
case .denied:
Alert.okAlert(vc: self, title: "アプリの位置情報サービスを\nオンにして下さい", message: "OKをタップすると設定アプリに移動します") { (_) in
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
}
default:
break
}
}else {
Alert.okAlert(vc: self, title: "位置情報サービスを\nオンにして下さい", message: "「設定」アプリ ⇒「プライバシー」⇒「位置情報サービス」からオンにできます")
}
}
}
では次に、推奨
しているコードでの実装↓
private var locationManager: CLLocationManager = {
var locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
locationManager.distanceFilter = 5
return locationManager
}()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
}
// バックグラウンド状態から戻った時に呼ばれるメソッド
@objc private func willEnterForeground() {
if CLLocationManager.locationServicesEnabled() {
// 認証ステータスの取得(推奨)
let status = locationManager.authorizationStatus
switch status {
// 許可しない場合
case .denied:
Alert.okAlert(vc: self, title: "アプリの位置情報サービスを\nオンにして下さい", message: "OKをタップすると設定アプリに移動します") { (_) in
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
}
default:
break
}
}else {
Alert.okAlert(vc: self, title: "位置情報サービスを\nオンにして下さい", message: "「設定」アプリ ⇒「プライバシー」⇒「位置情報サービス」からオンにできます")
}
}
}
さほど変化はないんですが、これをビルドしてみると違いが分かります。
まず、どちらも起動時
に認証ステータスが .denid
である場合はちゃんとアラートを表示します。
ですが、バックグラウンド状態
で .denid > .restrictedに変更してフォアグラウンド状態
に戻すとこうなります↓
本来、許可しない(.denid)
で表示されるアラートが
Appの使用中は許可(.authorizedWhenInUse)
でも表示されてしまいました。
この不具合が、発生してしまうので仕方なく非推奨のfunc authorizationStatus()
メソッド
を呼んでいる現状なんですね。
#authorizationStatusプロパティはどう使うんだろう?
色々、試行錯誤していきながら調べながら自分はこういう結論に至りました。
そもそも、iOS14で登場したauthorizationStatus
プロパティは
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager)
ありきで使用してこのメソッド内で使っていく。
じゃあ、そもそも非推奨のfunc authorizationStatus()
メソッドは使わなくても良いんじゃない?
そのメソッドはCLLocationManagerクラスの初期化及び、バックグラウンド・フォアグラウンド状態関係なく認証ステータスが変更されたら呼ばれる
デリゲートメソッドだし、willEnterForeground()
は必要ないのでは?↓
// バックグラウンド時に戻った時に呼ばれるメソッド
@objc private func willEnterForeground()
と思う方がいらっしゃると思います。
では、このような場面ではどうでしょうか?
例えば、ユーザーに対して位置情報の許可をリクエストして
アラートが表示され、許可しない
を選択したとします。
今までの流れからいくと、このようなアラートが表示されて設定アプリ
に画面遷移します。
これで、設定アプリに画面遷移したはいいけど何もしないで戻った時
に
func willEnterForeground()
を呼ばない場合どうでしょうか?
呼ばない場合は、何もチェックされません。
もちろん、認証ステータスが変更されていないので
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager)
も呼ばれません。
以上の理由からfunc willEnterForeground()
を使用していますし、
非推奨のfunc authorizationStatus()
メソッドも使用している現状なんですね。
この部分の改善方法を色々、調べたんですが最新の記事でも非推奨のfunc authorizationStatus()
メソッドを使用していて頭の中は???でいっぱいでした。
この解決方法をご存知の方は、コメントで教えて下さると有り難いです。
#おわり
という事で三部構成という長い記事になってしまいましたが、今回で完結です。
位置情報を取得するだけで、ここまで配慮しなくてはいけないというのはびっくりですね。
もしかしたら、ここは全然違うよー!という部分があるかもしれません。
そういう場合は遠慮なく、コメントして下さると有り難いです。
※おわりで言うのもなんですが、アラートのタイトルなどで何度も同じことを書くのは
マジックナンバー
扱いになってしまい駄目なのですが、これは後日、記事としてまとめて投稿します。
ここまでのソースコードは下記にて載せておきますので良かったら参考にしてみて下さい↓
最後まで読んで下さり、ありがとうございました。
#※追記
extentionファイル
を作って拡張すれば、ViewControllerのボリュームを抑えることも出来ます↓
import UIKit
import CoreLocation
extension CLLocationManager {
func alertStatusIfNeeded(vc: UIViewController) {
if #available(iOS 14.0, *) {
if CLLocationManager.locationServicesEnabled() {
let status = self.authorizationStatus
switch status {
case .notDetermined:
self.requestWhenInUseAuthorization()
case .restricted:
// アラート表示したり
case .denied:
// アラート表示したり
case .authorizedAlways:
self.startUpdatingLocation()
case .authorizedWhenInUse:
self.startUpdatingLocation()
default:
break
}
}else {
// アラート表示したり
}
}
}
func alertStatusIfNeededUnderiOSVer(vc: UIViewController) {
if CLLocationManager.locationServicesEnabled() {
let status = CLLocationManager.authorizationStatus()
switch status {
case .notDetermined:
self.requestWhenInUseAuthorization()
case .restricted:
// アラート表示したり
case .denied:
// アラート表示したり
case .authorizedAlways:
self.startUpdatingLocation()
case .authorizedWhenInUse:
self.startUpdatingLocation()
default:
break
}
}else {
// アラート表示したり
}
func alertStatusIfNeededBackground(vc: UIViewController) {
if !CLLocationManager.locationServicesEnabled() {
// アラート表示したり
return
}
let status = CLLocationManager.authorizationStatus()
if status == .denied {
// アラート表示したり
}
}
}
ViewControllerではこんな感じになります↓
※一部抜粋
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
manager.alertStatusIfNeeded(vc: self)
}
#ソースコード
こちらにもあげてます。
import UIKit
import CoreLocation
final class ViewController: UIViewController {
private var locationManager: CLLocationManager = {
var locationManager = CLLocationManager()
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
locationManager.distanceFilter = 5
return locationManager
}()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.requestWhenInUseAuthorization()
locationManager.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
}
@objc private func willEnterForeground() {
if CLLocationManager.locationServicesEnabled() {
let status = CLLocationManager.authorizationStatus()
switch status {
case .denied:
Alert.okAlert(vc: self, title: "アプリの位置情報サービスを\nオンにして下さい", message: "OKをタップすると設定アプリに移動します") { (_) in
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
}
default:
break
}
}else {
Alert.okAlert(vc: self, title: "位置情報サービスを\nオンにして下さい", message: "「設定」アプリ ⇒「プライバシー」⇒「位置情報サービス」からオンにできます")
}
}
}
extension ViewController: CLLocationManagerDelegate {
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
if #available(iOS 14.0, *) {
if CLLocationManager.locationServicesEnabled() {
let status = manager.authorizationStatus
switch status {
case .authorizedAlways, .authorizedWhenInUse:
manager.startUpdatingLocation()
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .denied:
Alert.okAlert(vc: self, title: "アプリの位置情報サービスを\nオンにして下さい", message: "OKをタップすると設定アプリに移動します") { (_) in
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
}
case .restricted:
Alert.okAlert(vc: self, title: "位置情報サービスの使用を\n許可されていません", message: "")
default:
break
}
}else {
Alert.okAlert(vc: self, title: "位置情報サービスを\nオンにして下さい", message: "「設定」アプリ ⇒「プライバシー」⇒「位置情報サービス」からオンにできます")
}
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if CLLocationManager.locationServicesEnabled() {
switch status {
case .authorizedAlways, .authorizedWhenInUse:
manager.startUpdatingLocation()
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .denied:
Alert.okAlert(vc: self, title: "アプリの位置情報サービスを\nオンにして下さい", message: "OKをタップすると設定アプリに移動します") { (_) in
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
}
case .restricted:
Alert.okAlert(vc: self, title: "位置情報サービスの使用を\n許可されていません", message: "")
default:
break
}
}else {
Alert.okAlert(vc: self, title: "位置情報サービスを\nオンにして下さい", message: "「設定」アプリ ⇒「プライバシー」⇒「位置情報サービス」からオンにできます")
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let gps = manager.location?.coordinate else {
return
}
manager.stopUpdatingLocation()
let lat = gps.latitude
let lng = gps.longitude
print("経度:\(String(describing: lat)), 緯度:\(String(describing: lng))")
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("\((error as NSError).domain)")
}
}
import UIKit
final class Alert {
static func okAlert(vc: UIViewController,title: String, message: String, handler: ((UIAlertAction) -> Void)? = nil) {
let okAlertVC = UIAlertController(title: title, message: message, preferredStyle: .alert)
okAlertVC.addAction(UIAlertAction(title: "OK", style: .default, handler: handler))
vc.present(okAlertVC, animated: true, completion: nil)
}
}