Обновления местоположения запуска в указанное c время в фоновом режиме - Swift (watchOS) - PullRequest
0 голосов
/ 14 января 2020

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

Пока приложение работает нормально. Он выбирает позицию на основе distanceFilter свойства CLLocationManager. Проблема в батарее. Подход, который я придерживался, поддерживает фоновые обновления местоположения в действии, даже если они выбираются только тогда, когда определенное c расстояние «покрыто».

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

Моя главная проблема заключается в том, что отключение обновления местоположения в фоновом режиме не позволяет мне возобновить его. Я пытался сделать это с помощью:

  • A Timer.
  • scheduleBackgroundRefresh(withPreferredDate:userInfo:scheduledCompletion:) метода, вызывающего startLocationUpdates() в делегате

Ничего не работает. Мой вопрос:

Есть ли способ возобновить фоновые обновления местоположения, если оно было ранее отключено? Заранее спасибо.

ОБНОВЛЕНИЕ n .2: Я пытался выполнить обновление местоположения с помощью WKApplicationRefreshBackgroundTask, но он просто игнорирует функцию requestLocation() (предложено @RomuloBM)

//In extension delegate handle() function
case let backgroundTask as WKApplicationRefreshBackgroundTask:
                // Be sure to complete the background ta
                LocMng = LocationManager() // I even tried to create a new element!
                LocMng.LocMng.requestLocation()// it is just ignored
                backgroundTask.setTaskCompletedWithSnapshot(false)

Я вызываю фоновую задачу с помощью этой функции в моем LocationManager:

//In didUpdateLocation
if background {
            WKExtension.shared().scheduleBackgroundRefresh(withPreferredDate: Date(timeIntervalSinceNow: 30), userInfo: nil){ _ in
                print("Done")
                self.background = false
                self.LocMng.stopUpdatingLocation()
            }
        }

Для справки, вот мой класс LocationManager:

enum ScanningMode {
    case Precise
    case Normal
}

class LocationManager : NSObject, CLLocationManagerDelegate, UNUserNotificationCenterDelegate, ObservableObject {

    let LocMng = CLLocationManager()
    let NotMng = UNUserNotificationCenter.current()
    var modeOfScanning: ScanningMode!
    var region: CLCircularRegion!
    var previousLocation: CLLocation!
    // variables for position...

    override init() {
        super.init()
        // stuff for my app...

        modeOfScanning = .Precise
        setupManager()
        setupNotification()
        startLocalization()


    }

    private func startLocalization(){
        switch modeOfScanning!{
        case ScanningMode.Precise:
            LocMng.desiredAccuracy = kCLLocationAccuracyBest
            LocMng.distanceFilter = 15
        case ScanningMode.Normal:
            LocMng.desiredAccuracy = kCLLocationAccuracyHundredMeters
            LocMng.distanceFilter = 80
        }
        LocMng.startUpdatingLocation()
    }

    private func setupManager(){
        LocMng.requestAlwaysAuthorization()
        LocMng.delegate = self
        LocMng.desiredAccuracy = kCLLocationAccuracyBest
    }

    private func setupNotification(){
        NotMng.delegate = self
        NotMng.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
                   if granted {
                       print("NotificationCenter Authorization Granted!")
                   }
        }
    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        if status == CLAuthorizationStatus.authorizedAlways{
        }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        LocMng.allowsBackgroundLocationUpdates = true

        // For the sake of clarity, I will cut out this chunk of code and 
        // just showing how I execute my action based on the result of location
        // This is just an example
        actualLocation = locations[length-1]
        //find if in a forget
        if previousLocation != nil{
            if !region.contains(actualLocation!.coordinate) &&     region.contains(previousLocation!.coordinate){
                  //Schedule notification
                  LocMng.stopUpdatingLocation() // <- this does not allow me to resume
            }
        }
        previousLocation = actualLocation
    }

}
...