Swift создает класс с использованием делегата - PullRequest
1 голос
/ 22 марта 2019

Об этом можно где-то говорить, но я не могу найти ни одной статьи, в которой говорится об этом.Я пытаюсь написать класс, который обернут вокруг родного Apple CoreLocation API.Моя цель - иметь возможность вызывать что-то вроде LocationTrack.getDPS и получать эти координаты gps от делегата locationManager.

class LocationTrack: CLLocationManagerDelegate  {

    if (CLLocationManager.locationServicesEnabled())
            {
                locationManager = CLLocationManager()
                locationManager.delegate = self
                locationManager.desiredAccuracy = kCLLocationAccuracyBest
                locationManager.requestAlwaysAuthorization()
                locationManager.startUpdatingLocation()
            }
        }

  func getDPS(completion: @escaping (result: [CLLocation]) -> () {

       //How to get below delegate response into this function?

    }

  func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

      print(locations)

}


    }

1 Ответ

1 голос
/ 22 марта 2019

Определите свойство для захвата вашего обработчика завершения:

private var handler: (([CLLocation]) -> Void)?

И getDPS сохраните его и начните обновлять локации:

func getDPS(_ completion: @escaping ([CLLocation]) -> Void) {
    handler = completion
    locationManager.startUpdatingLocation()
}

И тогда ваш didUpdateLocations может вызвать это закрытие:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    handler?(locations)
    handler = nil
    locationManager.stopUpdatingLocation()
}

Собрав все это воедино, может быть что-то вроде:

class LocationTrack: NSObject {
    private lazy var locationManager: CLLocationManager = {
        let locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestAlwaysAuthorization()   // perhaps `requestWhenInUseAuthorization` is better?
        return locationManager
    }()

    private var handler: (([CLLocation]) -> Void)?

    func getDPS(_ completion: @escaping ([CLLocation]) -> Void) {
        handler = completion
        locationManager.startUpdatingLocation()
    }
}

extension LocationTrack: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        handler?(locations)
        handler = nil
        locationManager.stopUpdatingLocation()
    }
}

Ясно, что вы можете добавить свою собственную обработку ошибок и то, что у вас есть, но, надеюсь, это иллюстрирует идею сохранения замыкания в свойстве и вызова его при получении обратного вызова вашего делегата.

...