77974


[前回のコメントの続き](https://ja.stackoverflow.com/questions/77953/cllocationmanager%e3%81%ae%e4%bd%bf%e3%81%84%e6%96%b9%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6)

前回の質問で、CLLocationManagerクラスを使った質問を行いました。  
その際、チャイカ様に質問に答えて頂きましたが、疑問を生じました。

[code]

    class LocationService: NSObject,CLLocationManagerDelegate {
        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)
        }
    }
    
    
[/code]

以上のコードで、必ずCLLocationManager型のインスタンスを持つプロパティを生成し、init関数が行われても削除されないためにと、CLLocationManagerクラスが持つdelegateプロパティをセットするためには、CLLocationManager型のインスタンスを生成しないといけないことを理解しました。  
その際、delegateプロパティで指定するselfは、LocationServiceを指しており、これはCLLocationManagerDelegateプロトコルを継承しており、delegateの呼び出し先を自身に設定していることと認識致しました。LocationServiceクラスには、delegate機能の位置情報を取得した際のような具体的な処理が書かれていると認識しています。

その際、チャイカ様のコメントで、  
「ではLocationServiceクラスは何のためにあるの？という話になりませんか？」という質問を頂きました。  
自分では、このLocationServiceクラスを他のクラスやメソッド、構造体から呼び、

[code]

    var locationManager = LocationService()
    
[/code]

のように、任意の場所で位置情報を取得するメソッドとしてこのクラスを定義していると認識しています。  
ご意見やご教授よろしくお願い致します。


CC BY-SA 4.0
2021-07-04T11:43:00.717
77964
2021-07-04T19:26:52.827
47147
question
swift delegate
Delegateの際の、呼び出し元クラスの意味とは？


その認識でほぼ間違い無いと思います。  
前回の質問のコメントでは、`LocationService`に`CLLocationManagerDelegate`プロトコルをサポートした別クラスのインスタンスもプロパティに持ちたいという意図を感じました。  
そうすると、クラス設計は

[code]

    class LocationDelegates: CLLocationManagerDelegate {
        func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
            // 中略
        }
    
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            // 中略
        }
    
        func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
            // 中略
        }
    }
    
[/code]

と、`CLLocationManagerDelegate`から委譲される処理を担うクラスと

[code]

    class LocationService: NSObject {
        private let locationManager = CLLocationManager()
        private let locationDelegates: LocationDelegates = LocationDelegates()
    
        override init() {
            super.init()
            locationManager.delegate = locationDelegates
        }
        // 以下略
    }
    
[/code]

と、`Core Location`をハンドリングするだけのクラスの２つのクラスの様になり、クラスが一つ増えてしまい、管理や分割の手間が増えます。  
これでは、`LocationService`クラスが無駄だよね？と言いたかったわけですが、今回の質問のコードで必要な内容を理解されていることが解りましたので「`LocationService`クラスは何のためにあるの？」という質問に関しては理解しておられるようなので解決済みとさせてください。

もちろん、`Delegates`を複数のインスタンスから呼ばせたいが処理は共通で問題無い時には本回答のように管理・保持クラスと`Delegate`を担うクラスを分けた方がトータルでのコード量が少なくなる場合もありますが、そういうケースはレアケースだと思って下さい。


CC BY-SA 4.0
2021-07-04T19:21:23.930
77974
2021-07-04T19:26:52.827
2021-07-04T19:26:52.827
14745
14745
77964
answer