複数の CLLocationManager を使う

Swift 4.2.1
Deployment Target: 9.0

CoreLocation で位置情報を取得する際に、複数のCLLocationManagerインスタンスを同時に立ち上げて動かしたときにどうなるか気になったので試してみた。
結論としては、それぞれのインスタンスが影響し合うことなく別々に制御(startやstop) できた。

以下検証コード。

import UIKit
import CoreLocation

class ViewController: UIViewController {

    private let locationServiceA = LocationService.init(tag: "A")
    private let locationServiceB = LocationService.init(tag: "B")
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func handleStartButtonA(_ sender: UIButton) {
        locationServiceA.startUpdating()
    }
    @IBAction func handleStartButtonB(_ sender: UIButton) {
        locationServiceB.startUpdating()
    }
    @IBAction func handleStopButtonA(_ sender: UIButton) {
        locationServiceA.stopUpdating()
    }
    @IBAction func handleStopButtonB(_ sender: UIButton) {
        locationServiceB.stopUpdating()
    }
}

class LocationService: NSObject {
    private let locationManager = CLLocationManager()
    private var tag = ""
    
    override init() {
        super.init()
        locationManager.delegate = self
    }
    
    convenience init(tag: String) {
        self.init()
        self.tag = tag
    }
    
    func startUpdating() {
        print("tag:\(tag) startUpdating")
        locationManager.startUpdatingLocation()
    }
    
    func stopUpdating() {
        print("tag:\(tag) stopUpdating")
        locationManager.stopUpdatingLocation()
    }
    
    func checkPermisson() {
        switch CLLocationManager.authorizationStatus() {
        case .notDetermined:
            print("notDetermined")
        case .restricted:
            print("restricted")
        case .denied:
            print("denied")
        case .authorizedAlways:
            print("authorizedAlways")
        case .authorizedWhenInUse:
            print("authorizedWhenInUse")
        }
    }
}

extension LocationService: CLLocationManagerDelegate {
    
    //  このメソッドは locationManager.delegate = self を実行したタイミングでまず1回呼ばれる
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        print("tag:\(tag) didChangeAuthorization -> ", status.rawValue)
        if status == .notDetermined {
            locationManager.requestWhenInUseAuthorization()
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        if let location = locations.last {
            let latitude = location.coordinate.latitude
            let longitude = location.coordinate.longitude
            let timestamp = location.timestamp.description
            print("tag:\(tag) didUpdateLocations -> latitude:\(latitude) longitude:\(longitude) timestamp:\(timestamp)")
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("tag:\(tag) didFailWithError -> ", error)
    }
}

Info.plist に以下追加

アプリ使用時のみ位置情報を取得する場合

<key>NSLocationWhenInUseUsageDescription</key>
<string>位置情報を確認するために利用します。</string>

常に位置情報を取得する場合

<key>NSLocationAlwaysUsageDescription</key>
<string>位置情報を確認するために利用します。</string>