42
45

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[swift5]iOSアプリで位置情報取得機能を実装

Last updated at Posted at 2019-12-08

現在いる位置情報をラベルに反映するアプリの実装方法を紹介します!

ここでは、"常に位置情報を取得しない"実装にします。
"常に位置情報を取得する"ものについては別途記載します。(作成が完了したらここにリンクを追加します・・・)

##アプリの概要

デフォルト

緯度と経度を表示するラベルに「デフォルト」と表示されています。

default_location.png

位置情報を取得ボタン押下時

緯度と経度を表示するラベルに、位置情報が表示されます。
(画像は、シュミレータにて位置情報を東京に設定しています。)

tokyo_location.png

スクリーンショット 2019-12-08 19.31.22.png

クリアボタン押下時

緯度と経度を表示するラベルに「デフォルト」と表示されます。

clear_location.png

動作環境

対象 バージョン
iOS 13.3
macOS Catalina 10.15.2
Xcode 11.3.1
Swift 5.1.3

現在地を表示

Info.plistの修正

Info.plist に、「Privacy - Location When In Use Usage Discription」を追加してください。

###ファイル作成

  • Storyboard
    • ここでは、"Location.storyboard" とします
  • ViewController.swift
    • ここでは、"LocationViewController.swift" とします

画面を作成

ラベル4つとボタン2つを配置します。

default_location.png

画面とソースの紐付け

ラベル2つとボタン2つをソースコード上に紐付けします。

/// 緯度を表示するラベル
@IBOutlet weak var latitude: UILabel!
/// 経度を表示するラベル
@IBOutlet weak var longitude: UILabel!

/// "位置情報を取得"ボタンを押下した際、位置情報をラベルに反映する
/// - Parameter sender: "位置情報を取得"ボタン
@IBAction func getLocationInfo(_ sender: Any) {
}

/// "クリア"ボタンを押下した際、ラベルを初期化する
/// - Parameter sender: "クリア"ボタン
@IBAction func clearLabel(_ sender: Any) {
}

Core Location のインポート

import CoreLocation

マネージャの初期化

はじめに、フィールド変数として locationManager を定義します。

/// ロケーションマネージャ
var locationManager: CLLocationManager!

次に、ロケーションマネージャをセットアップするメソッドを実装します。

/// ロケーションマネージャのセットアップ
func setupLocationManager() {
    locationManager = CLLocationManager()
}

また、このメソッドを viewDidLoad で呼び出します。

override func viewDidLoad() {
    super.viewDidLoad()

    // ロケーションマネージャのセットアップ
    setupLocationManager()
}

位置情報取得許可ダイアログの表示

位置情報取得許可ダイアログを表示する処理を実装します。

dialog.png

ロケーションマネージャのセットアップするメソッド(本ページだと、setupLocationManager メソッド)の最後尾に以下の処理を実装します。

// 位置情報取得許可ダイアログの表示
guard let locationManager = locationManager else { return }
locationManager.requestWhenInUseAuthorization()

マネージャの設定

マネージャの設定を行います。
また、ユーザが「App使用中は許可」または「1度だけ許可」の許可を押下した場合のみ、位置情報取得を開始します。

ロケーションマネージャのセットアップするメソッド(本ページだと、setupLocationManager メソッド)の最後尾に以下の処理を実装します。

// マネージャの設定
let status = CLLocationManager.authorizationStatus()
// ステータスごとの処理
if status == .authorizedWhenInUse {
    locationManager.delegate = self
    // 位置情報取得を開始
    locationManager.startUpdatingLocation()
}

位置情報が更新されるたびに位置情報を取得

位置情報が更新されるたびに位置情報を取得するため、CLLocationManagerDelegate プロトコルを採用します。

はじめに、位置情報を格納する用のフィールド変数を実装します。

// 緯度
var latitudeNow: String = ""
// 経度
var longitudeNow: String = ""

次に、setupLocationManager()メソッド内で、ユーザが「App使用中は許可」または「1度だけ許可」の許可を押下した場合のみ locationViewController が管理マネージャのデリゲート先になるようにします。

// ステータスごとの処理
if status == .authorizedWhenInUse {
    locationManager.delegate = self // これを追加
    // 位置情報取得を開始
    locationManager.startUpdatingLocation()
}

次に、CLLocationManagerDelegate 用の extention を実装します。
また、その中に locationManager(_:didUpdateLocations:) メソッドを実装します。

extension LocationViewController: CLLocationManagerDelegate {
    /// 位置情報が更新された際、位置情報を格納する
    /// - Parameters:
    ///   - manager: ロケーションマネージャ
    ///   - locations: 位置情報
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    }
}

最後に、位置情報を取得するたびに位置情報を格納する用のフィールド変数にセットします。

extension LocationViewController: CLLocationManagerDelegate {

