2016-10-03 7 views
11

iOS10でプッシュ通知を受け取るように髪を引き裂く。現在の設定:func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> BooliOS 10 UNUserNotificationCenterDelegateが呼び出されていません。プッシュ通知が機能しない

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)

if #available(iOS 10.0, *) { 

      let center = UNUserNotificationCenter.current() 
      center.delegate = self 
      center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in 

       if error == nil { 
        print("DID REQUEST THE NOTIFICATION") 
        UIApplication.shared.registerForRemoteNotifications() 
       } 
      } 
      print("DID SET DELEGATE") 
     } 

print("DID REGISTER FOR A REMOTE NOTIFICATION AND THE TOKEN IS \(deviceToken.base64EncodedString())"   
let request = UpdatePushNotificationSubscription_Request(deviceToken: deviceToken) 
updatePushNotificationSubscriptionWorker.updateSubscription(request) 

私は、トークンが正しくバックエンドにアップロードされ、それが実際に一致しないチェックしています。

は私も実装している:

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

     print("GOT A NOTIFICATION") 

    } 


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

     //This is for the user tapping on the notification 
     print("GOT A NOTIFICATION") 
    } 

は私がすべてのターゲットに対して資格を設定し、プッシュを有効にしている:私はバックエンドデバイスからメッセージを送信しようとすると、

enter image description here

今ただ何も受け取りません。デリゲートは呼び出されていません。ここで私が何をやっているのか分かりません。 iOS9とAndroid搭載端末ではプッシュが機能しています。私が間違っているかもしれないことへのあらゆる指針?

+0

私はまだ同じpを持っているので、これは本当に答えではありませんあなたのような迷惑行為。あなたのデバイストークンが正しく解析されているかどうかチェックしてください。私にとっては、ios10の時点ではそうではありませんでした。しかし、私はそれを修正しましたが、私はまだ呼び出された代議員を持っていません – andrei

+0

あなたは解決策を見つけましたか? – boidkan

+0

誰にもこれに対する解決策がありましたか?私はiOS 10以降も同じ問題が発生しています - 今iOS 10.1.1 –

答えて

14

AppDelegateクラスに、プロトコルを実装する別のクラスではなく、UNUserNotificationCenterDelegateプロトコルを実装するようにしてください。

私はデリゲートのための別のクラスを持っていましたが、動作しませんでした。

import UIKit 
import UserNotifications 

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { 

var window: UIWindow? 

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

    UIApplication.shared.registerForRemoteNotifications() 

    let center = UNUserNotificationCenter.current() 
    center.delegate = self //DID NOT WORK WHEN self WAS MyOtherDelegateClass() 

    center.requestAuthorization(options: [.alert, .sound, .badge]) { 
     (granted, error) in 
      // Enable or disable features based on authorization. 
      if granted { 
       // update application settings 
      } 
    } 

    return true 
} 

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

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

// and so forth for your other AppDelegate stuff 
+1

UNUserNotificationCenter.current()。デリゲートは弱いので、自分自身を生かしておく必要があります。それがAppDelegateがここで良い候補者になっている理由です。あなたはそれのためのクラスjusteを構築し、AppDelegateや他のどこでも生き続けることができます:) – zarghol

+0

@PO Bengtsson and @zargholありがとう!私の 'UNUserNotificationCenterDelegate'メソッドがなぜ呼び出されていないのか理解してくれました。私は通知を扱う別のクラスを持っています。デリゲートメソッドが呼び出されるようにするには、どうすればこのクラスを生き生きとした状態に保つことができますか? –

+0

あなたは単にクラスのシングルトンを使うか、あなたのクラスのどこかで強い参照を保持することでこれを行うことができます(appdelegate、あなたの現在のビューコントローラ...) – zarghol

13

この答えはUserNotificationsフレームワークを使用して、iOSの10+に関連する:これは、私はそれが働いて得たときに私のコードが見えた方法です。

UNUserNotificationCenterDelegateプロトコルに準拠するには、クラスが必要です。このために新しいクラスを作成するかどうかは関係ありません。または、クラスをAppDelegateクラスに追加するかどうかは関係ありません。私は専用のクラスを作成することをお勧めしたいと思います。この回答のために、UserNotificationControllerクラスを作成するとします。

