UNLocationNotificationTrigger работает в симуляторе, но не на физическом устройстве

Я подписался на напоминание на основе местоположения со следующим кодом:

let center = CLLocationCoordinate2D(latitude: tapp.location.latitude, longitude: tapp.location.longitude)
let region = CLCircularRegion(center: center, radius: CLLocationDistance(tapp.reminder), identifier: tapp.name)
locationManager.distanceFilter = 100
locationManager.startMonitoring(for: region)
region.notifyOnEntry = true
region.notifyOnExit = false
let trigger = UNLocationNotificationTrigger(region: region, repeats: false)
let request = UNNotificationRequest(identifier: "\(tapp.location.latitude)|\(tapp.location.longitude)", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)

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

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

1 ответ

Я в похожей ситуации. Уведомления о местоположении запускаются на симуляторе, пробуются на переднем плане, в фоновом режиме и в закрытом состоянии приложения. На симуляторе срабатывает во всех случаях, а на реальном устройстве вообще не срабатывает, даже на переднем плане.

Вот мой код для запроса разрешения на местоположение

      lazy var locationManager: CLLocationManager = createLocationManager()
    
    private func createLocationManager() -> CLLocationManager {
      let manager = CLLocationManager()
      manager.allowsBackgroundLocationUpdates = true
      
      return manager
    }

init() {
        super.init()

        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.startMonitoringSignificantLocationChanges()
        locationManager.startUpdatingLocation()
        locationManager.allowsBackgroundLocationUpdates = true
}

func askForPermissionIfNeeded() {
        if CLLocationManager.locationServicesEnabled() {
            if !self.isLocationPermissionAsked {
                locationManager.requestAlwaysAuthorization()
                locationManager.startUpdatingLocation()
            }
        }
    }

И вот мой код для запроса разрешений на уведомления

      func requestNotificationAuthorization(completion: @escaping () -> Void) {
        let options: UNAuthorizationOptions = [.sound, .alert, .badge]
        notificationCenter
            .requestAuthorization(options: options) { result, _ in
                print("Notification Auth Request result: \(result)")
                completion()
            }
    }

И вот мой код для регистрации уведомления о местоположении

      private func registerNotification(region: CLRegion) {
        let notificationContent = UNMutableNotificationContent()
        notificationContent.title = "Active location nearby"
        notificationContent.body = "Do you want to bla bla bla?"
        notificationContent.sound = .default
        
        let trigger = UNLocationNotificationTrigger(region: region, repeats: false)
        
        let request = UNNotificationRequest(
            identifier: region.identifier,
            content: notificationContent,
            trigger: trigger)
        
        notificationCenter
            .add(request) { error in
                if error != nil {
                    print("Error: \(String(describing: error))")
                }
            }
    }

Все это работает на симуляторе и не работает на устройстве... или, по крайней мере, уведомление не срабатывает.

НО я нашел обходной путь, который по крайней мере в моем случае работает -> Мониторинг региона

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

      locationManager.startMonitoring(for: fenceRegion)

И с помощью метода делегата didEnterRegion я регистрирую там уведомление и заменяю триггер на триггер времени вместо триггера местоположения

      func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
        if region is CLCircularRegion {
            registerNotification(region: region)
// Replace let timeTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false) in registerNotification
        }
    }

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

Другие вопросы по тегам