关于警报:
当本地通知触发时,您的应用程序可能仍处于前台,因此您需要实现委托方法才能使通知执行任何操作。例如,在委托中定义此方法将允许通知显示警报、发出声音并更新徽章:
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert,.badge,.sound])
}
关于徽章:
我观察到创建一个UNMutableNotificationContent
对象并仅指定徽章值(作为 NSNumber 对象)适用于除 0 之外的所有徽章值(即,您无法以这种方式清除徽章)。我还没有找到任何文档来解释为什么 0 的行为与任何其他值不同,特别是因为 .badge 属性被定义为NSNumber?
,所以框架应该能够区分nil
(没有变化)和0
(清除徽章)。
我已经提交了一份radar http://www.openradar.me/29859960反对这一点。
作为解决方法,我发现设置title
财产在UNMutableNotificationContent
对象,其徽章值为NSNumber(value: 0)
does火。如果title
财产丢失,它不会着火。
添加 title 属性仍然不会向用户发出警报(更新:iOS 11 中不再出现这种情况!),所以这是一种静默地将徽章值更新为 0 的方法,无需调用 UIApplication 对象(通过UIApplication.shared.applicationIconBadgeNumber = 0
).
这是我的示例项目中的全部代码; ViewController 代码中有一个标记,显示插入 title 属性可以解决问题:
//
// AppDelegate.swift
// userNotificationZeroBadgeTest
//
// Created by Jeff Vautin on 1/3/17.
// Copyright © 2017 Jeff Vautin. All rights reserved.
//
import UIKit
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .sound]) { (success, error) -> Void in
print("Badge auth: \(success)")
}
// For handling Foreground notifications, this needs to be assigned before finishing this method
let vc = window?.rootViewController as! ViewController
let center = UNUserNotificationCenter.current()
center.delegate = vc
return true
}
}
//
// ViewController.swift
// userNotificationZeroBadgeTest
//
// Created by Jeff Vautin on 1/3/17.
// Copyright © 2017 Jeff Vautin. All rights reserved.
//
import UIKit
import UserNotifications
class ViewController: UIViewController, UNUserNotificationCenterDelegate {
@IBAction func start(_ sender: Any) {
// Reset badge directly (this always works)
UIApplication.shared.applicationIconBadgeNumber = 0
let center = UNUserNotificationCenter.current()
// Schedule badge value of 1 in 5 seconds
let notificationBadgeOneContent = UNMutableNotificationContent()
notificationBadgeOneContent.badge = NSNumber(value: 1)
let notificationBadgeOneTrigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 1*5, repeats: false)
let notificationBadgeOneRequest = UNNotificationRequest.init(identifier: "1", content: notificationBadgeOneContent, trigger: notificationBadgeOneTrigger)
center.add(notificationBadgeOneRequest)
// Schedule badge value of 2 in 10 seconds
let notificationBadgeTwoContent = UNMutableNotificationContent()
notificationBadgeTwoContent.badge = NSNumber(value: 2)
let notificationBadgeTwoTrigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 2*5, repeats: false)
let notificationBadgeTwoRequest = UNNotificationRequest.init(identifier: "2", content: notificationBadgeTwoContent, trigger: notificationBadgeTwoTrigger)
center.add(notificationBadgeTwoRequest)
// Schedule badge value of 3 in 15 seconds
let notificationBadgeThreeContent = UNMutableNotificationContent()
notificationBadgeThreeContent.badge = NSNumber(value: 3)
let notificationBadgeThreeTrigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 3*5, repeats: false)
let notificationBadgeThreeRequest = UNNotificationRequest.init(identifier: "3", content: notificationBadgeThreeContent, trigger: notificationBadgeThreeTrigger)
center.add(notificationBadgeThreeRequest)
// Schedule badge value of 4 in 20 seconds
let notificationBadgeFourContent = UNMutableNotificationContent()
notificationBadgeFourContent.badge = NSNumber(value: 4)
let notificationBadgeFourTrigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 4*5, repeats: false)
let notificationBadgeFourRequest = UNNotificationRequest.init(identifier: "4", content: notificationBadgeFourContent, trigger: notificationBadgeFourTrigger)
center.add(notificationBadgeFourRequest)
// Schedule badge value of 0 in 25 seconds
let notificationBadgeZeroContent = UNMutableNotificationContent()
// MARK: Uncommenting this line setting title property will cause notification to fire properly.
//notificationBadgeZeroContent.title = "Zero!"
notificationBadgeZeroContent.badge = NSNumber(value: 0)
let notificationBadgeZeroTrigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 5*5, repeats: false)
let notificationBadgeZeroRequest = UNNotificationRequest.init(identifier: "0", content: notificationBadgeZeroContent, trigger: notificationBadgeZeroTrigger)
center.add(notificationBadgeZeroRequest)
}
@IBAction func listNotifications(_ sender: Any) {
let center = UNUserNotificationCenter.current()
center.getDeliveredNotifications() { (notificationArray) -> Void in
print("Delivered notifications: \(notificationArray)")
}
center.getPendingNotificationRequests() { (notificationArray) -> Void in
print("Pending notifications: \(notificationArray)")
}
}
// MARK: UNUserNotificationCenterDelegate
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
print("Received notification: \(notification)")
completionHandler([.alert,.badge,.sound])
}
}