    /// 位置情報が更新された際、位置情報を格納する
    /// - Parameters:
    ///   - manager: ロケーションマネージャ
    ///   - locations: 位置情報
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location = locations.first
        let latitude = location?.coordinate.latitude
        let longitude = location?.coordinate.longitude
        // 位置情報を格納する
        self.latitudeNow = String(latitude!)
        self.longitudeNow = String(longitude!)
    }
}

ボタンを押下するたびに承認ステータスごとの処理

/// "位置情報を取得"ボタンを押下した際、位置情報をラベルに反映する
/// - Parameter sender: "位置情報を取得"ボタン
@IBAction func getLocationInfo(_ sender: Any) {
    // マネージャの設定
    let status = CLLocationManager.authorizationStatus()
    if status == .denied {
        showAlert()
    } else if status == .authorizedWhenInUse {
        self.latitude.text = latitudeNow
        self.longitude.text = longitudeNow
    }
}
/// アラートを表示する
func showAlert() {
    let alertTitle = "位置情報取得が許可されていません。"
    let alertMessage = "設定アプリの「プライバシー > 位置情報サービス」から変更してください。"
    let alert: UIAlertController = UIAlertController(
        title: alertTitle,
        message: alertMessage,
        preferredStyle:  UIAlertController.Style.alert
    )
    // OKボタン
    let defaultAction: UIAlertAction = UIAlertAction(
        title: "OK",
        style: UIAlertAction.Style.default,
        handler: nil
    )
    // UIAlertController に Action を追加
    alert.addAction(defaultAction)
    // Alertを表示
    present(alert, animated: true, completion: nil)
}

ボタンを押下するたびにラベルを初期化

/// "クリア"ボタンを押下した際、ラベルを初期化する
/// - Parameter sender: "クリア"ボタン
@IBAction func clearLabel(_ sender: Any) {
    self.latitude.text = "デフォルト"
    self.longitude.text = "デフォルト"
}

ソースコード


import UIKit
import CoreLocation

/// Location の View
class LocationViewController: UIViewController {

    /// 緯度を表示するラベル
    @IBOutlet weak var latitude: UILabel!
    /// 経度を表示するラベル
    @IBOutlet weak var longitude: UILabel!

    // 緯度
    var latitudeNow: String = ""
    // 経度
    var longitudeNow: String = ""

    /// ロケーションマネージャ
    var locationManager: CLLocationManager!

    override func viewDidLoad() {
        super.viewDidLoad()

        // ロケーションマネージャのセットアップ
        setupLocationManager()
    }

    /// "位置情報を取得"ボタンを押下した際、位置情報をラベルに反映する
    /// - Parameter sender: "位置情報を取得"ボタン
    @IBAction func getLocationInfo(_ sender: Any) {
        // マネージャの設定
        let status = CLLocationManager.authorizationStatus()
        if status == .denied {
            showAlert()
        } else if status == .authorizedWhenInUse {
            self.latitude.text = latitudeNow
            self.longitude.text = longitudeNow
        }
    }

    /// "クリア"ボタンを押下した際、ラベルを初期化する
    /// - Parameter sender: "クリア"ボタン
    @IBAction func clearLabel(_ sender: Any) {
        self.latitude.text = "デフォルト"
        self.longitude.text = "デフォルト"
    }


    /// ロケーションマネージャのセットアップ
    func setupLocationManager() {
        locationManager = CLLocationManager()

        // 権限をリクエスト
        guard let locationManager = locationManager else { return }
        locationManager.requestWhenInUseAuthorization()

        // マネージャの設定
        let status = CLLocationManager.authorizationStatus()

        // ステータスごとの処理
        if status == .authorizedWhenInUse {
            locationManager.delegate = self
            locationManager.startUpdatingLocation()
        }
    }

    /// アラートを表示する
    func showAlert() {
        let alertTitle = "位置情報取得が許可されていません。"
        let alertMessage = "設定アプリの「プライバシー > 位置情報サービス」から変更してください。"
        let alert: UIAlertController = UIAlertController(
            title: alertTitle,
            message: alertMessage,
            preferredStyle:  UIAlertController.Style.alert
        )
        // OKボタン
        let defaultAction: UIAlertAction = UIAlertAction(
            title: "OK",
            style: UIAlertAction.Style.default,
            handler: nil
        )
        // UIAlertController に Action を追加
        alert.addAction(defaultAction)
        // Alertを表示
        present(alert, animated: true, completion: nil)
    }
}

extension LocationViewController: CLLocationManagerDelegate {

    /// 位置情報が更新された際、位置情報を格納する
    /// - Parameters:
    ///   - manager: ロケーションマネージャ
    ///   - locations: 位置情報
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location = locations.first
        let latitude = location?.coordinate.latitude
        let longitude = location?.coordinate.longitude
        // 位置情報を格納する
        self.latitudeNow = String(latitude!)
        self.longitudeNow = String(longitude!)
    }
}
42
45
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
45

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?