【问题标题】:Daily Local Notifications Are Not Working每日本地通知不起作用
【发布时间】:2022-01-19 21:43:37
【问题描述】:

我的问题是我正在尝试安排每天在特定时间发送的通知,这是我的代码

import SwiftUI

struct notifView: View {
    var body: some View {
        VStack {
            VStack {
                Button("Request Permission") {
                    let center = UNUserNotificationCenter.current()

                    center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
                        if granted {
                            print("Access Granted!")
                        } else {
                            print("Access Not Granted")
                        }
                    }
                }
                .frame(width: 200, height: 60, alignment: .center)
                .foregroundColor(.black)
                .background(Color.blue)
                .cornerRadius(10.0)
                .padding()
                Button("Add Notifications For Morning") {
                    func scheduleNotification() {
                        let center = UNUserNotificationCenter.current()

                        let content = UNMutableNotificationContent()
                        content.title = "Morning Time"
                        content.body = "Wake Up And Be Productive!"
                        content.categoryIdentifier = "reminder"
                        content.sound = UNNotificationSound.default

                        var dateComponents = DateComponents()
                        dateComponents.hour = 6
                        dateComponents.minute = 30
                        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)

                        let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
                        center.add(request)
                    }
                }
                .padding()
                Button("Add Notifications For Middle Of The Day") {
                    func scheduleNotification() {
                        let center = UNUserNotificationCenter.current()

                        let content = UNMutableNotificationContent()
                        content.title = "Middle Of The Day"
                        content.body = "Did you have your daily run?"
                        content.categoryIdentifier = "reminder"
                        content.sound = UNNotificationSound.default

                        var dateComponents = DateComponents()
                        dateComponents.hour = 12
                        dateComponents.minute = 30
                        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)

                        let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
                        center.add(request)
                    }
                }
                .padding()
                Button("Add Notifications For Night") {
                    func scheduleNotification() {
                        let center = UNUserNotificationCenter.current()

                        let content = UNMutableNotificationContent()
                        content.title = "Night Time"
                        content.body = "Time to sleep"
                        content.categoryIdentifier = "reminder"
                        content.sound = UNNotificationSound.default

                        var dateComponents = DateComponents()
                        dateComponents.hour = 20
                        dateComponents.minute = 51
                        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)

                        let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
                        center.add(request)
                    }
                }
                .foregroundColor(.blue)
                .padding()
            }
        }
    }
}

struct notifView_Previews: PreviewProvider {
    static var previews: some View {
        notifView()
    }
}

【问题讨论】:

标签: ios swift xcode swiftui


【解决方案1】:

我在这段视频的帮助下成功了: https://www.youtube.com/watch?v=mG9BVAs8AIo

还有来自@lorem ipsum 的一些代码非常感谢您的帮助

import SwiftUI
import UserNotifications

struct notifView: View {
    var body: some View {
        VStack {
            Button("Request Permission") {
                NotificationManager.instance.requestAuthorization()
            }
            .padding()
            .background(Color.green)
            .cornerRadius(10)
            Button("1st Notification") {
                
                var dateComponents = DateComponents()
                dateComponents.hour = 4
                dateComponents.minute = 01

// reusable code thanks to lorem ipsum
                
              NotificationManager.instance.scheduleTriggerNotification(title: "1st Notification", body: "1st Notification Body", categoryIdentifier: UUID().uuidString, dateComponents: dateComponents, repeats: true)
            }
            .padding()
            .background(Color.yellow)
            .cornerRadius(10)
            Button("2nd Notification") {
                
                var dateComponents = DateComponents()
                dateComponents.hour = 5
                dateComponents.minute = 40

// reusable code thanks to lorem ipsum
                
                NotificationManager.instance.scheduleTriggerNotification(title: "2nd Notification", body: "2nd Notification Body", categoryIdentifier: UUID().uuidString, dateComponents: dateComponents, repeats: true)
            }
            .padding()
            .background(Color.yellow)
            .cornerRadius(10)
            Button("3rd Notification") {
                
                var dateComponents = DateComponents()
                dateComponents.hour = 12
                dateComponents.minute = 10

// reusable code thanks to lorem ipsum
                
                NotificationManager.instance.scheduleTriggerNotification(title: "3rd Notification", body: "3rd Notification Body", categoryIdentifier: UUID().uuidString, dateComponents: dateComponents, repeats: true)
            }
            .padding()
            .background(Color.yellow)
            .cornerRadius(10)
        }
    }
}

class NotificationManager {
    
    static let instance = NotificationManager()
    
    func requestAuthorization() {
        let options: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(options: options) { (success, error) in
            if let error = error {
                print("ERROR: \(error)")
            } else {
                print("SUCCESS")
            }
        }
    }
    // reusable code thanks to lorem ipsum
    func scheduleTriggerNotification(title: String, body: String, categoryIdentifier: String, dateComponents : DateComponents, repeats: Bool) {
            print(#function)
            let content = UNMutableNotificationContent()
            content.title = title
            content.body = body
            content.categoryIdentifier = categoryIdentifier
            content.sound = UNNotificationSound.default
            
            let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: repeats)
            
            let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
        UNUserNotificationCenter.current().add(request)
        }
    
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        notifView()
    }
}