クラスには、次のメソッドを持つことができます。

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

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

は、その後、あなたの AppDelegate.application(_:didFinishLaunchingWithOptions:)方法では、あなたの UserNotificationControllerクラスのインスタンスに UNUserNotificationCenter.current()オブジェクトに delegateを設定する必要があります。おそらく共有インスタンスを使用したいと思うでしょう。

UNUserNotificationCenter.requestAuthorization(options:completionHandler:)メソッドとcompletionHandlerの通知を有効にするようにユーザーからの許可を要求するには、grantedの値を確認します。 trueの場合は、UIApplication.shared.registerForRemoteNotifications()を呼び出してリモート通知を登録します。

今、アプリがプッシュ通知を受け取ると、いくつかの状況が発生する可能性があります。私はここで最も一般的なケースを列挙しようとします。

ローカル通知:アプリがフォアグラウンドである場合

、アプリがUserNotificationController .userNotificationCenter(_:willPresent:withCompletionHandler:)を呼び出します。

アプリがバックグラウンド(実行中または実行中)の場合、通知がタップされるまで何も呼び出されず、その時点でアプリが開き、UserNotificationController .userNotificationCenter(_:didReceive:withCompletionHandler:)が呼び出されます。

リモート通知:

ペイロードの内容は、何が起こるかに影響します。 3ペイロードの例、a)は普通alertbadge、および1またはtrueに設定mutable-contentオプション()を含むcontent-availableオプション(1またはtrueに設定されている)、C)を含むsoundオプションB)があります。さらに、技術的にはd)content-availablemutable-contentの両方を持っていますが、どちらの場合もトリガします。

は)ちょうどalertsoundは、badge情報:

これは、ローカル通知と同じように動作します。 Bの

)真content-available ==:アプリがフォアグラウンドである場合

は、UserNotificationController .userNotificationCenter(_:willPresent:withCompletionHandler:)が呼び出されます。

アプリがバックグラウンドで(実行中かどうかにかかわらず)AppDelegate.application(_:didReceiveRemoteNotification:fetchCompletionHandler:)が呼び出され、UserNotificationControllerクラスのメソッドの1つではありません。真Cについては

mutable-content ==:

、あなたのアプリケーションにUNNotificationServiceExtensionを追加した場合は、通知を処理すると、内容を変更することができます。これは、メインアプリケーションの状態に関係なく発生します。ユーザーが(オプションで変更した)通知をタップすると、上記のローカル通知のように処理されます。

UNNotificationServiceExtensionがない場合、通知は上記の通常のリモート通知のように扱われます。

追加メモ:

mutable-contentを使用して、あなたはペイロードでalert情報を含まなければならない、またはシステムが、それは不変のように扱い、あなたのUNNotificationServiceExtensionにコールすることはありません。変更された通知にはまだalert情報が含まれている必要があります。そうしないと、元の通知ペイロードが使用されます。残念ながら、通知がユーザーに表示されないようにする方法はありません。

content-availableを使用している場合、ユーザーが最後にアプリを強制終了した場合、システムはアプリを再起動したり、AppDelegate.application(_:didReceiveRemoteNotification:fetchCompletionHandler:)に電話をかけたりしません。それでも、警告は表示され、サウンドが再生され、ペイロードに示されているバッジが更新されます。

+2

ファンタスティック答え – shim

0

たぶん、UNNotificationCategoryのintentIdentifiersを設定していない場合は、このようなコード:あなたはこのようintentIdentifiersを設定する必要がありますので、それは、UNUserNotificationCenterのデリゲートメソッドを呼び出しません

UNNotificationCategory* expiredCategory = [UNNotificationCategory 
              categoryWithIdentifier:@"TIMER_EXPIRED" 
              actions:@[snoozeAction, stopAction] 
              intentIdentifiers:@[] 
              options:UNNotificationCategoryOptionCustomDismissAction]; 

UNNotificationCategory* expiredCategory = [UNNotificationCategory 
              categoryWithIdentifier:@"TIMER_EXPIRED" 
              actions:@[snoozeAction, stopAction] 
              intentIdentifiers:@[@"a",@"b"] 
              options:UNNotificationCategoryOptionCustomDismissAction]; 
関連する問題