如何在 iOS 10 中处理 UserNotifications 操作
Posted
技术标签:
【中文标题】如何在 iOS 10 中处理 UserNotifications 操作【英文标题】:How to handle UserNotifications Actions in iOS 10 【发布时间】:2016-09-08 15:58:33 【问题描述】:所以我可以像这样安排通知;
//ios 10 Notification
if #available(iOS 10.0, *)
var displayDate: String
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = DateFormatter.Style.full
return dateFormatter.string(from: datePicker.date as Date)
let notif = UNMutableNotificationContent()
notif.title = "I am a Reminder"
notif.subtitle = "\(displayDate)"
notif.body = "Here's the body of the notification"
notif.sound = UNNotificationSound.default()
notif.categoryIdentifier = "reminderNotification"
let today = NSDate()
let interval = datePicker.date.timeIntervalSince(today as Date)
let notifTrigger = UNTimeIntervalNotificationTrigger(timeInterval: interval, repeats: false)
let request = UNNotificationRequest(identifier: "reminderNotif", content: notif, trigger: notifTrigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: error in
if error != nil
print(error)
// completion(Success: false)
else
//completion(Sucess: true)
)
我已在 appDelegate
中请求权限,并且使用通知扩展程序在我的自定义视图中显示的通知很好。
我在appDelegate
中为通知类别添加了通知操作;这些也会出现。
//Notifications Actions
private func configureUserNotifications()
if #available(iOS 10.0, *)
let tomorrowAction = UNNotificationAction(identifier: "tomorrowReminder", title: "Remind Me Tomorrow", options: [])
let dismissAction = UNNotificationAction(identifier: "dismissReminder", title: "Dismiss", options: [])
let category = UNNotificationCategory(identifier: "reminderNotification", actions: [tomorrowAction, dismissAction], intentIdentifiers: [], options: [.customDismissAction])
UNUserNotificationCenter.current().setNotificationCategories([category])
else
// Fallback on earlier versions
我在通知扩展.plist
文件中设置了相同的类别。在通知扩展中,当用户点击某个操作时,我有以下内容可以更改文本。
//Handle Notification Actions And Update Notification Window
private func didReceive(_ response: UNNotificationResponse, completionHandler done: (UNNotificationContentExtensionResponseOption) -> Void)
if response.actionIdentifier == "tomorrowReminder"
print("Tomrrow Button Pressed")
subLabel.text = "Reminder For Tomorrow"
subLabel.textColor = UIColor.blue
done(.dismissAndForwardAction)
if response.actionIdentifier == "dismissReminder"
print("Dismiss Button Pressed")
done(.dismiss)
else
print("Else response")
done(.dismissAndForwardAction)
但是文本没有改变,也没有调用任何语句;
在 appDelegate 中我有以下内容;
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool
if #available(iOS 10.0, *)
UNUserNotificationCenter.current().delegate = self
configureUserNotifications()
extension AppDelegate: UNUserNotificationCenterDelegate
@available(iOS 10.0, *)
private func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void)
completionHandler([.alert, .sound])
@available(iOS 10.0, *)
private func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void)
print("Recieved Action For \(response.actionIdentifier)")
if response.actionIdentifier == "tomorrowReminder"
print("Tomorrow Reminder")
//Set new reminder for tomorrow using the notification content title
completionHandler()
if response.actionIdentifier == "dismissReminder"
print("Dismiss Reminder...")
completionHandler()
这两个函数实际上都没有在appDelegate
中调用。我不确定更新扩展视图的问题是否与应用程序委托有关。我不这么认为,我已经按照苹果的 WWDC 视频以及其他教程,查看了文档 API 并无法弄清楚;
PS:过去几周我一直在研究并试图弄清楚这一点,这似乎相当简单,我不确定我错过了什么。我知道我不是唯一一个有这些问题的人。
【问题讨论】:
【参考方案1】:我没有检查你的整个代码,但至少,这些函数头需要更改如下:
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void)
func didReceive(_ response: UNNotificationResponse,
completionHandler done: @escaping (UNNotificationContentExtensionResponseOption) -> Void)
简单的规则:
删除private
,添加@escaping
。
您可能从 Xcode 收到了错误的建议,但将它们设为 private
,不会生成 Objective-C 入口点。 iOS 运行时在内部使用 Objective-C 选择器,因此它无法找到您的方法,因此它们不会被执行。
【讨论】:
@escaping
是什么意思?
天哪,谢谢!你知道我如何在应用程序委托中notification.request.content.title
来安排新的通知吗?例如,我正在尝试安排一个提醒,并有一个动作要在明天再次提醒
没关系,我只需要使用response.notification.request.content.title
@Honey, @escaping
的意思是“这个闭包可能会在以后执行”。编译器可以轻松优化在map
、filter
等中经常使用的非转义闭包,Swift 3 已将其设为默认值。所有完成处理程序都会在某些任务完成后执行——稍后,因此我们需要为 Swift 3 中的所有完成处理程序注解 @escaping
。
@Honey,有a nice article here in SO。 swift.org's article 不是那么好,但是对于使用 Swift 2&3 的人来说,这是必看的。Apple 的文档正在改进,the latest references(不幸的是不是所有最新的)和Xcode release notes 给我们一些信息。 以上是关于如何在 iOS 10 中处理 UserNotifications 操作的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS 13 Objective-c 中处理鼠标事件
如何在 SKstoreviewcontroller ios 中处理提交按钮操作