web-dev-qa-db-ja.com

iOS10でUserNotificationsアクションを処理する方法

だから私はそのように通知をスケジュールすることができます。

//iOS 10 Notification
if #available(iOS 10.0, *) {

    var displayDate: String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = DateFormatter.Style.full
        return dateFormatter.string(from: datePicker.date as Date)
    }
    let notif = UNMutableNotificationContent()


    notif.title = "I am a Reminder"
    notif.subtitle = "\(displayDate)"
    notif.body = "Here's the body of the notification"
    notif.sound = UNNotificationSound.default()
    notif.categoryIdentifier = "reminderNotification"

    let today = NSDate()
    let interval = datePicker.date.timeIntervalSince(today as Date)

    let notifTrigger = UNTimeIntervalNotificationTrigger(timeInterval: interval, repeats: false)

    let request = UNNotificationRequest(identifier: "reminderNotif", content: notif, trigger: notifTrigger)

    UNUserNotificationCenter.current().add(request, withCompletionHandler: { error in
        if error != nil {
            print(error)
           // completion(Success: false)
        } else {
            //completion(Sucess: true)
        }
        })
}

appDelegateで権限を要求しましたが、通知拡張機能を使用したカスタムビューで通知が正常に表示されます。

通知カテゴリのappDelegateに通知アクションを追加しました。これらも表示されます。

//Notifications Actions 

private func configureUserNotifications() {
    if #available(iOS 10.0, *) {

        let tomorrowAction = UNNotificationAction(identifier: "tomorrowReminder", title: "Remind Me Tomorrow", options: [])

        let dismissAction = UNNotificationAction(identifier: "dismissReminder", title: "Dismiss", options: [])


        let category = UNNotificationCategory(identifier: "reminderNotification", actions: [tomorrowAction, dismissAction], intentIdentifiers: [], options: [.customDismissAction])

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

    } else {
        // Fallback on earlier versions
    }
}

通知拡張機能に同じカテゴリを設定しています.plistファイル。また、通知拡張機能には、ユーザーがアクションをタップしたときにテキストを変更するための次のものがあります。

 //Handle Notification Actions And Update Notification Window 


 private func didReceive(_ response: UNNotificationResponse, completionHandler done: (UNNotificationContentExtensionResponseOption) -> Void) {

    if response.actionIdentifier == "tomorrowReminder" {
        print("Tomrrow Button Pressed")
        subLabel.text = "Reminder For Tomorrow"
        subLabel.textColor = UIColor.blue
        done(.dismissAndForwardAction)
    }

    if response.actionIdentifier == "dismissReminder" {
        print("Dismiss Button Pressed")
        done(.dismiss)

    } else {
        print("Else response")
        done(.dismissAndForwardAction)
    }

}

ただし、テキストは変更されず、どのステートメントも呼び出されません。

AppDelegateには、次のものがあります。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
    if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().delegate = self
        configureUserNotifications()

    }
}

extension AppDelegate: UNUserNotificationCenterDelegate {

@available(iOS 10.0, *)
private func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
    completionHandler([.alert, .sound])
}

@available(iOS 10.0, *)
private func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {

    print("Recieved Action For \(response.actionIdentifier)")

    if response.actionIdentifier == "tomorrowReminder" {
        print("Tomorrow Reminder")


        //Set new reminder for tomorrow using the notification content title



        completionHandler()
    }

    if response.actionIdentifier == "dismissReminder" {
        print("Dismiss Reminder...")
        completionHandler()
    }
}

}

これらの関数はどちらも、実際にはappDelegateでも呼び出されません。拡張機能ビューの更新に関する問題がアプリデリゲートに関連しているかどうかはわかりません。私はそうは思いません。私はAppleのWWDCビデオや他のチュートリアルに従って、ドキュメントAPIを調べましたが、理解できません。

  • 通知拡張テキストラベルが更新されないのはなぜですか?
  • AppDelegateの関数が呼び出されないのはなぜですか?
  • アプリデリゲートの通知コンテンツを使用してアクションに使用するにはどうすればよいですか?

PS:私は過去数週間、これを調査して理解しようとしてきましたが、それはかなり簡単に思えたので、何が欠けているのかわかりません。これらの問題を抱えているのは私だけではないことを私は知っています。

8
A.Roe

私はあなたのコード全体をチェックしていませんが、少なくとも、これらの関数ヘッダーは次のように変更する必要があります。

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

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

func didReceive(_ response: UNNotificationResponse,
                completionHandler done: @escaping (UNNotificationContentExtensionResponseOption) -> Void) {

単純なルール:privateを削除し、@escapingを追加します。

Xcodeから間違った提案を受け取った可能性がありますが、それらをprivateにすると、Objective-Cエントリポイントは生成されません。 iOSランタイムは内部でObjective-Cセレクターを使用するため、メソッドを見つけることができないため、メソッドは実行されません。

4
OOPer