web-dev-qa-db-fra.com

Afficher les notifications locales lorsque l'application est au premier plan Swift 3

Apparemment, cela est maintenant possible avec ios10:

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

Cette réponse dit essentiellement les outils nécessaires pour le faire:

Affichage d'une bannière de notification stock iOS lorsque votre application est ouverte et au premier plan?

Je ne comprends tout simplement pas comment mettre tout cela en place.

Je ne sais pas à quel point c'est important, mais je ne peux pas garder l'option optionnelle func et xcode veut que je la passe en mode privé.

J'essaie de montrer le badge et la documentation fournit

static var badge: UNNotificationPresentationOptions { get }

Peu perdu ici.

Et puis je suppose que si je veux exclure un certain contrôleur de vue de l'obtention de ces badges et que je n'utilise pas de contrôleur de navigation, ce code que j'ai trouvé fonctionnerait? : var fenêtre: UIWindow?

if let viewControllers = window?.rootViewController?.childViewControllers {
for viewController in viewControllers {
    if viewController.isKindOfClass(MyViewControllerClass) {
        print("Found it!!!")
        }
    }
}
31
user6820041

Il existe une méthode de délégation pour afficher la notification lorsque l'application est ouverte dans iOS 10. Vous devez l'implémenter pour que les notifications enrichies fonctionnent lorsque l'application est ouverte.

extension ViewController: UNUserNotificationCenterDelegate {

    //for displaying notification when app is in foreground
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

        //If you don't want to show notification when app is open, do something here else and make a return here. 
        //Even you you don't implement this delegate method, you will not see the notification on the specified controller. So, you have to implement this delegate and make sure the below line execute. i.e. completionHandler.

        completionHandler([.alert, .badge, .sound]) 
    }

    // For handling tap and user actions
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

        switch response.actionIdentifier {
        case "action1":
            print("Action First Tapped")
        case "action2":
            print("Action Second Tapped")
        default:
            break
        }
        completionHandler()
    }

}

Pour planifier une notification dans iOS 10 et fournir un badge

override func viewDidLoad() {
    super.viewDidLoad()

    // set UNUserNotificationCenter delegate to self
    UNUserNotificationCenter.current().delegate = self
    scheduleNotifications()
}

func scheduleNotifications() {

    let content = UNMutableNotificationContent()
    let requestIdentifier = "rajanNotification"

    content.badge = 1
    content.title = "This is a rich notification"
    content.subtitle = "Hello there, I am Rajan Maheshwari"
    content.body = "Hello body"
    content.categoryIdentifier = "actionCategory"
    content.sound = UNNotificationSound.default()

    // If you want to attach any image to show in local notification
    let url = Bundle.main.url(forResource: "notificationImage", withExtension: ".jpg")
    do {
        let attachment = try? UNNotificationAttachment(identifier: requestIdentifier, url: url!, options: nil)
        content.attachments = [attachment!]
    }      

    let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 3.0, repeats: false)

    let request = UNNotificationRequest(identifier: requestIdentifier, content: content, trigger: trigger)
    UNUserNotificationCenter.current().add(request) { (error:Error?) in

        if error != nil {
            print(error?.localizedDescription)
        }     
        print("Notification Register Success")
    }
}

Pour vous inscrire à AppDelegate, nous devons écrire ce morceau de code dans didFinishLaunchingWithOptions

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        registerForRichNotifications()
        return true
    }

J'ai défini des actions aussi ici. Vous pouvez les sauter

func registerForRichNotifications() {

       UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.badge,.sound]) { (granted:Bool, error:Error?) in
            if error != nil {
                print(error?.localizedDescription)
            }
            if granted {
                print("Permission granted")
            } else {
                print("Permission not granted")
            }
        }

        //actions defination
        let action1 = UNNotificationAction(identifier: "action1", title: "Action First", options: [.foreground])
        let action2 = UNNotificationAction(identifier: "action2", title: "Action Second", options: [.foreground])

        let category = UNNotificationCategory(identifier: "actionCategory", actions: [action1,action2], intentIdentifiers: [], options: [])

        UNUserNotificationCenter.current().setNotificationCategories([category])

    }

