web-dev-qa-db-ja.com

アプリがフォアグラウンドにあるときにローカル通知を表示するSwift 3

どうやらこれはios10で可能になりました:

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

この回答は、基本的にそれを行うために必要なツールを示しています。

アプリが開いてフォアグラウンドにあるときに、iOSの通知通知バナーを表示しますか?

私はそれをすべてまとめる方法を本当に理解していないだけです。

これがどれほど重要かはわかりませんが、オプションのfuncを保持できず、xcodeはプライベートに切り替えることを望んでいます。

バッジを表示しようとしていますが、ドキュメントは

static var badge: UNNotificationPresentationOptions { get }

ここで少し失われました。

そして、特定のView Controllerをこれらのバッジの取得から除外したい場合、私が見つけたNavigation Controllerを使用していない場合、このコードは機能しますか? :var window:UIWindow?

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

IOS 10でアプリが開いているときに通知を表示するデリゲートメソッドがあります。アプリが開いているときにリッチ通知を機能させるには、これを実装する必要があります。

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

}

IOS 10で通知をスケジュールし、バッジを提供するため

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

AppDelegateに登録するには、このコードをdidFinishLaunchingWithOptionsで記述する必要があります

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

ここでもアクションを定義しました。あなたはそれらをスキップしてもよい

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

    }

通知バナーをアプリケーション全体のどこにでも表示する場合は、UNUserNotificationDelegateAppDelegateのデリゲートを記述し、UNUserNotificationCenterの現在のデリゲートを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]) 
    }
}

詳細については、このリンクを確認してください
https://www.youtube.com/watch?v=Svul_gCtzck

Githubサンプル
https://github.com/kenechilearnscode/UserNotificationsTutorial

これが出力です

enter image description here

enter image description here

75

Swift 3 | iOS 10 +

ローカル通知をスケジュールする方法を知っていると仮定します。

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

AppDelegateUNUserNotificationCenterDelegateプロトコルを実装させ、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)
    }
}

これで、アプリがフォアグラウンドにあるときにローカル通知が表示されます。

NUserNotificationCenterDelegate のドキュメントを参照してください。

16
Derek Soike

アプリがフォアグラウンドにあるときに通知を表示するための鍵も設定されています。

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

あなたのUNNotificationRequestで。その他については、 Rajan Maheshwari による優れた回答を参照してください。

14
brown

アプリがフォアグラウンドで開かれている場合userNotificationCenterメソッドの呼び出し

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