首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么本地通知没有触发UNCalendarNotificationTrigger

为什么本地通知没有触发UNCalendarNotificationTrigger
EN

Stack Overflow用户
提问于 2021-09-24 06:32:55
回答 2查看 692关注 0票数 1

当地的通知应该在25-9-2021发射。这是火时间的打印对象

▿年:2021年月:9天: 26 isLeapMonth: false

  • 年:2021年
  • 月: 9
  • day : 25
  • isLeapMonth :false

F 211

代码语言:javascript
运行
复制
let content = UNMutableNotificationContent()
content.title = "Test title"
content.body = "sample test body"
var trigger:UNCalendarNotificationTrigger
let n = 1
let nextTriggerDate = Calendar.current.date(byAdding: .day, value: n, to: Date())!
let comps = Calendar.current.dateComponents([.year, .month, .day], from: nextTriggerDate)
trigger = UNCalendarNotificationTrigger(dateMatching: comps, repeats: false)
content.subtitle = "Sub title-Date-NonRepeat"
let request = UNNotificationRequest(identifier: "test.my.example", content: content, trigger: trigger)    
UNUserNotificationCenter.current().add(request) { Error in                        
    if let err = Error {
        print("Notification Error:\(String(describing: err))")
    }
}

我再次添加了以下代码更改的日期时间

代码语言:javascript
运行
复制
var comps = Calendar.current.dateComponents([.year, .month, .day], from: nextTriggerDate)
comps.day = 25
comps.hour = 12
comps.minute = 17
comps.second = 10

这是复配变量的PO

var comps = Calendar.current.dateComponents(.year,.month,.day,from: nextTriggerDate) comps.day = 25 comps.hour = 12 comps.minute = 17 comps.second = 10

我给出了日期,看看它是否启动,我只给出了日期和时间,看它是否启动,我在主线程中做了整件事情,它不起作用

有人能让我明白我在这里做错了什么吗

EN

回答 2

Stack Overflow用户

发布于 2021-09-26 18:37:03

你可能不会先请求许可

代码语言:javascript
运行
复制
    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 one 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 custom trigger") {
                    let apiDate = DateComponents(year: 2021, month: 11, day: 10, hour: 16, minute: 0, second: 0)
                    notificationManager.scheduleBasedOnDaysBeforeDate(title: "test", body: "test", baseDate: Calendar.current.date(from: apiDate)!, xDaysBefore: 10, count: 12, identifier: UUID().uuidString)
                }
                .padding()

                Button("Print Notifications") {
                    //Reusable method
                    self.notificationManager.printNotifications()
                }
                Button("Print Delivered Notifications") {
                    //Reusable method
                    self.notificationManager.printDeliveredNotifications()
                }
                .foregroundColor(.blue)
                .padding()
                Button("Delete Notifications") {
                    //Reusable method
                    self.notificationManager.deleteNotifications()
                }
                .foregroundColor(.blue)
                .padding()
            }
        }
    }
}
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 scheduleUNCalendarNotificationTrigger(title: String, body: String, dateComponents: DateComponents, identifier: String, repeats: Bool = false){
        print(#function)
        let content = UNMutableNotificationContent()
        content.title = title
        content.body = body
        content.sound = .default
        
        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: repeats)
        let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
        notificationCenter.add(request) { (error) in
            if error != nil {
                print(error!)
            }
        }
    }
    func scheduleUNTimeIntervalNotificationTrigger(title: String, body: String, timeInterval: TimeInterval, identifier: String, repeats: Bool = false){
        print(#function)
        let content = UNMutableNotificationContent()
        content.title = title
        content.body = body
        content.sound = .default

        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: timeInterval, repeats: repeats)
        let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
        notificationCenter.add(request) { (error) in
            if error != nil {
                print(error!)
            }
        }
    }
    ///Schedules `count` number of monthly notifications that occur `xDaysBefore` the `baseDate`
    func scheduleBasedOnDaysBeforeDate(title: String, body: String, baseDate: Date, xDaysBefore: Int, count: Int, identifier: String){
        print(#function)
        var nextBaseDate: Date = baseDate
        
        for n in 1...count{
            
            guard let triggerDate: Date = Calendar.current.date(byAdding: .day, value: -xDaysBefore, to: nextBaseDate) else{
                return
            }
            let components: DateComponents = Calendar.current.dateComponents([.month,.day, .hour,.minute,.second], from: triggerDate)
            let id = identifier.appending(" \(n)")
            scheduleUNCalendarNotificationTrigger(title: title, body: body, dateComponents: components, identifier: id)
            //OR if you want specific seconds 
            //let interval = Calendar.current.dateComponents([.second], from: Date(), to: triggerDate).second ?? 1
            
            //scheduleUNTimeIntervalNotificationTrigger(title: title, body: body, timeInterval: TimeInterval(interval), identifier: id)
            
            let next = Calendar.current.date(byAdding: .month, value: 1, to: nextBaseDate)
            
            if next != nil{
                
                nextBaseDate = next!
            }else{
                print("next == nil")
                return
            }
        }
        self.printNotifications()
        
    }
    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()
    }
    
    ///Prints to console schduled notifications
    func printNotifications(){
        print(#function)
        notificationCenter.getPendingNotificationRequests { request in
            print("UNTimeIntervalNotificationTrigger Pending Notification")
            for req in request{
                if req.trigger is UNTimeIntervalNotificationTrigger{
                    print((req.trigger as! UNTimeIntervalNotificationTrigger).nextTriggerDate()?.description ?? "invalid next trigger date")
                }
            }
            print("UNCalendarNotificationTrigger Pending Notification")
            for req in request{
                if req.trigger is UNCalendarNotificationTrigger{
                    print((req.trigger as! UNCalendarNotificationTrigger).nextTriggerDate()?.description ?? "invalid next trigger date")
                }
            }
        }
    }
    ///Prints to console delivered notifications
    func printDeliveredNotifications(){
        print(#function)
        notificationCenter.getDeliveredNotifications { request in
            for req in request{
                print(req)
            }
        }
    }
    //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()
    }
}

