#iOS10で位置情報を取得するには
ヘルス系のアプリでは現在位置情報、マップ系のアプリではどこかしらの位置情報を取得して周辺地図を表示したいことがあります。
現在位置を取得する方法・概要を記しておきます。(自分のために)
Swiftの基本的な文法や記述に関して、詳しく知りたい方は「10歳になったらプログラミングをはじめよう(iBooks Storeでみる)」を参考にしていただければと思います。
Xcodeの基本的な使い方に関しては「Hello, world. Swift3(iBooks Storeでみる)」を参考にしてください。
##プロジェクトの概要
ビルド後、コンソールに位置情報(緯度:latitude, 経度:longitude)を出力する。
(Xcodeの機能を使って、シミュレータGPSが取得する位置データをシミュレートさせます)
##動作環境
Xcode8.1
iOS10.1
Swift3.0.1
##知っておくこと
###CoreLocationフレームワーク
iOS SDKには位置情報関連の機能がパッケージされたCoreLocation フレームワーク
があります。import
するとCoreLocation
の機能がファイル内で使えるようになります。
プロジェクトナビゲータのLinked Frameworks And Libraries
に、CoreLocation
を追加しておきましょう。
###プライバシー情報の取得について
iOSアプリでは、ユーザの位置や連絡先、ヘルスなどプライバシーに関わる情報を取得する前に、ユーザから許可を得る必要があります。
許可を得るためには、Info.plist
にその告知文を追加する必要があります。
Key: Location When In Use Usage Description
Value: 任意の文字列
(「このアプリは位置情報を取得します」的な内容)
###権限リクエストの種類
アプリがユーザから得られる認証にはいくつかの種類があります。
####authorizedAlways
常に許可する。
####authorizedWhenInUse
使用中だけ許可する。
####denied
許可しない。
##手順
大まかな流れは、以下のようになります。
1.フレームワークをインポート、マネージャ初期化
2.権限をリクエスト
3.マネージャの設定
4.プロトコルを採用して、デリゲートメソッドを実装
###1. フレームワークのインポートとマネージャ初期化
CoreLocationフレームワークをインポートします。
import CoreLocation
位置情報の機能を管理する'CLLocationManager'クラスのインスタンスlocationManager
をViewController
クラスのメンバプロパティとして宣言しておきます。
locationManager
オブジェクトの初期化は、setupLocationManager()
メソッドを定義して行なっています。
class ViewController: UIViewController {
var locationManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
setupLocationManager()
}
func setupLocationManager() {
locationManager = CLLocationManager()
}
}
###2. 権限をリクエスト
ユーザに対して、位置情報を取得する許可をリクエストします。
setupLocationManager()
メソッド内で実装します。
今回は「アプリ使用中のみ許可を得る」ことにするので、インスタンスメソッドrequestWhenInUseAuthorization()
を使います。
ただし、locationManager
オブジェクトが初期化に成功している場合のみ許可をリクエストします。
class ViewController: UIViewController {
var locationManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
setupLocationManager()
}
func setupLocationManager() {
locationManager = CLLocationManager()
guard let locationManager = locationManager else { return }
locationManager.requestWhenInUseAuthorization()
}
}
###3. マネージャの設定
ユーザから「アプリ使用中の位置情報取得」の許可が得られた場合のみ、マネージャの設定を行います。
管理マネージャが位置情報を更新するペースをdistanceFilter
プロパティにメートル単位で設定します。
startUpdatingLocation()
メソッドで、位置情報の取得を開始しています。
class ViewController: UIViewController {
var locationManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
setupLocationManager()
}
func setupLocationManager() {
locationManager = CLLocationManager()
guard let locationManager = locationManager else { return }
locationManager.requestWhenInUseAuthorization()
let status = CLLocationManager.authorizationStatus()
if status == .authorizedWhenInUse {
locationManager.distanceFilter = 10
locationManager.startUpdatingLocation()
}
}
}
###4. プロトコル採用とデリゲートメソッド実装
ViewController
クラスにCLLocationManagerDelegate
プロトコルを採用します。
setupLocationManager()
メソッド内で、許可ステータスが.authorizedWhenInUse
の場合にViewController
クラスが管理マネージャのデリゲート先になるようにします。
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
setupLocationManager()
}
func setupLocationManager() {
locationManager = CLLocationManager()
guard let locationManager = locationManager else { return }
locationManager.requestWhenInUseAuthorization()
let status = CLLocationManager.authorizationStatus()
if status == .authorizedWhenInUse {
locationManager.delegate = self
locationManager.distanceFilter = 10
locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.first
let latitude = location?.coordinate.latitude
let longitude = location?.coordinate.longitude
print("latitude: \(latitude!)\nlongitude: \(longitude!)")
}
}
locationManager(_: didUpdateLocations:)
デリゲートメソッドは、位置情報を取得・更新するたびに呼ばれます。
##ビルド
忘れずにInfo.plist
に宣言文のKey:Valueセットを追加しておいてください。
また、プロジェクトナビゲータのLinked Frameworks And Libraries
にCoreLocation
を追加していないと、位置情報は取得できません。
シミュレータで位置情報を取得するには、エディタエリア下部のボタンからシミュレートできます。
ロケーションを変更するたびに、コンソールに経度・緯度が出力されます。