#swift #core-location
#swift #расположение ядра
Вопрос:
Об этом где-то можно было бы поговорить, но я не могу найти ни одной статьи, в которой говорится об этом. Я пытаюсь написать класс, который использует собственный API CoreLocation от Apple. Моя цель — иметь возможность вызывать что-то вроде 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. Почему бы вам не создать свойство для CLLocationManager?
Ответ №1:
Определите свойство для захвата вашего обработчика завершения:
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()
}
}
Очевидно, что вы можете добавить свою собственную обработку ошибок и все, что у вас есть, но, надеюсь, это иллюстрирует идею сохранения закрытия в свойстве и вызова его при получении обратного вызова делегата.
Комментарии:
1. Это здорово. Можете ли вы объяснить необходимость
NSObject
определения класса in и определенияlocationManager
aslazy
?2. @Nick — I подкласс,
NSObject
потому чтоCLLocationManager
это Objective-C, где все объекты являютсяNSObject
подклассами.delegate
ИзCLLocationManager
должен бытьNSObject
подкласс. Попробуйте удалитьNSObject
наследование, и вы получите предупреждение компилятора, в котором он пытается установить себя в качествеdelegate
. Что касаетсяlazy
, я делаю это, потому что хочу использовать замыкание для инициализацииlocationManager
(сохраняет код красивым и аккуратным), но я не могу ссылатьсяself
на закрытие, если оно не является ленивым (т. Е. Создается позже при первом обращении, а не приLocationTrack
первом создании экземпляра).