web-dev-qa-db-fra.com

UNUserNotificationCenter n'a pas reçu de réponse, mais le gestionnaire d'achèvement n'est jamais appelé iOS10, Swift 2.3

Je planifie de nouvelles notifications dans iOS10, comme ceci:

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
}

Je suis capable de programmer des notifications et de recevoir des notifications locales au bon moment. BUT: Les méthodes de délégué que j'ai utilisées conformément au tutoriel ne sont jamais exécutées. Toutefois, la didReceiveLocalNotification est exécutée chaque fois que je tape sur la notification:

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")

    }
}

DidecreceiveLocalNotification n'a-t-il pas été déconseillé? Comment faire pour que ces méthodes s'appellent?

PDATE:

J'ai mis à jour mon code avec quelques suggestions d'ici, à savoir:

  1. J'ai ajouté l'attribution de UNUserNotificationCenter.delegate à applicationDidFinishLaunchingWithOptions.
  2. J'ai également essayé de déplacer ces méthodes (méthodes déléguées) de l'extension vers la classe NotificationsController.Swift et de définir cette classe comme UNUserNotificationCenterDelegate. N'a pas travaillé pour moi non plus.
36
Async-

L'identifiant de la demande n'est pas la catégorie de notification.

Ajoutez simplement cette ligne:

content.categoryIdentifier = identifier

Mise à jour: Je viens de créer une application simple. Tout semble bien fonctionner:

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])
}

}

Mise à jour 2: réécrit en 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()
}

}
18
livsik

Utilisez la méthode belwo delegate pour Swift 2.3:

func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void)
6
user2084611

J'ai trouvé la réponse à cela. La méthode déléguée ci-dessous est appelée lors de l'exécution de l'application sur Xcode 8 avec Swift 2.3 et la cible de déploiement minimale comme iOS 9.3.

func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void)

Dans Swift 3.0 Utilisation,

func userNotificationCenter(_ center: UNUserNotificationCenter, 
                      didReceive response: UNNotificationResponse, 
           withCompletionHandler completionHandler: @escaping () -> Void)

Référence: https://developer.Apple.com/reference/usernotifications/unusernotificationcenterdelegate/1649501-usernotificationcenter

4
user1140780

Assurez-vous que votre AppDelegate implémente le protocole UNUserNotificationCenterDelegate.

Pour Swift

let center = UNUserNotificationCenter.current()
center.delegate = self

Pour Objective-c

//set delegate to self
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];

Assigner un délégué à soi déclenchera les méthodes suivantes.

// 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")
      }
4
Avijit Nagare

Selon les NUserNotificationCenterDelegate docs :

Important

Vous devez affecter votre objet délégué à l'objet UNUserNotificationCenter au plus tard avant le lancement de votre application. Par exemple, dans une application iOS, vous devez l'affecter dans la méthode applicationWillFinishLaunching ( :) ou applicationDidFinishLaunching ( :).

Il peut donc s'agir de définir le délégué du centre de notifications trop tard.

3
spassas

Pour Swift 3.

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()
}
2
Matias Tebele

Vous utilisez des signatures de fonction incorrectes

Les signatures de fonction correctes dans Swift sont:

func userNotificationCenter(UNUserNotificationCenter, willPresent: UNNotification, withCompletionHandler: (UNNotificationPresentationOptions) -> Void) {

//your code here

}

et

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {

//your code here

}
1
crow

Vérifiez que seul votre AppDelegate est défini en tant que délégué UNUserNotificationCenter.

Utilises-tu...

UNUserNotificationCenter.current().delegate = self

... plus d'une fois? J'essayais de capturer des notifications avec des résultats différents dans tous mes contrôleurs de vue en modifiant le délégué dans chacun d'eux et en utilisant chacun cette fonction:

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
   // code
}

Le problème pour moi était que je n'avais pas encore implémenté leurs fonctionnalités et que la fonction userNotificationCenter originale "didReceive" dans mon AppDelegate n'était pas appelée. C'est peut-être pour ça que le vôtre ne s'appelle pas.

1
Caleb Hensley

La documentation dit de définir le délégué dans applicationWillFinishLaunching (:) ou applicationDidFinishLaunching (:). Donc, incluez le code suivant dans AppDelegate:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
   UNUserNotificationCenter.current().delegate = self
}

Une fois ce délégué défini, la fonction willPresent suivante sera appelée.

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
   print("willPresent")
   completionHandler([.alert, .sound])
}
0
bartosss