【Swift】端末の位置情報を利用するための準備。(Swift 2.1、XCode 7.2)
GPSを内蔵している端末は位置情報を利用できる
GPSを内蔵しているiPhoneやiPadがあれば、ソースコードで端末の位置情報を利用することができる。目的地以外でピンを刺したい場所といえば現在地だ。
そこで、本記事では、端末の位置情報を利用するための準備について説明する。
位置情報を利用するための準備
位置情報を利用するには、プロジェクト内で共通に使うプロパティリスト(info.plist)にプロパティを追加しておく必要がある。
下図赤枠のinfo.plistをクリックしてプロパティ一覧を表示する。一覧にマウスカーソルを持っていくと下図黄緑枠の「+」ボタンが表示されるので押す(どこの行の「+」ボタンでも良い)。
そして、以下の2つのいずれか、または両方の設定を追加する。1つ目はアプリを使っているときのみ位置情報を利用する場合に設定し、2つ目はアプリがバックグラウンドの状態でも位置情報を利用し続ける場合に設定する。
Key | Type | Value | |
---|---|---|---|
1 | NSLocationWhenInUseUsageDescription | String | 理由(例、端末の位置を常に地図に表示するために位置情報を利用します。) |
2 | NSLocationAlwaysUsageDescription | String | 理由(例、端末の位置を常に地図に表示するために位置情報を利用します。) |
位置情報サービスのON、OFFを確認する
アプリが端末の位置情報を取得するには、位置情報サービスがONになっていて、かつ、位置情報の利用をユーザーに許可してもらう必要がある。
位置情報サービスのON、OFFは、設定⇒「プライバシー」⇒「位置情報サービス」で確認できる。スイッチをONにすると位置情報サービスを利用すことになり、スイッチをOFFにするとすべてのアプリが位置情報を利用できなくなる。
ソースコードから位置情報サービスのON、OFFを確認するには以下のメソッドを呼び出す。trueの場合は利用可能、falseの場合は利用不可。
1 2 3 |
//位置情報サービスが利用できるかを確認 CLLocationManager.locationServicesEnabled() |
アプリインストール後の初回起動で、位置情報を使おうとしたときに位置情報サービスがOFFだった場合、下図のような、設定変更を促す画面が表示される。ただし、二回目以降は表示されない。
位置情報の利用許可を確認する
アプリ個別の位置情報の利用許可状況を確認するには、「設定」⇒「プライバシー」⇒「位置情報サービス」⇒アプリ名で確認する。先ほどinfo.plistに追加した項目がここに表示される。下図は「常に許可」に設定されている。
ソースコードからこの設定を確認するには以下のメソッドを呼び出す。設定状況に応じで5つのステータスのいずれかが戻ってくる。
1 2 |
CLLocationManager.authorizationStatus() |
下表は5つのステータスと設定内容。
ステータス | 説明 | |
---|---|---|
1 | CLAuthorizationStatus.NotDetermined | まだ設定していない。 |
2 | CLAuthorizationStatus.Restricted | 「設定」⇒「一般」⇒「機能制限」で、位置情報サービスの利用が制限されている。 |
3 | CLAuthorizationStatus.Denied | 「許可しない」に設定されている。 |
4 | CLAuthorizationStatus.AuthorizedWhenInUse | 「このAppの使用中のみ許可」に設定されている。 |
5 | CLAuthorizationStatus.AuthorizedAlways | 「常に許可」に設定されている。 |
ステータスがCLAuthorizationStatus.NotDetermined(未設定)のときに以下のメソッドを呼び出すと、設定を変更する画面をポップアップ表示することができる。(testManagerはCLLocationManagerクラスのインスタンス)
1 2 3 4 5 6 |
//「このAppの使用中のみ許可」に変更する画面をポップアップ表示する。 testManager.requestWhenInUseAuthorization() //「常に許可」に変更する画面をポップアップ表示する testManager.requestAlwaysAuthorization() |
下図はrequestWhenInUseAuthorizationメソッドを呼んだ結果。
下図はrequestAlwaysAuthorizationメソッドを呼んだ結果。このメッセージを呼んだユーザーは、アプリが停止しても位置情報が取得され続けると誤解してしまいそうだ。
一方、ステータスがCLAuthorizationStatus.NotDetermined(未設定)以外のときに上記のメソッドを呼んでも何も表示されない。これは、設定したにも関わらずアプリを起動するたびに許可を促されるのを防止するためと考えられる。
しかし、「許可しない」や「機能制限」で位置情報が取得できないままだとアプリとして成り立たない場合は、起動するたびに設定変更を促すしかない。
そこで、位置情報サービスのON、OFFと利用許可のステータスに応じて、以下のコードのように処理を分けるのが良い。
ちなみにViewDidLoadメソッドのプロセスからpresentViewControllerメソッドを呼び出すとエラーが発生するので、画面が表示された直後に呼び出されるviewDidAppearメソッドの中で処理を記述している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
// // ViewController.swift // import UIKit import CoreLocation class ViewController: UIViewController,CLLocationManagerDelegate { var testManager:CLLocationManager! //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() testManager = CLLocationManager() } //画面表示後の呼び出しメソッド override func viewDidAppear(animated: Bool) { if(CLLocationManager.locationServicesEnabled() == true){ switch CLLocationManager.authorizationStatus() { //未設定の場合 case CLAuthorizationStatus.NotDetermined: testManager.requestWhenInUseAuthorization() //機能制限されている場合 case CLAuthorizationStatus.Restricted: alertMessage("位置情報サービスの利用が制限されている利用できません。「設定」⇒「一般」⇒「機能制限」") //「許可しない」に設定されている場合 case CLAuthorizationStatus.Denied: alertMessage("位置情報の利用が許可されていないため利用できません。「設定」⇒「プライバシー」⇒「位置情報サービス」⇒「アプリ名」") //「このAppの使用中のみ許可」に設定されている場合 case CLAuthorizationStatus.AuthorizedWhenInUse: //位置情報の取得を開始する。 testManager.startUpdatingLocation() //「常に許可」に設定されている場合 case CLAuthorizationStatus.AuthorizedAlways: //位置情報の取得を開始する。 testManager.startUpdatingLocation() } } else { //位置情報サービスがOFFの場合 alertMessage("位置情報サービスがONになっていないため利用できません。「設定」⇒「プライバシー」⇒「位置情報サービス」") } } //メッセージ出力メソッド func alertMessage(message:String) { let aleartController = UIAlertController(title: "注意", message: message, preferredStyle: .Alert) let defaultAction = UIAlertAction(title:"OK", style: .Default, handler:nil) aleartController.addAction(defaultAction) presentViewController(aleartController, animated:true, completion:nil) } } |
次回記事は、位置情報サービスを利用して地図上の現在位置にピンを刺す方法を説明する。