|
|||||
|
対象: GPSから位置情報を取得する(Swift)iOSでGPSから現在位置を取得するために必要な事は概ね以下になる。
SwiftでGPSから位置情報を取得する場合も、必要なことは本質的にObjective-Cの場合と同じである。しかし、Swiftの場合CoreLocation.frameworkのリンクは不要で、かつコードもallocやらinitやらがない分Objective-Cよりも簡潔な印象を受ける。 まず、ViewController.swiftの冒頭でCoreLocationをimportする。 import UIKit import CoreLocation そして、CLLocationManager型のプロパティを、例えばlocationManagerという名前でViewControllerクラスに用意する。ViewControllerクラスでは、CLLocationManagerDelegateを継承する。これによって、locationManager:didUpdateLocationsデリゲートメソッドで位置情報を受け取ることができるようになる。
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationManager: CLLocationManager!
locationManager:didUpdateLocationsデリゲートメソッドをViewControllerクラスに追加する。ViewControllerクラスの空いているところでlocationの頭文字"l"を入力すると、locationManager等の候補が表示されるはずなので、didUpdateLocationsのものを選択すれば簡単に追加できるだろう。
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
}
viewDidLoadメソッドでCLLocationManagerのインスタンスを生成する。生成したインスタンスのdelegateプロパティにViewControllerクラス自身を割り当てる。最後にstartUpdatingLocationメソッドを呼び出して情報の更新を開始すれば、端末で位置情報を取得することができる。 コード全体を以下に示す。因みにlabelLatitude、labelLongitude、及びlabelTimeは、それぞれ緯度、経度、及び受信時刻を表示するためのLabelのReferencing outletである。
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationManager: CLLocationManager!
@IBOutlet weak var labelLatitude: UILabel!
@IBOutlet weak var labelLongitude: UILabel!
@IBOutlet weak var labelTime: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if locationManager == nil {
locationManager = CLLocationManager()
if #available(iOS 8.0, *) {
// NSLocationWhenInUseUsageDescriptionに設定したメッセージでユーザに確認
locationManager.requestWhenInUseAuthorization()
// NSLocationAlwaysAndWhenInUseUsageDescriptionに設定したメッセージでユーザに確認
//locationManager.requestAlwaysAuthorization()
}
}
locationManager.delegate = self
locationManager.startUpdatingLocation()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.last {
let latitude = String(format: "%+.06f", location.coordinate.latitude)
let longitude = String(format: "%+.06f", location.coordinate.longitude)
let df = DateFormatter()
df.dateFormat = "yyyy/MM/dd HH:mm:ss"
let timestamp = df.string(from: location.timestamp)
print("\(timestamp) \(latitude) \(longitude)")
labelLatitude.text = latitude
labelLongitude.text = longitude
labelTime.text = timestamp
}
}
}
locationManager:didUpdateLocationsデリゲートメソッドは位置情報の更新があったときに呼ばれる。locations引数はCLLocationの配列で、末尾が最新の位置情報であるので、これを取り出して緯度、及び経度を得ることができる。位置情報の更新間隔はdistanceFilterプロパティである程度制御できる。 尚、iOS 8以降(iOS 11以降については後述)の場合、以下が必要になることを改めて記載しておく。生成したロケーションマネージャでrequestWhenInUseAuthorizationメソッド、またはrequestAlwaysAuthorizationメソッドを呼び出し、ユーザから位置情報の利用について承認を得なければならない。
if #available(iOS 8.0, *) {
// NSLocationWhenInUseUsageDescriptionに設定したメッセージでユーザに確認
locationManager.requestWhenInUseAuthorization()
// NSLocationAlwaysUsageDescriptionに設定したメッセージでユーザに確認
//locationManager.requestAlwaysAuthorization()
}
これに先立って、2つのメソッドがそれぞれユーザに承認を得るときに利用するメッセージを予めInfo.plistで定義しておく必要がある。
作成したアプリを実行すると、以下のような確認メッセージが表示される。(iOS 11でアプリ実行)
尚、この設定は端末の[設定] > [アプリ名(恐らく下のほうで見つかる)] > [位置情報]で変更できる。(iOS 11でアプリ実行)
更に、iOS 11で若干の仕様変更があり、requestAlwaysAuthorizationするとコンソールに以下のようなメッセージが表示され、位置情報を得ることができなかった。iOS 11でrequestAlwaysAuthorizationするときには、Info.plistでNSLocationAlwaysAndWhenInUseUsageDescriptionとNSLocationWhenInUseUsageDescriptionの両方を定義しておかなければならない。iOS 11だけでなく、iOS 10以下にも対応する必要があるなら、NSLocationAlwaysUsageDescriptionも合わせて定義しておくと良い。 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
(2015/01/28) () iOS 11関連の修正。
Copyright© 2004-2019 モバイル開発系(K) All rights reserved.
[Home]
|
|||||