Как показывать регион уведомления для iOS не чаще одного раза в месяц? - PullRequest
0 голосов
/ 30 января 2019

Цель развертывания моего приложения - 10.0, и я использовал UNUserNotificationCenter, чтобы показать уведомление региона, даже когда приложение закрыто / убито.Но новая миссия - показывать его не чаще одного раза в месяц, хотя пользователь может входить в регион чаще, чем раз в месяц.

То, что я пробовал до сих пор (что работало замечательно), это ...

    let content = UNMutableNotificationContent()

    content.title = "... Reminder"
    content.body = "Welcome to \(element.name). Please let us know how we can serve you and your loved ones, and we hope ... will simplify your visit here."
    content.sound = UNNotificationSound.default
    content.categoryIdentifier = "LOCATION_CAT"

    let centerCoordinate2D = element.location.coordinate
    let identifierName = element.name.replacingOccurrences(of: " ", with: "_")
    let region = CLCircularRegion(center: centerCoordinate2D, radius: 300, identifier: identifierName)
    region.notifyOnExit = false
    region.notifyOnEntry = true
    let trigger = UNLocationNotificationTrigger(region: region, repeats: true)

    // request = content + trigger
    let request = UNNotificationRequest(identifier: "REGION \(element.name)", content: content, trigger: trigger)

    // add (or "schedule") request to center
    let center = UNUserNotificationCenter.current()
    center.add(request, withCompletionHandler: { (error: Error?) in

        if let theError = error {
            print(theError.localizedDescription)
        }
    })

Но затем, чтобы это происходило не чаще одного раза в месяц, я сделал следующее:

    let centerCoordinate2D = element.location.coordinate
    let identifierName = element.name.replacingOccurrences(of: " ", with: "_")
    let region = CLCircularRegion(center: centerCoordinate2D, radius: 300, identifier: identifierName)
    region.notifyOnExit = true
    region.notifyOnEntry = true

    R.shared.appleLocationManager.startMonitoring(for: region)

Также в AppDelegate.swift,

extension AppDelegate: CLLocationManagerDelegate {

    // called when user Enters a monitored region
    func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {

        print("AppDelegate.locationManager( didEnterRegion ): called with region identifier: \(region.identifier)")

        if region is CLCircularRegion {
            // Do what you want if this information
            self.handleEvent(forRegion: region)
        }
    }

    func handleEvent(forRegion region: CLRegion) {

        // we save 'date' with "NOTIFICATION DATE request_identifier" as its key.
        let key = "NOTIFICATION DATE \(region.identifier)"
        let defaultValue = defaults.double(forKey: key)
        if defaultValue == 0 {
            print("AppDelegate.handleEvent(): need to show notification: no key")

            // set value first.
            defaults.set(Date().timeIntervalSince1970, forKey: key)

            showNotification(forRegion: region)

        } else {
            let diff = Date().timeIntervalSince(Date(timeIntervalSince1970: defaultValue))
            if  diff > 60 * 60 * 24 * 30 {
                print("AppDelegate.handleEvent(): need to show notification: diff > 30 days")

                // set value first.
                defaults.set(Date().timeIntervalSince1970, forKey: key)

                showNotification(forRegion: region)

            } else {
                // just pass.
                print("AppDelegate.handleEvent(): need NOT to show notification: diff: \(dot2(diff / 24 / 60)) mins")
            }
        }
    }

    func showNotification(forRegion region: CLRegion, message: String = "") {

        // customize your notification content
        let content = UNMutableNotificationContent()
        content.title = "... Reminder"
        let hospitalName = region.identifier.replacingOccurrences(of: "_", with: " ")
        content.body = "Welcome to \(hospitalName). \(message) Please let us know how we can serve you and your loved ones, and we hope ... will simplify your visit here."
        content.sound = UNNotificationSound.default

        // the actual trigger object
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0,
                                                        repeats: false)

        // notification unique identifier, for this example, same as the region to avoid duplicate notifications
        let identifier = "REGION \(hospitalName)"

        // the notification request object
        let request = UNNotificationRequest(identifier: identifier,
                                            content: content,
                                            trigger: trigger)

        // trying to add the notification request to notification center
        UNUserNotificationCenter.current().add(request, withCompletionHandler: { (error) in

            if let theError = error {
                print(theError.localizedDescription)
            }
        })
    }

со следующим, все еще для класса AppDelegate:

let appleLocationManager = CLLocationManager()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    self.appleLocationManager.delegate = self
    ...
}

Я думаю, что в коде есть ошибка, но мне не ясно, будет ли вызываться locationManager( didExitRegion: ), даже когда приложение закрыто / убито -в этом случае appleLocationManager не работает?

Если я не могу использовать locationManager( didExitRegion: ) для этой проблемы, что я могу сделать, чтобы уведомление региона происходило не чаще одного раза в месяц?Я также знаю, что существует другой тип триггера, UNTimeIntervalNotificationTrigger или UNLocationNotificationTrigger, и я хотел как-то использовать их для решения этой проблемы, но есть ли способ заставить его запускать часть моего кода, даже когда приложение не работает навсе?Если это невозможно решить, разве недостаточно сказать, что уведомление региона слишком ограничено?

1 Ответ

0 голосов
/ 30 января 2019

Описанный как документ Apple, мониторинг региона с помощью CLLocationManager пробуждает ваше приложение, если это необходимо.

cf https://developer.apple.com/documentation/corelocation/monitoring_the_user_s_proximity_to_geographic_regions

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

Вы также можете определить, запускается ли приложение с помощью регионального уведомления с помощью UIApplication.LaunchOptionsKey.

Уведомления о пересечении границы доставляются объекту делегата вашего менеджера местоположения.В частности, диспетчер местоположений вызывает методы locationManager (: didEnterRegion :) или locationManager (: didExitRegion :) своего делегата.Если ваше приложение было запущено, вы должны сразу настроить объект CLLocationManager и делегировать объект, чтобы вы могли получать эти уведомления.Чтобы определить, было ли ваше приложение запущено для события местоположения, найдите UIApplication.LaunchOptionsKey в словаре параметров запуска.

...