运行这段代码。先单击“请求权限”,然后单击“添加自定义触发器”,单击“打印”时,应在控制台中看到通知。

票数 2
EN

Stack Overflow用户

发布于 2021-09-26 20:38:03

我已经看过了您的代码,很明显,您正在正确地添加日历触发器,并且在其中一个注释中提到,您在添加时也获得了必要的许可。

对我来说就像是约会时间的问题。检查datetime到datetime组件会话是否正确进行。

如果您正在模拟器上测试,当您来回更改系统中的日期时,事情可能会变得疯狂。

我建议你用真正的设备进行测试。

你就是这样得到许可的

代码语言:javascript
运行
复制
  UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.announcement,.sound]) { [self]
                    (granted, error) in
                    if granted {
                 print("granted")
                    } else {
                 print("denied or error")
                    }
                }

您可以使用下面的代码查询可用通知列表,以便在预期的日期时间正确调度。

代码语言:javascript
运行
复制
var text:NSMutableAttributedString? = NSMutableAttributedString(string: "List of notification requests and it's time\n")

UNUserNotificationCenter.current().getPendingNotificationRequests() { [weak self] requests in
                DispatchQueue.main.async {
                for request in requests {
                            guard let trigger = request.trigger as? UNCalendarNotificationTrigger else { return }
                            text?.append(NSAttributedString(string: "\nTrigger Date:\(trigger.nextTriggerDate()?.description) \nDateTime Component:\(trigger.dateComponents.description)\n"))
                        }
                print(text)
                    }

更新(下面的Credit(lorem ipsum)来自问题中的这个answer )

代码语言:javascript
运行
复制
func getFireDatetime(apiDate: Date, numberOfDaysBeforeApiDate: Int,repeat:Bool) -> DateComponents? {
    if let fireDate: Date = apiDate.dateByAdding(days: -numberOfDaysBeforeApiDate) {
        if repeat {
            return Calendar.current.dateComponents([.day, .hour, .minute, .second], from: fireDate)
        }
        return Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: fireDate)
    }
return nil
}

调用getFireDatetime方法,这将解决所有问题

P.S

  • Date()在通用时间内给出时间,而Datetime组件则给出设备当前日历设置的日期时间.

当您使用Datetime组件时,automatically应该处理

  • ,时区更改和日照节省。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69310525

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档