ios – 用户通知框架徽章不会增加

前端之家收集整理的这篇文章主要介绍了ios – 用户通知框架徽章不会增加前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在我的应用程序中使用UserNotification框架并发送本地通知(不是推送通知),我想将徽章设置为收到的通知数量,所以我做的是将收到的通知数设置为用户默认值然后我尝试过将值分配给徽章以获取徽章编号,但徽章编号不会增加.这是我的代码

设置接收通知的值

center.getDeliveredNotifications { notification in

    UserDefaults.standard.set(notification.count,forKey: Constants.NOTIFICATION_COUNT)
    print("notification.count \(notification.count)")
    print(".count noti \(UserDefaults.standard.integer(forKey: Constants.NOTIFICATION_COUNT))")

}

这准确地打印了收到的通知数量,当我决定将其设置为我的徽章时,它只显示1

content.badge = NSNumber(value: UserDefaults.standard.integer(forKey: Constants.NOTIFICATION_COUNT))

我不知道为什么价值不会每次都增加.任何帮助,将不胜感激.

或者,如果可以在应用程序的任何位置始终更新徽章.

解决方法

像这样发送本地通知
func sendNotification(title: String,subtitle: String,body: String,timeInterval: TimeInterval) {
    let center = UNUserNotificationCenter.current()
    center.getPendingNotificationRequests(completionHandler: { pendingNotificationRequests in

        //Use the main thread since we want to access UIApplication.shared.applicationIconBadgeNumber
        DispatchQueue.main.sync {

            //Create the new content
            let content = UNMutableNotificationContent()
            content.title = title
            content.subtitle = subtitle
            content.body = body

            //Let's store the firing date of this notification in content.userInfo
            let firingDate = Date().timeIntervalSince1970 + timeInterval
            content.userInfo = ["timeInterval": firingDate]

            //get the count of pending notification that will be fired earlier than this one
            let earlierNotificationsCount: Int = pendingNotificationRequests.filter { request in

                let userInfo = request.content.userInfo
                if let time = userInfo["timeInterval"] as? Double {
                    if time < firingDate {
                        return true
                    } else {

                        //Here we update the notofication that have been created earlier,BUT have a later firing date
                        let newContent: UNMutableNotificationContent = request.content.mutableCopy() as! UNMutableNotificationContent
                        newContent.badge = (Int(truncating: request.content.badge ?? 0) + 1) as NSNumber
                        let newRequest: UNNotificationRequest =
                            UNNotificationRequest(identifier: request.identifier,content: newContent,trigger: request.trigger)
                        center.add(newRequest,withCompletionHandler: { (error) in
                            // Handle error
                        })
                        return false
                    }
                }
                return false
            }.count

            //Set the badge
            content.badge =  NSNumber(integerLiteral: UIApplication.shared.applicationIconBadgeNumber + earlierNotificationsCount + 1)
            let trigger = UNTimeIntervalNotificationTrigger(timeInterval: timeInterval,repeats: false)

            let requestIdentifier = UUID().uuidString  //You probably want to save these request identifiers if you want to remove the corresponding notifications later
            let request = UNNotificationRequest(identifier: requestIdentifier,content: content,trigger: trigger)

            center.add(request,withCompletionHandler: { (error) in
                // Handle error
            })
        }
    })
}

(您可能需要保存请求的标识符(如果您想更新它们,可以在用户默认值或核心数据中保存,甚至可以通过removePendingNotificationRequests(withIdentifiers:)取消它们)

您可以像这样调用上面的函数

sendNotification(title: "Meeting Reminder",subtitle: "Staff Meeting in 20 minutes",body: "Don't forget to bring coffee.",timeInterval: 10)

将您的视图控制器声明为UNUserNotificationCenterDelegate:

class ViewController: UIViewController,UNUserNotificationCenterDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        UNUserNotificationCenter.current().delegate = self
    }
    //...
}

要处理与通知的互动,请更新应用的徽章以及即将发布的通知的徽章:

func userNotificationCenter(_ center: UNUserNotificationCenter,didReceive response: UNNotificationResponse,withCompletionHandler completionHandler: @escaping () -> Void) {

    //UI updates are done in the main thread
    DispatchQueue.main.async {
        UIApplication.shared.applicationIconBadgeNumber -= 1
    }

    let center = UNUserNotificationCenter.current()
    center.getPendingNotificationRequests(completionHandler: {requests in
        //Update only the notifications that have userInfo["timeInterval"] set
        let newRequests: [UNNotificationRequest] =
            requests
                .filter{ rq in
                    return rq.content.userInfo["timeInterval"] is Double?
                }
                .map { request in
                    let newContent: UNMutableNotificationContent = request.content.mutableCopy() as! UNMutableNotificationContent
                    newContent.badge = (Int(truncating: request.content.badge ?? 0) - 1) as NSNumber
                    let newRequest: UNNotificationRequest =
                        UNNotificationRequest(identifier: request.identifier,trigger: request.trigger)
                    return newRequest
        }
        newRequests.forEach { center.add($0,withCompletionHandler: { (error) in
            // Handle error
        })
        }
    })
    completionHandler()
}