【讨论】:

  • 仅供参考,重复使用静态调用被认为是不好的做法。这就是为什么我将变量放在顶部并在管理器中添加了 notificationCenter 变量的原因。
【解决方案2】:

在今天的日期中添加一天,以便我们得到第二天,然后添加您要触发通知的具体时间。

var triggerComponents = DateComponents()

let nextDay = Calendar.current.date(byAdding: .day, value: 1, to: Date()) ?? Date()
triggerComponents = Calendar.current.dateComponents([.year, .month, .day, .hour], from: nextDay)
triggerComponents.hour = 14

【讨论】:

    【解决方案3】:

    查看代码中的cmets

    import SwiftUI
    //struct and class should start with an uppercase
    struct NotificationView: View {
        //Central location for Notification code including the delegate
        // A call to the notificationManager just like the line of code below has to be included in
        // application(_:willFinishLaunchingWithOptions:) or
        // application(_:didFinishLaunchingWithOptions:)
        //https://developer.apple.com/documentation/usernotifications/unusernotificationcenterdelegate
        //https://www.hackingwithswift.com/quick-start/swiftui/how-to-add-an-appdelegate-to-a-swiftui-app
        let notificationManager: NotificationManager = NotificationManager.shared
        var body: some View {
            VStack {
                VStack {
                    Button("Request Permission") {
                        //Call a func here don't define it
                        notificationManager.requestAuthorization()
                    }
                    .frame(width: 200, height: 60, alignment: .center)
                    .foregroundColor(.black)
                    .background(Color.blue)
                    .cornerRadius(10.0)
                    .padding()
                    Button("Add Notifications For Morning") {
                        //Unique date components
                        var dateComponents = DateComponents()
                        dateComponents.hour = 6
                        dateComponents.minute = 30
                        //Reusable method
                        self.notificationManager.scheduleTriggerNotification(title: "Morning Time", body: "Wake Up And Be Productive!", categoryIdentifier: "reminder", dateComponents: dateComponents, repeats: true)
                    }
                    .padding()
                    Button("Add Notifications For Middle Of The Day") {
                        var dateComponents = DateComponents()
                        dateComponents.hour = 12
                        dateComponents.minute = 30
                        //Reusable method
                        self.notificationManager.scheduleTriggerNotification(title: "Middle Of The Day", body: "Did you have your daily run?", categoryIdentifier: "reminder", dateComponents: dateComponents, repeats: true)
                        
                    }
                    .padding()
                    Button("Add Notifications For Night") {
                        var dateComponents = DateComponents()
                        dateComponents.hour = 20
                        dateComponents.minute = 51
                        //Reusable method
                        self.notificationManager.scheduleTriggerNotification(title: "Night Time", body: "Time to sleep", categoryIdentifier: "reminder", dateComponents: dateComponents, repeats: true)
                        
                    }
                    .foregroundColor(.blue)
                    .padding()
                    
                    Button("Print Notifications") {
                        //Reusable method
                        self.notificationManager.printNotifications()
                    }
                    .foregroundColor(.blue)
                    .padding()
                    Button("Delete Notifications") {
                        //Reusable method
                        self.notificationManager.deleteNotifications()
                    }
                    .foregroundColor(.blue)
                    .padding()
                }
            }
        }
    }
    //You need a central location for the notification code because
    // it is needed in more than 1 spot. At launch in the AppDelegate
    // and wherever you schedule your notifications
    class NotificationManager: NSObject, UNUserNotificationCenterDelegate{
        //Singleton is requierd because of delegate
        static let shared: NotificationManager = NotificationManager()
        let notificationCenter = UNUserNotificationCenter.current()
        
        private override init(){
            super.init()
            //This assigns the delegate
            notificationCenter.delegate = self
        }
        
        func requestAuthorization() {
            print(#function)
            notificationCenter.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
                if granted {
                    print("Access Granted!")
                } else {
                    print("Access Not Granted")
                }
            }
        }
        
        func deleteNotifications(){
            print(#function)
            notificationCenter.removeAllPendingNotificationRequests()
        }
        ///This is just a reusable form of all the copy and paste you did in your buttons. If you have to copy and paste make it reusable.
        func scheduleTriggerNotification(title: String, body: String, categoryIdentifier: String, dateComponents : DateComponents, repeats: Bool) {
            print(#function)
            let content = UNMutableNotificationContent()
            content.title = title
            content.body = body
            content.categoryIdentifier = categoryIdentifier
            content.sound = UNNotificationSound.default
            
            let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: repeats)
            
            let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
            notificationCenter.add(request)
        }
        ///Prints to console schduled notifications
        func printNotifications(){
            print(#function)
            notificationCenter.getPendingNotificationRequests { request in
                for req in request{
                    if req.trigger is UNCalendarNotificationTrigger{
                        print((req.trigger as! UNCalendarNotificationTrigger).nextTriggerDate()?.description ?? "invalid next trigger date")
                    }
                }
            }
        }
        //MARK: UNUserNotificationCenterDelegate
        func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
            
            completionHandler(.banner)
        }
    }
    struct NotificationView_Previews: PreviewProvider {
        static var previews: some View {
            NotificationView()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-29
      • 1970-01-01
      • 2017-06-23
      • 1970-01-01
      • 1970-01-01
      • 2012-02-26
      相关资源
      最近更新 更多