Доступ к текущему местоположению пользователя в пользовательских приложениях Sirikit, iOS, swift

Я создал пользовательское намерение Sirikit, в классе IntentHandler я не могу найти местоположение пользователя, где конфиденциальность местоположения установлена ​​​​по умолчанию «Всегда». пожалуйста, посмотрите на код.

    import Foundation
import CoreData
import CoreLocation
class PhotoOfTheDayIntentHandler: NSObject, PhotoOfTheDayIntentHandling {
let context = CoreDataStorage.mainQueueContext()
var counter : DistanceEntity?
var locationManger = CLLocationManager()
    func confirm(intent: PhotoOfTheDayIntent, completion: @escaping (PhotoOfTheDayIntentResponse) -> Void) {
        completion(PhotoOfTheDayIntentResponse(code: .ready, userActivity: nil))
}

func handle(intent: PhotoOfTheDayIntent, completion: @escaping (PhotoOfTheDayIntentResponse) -> Void) {
    self.context.performAndWait{ () -> Void in
        let counter = NSManagedObject.findAllForEntity("DistanceEntity", context: self.context)
        if (counter?.last != nil) {
            self.counter = (counter!.last as! DistanceEntity)
                let currentLocation: CLLocation = locationManger.location!
                let greenLocation = CLLocation(latitude:self.counter!.latitude, longitude: self.counter!.longitude)
                let distanceInMeters = currentLocation.distance(from: greenLocation) // result is in meters
                debugPrint("distanceInMeters",distanceInMeters)
                completion(PhotoOfTheDayIntentResponse.success(photoTitle: "\(distanceInMeters) Meter"))
            completion(PhotoOfTheDayIntentResponse.success(photoTitle: "\(self.counter!.distance) Meter"))
        }
    }
}
}

если я прокомментирую диспетчер местоположения, он вылетит.


person Shubham Tomar    schedule 25.02.2019    source источник
comment
Вы нашли решение для получения местоположения пользователя в обработчике намерений?   -  person Tongo    schedule 13.06.2019
comment
да, я нашел решение.   -  person Shubham Tomar    schedule 15.06.2019
comment
Можете ли вы опубликовать решение здесь? У меня такая же проблема. Спасибо   -  person Tongo    schedule 17.06.2019
comment
@Tongo Я добавил ответ ниже, который может вам помочь. stackoverflow.com/a/59585774/1322262   -  person aross    schedule 18.01.2020


Ответы (2)


TLDR: создайте CLLocationManager в основном потоке, и он должен работать.


Если вы откроете Console.app на своем Mac и отслеживаете устройство, на котором работает Siri Intent, вы, вероятно, увидите сообщение, подобное этому:

Диспетчер расположения (0xe86bdf0) был создан в очереди отправки, выполняющейся в потоке, отличном от основного потока.

(Точно так же, как в этом вопросе: менеджер местоположений был создан в очереди отправки< /а>.)

Проблема в том, что базовое местоположение должно быть создано в цикле выполнения, присоединенном к основному циклу. Самое простое решение — создать CLLocationManager в основном цикле.

Вот пример обработчика намерений, который использует местоположение.

import Foundation
import CoreLocation

class ExampleIntentHandler: NSObject, ExampleIntentIntentHandling, CLLocationManagerDelegate {
    private var locationManager: CLLocationManager?

    var onDidChangeAuthorization: ((ExampleIntentResponse) -> Void)?
    var onDidUpdateLocations: ((ExampleIntentResponse) -> Void)?

    func confirm(intent: CurrentSpeedIntent, completion: @escaping (CurrentSpeedIntentResponse) -> Void) {
        DispatchQueue.main.async {
            self.onDidChangeAuthorization = completion
            self.locationManager = CLLocationManager()
            self.locationManager?.delegate = self
            self.locationManager?.requestWhenInUseAuthorization()
        }
    }

    func handle(intent: CurrentSpeedIntent, completion: @escaping (CurrentSpeedIntentResponse) -> Void) {
        DispatchQueue.main.async {
            self.onDidUpdateLocations = completion
            self.locationManager = CLLocationManager()
            self.locationManager?.delegate = self
            self.locationManager?.desiredAccuracy = kCLLocationAccuracyBest
            self.locationManager?.startUpdatingLocation()
        }
    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        switch status {
        case .authorizedAlways, .authorizedWhenInUse:
            let response = ExampleIntentResponse(code: .ready, userActivity: nil)
            onDidChangeAuthorization?(response)
        default:
            let response = ExampleIntentResponse(code: .failure, userActivity: nil)
            onDidChangeAuthorization?(response)
        }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let location = locations.last else {
            return
        }

        // Do something with the `location` but note that this
        // method could be called multiple times by iOS. So if
        // you do more that just responding, like fetching a
        // photo, or manipulate something in your database you
        // will probably set some kind of variable here and 
        // stop if that is already set.
        // 
        // Example:
        //     guard intentHandled == false else { return }
        //     intentHandled = true
        // 
        // The `intentHandled` must of course be a instance variable

        // Don't forget to respond!
        let response = ExampleIntentResponse(code: .success, userActivity: nil)
        self.onDidUpdateLocations?(response)
    }
}

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

Запрос на использование местоположения также должен быть сначала сделан в приложении, если это еще не сделано.

person aross    schedule 03.01.2020

person    schedule
comment
Не могли бы вы объяснить больше об этом? Я до сих пор не могу понять, как вы инициализируете locationManager в намерении - person Alex Cheng; 02.08.2019