这会在通知与点击进行交互时通过减少应用徽章来更新应用徽章.此外,它还会更新待处理通知内容徽章.添加具有相同标识符的通知请求只会更新待处理通知.

要在前台接收通知,并在未与通知交互时增加应用徽章图标,请执行以下操作:

func userNotificationCenter(_ center: UNUserNotificationCenter,willPresent notification: UNNotification,withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    DispatchQueue.main.async {
        UIApplication.shared.applicationIconBadgeNumber += 1
    }
    completionHandler([.alert,.sound])
}

这是一些GIF:

> 1st:接收本地通知增加应用徽章.而与通知进行交互会减少应用徽章.
> 2nd:应用程序被杀时接收本地通知(我在此使用了15秒的触发timeInterval).
> 3rd:在前台接收通知增加应用程序徽章,除非用户与之交互.

我的测试项目中使用的完整类看起来像这样:

import UIKit
import UserNotifications

class ViewController: UIViewController,UNUserNotificationCenterDelegate {
    var bit = true
    @IBAction func send(_ sender: UIButton) {
        let time: TimeInterval = bit ? 8 : 4
        bit.toggle()
        sendNotification(title: "Meeting Reminder",timeInterval: time)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view,typically from a nib.

        UNUserNotificationCenter.current().delegate = self
    }

    func sendNotification(title: String,timeInterval: TimeInterval) {
        let center = UNUserNotificationCenter.current()
        center.getPendingNotificationRequests(completionHandler: { pendingNotificationRequests in
            DispatchQueue.main.sync {
                let content = UNMutableNotificationContent()
                content.title = title
                content.subtitle = subtitle
                content.body = body
                let firingDate = Date().timeIntervalSince1970 + timeInterval
                content.userInfo = ["timeInterval": firingDate]
                let earlierNotificationsCount: Int = pendingNotificationRequests.filter { request in
                    let userInfo = request.content.userInfo
                    if let time = userInfo["timeInterval"] as? Double {
                        if time < firingDate {
                            return true
                        } else {
                            let newContent: UNMutableNotificationContent = request.content.mutableCopy() as! UNMutableNotificationContent
                            newContent.badge = (Int(truncating: request.content.badge ?? 0) + 1) as NSNumber
                            let newRequest: UNNotificationRequest =
                                UNNotificationRequest(identifier: request.identifier,trigger: request.trigger)
                            center.add(newRequest,withCompletionHandler: { (error) in
                                // Handle error
                            })
                            return false
                        }
                    }
                    return false
                    }.count
                content.badge =  NSNumber(integerLiteral: UIApplication.shared.applicationIconBadgeNumber + earlierNotificationsCount + 1)
                let trigger = UNTimeIntervalNotificationTrigger(timeInterval: timeInterval,repeats: false)

                let requestIdentifier = UUID().uuidString  //You probably want to save these request identifiers if you want to remove the corresponding notifications later
                let request = UNNotificationRequest(identifier: requestIdentifier,trigger: trigger)

                center.add(request,withCompletionHandler: { (error) in
                    // Handle error
                })
            }
        })
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter,withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        DispatchQueue.main.async {
            UIApplication.shared.applicationIconBadgeNumber += 1
        }
        completionHandler([.alert,.sound])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter,withCompletionHandler completionHandler: @escaping () -> Void) {
        DispatchQueue.main.async {
            UIApplication.shared.applicationIconBadgeNumber -= 1
        }

        let center = UNUserNotificationCenter.current()
        center.getPendingNotificationRequests(completionHandler: {requests in
            let newRequests: [UNNotificationRequest] =
                requests
                    .filter{ rq in
                        return rq.content.userInfo["timeInterval"] is Double? 
                    }
                    .map { request in
                        let newContent: UNMutableNotificationContent = request.content.mutableCopy() as! UNMutableNotificationContent
                        newContent.badge = (Int(truncating: request.content.badge ?? 0) - 1) as NSNumber
                        let newRequest: UNNotificationRequest =
                            UNNotificationRequest(identifier: request.identifier,trigger: request.trigger)
                        return newRequest
            }
            newRequests.forEach { center.add($0,withCompletionHandler: { (error) in
                // Handle error
            })
            }
        })
        completionHandler()
    }
}
原文链接:https://www.f2er.com/iOS/331888.html

猜你在找的iOS相关文章