iOS 第一次和最后一次使用后的本地通知

iOS Local Notifications after first and last use

我正在尝试设置在两种情况下触发的本地通知: - 首次使用该应用程序后的 x 天数 - 如果用户已经 x 天没有使用该应用程序

这可能吗?我在网上找到的所有信息都是关于将通知设置为在特定时间关闭,但如何根据应用程序的第一次和最后一次使用发送通知?

首先,您需要一个注册通知的请求,在通知被授予后,您可以调用在特定时间触发通知的函数。

AppDelegate

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

    let center = UNUserNotificationCenter.current()
    let options: UNAuthorizationOptions = [.alert, .sound]
    center.requestAuthorization(options: options, completionHandler: { granted, error in
        if granted {
            self.setNotificationForFirstTimeUseApp()
            self.setNotificationForLastTimeUseApp()
            print("Notification is granted")
        } else {
            print("Notification is not granted")
        }
    })
    return true
}

创建在特定时间触发通知的函数:

func setNotificationForFirstTimeUseApp() {
    // Check the app, if it is opened before
    if let _ = UserDefaults.standard.value(forKey: "appOpened") as? Bool {
        return
    }

    // Save a flag on preferences that it tells the app is opened for the first time
    UserDefaults.standard.set(true, forKey: "appOpened")

    let content = UNMutableNotificationContent()
    content.title = "Using for the first time - Notification" // Add your own title
    content.body = "Awesome thank you for using this application!" // Add your own description
    content.sound = UNNotificationSound.default

    var calendar = Calendar(identifier: .gregorian)
    calendar.timeZone = NSTimeZone.local

    // Specific the time you want to fire the notification (after some days, hours, minutes...)
    if let date = Date.getDateByAdding(days: 0, hours: 0, minutes: 0, seconds: 5) {

        let componentsForFireDate = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second, .timeZone], from: date)

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

        let identifier = "firstTimeUseApp"
        let request = UNNotificationRequest(
            identifier: identifier,
            content: content,
            trigger: trigger)

        let center = UNUserNotificationCenter.current()
        center.add(request, withCompletionHandler: { error in
            if error != nil {
                if let error = error {
                    print("Something went wrong: \(error)")
                }
            }
        })

        center.getPendingNotificationRequests(completionHandler: { requests in
            print(String(format: "PendingNotificationRequests %i", requests.count))
            for req in requests {
                let trigger = req.trigger
                if let trigger = trigger {
                    print("trigger \(trigger)")
                }
            }
        })
    }

}

func setNotificationForLastTimeUseApp () {
    let content = UNMutableNotificationContent()
    content.title = "Using for the last time - Notification" // Add your own title
    content.body = "You have not used the application for a long time!" // Add your own description
    content.sound = UNNotificationSound.default

    var calendar = Calendar(identifier: .gregorian)
    calendar.timeZone = NSTimeZone.local

    // Specific the time you want to fire the notification (after some days, hours, minutes...)
    if let date = Date.getDateByAdding(days: 0, hours: 0, minutes: 0, seconds: 10) {
        let componentsForFireDate = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second, .timeZone], from: date)

        let trigger = UNCalendarNotificationTrigger(dateMatching: componentsForFireDate, repeats: false)
        let identifier = "lastTimeUseApp"

        let request = UNNotificationRequest(
            identifier: identifier,
            content: content,
            trigger: trigger)

        let center = UNUserNotificationCenter.current()
        // Remove pending notifications
        center.removePendingNotificationRequests(withIdentifiers: [identifier])
        center.add(request, withCompletionHandler: { error in
            if error != nil {
                if let error = error {
                    print("Something went wrong: \(error)")
                }
            }
        })

        center.getPendingNotificationRequests(completionHandler: { requests in
            print(String(format: "PendingNotificationRequests %i", requests.count))
            for req in requests {
                let trigger = req.trigger
                if let trigger = trigger {
                    print("trigger \(trigger)")
                }
            }
        })
    }
}

最后,添加此功能。它将通过从现在开始添加天、小时、分钟和秒来计算未来日期。

extension Date {
    static func getDateByAdding(days: Int, hours: Int, minutes: Int, seconds: Int) -> Date? {
        let currentDate = Date()
        var dateComponent = DateComponents()
        dateComponent.day = days
        dateComponent.hour = hours
        dateComponent.minute = minutes
        dateComponent.second = seconds
        let futureDate = Calendar.current.date(byAdding: dateComponent, to: currentDate)
        return futureDate
    }
}

希望这个回答对您的问题有所帮助!