Si vous souhaitez que votre bannière de notification apparaisse partout dans l’application, vous pouvez écrire le délégué de UNUserNotificationDelegate dans AppDelegate et transformer le délégué UNUserNotificationCenter actuel en AppDelegate

extension AppDelegate: UNUserNotificationCenterDelegate {

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        print(response.notification.request.content.userInfo)
        completionHandler()
    }

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

Vérifiez ce lien pour plus de détails
https://www.youtube.com/watch?v=Svul_gCtzck

Échantillon Github
https://github.com/kenechilearnscode/UserNotificationsTutorial

Voici la sortie

enter image description here

enter image description here

75
Rajan Maheshwari

Swift 3 | iOS 10 +

En supposant que vous sachiez planifier une notification locale:

func scheduleLocalNotification(forDate notificationDate: Date) {

    let calendar = Calendar.init(identifier: .gregorian)

    let requestId: String = "123"
    let title: String = "Notification Title"
    let body: String = "Notification Body"

    // construct notification content
    let content = UNMutableNotificationContent()
    content.title = NSString.localizedUserNotificationString(forKey: title, arguments: nil)
    content.body = NSString.localizedUserNotificationString(forKey: body, arguments: nil)
    content.sound = UNNotificationSound.default()
    content.badge = 1
    content.userInfo = [
        "key1": "value1"
    ]

    // configure trigger
    let calendarComponents: [Calendar.Component] = [.year, .month, .day, .hour, .minute]
    let dateComponents = calendar.dateComponents(calendarComponents, from: notificationDate)
    let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)

    // create the request
    let request = UNNotificationRequest.init(identifier: requestId, content: content, trigger: trigger)

    // schedule notification
    UNUserNotificationCenter.current().add(request) { (error: Error?) in
        if let error = error {
            // handle error
        }
    }
}

Vous devez faire en sorte que votre AppDelegate implémente le protocole UNUserNotificationCenterDelegate et le définit comme délégué du centre de notifications avec UNUserNotificationCenter.current().delegate = self.

// AppDelegate.Swift

import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions 
        launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        // set app delegate as notification center delegate
        UNUserNotificationCenter.current().delegate = self
    }
}

extension AppDelegate: UNUserNotificationCenterDelegate {

    // called when user interacts with notification (app not running in foreground)
    func userNotificationCenter(_ center: UNUserNotificationCenter, 
        didReceive response: UNNotificationResponse, withCompletionHandler 
        completionHandler: @escaping () -> Void) {

        // do something with the notification
        print(response.notification.request.content.userInfo)

        // the docs say you should execute this asap
        return completionHandler()
    }

    // called if app is running in foreground
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent 
        notification: UNNotification, withCompletionHandler completionHandler: 
        @escaping (UNNotificationPresentationOptions) -> Void) {

        // show alert while app is running in foreground
        return completionHandler(UNNotificationPresentationOptions.alert)
    }
}

Vos notifications locales apparaîtront désormais lorsque votre application sera au premier plan.

Voir les docs NUserNotificationCenterDelegate pour plus de détails.

16
Derek Soike

La clé pour que vos notifications s'affichent lorsque votre application est au premier plan consiste également à définir:

content.setValue(true, forKey: "shouldAlwaysAlertWhileAppIsForeground")

dans votre UNNotificationRequest. Pour le reste, voir l'excellente réponse de Rajan Maheshwari .

14
brown

Lorsque votre application est ouverte dans l'appel de méthode userNotificationCenter de premier plan

func userNotificationCenter(_ center: UNUserNotificationCenter,
   willPresent notification: UNNotification, 
   withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) 
{
    completionHandler(.alert)
}
3
Sourabh Kumbhar