我在我的应用程序中使用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()
    }
}

ios – 用户通知框架徽章不会增加的更多相关文章

  1. ios – 如何调整标签栏徽章位置?

    我在标签栏上显示徽章,但是当数字增加时,它会转到标签栏项目,如图所示我想稍微向左移动徽章视图,使其适合选定的选项卡image.i尝试如here所述,但没有运气.那么有没有办法调整徽章视图位置?任何帮助将不胜感激.解决方法我发现Kateryna的答案对于让我走上正轨非常有用,但我必须稍微更新一下:请注意,选项卡整数不是零索引,因此第一个选项卡将是数字1,第二个选项卡将是2,等等.

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

    我在我的应用程序中使用UserNotification框架并发送本地通知(不是推送通知),我想将徽章设置为收到的通知数量,所以我做的是将收到的通知数设置为用户默认值然后我尝试过将值分配给徽章以获取徽章编号,但徽章编号不会增加.这是我的代码设置接收通知的值这准确地打印了收到的通知数量,当我决定将其设置为我的徽章时,它只显示1我不知道为什么价值不会每次都增加.任何帮助,将不胜感激.或者,如果可以在应用

  3. ios – 为什么标签栏项目的徽章没有更改

    我正在尝试更改标签栏项目的徽章但没有成功.我明白标签栏控制器负责控制器的标签栏.但是,标签栏本身中的某些内容可以由视图控制器(例如徽章)管理在我的代码中,我尝试在视图中加载但徽章中没有任何内容然后我试了一下:哪个不起作用,好吧,我知道为什么第二个代码不起作用,它与使用导航控制器而不是导航项更改导航控件的标题相同.但我不知道为什么第一个代码不起作用这是我的应用程序的hiechy,我在TeamsTab

  4. ios – 清除applicationIconBadgeNumber而不删除无效的通知

    解决方法使用空的本地通知间接将应用程序徽章设置为-1,但是在清除应用程序徽章计数时,它会在托盘中保留通知.Swift版本在iOS9和10上测试的方法.

  5. ios – 从客户端增加徽章数量而不是从有效负载接收计数增加

    我正在处理接收通知和设置应用程序徽章的应用程序.问题是,当应用程序处于后台状态或终止时,徽章计数不会增加.它保持不变.当应用程序在前台方法调用和徽章数量增加时.我已经从服务器端做了那件事,但我想知道有什么方法在应用程序处于后台时执行或终止以增加应用程序徽章号码?

  6. ios – 应用程序关闭时本地通知不更新徽章编号

    我注意到,当在ios设备中收到本地通知时,通知会显示在通知中心,但应用程序徽章编号在应用程序关闭时不会更新.我需要触摸通知中心中的通知,以便将本地推送消息传输到应用程序.这是正常行为吗?这可以通过使用远程推送通知来解决吗?解决方法您可以在UIlocalnotification对象中使用applicationIconBadgeNumber参数.基本上:例:但问题是,徽章编号在后续(多个)本地通知中没有增加.在这种情况下,是的…推送通知似乎是要走的路(但要注意推送通知并不总是可靠的……

  7. ios – 在Swift更新徽章柜台

    使用以下代码,我可以在应用编译后立即在徽章图标中找到:我尝试了下一个变体:初始化一个新的varbadgeCount=0及更高版本:但是当我收到新的通知,它不会更新到1.有谁知道如何解决它?

  8. ios – 在Swift中更新未选择的tabBarItem的徽章

    我有一个导航控制器与4个标签栏项目.每个人都有导航控制器.当我得到推送通知时,我想要能够更改第4个标签栏徽章号,无论在什么视图或标签中我都需要使用自动布局,因此我无法在应用程序委托中使用任何以编程方式解决的问题.我从一个视图模板启动了项目.我试图去到所需的标签,更改徽章值并回来,但当然不行.tabBarController似乎只对当前选项卡栏项目进行了引用.解决方法无需选择该索引来更新徽章值.采取

  9. IOS 10.2简单警报和徽章上的UserNotifications问题

    徽章问题我也试过在我的应用程序图标上实现了一个很好的标记,直到我试图删除它.这是执行它的功能:现在它没有增加徽章编号,因为它的名称应该建议,但它只是将徽章编号设置为1.文档说如果你将content.badge设置为0,它会删除它,但这不起作用.我尝试使用其他数字,当我手动将其更改为“2”,“3”等时……

  10. Swift-删除推送通知徽章号码?

    我试图删除图标徽章在swift,但PFInstallation似乎不再工作了。我如何做到这一点?

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部