UNUserNotificationCenter получил ответ с обработчиком завершения никогда не вызывается iOS10, swift 2.3
Я планирую новые уведомления в iOS10, например:
func scheduleNotification (event : Meeting, todaysBadgeCounter: Int) {
if #available(iOS 10.0, *) {
let minutesBefore = 10
//interval in seconds from current point in time to notification
let interval : NSTimeInterval = NSTimeInterval(secondsFromNowTo(event.startTime.dateByAddingTimeInterval(-minutesBefore * 60)))
//only schedule in the future
if(interval > 0){
let category = NotificationsController.notificationCategory
let center = NotificationsController.notificationCenter
center.setNotificationCategories([category])
let content = UNMutableNotificationContent()
content.title = NSString.localizedUserNotificationStringForKey(event.title, arguments: nil)
if(minutesBefore <= 1){
content.body = NSString.localizedUserNotificationStringForKey("IOS10: Your (event.title) is about to start", arguments: nil)
}else{
content.body = NSString.localizedUserNotificationStringForKey("IOS10: You have (event.title) in (Int(minutesBefore)) minutes", arguments: nil)
}
content.sound = UNNotificationSound.defaultSound()
let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: interval, repeats: false)
let identifier = NSString.localizedUserNotificationStringForKey("sampleRequest(event.UUID)", arguments: nil)
let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)
//setting the delegate
center.delegate = self
center.addNotificationRequest(request, withCompletionHandler: { (error) in
// handle the error if needed
log.error(error?.localizedDescription)
print("SCHEDULING >=iOS10:", event.title, ", interval:", interval)
})
}
//return category
@available(iOS 10.0, *)
class var notificationCategory : UNNotificationCategory {
struct Static {
static let callNow = UNNotificationAction(identifier: NotificationActions.callNow.rawValue, title: "Call now", options: [])
static let clear = UNNotificationAction(identifier: NotificationActions.clear.rawValue, title: "Clear", options: [])
static let category : UNNotificationCategory = UNNotificationCategory.init(identifier: "CALLINNOTIFICATION", actions: [callNow, clear], intentIdentifiers: [], options: [])
}
return Static.category
}
Я могу запланировать уведомления и получать уведомления в нужное время. но: мои методы делегата, которые я использовал в соответствии с учебником, никогда не выполняются, однако didReceiveLocalNotification выполняется каждый раз, когда я нажимаю на уведомление:
extension NotificationsController: UNUserNotificationCenterDelegate {
@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
print("IOS10 delivered")
// Response has actionIdentifier, userText, Notification (which has Request, which has Trigger and Content)
switch response.actionIdentifier {
case NotificationActions.NotifyBefore.rawValue:
print("notify")
break
case NotificationActions.callNow.rawValue:
print("callNow")
break
case NotificationActions.clear.rawValue:
print("clear")
default: break
}
}
@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
// Delivers a notification to an app running in the foreground.
print("IOS10 delivered 2222")
}
}
не было ли didreceivelocalnotification устаревшим? Как заставить эти методы называться?
обновление:
я обновил свой код с некоторыми предложениями, а именно:
- я добавил назначение UNUserNotificationCenter.делегировать в applicationDidFinishLaunchingWithoptions.
- я также попытался переместить эти методы (методы делегирования) из расширения в NotificationsController.класс swift и установка этого класса как UNUserNotificationCenterDelegate. У меня тоже не получилось.
8 ответов
идентификатор запроса не является категорией уведомлений.
просто добавьте эту строку:
content.categoryIdentifier = identifier
обновление: Просто сделал простое приложение. Кажется, все работает нормально:
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
if granted {
self.registerCategory()
self.scheduleNotification(event: "test", interval: 3)
self.scheduleNotification(event: "test2", interval: 5)
}
}
return true
}
func registerCategory() -> Void{
let callNow = UNNotificationAction(identifier: "call", title: "Call now", options: [])
let clear = UNNotificationAction(identifier: "clear", title: "Clear", options: [])
let category : UNNotificationCategory = UNNotificationCategory.init(identifier: "CALLINNOTIFICATION", actions: [callNow, clear], intentIdentifiers: [], options: [])
let center = UNUserNotificationCenter.current()
center.setNotificationCategories([category])
}
func scheduleNotification (event : String, interval: TimeInterval) {
let content = UNMutableNotificationContent()
content.title = event
content.body = "body"
content.categoryIdentifier = "CALLINNOTIFICATION"
let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: interval, repeats: false)
let identifier = "id_"+event
let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)
let center = UNUserNotificationCenter.current()
center.add(request, withCompletionHandler: { (error) in
})
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
print("didReceive")
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
print("willPresent")
completionHandler([.badge, .alert, .sound])
}
}
обновление 2: переписано в Swift 2.3
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func applicationDidFinishLaunching(application: UIApplication) {
UNUserNotificationCenter.currentNotificationCenter().delegate = self
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Badge, .Sound, .Alert]) { (granted, error) in
if granted {
self.registerCategory()
self.scheduleNotification("test", interval: 3)
self.scheduleNotification("test2", interval: 5)
}
}
}
func registerCategory() -> Void{
let callNow = UNNotificationAction(identifier: "call", title: "Call now", options: [])
let clear = UNNotificationAction(identifier: "clear", title: "Clear", options: [])
let category : UNNotificationCategory = UNNotificationCategory.init(identifier: "CALLINNOTIFICATION", actions: [callNow, clear], intentIdentifiers: [], options: [])
let center = UNUserNotificationCenter.currentNotificationCenter()
center.setNotificationCategories([category])
}
func scheduleNotification(event : String, interval: NSTimeInterval) {
let content = UNMutableNotificationContent()
content.title = event
content.body = "body"
content.categoryIdentifier = "CALLINNOTIFICATION"
let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: interval, repeats: false)
let identifier = "id_"+event
let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)
let center = UNUserNotificationCenter.currentNotificationCenter()
center.addNotificationRequest(request) { (error) in
}
}
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
print("willPresent")
completionHandler([.Badge, .Alert, .Sound])
}
func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
print("didReceive")
completionHandler()
}
}
Я нашел ответ на этот. Ниже метод делегата вызывается при запуске приложения на Xcode 8 С Swift 2.3 и минимальной целью развертывания как iOS 9.3.
func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void)
в swift 3.0 использовать,
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void)
используйте метод делегата belwo для Swift 2.3:
func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void)
убедитесь, что ваш AppDelegate реализует UNUserNotificationCenterDelegate
протокол.
Для Swift
let center = UNUserNotificationCenter.current()
center.delegate = self
для Objective-c
//set delegate to self
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
назначение делегата self вызовет следующие методы.
// App in foreground
private func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
print("willPresent")
}
//On Action click
private func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
print("didReceive")
}
по словам UNUserNotificationCenterDelegate docs:
важно
необходимо назначить объект делегата центру UNUserNotificationCenter объект не позднее, чем приложение завершит запуск. Например, в приложение iOS, вы должны назначить его в applicationWillFinishLaunching (:) или applicationDidFinishLaunching(:) способ.
таким образом, это может быть проблема установки уведомления Делегат центра опоздал.
Для Swift 3.0
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
print("** willPresent")
completionHandler([.badge, .alert, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
print("** didReceive")
completionHandler()
}
вы используете неправильные сигнатуры функций
правильные сигнатуры функций в swift:
func userNotificationCenter(UNUserNotificationCenter, willPresent: UNNotification, withCompletionHandler: (UNNotificationPresentationOptions) -> Void) {
//your code here
}
и
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
//your code here
}
в документах говорится, чтобы установить делегат в applicationWillFinishLaunching (:) или applicationDidFinishLaunching (:). Поэтому включите следующий код в AppDelegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().delegate = self
}
после этого делегат устанавливается, следующая функция будет представления будет называться.
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
print("willPresent")
completionHandler([.alert, .sound])
}