10
9

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 1 year has passed since last update.

【iOS】位置情報を取得するCLLocationManagerの基本知識

Posted at

位置情報の取得

iOS14で位置情報を取得する
iOSアプリで位置情報を取得するときに配慮する点をまとめてみた①
Adding Location Services to Your App

デバイスが対応しているかを確認

位置情報サービスをアプリで利用する場合は、アプリを使用するデバイスが対応しているか確認する必要がある。

メソッド 概要
significantLocationChangeMonitoringAvailable() 位置情報が大きく変化した場合に、位置情報が更新できるかどうか
isMonitoringAvailable(for:) 現在地が位置情報を取得できる地点かどうか
headingAvailable() 進行方向を追跡できるかどうか
isRangingAvailable() iBeaconに対応しているかどうか

位置情報サービスが利用できない場合のエラーハンドリング

また、デバイスで位置情報サービスが利用できない場合に送出されるエラーをハンドリングするため、
CLLocationManagerDelegateで定義されたlocationManager(_:didFailWithError:)を実装するのが望ましい。

ユーザに位置情報サービスの認証を求める

Choosing the Location Services Authorization to Request

位置情報サービスの認証状態はアプリの使用中のみ常時の2つがあり、それぞれ以下のタイミングで位置情報サービスの利用が可能となる。

認証状態 利用可能タイミング
アプリの使用中のみ フォアグラウンドで実行中の場合
バックグラウンドで実行中 かつ 位置情報インジケータが有効である場合
常時 -

ただし、プライバシーや電力消費量などの点で、位置情報サービスの利用はなるべくアプリの使用中のみに限定するのが望ましい。

位置情報サービスの利用とイベントの受信

クラス・プロトコル メソッド 概要
CLLocationManager startUpdatingLocation() 位置情報サービスの開始
CLLocationManagerDelegate locationManagerDidChangeAuthorization(_:) 位置情報サービスの認証状態が変化
CLLocationManagerDelegate locationManager(_:didUpdateLocations:) 位置情報が変化
CLLocationManagerDelegate locationManager(_:didUpdateHeading:) 進行方向が変化
CLLocationManager requestLocation() 現在地の取得
CLLocationManager stopUpdatingLocation() 位置情報サービスの終了

CLLocationManager

CLLocationManager

位置情報を扱うCore Locationサービスの開始と停止・設定を行う場合はCLLocationManagerを利用する。

CLLocationManagerは非同期で動作するTaskを実行するため、ローカル変数ではなく強参照のプロパティとしてアプリ内に保管しておく必要がある。

また、CLLocationManagerの初期化時にCLLocationManagerDelegateで抽象的に定義されたlocationManagerDidChangeAuthorization(_:)メソッドを呼び出すため、
CLLocationManagerDelegateプロトコルの実装クラスに対して、CLLocationManagerインスタンスのdelegateプロパティをセットする必要がある。

class ViewController: UIViewController {
  // CLLocationManagerは非同期処理を行うため、強参照のプロパティとしてアプリ内で保管させる
  var locationManager: CLLocationManager?
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    locationManager = CLLocationManager()
    
    // CLLocationManagerがCLLocationManagerDelegateプロトコルの抽象メソッドを実行するときは、
    // CLLocationManagerDelegateプロトコルの実装クラスであるViewControllerに実行してもらう
    locationManager!.delegate = self
    
    // アプリの使用中のみ位置情報サービスの利用許可を求める
    locationManager!.requestWhenInUseAuthorization()
  }
}

// Delegateプロトコルの抽象メソッドを実装
// → ここで具体的な処理が実装される
extension ViewController: CLLocationManagerDelegate {
  func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
    // 位置情報サービスの認証情報が変更された場合に実行する処理
  }
}

位置情報の取得に関する設定

[iOS14]WWDC 2020 Core Location 新要素 Preciseについて
位置情報を正確にトラッキングする技術 in iOS — (第3回) バックグランドでのトラッキング、精度、バッテリー消費

CLLocationManagerstartUpdatingLocation()requestLocation()で位置情報を取得する前に、
CLLocationManagerの位置情報の取得タイミングや取得精度などを定義する各プロパティに値をセットする。

プロパティ 概要
accuracyAuthorization CLAccuracyAuthorization ユーザの承認によって決まる位置情報の取得精度
pausesLocationUpdatesAutomatically Bool 位置情報が変化していない場合(※activityTypeを参照)に、位置情報の更新を一時停止するかどうか
allowsBackgroundLocationUpdates Bool バックグラウンドでの位置情報の更新を行うかどうか
showsBackgroundLocationIndicator Bool バックグラウンドで位置情報の取得を行っている場合に、インジケータを表示するかどうか
activityType CLActivityType 位置情報が変化しているかどうかを識別するためのユーザのアクティビティ情報
distanceFilter CLLocationDistance 位置情報の取得間隔(距離)
desiredAccuracy CLLocationAccuracy 位置情報の取得精度
headingFilter CLLocationDegrees 進行方向の取得間隔(角度)
headingOrientation CLDeviceOrientation 進行方向を決定する際の画面の向き

Delegateパターン

【Swift入門】難解なデリゲート(delegate)の使い方を理解しよう!

// Delegateプロトコル … 担当範囲のメソッドを抽象的に定義
protocol AttackDelegate {
  // 攻撃するだけ(防御や回避は担当範囲外)
  func attack()
}

// 依頼者 … 戦闘を行うが、どんな攻撃をするかは未定
class Fighter {
  // 攻撃方法は後から自由に変更可能
  var atkDelegate: AttackDelegate?
  
  // 戦う
  func fight() {
    // 攻撃方法が決まっている場合は攻撃
    if let delegate = self.delegate {
      delegate.attack()
    }
  }
}

// 実行者 … 攻撃方法を決める(攻撃専門で、防御や回避は担当範囲外)
class Boxer: AttackDelegate {
  // 攻撃方法を決める
  func attack() {
    print("パンチ")
  }
}

// ↓↓↓

let fighter = Fighter()       // Fighterをインスタンス化
let boxer = Boxer()           // Boxerをインスタンス化
fighter.atkDelegate = boxer   // 攻撃をBoxerに委譲
fighter.fight()               // Boxerにパンチしてもらう
10
9
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
10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?