Отправьте локальные уведомления следующим образом:
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,
content: newContent,
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])
}
Вот несколько гифок:
1 : получение локальных уведомлений увеличивает значок приложения. В то время как взаимодействие с уведомлением уменьшает значок приложения.
2 : получение локальных уведомлений при завершении работы приложения (я использовал триггер timeInterval из 15 секунд в этом).
3: получение уведомления на переднем плане увеличивает значок приложения, если пользователь не взаимодействует с Это.
Полный класс, используемый в моем тестовом проекте, выглядит так:
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",
subtitle: "Staff Meeting in 20 minutes",
body: "Don't forget to bring coffee.",
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, subtitle: String, body: 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,
content: newContent,
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,
content: content, trigger: trigger)
center.add(request, withCompletionHandler: { (error) in
// Handle error
})
}
})
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
DispatchQueue.main.async {
UIApplication.shared.applicationIconBadgeNumber += 1
}
completionHandler([.alert, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, 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,
content: newContent,
trigger: request.trigger)
return newRequest
}
newRequests.forEach { center.add($0, withCompletionHandler: { (error) in
// Handle error
})
}
})
completionHandler()
}
}
person
ielyamani
schedule
16.09.2018
center.getDeliveredNotifications
? - person ielyamani   schedule 16.09.2018