在 iOS 10 中安排和处理本地通知
Posted
技术标签:
【中文标题】在 iOS 10 中安排和处理本地通知【英文标题】:Schedule and handle local notifications in iOS 10 【发布时间】:2016-10-11 13:02:47 【问题描述】:我一直在从事我的一个项目,我允许用户在他们想要的时间安排多个通知。
ios 10 让我们能够使用 DateComponents 作为通知的触发日期,但我有点不知道应该如何安排和处理多个通知。
每个通知都需要自己的请求,然后又需要自己的标识符,否则您无法创建多个通知。
我认为我必须使用标识符来安排和处理通知,但现在我的代码是如此混乱,以至于我一直在认真地问自己是否没有更简单的方法来做到这一点。
根据我的数据模型,通知唯一标识符由以下部分组成:
-
我的模型的 ID
每次创建新通知时递增的数字
以上内容用下划线分隔
因此,例如,如果我必须为 id 为 3 的对象安排 10 个通知,它将如下所示:3_1, 3_2, 3_3...
每次收到通知时,我都会循环通过收到的通知来更新我的 UI。当用户希望删除接收到的特定模型的通知时,我会通过检查以相同 ID 开头的标识符来循环接收通知的唯一标识符。
我真的不知道如何才能做到这一点,因为根据文档,删除传递的通知的唯一方法是使用标识符:UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers:)
问题是,它会产生各种各样的问题,虽然我可以轻松地纠正它们,但它看起来很老套。我并不为我所做的事情感到骄傲,我正在寻找更聪明的方法来解决它。我故意没有发布任何代码,因为那不是问题。方法是真正的问题。
我在这里问是因为UserNotifications
框架是相当新的,我还没有找到关于这个主题的资源。
有什么想法吗?提前致谢。
编辑:这是一些代码。
@available(iOS 10.0, *)
func checkDeliveredAndPendingNotifications(completionHandler: @escaping (_ identifierDictionary: Dictionary<String, Int>) -> ())
var identifierDictionary:[String: Int] = [:]
UNUserNotificationCenter.current().getDeliveredNotifications (notifications) in
for notification in notifications
let identifierArraySplit = notification.request.identifier.components(separatedBy: "_")
if identifierDictionary[identifierArraySplit[0]] == nil || identifierDictionary[identifierArraySplit[0]]! < Int(identifierArraySplit[1])!
identifierDictionary[identifierArraySplit[0]] = Int(identifierArraySplit[1])
UNUserNotificationCenter.current().getPendingNotificationRequests(completionHandler: (requests) in
for request in requests
let identifierArraySplit = request.identifier.components(separatedBy: "_")
if identifierDictionary[identifierArraySplit[0]] == nil || Int(identifierArraySplit[1])! > identifierDictionary[identifierArraySplit[0]]!
identifierDictionary[identifierArraySplit[0]] = Int(identifierArraySplit[1])
completionHandler(identifierDictionary)
)
@available(iOS 10.0, *)
func generateNotifications()
for medecine in medecines
self.checkDeliveredAndPendingNotifications(completionHandler: (identifierDictionary) in
DispatchQueue.main.async
self.createNotification(medecineName: medecine.name, medecineId: medecine.id, identifierDictionary: identifierDictionary)
)
@available(iOS 10.0, *)
func createNotification(medecineName: String, medecineId: Int identifierDictionary: Dictionary<String, Int>)
let takeMedecineAction = UNNotificationAction(identifier: "TAKE", title: "Take your medecine", options: [.destructive])
let category = UNNotificationCategory(identifier: "message", actions: [takeMedecineAction], intentIdentifiers:[], options: [])
UNUserNotificationCenter.current().setNotificationCategories([category])
let takeMedecineContent = UNMutableNotificationContent()
takeMedecineContent.userInfo = ["id": medecineId]
takeMedecineContent.categoryIdentifier = "message"
takeMedecineContent.title = medecineName
takeMedecineContent.body = "It's time for your medecine"
takeMedecineContent.badge = 1
takeMedecineContent.sound = UNNotificationSound.default()
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: false)
var takeMedecineIdentifier = ""
for identifier in identifierDictionary
if Int(identifier.key) == medecineId
let nextIdentifierValue = identifier.value + 1
takeMedecineIdentifier = String(medecineId) + "_" + String(nextIdentifierValue)
let takeMedecineRequest = UNNotificationRequest(identifier: takeMedecineIdentifier, content: takeMedecineContent, trigger: trigger)
UNUserNotificationCenter.current().add(takeMedecineRequest, withCompletionHandler: (error) in
if let _ = error
print("There was an error : \(error)")
)
在checkDeliveredAndPendingNotifications
方法中,我循环遍历所有未决和已传递的通知,因此稍后我可以创建一个尚不存在的标识符。我还没有找到另一种方法来为每个通知生成唯一标识符。
由于大部分工作是在另一个异步队列上完成的,所以当他完成工作时,我还创建了一个完成处理程序。然后我在主线程上调用createNotification
方法(因为我使用的是Realm,我也有义务这样做),这应该会创建一个通知。
这里的问题是func add(UNNotificationRequest, withCompletionHandler: (Error?) -> Void)? = nil)
方法也在异步工作。因此,当我回到 generateNotifications
中的循环时,checkDeliveredAndPendingNotifications
返回不正确的数据。好吧,没有错,只是通知还没有创建……
我是线程方面的菜鸟,我被这些操作困住了,我不知道该去哪里。我不确定我是否以正确的方式解决问题。
【问题讨论】:
我不太明白你的问题,似乎本地通知需要标识符,你应该发布一些代码,因为很难看出哪里变得混乱 请解释一下你到底在问什么。你哪里有问题?你见过这样的例子吗? appcoda.com/ios10-user-notifications-guide 如果您想了解新的UNUserNotificationCenter
,请查看我发布的这个答案。 ***.com/questions/39713605/…
@damienBannerot 很抱歉回答迟了,我一直在格式化我的代码以使我的问题更容易理解。
【参考方案1】:
您可以根据需要获取所有通知并设置/删除。看看这个 Objc c 和 swift 的公认答案。
How to schedule a local notification in iOS 10 (objective-c)
【讨论】:
我在为每个通知创建特定标识符时遇到了特定问题。我已经更新了我的答案,抱歉这么含糊。以上是关于在 iOS 10 中安排和处理本地通知的主要内容,如果未能解决你的问题,请参考以下文章