首页 > 解决方案 > 每 X 天本地通知 - Swift

问题描述

在我开始之前,请不要烧我,因为我知道这已经被问了数百次,没有可靠的答案,但我相信有一个使用后台刷新的解决方案。https://medisafe.com/ app 似乎已经解决了!

目标:每 x 天在指定时间触发本地通知

我的解决方案

第 1 步:从开始日期和奇数发生(本例 2)天(已编辑)获取计时器间隔

第 2 步:在此差异上设置间隔计时器并重复

第 3 步:激活后台刷新(如果应用程序甚至被终止,它将在后台加载应用程序并给我一个小窗口来执行一些任务)

step 4. 设置后台刷新每天触发一次

第 5 步:执行 get items api,它将刷新所有计时器和通知

步骤 6 坐下来,对我的解决方案感到惊讶地微笑

但这失败了。

所以一个计时器间隔

 let newTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 172800,repeats: true)

但这只会在每天执行后台获取时重置计时器,它将从现在触发 2 天,而不是从开始日期触发。

因此,必须有一种比较日期小时和分钟(开始日期、x 日期和当前日期)的方法来计算计时器间隔值。

目前我正在使用日历组件。触发每天即时执行以下操作

      var triggerType : DateComponents? {
    var triggerT : DateComponents?
    var cal = Calendar(identifier: .gregorian)
    cal.firstWeekday = 2
    if let notificationModel = self.notificationModel {
        switch notificationModel.reminderType {
        case .daily?, .weekly?:
            if let date = notificationModel.date {
                triggerT = cal.dateComponents([.weekday, .hour, .minute], from:date)
                if let weekday = notificationModel.weekday {
                    triggerT?.weekday = weekday
                }
            }
        case .alternateDays?:
            if let date = notificationModel.date {
                triggerT = cal.dateComponents([ .hour, .minute], from:date)
                // THIS IS WHERE I NEED HELP
            }
        case .monthly?:
            if let date = notificationModel.date {
                triggerT = cal.dateComponents([.day,.hour,.minute], from: date)
            }
        case .yearly?:
            triggerT = Calendar.current.dateComponents([.month,.day,.hour,.minute], from: (notificationModel.date)!)
        case .oneOff?:
            triggerT = Calendar.current.dateComponents([.year,.month,.day,.hour,.minute], from: (notificationModel.date)!)
        case .none:
            DispatchQueue.main.async {
                if let category = self.notificationModel?.category, let title = self.notificationModel?.title {
                    Toast.down("An error was discovered in \(category). Please change the occurance value for the following \(title)")
                }
            }
        }
    } else {
        print("NOTIFICATION MODEL IS CORRUPT")
    }
    return triggerT
}

func add(notification: NotificationModel){
    let content = UNMutableNotificationContent()

    if let title = notification.title,
        let body = notification.body,
        let identifier = notification.identifier {


        content.title = title
        content.body = body
        content.sound = UNNotificationSound.default()
        content.categoryIdentifier = (notification.category?.rawValue)!
        content.setValue("YES", forKeyPath: "shouldAlwaysAlertWhileAppIsForeground")

        var trigger : UNCalendarNotificationTrigger?

        if let triggerType = self.triggerType {

            if let occurance = notification.occurance {
                if occurance > 0 {
                }
            }
            trigger = UNCalendarNotificationTrigger(dateMatching: triggerType, repeats: true)

        } else {
            return
        }

        let interval = Date().timeIntervalSince1970
        let identifierString = "2\(interval)"

        var request : UNNotificationRequest!
        if notification.reminderType == .alternateDays {
            print("ADDING TIMER NOTIFICATION")
            print("REMINDER TIME = \(notification.date)")
            // 172800 = two days
            let newTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 172800,
                                                        repeats: true)
            request = UNNotificationRequest(identifier: identifierString,
                                            content: content, trigger: newTrigger)
        } else {
            request = UNNotificationRequest(identifier: identifierString,
                                            content: content, trigger: trigger)
        }


        center.add(request, withCompletionHandler: { (error) in
            if let error = error {
                // Something went wrong
                print(error.localizedDescription)
            } else
            {
                print("ADDING NOTIDCIATION \(content.title)")

            }
        })



        //SNOOZE OR DELETE NOTIFICATIONS
        let snoozeAction = UNNotificationAction(identifier: "Snooze",                                          title: "Snooze", options: [])
        let deleteAction = UNNotificationAction(identifier: "UYLDeleteAction",title: "Delete", options: [.destructive])
        //Create a category with the actions: This requires another unique identifier (you probably want to define these magic strings in an enum):
        let category = UNNotificationCategory(identifier: notification.category!.rawValue,
                                              actions: [snoozeAction,deleteAction],
                                              intentIdentifiers: [], options: [])

        //Register the category with the notification center. It is recommended to do this early in the app lifecycle.

        center.setNotificationCategories([category])
        //To include this action in our notifications we need to set the category in the notification content:

    } else {
        print("Failed to add notification")
    }
}

但是,我想要每隔一天,不想使用 64 通知限制。

谢谢你的时间

托马斯

标签: swiftnsnotificationcenter

解决方案


假设您想在 2、4 和 6 天后触发通知,您可以这样做:

对于我的示例,我添加了扩展名Date

extension Date {
    func adding(days: Int) -> Date? {
        var dateComponents = DateComponents()
        dateComponents.day = days

        return NSCalendar.current.date(byAdding: dateComponents, to: self)
    }
}

然后你可以为指定的日期创建新的通知,在这个例子中是从现在开始的 2、4、6 天

let date = Date()
for i in [2, 4, 6] {
    if let date = date.adding(days: i) {
        scheduleNotification(withDate: date)
    }
}

func scheduleNotification(withDate date: Date) {
    let notificationContent = UNMutableNotificationContent()
    notificationContent.title = "Title"
    notificationContent.subtitle = "Subtitle"
    notificationContent.body = "Body"

    let identifier = "Make up identifiers here"
    let dateComponents = Calendar.autoupdatingCurrent.dateComponents([.day, .month, .year, .hour, .minute, .second], from: date)

    let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)

    let notificationReques = UNNotificationRequest(identifier: identifier, content: notificationContent, trigger: trigger)

    UNUserNotificationCenter.current().add(notificationReques) { error in
        if let e = error {
            print("Error \(e.localizedDescription)")
        }
    }
}

这应该安排 3 个通知 - 从现在起 2、4、6 天......


推荐阅读