web-dev-qa-db-ja.com

didRegisterForRemoteNotificationsWithDeviceTokenが呼び出されない理由

Appleプッシュ通知サービス。私は このチュートリアル で説明されているステップバイステップの指示に従っています。

それでも、メソッドは呼び出されません。何が問題の原因なのかわかりません。誰も私を助けることができますか?

    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
        //NSString * token = [[NSString alloc] initWithData:deviceTokenencoding:NSUTF8StringEncoding];
        NSString *str = [NSString stringWithFormat:@"Device Token=%@",deviceToken];
        NSLog(@"Device Token:%@",str);

        //NSLog(@"Device token is called");
        //const void *devTokenBytes = [deviceToken bytes];
        //NSLog(@"Device Token");
    }

    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { 
        NSString *str = [NSString stringWithFormat: @"Error: %@", err];
        NSLog(@"Error:%@",str);    
    }
82
Muzammil

同じ問題がありました:registerForRemoteNotificationTypes:を呼び出すと、application:didRegisterForRemoteNotificationsWithDeviceToken:application:didFailToRegisterForRemoteNotificationsWithError:も呼び出されませんでした

最終的に、Appleのテクニカルノート TN2265 を使用してこの問題を解決しました。

これは私がやったことです:

まず最初に、「aps-environment」キーのプロビジョニングプロファイルと.appファイル自体のコード署名の検証を含め、実際に Push Notificationに正しく登録 であることを再確認しました。すべて正しくセットアップしました。

次に、コンソールでプッシュ通知ステータスメッセージをデバッグする必要がありました(デバイスにPersistentConnectionLogging.mobileconfigプロビジョニングプロファイルをインストールして再起動する必要があります。「プッシュステータスメッセージの監視」の TN2265 を参照してください)。私はapnsプロセスがタイマーを開始し、最小発火日を計算することに気付きました。これにより、通常この時点で表示されるプッシュ通知登録確認メッセージは、TN2265に示されるようにAPNSによって抑制されます。

iOSでのプッシュ通知許可アラートのリセット

プッシュ対応アプリがプッシュ通知に初めて登録するとき、iOSはユーザーにそのアプリの通知を受信するかどうかを尋ねます。ユーザーがこのアラートに応答すると、デバイスが復元されるか、アプリが少なくとも1日アンインストールされない限り、アラートは再度表示されません。

アプリの初回実行をシミュレートする場合は、アプリを1日アンインストールしたままにしておくことができます。システムクロックを1日以上進め、デバイスの電源を完全にオフにしてから再びオンにすることで、実際に1日待つことなく後者を実現できます。

そのため、デバイスからアプリを削除し、[設定]でiPhoneの日付を手動で変更し、デバイスを再起動して、アプリを再インストールしました。

次回、私のコードがregisterForRemoteNotificationTypesを呼び出したとき、期待どおりにコールバックを受け取りました。

これで問題は解決しました。それが役に立てば幸い。

69
100grams

IOS 8では、一部のメソッドは廃止されました。 iOS 8との互換性については、以下の手順に従ってください

1.通知を登録する

if([[UIDevice currentDevice] systemVersion].floatValue >= 8.0)
{
    UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];    
}
else
{
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge)];
}

2.新しい2つのメソッドを追加する

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
    //register to receive notifications
    [application registerForRemoteNotifications];
}

//For interactive notification only
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
    //handle the actions
    if ([identifier isEqualToString:@"declineAction"]){
    }
    else if ([identifier isEqualToString:@"answerAction"]){
    }
}

注:iOS 8では、didRegisterForRemoteNotificationsWithDeviceTokenおよびdidReceiveRemoteNotification。に加えて、上記の2つの新しいメソッドが必要です。それ以外の場合、デリゲートメソッドは呼び出されません。

参照: リモート通知iOS 8

66
user4034301

iOS 8では、プッシュ通知へのアクセスを異なる方法で要求することに加えて、異なる方法で登録する必要があります。

アクセスをリクエスト:

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    // iOS 8
    UIUserNotificationSettings* settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
} else {
    // iOS 7 or iOS 6
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}

登録済みデバイスの処理:

// New in iOS 8
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
}

// iOS 7 or iOS 6
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
    // Send token to server
}
26
Kyle Clegg

必ずコードを呼び出してください(サポートされている通知の種類に従って更新してください)

[[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];

プロビジョニングプロファイルはAPNS対応です。 APNSを有効にした後、プロビジョニングプロファイルを再ダウンロードする必要がある場合があります。問題が発生してエラーが発生する場合は、Entitlements.plistを作成し、ビルドの種類に応じて値「開発」または「プロダクション」のキー「aps-environment」を追加する必要があります(通常、このキーと値のペアはプロビジョニングプロファイルに含まれていますが、Xcodeが混乱することもあります)。

12

シミュレーターではリモート通知がサポートされていないことに注意してください。そのため、シミュレータでアプリを実行する場合、didRegisterForRemoteNotificationsWithDeviceTokenは呼び出されません。

11
Eric

以前にプロビジョニングプロファイルを使用してApple Push Notificationサービスを有効化および構成する場合は、プロビジョニングプロファイルを再度ダウンロードする必要があります。

Xcode OrganizerおよびiPhone/iPadからプロビジョニングプロファイルを削除します。 Settings -> General -> Profiles -> [Your provisioning] -> Removeに移動します。

ダウンロードした新しいプロビジョニングプロファイルをインストールします。次に、XCodeからプロジェクトを削除して実行します。ここで、didRegisterForRemoteNotificationsWithDeviceTokenを呼び出す必要があります。

6
Borislav Gizdov

既存のアプリIDにプッシュを追加した場合は、プロビジョニングプロファイルを再生成してください。そうしないと、プロファイルはアプリIDでのプッシュの有効化を認識しません。

3

私は間違いを犯し、ここで私を導く実装の詳細を見落としました。アプリケーションのオンボーディングプロセスの後半で、空想を得てプッシュ通知をユーザーに要求しようとしたため、registerForRemoteNotificationTypesdidRegisterForRemoteNotificationsWithDeviceToken、およびdidFailToRegisterForRemoteNotificationsWithErrorがすべてカスタムUIViewにありました。

修正:didRegisterForRemoteNotificationsWithDeviceTokendidFailToRegisterForRemoteNotificationsWithErrorUIApplicationDelegateYourAppDelegate.m)トリガーされます。

今は明らかだね.

3
GraehamF

インターネット接続がオンになっていることを確認してください。インターネットに接続されているため、仕事の通知を受け取るのに何時間もかかりました。

3
Rendel

これを試してみてください、

最初のステップ

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

上記の方法で以下のコードを追加します

 UIApplication *application = [UIApplication sharedApplication];
 if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge
                                                                                     |UIUserNotificationTypeSound
                                                                                     |UIUserNotificationTypeAlert) categories:nil];
[application registerUserNotificationSettings:settings];
 } 
 else {
      UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
     }

第二段階

以下のコードを追加

 #ifdef __IPHONE_8_0
   - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
   {
  //register to receive notifications
  [application registerForRemoteNotifications];
  }

 - (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
  {
    //handle the actions
    if ([identifier isEqualToString:@"declineAction"]){
    }
   else if ([identifier isEqualToString:@"answerAction"]){
   }
}
 #endif

以下の機能でデバイストークンを取得します

 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 

詳細な回答については、 This を参照してください。

これが何らかの助けになることを願っています。

3
Jaywant Khedkar
-​(BOOL)application:(UIApplication​*)application​ didFinishLaunchingWithOptions:(NSDictionary​*)launchOptions​{​​​​ ​​​​ ​​​​//​Override​point​for​customization​after​application​launch.
​​​​//​Add​the​view​controller’s​view​to​the​window​and​display. ​​​​[window​addSubview:viewController.view]; ​​​​[window​makeKeyAndVisible];
NSLog(@”Registering for Push notifications...”);
 [[UIApplication sharedApplication]
registerForRemoteNotificationTypes: (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound)]; 
​​​​return​YES;
}


- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
}
NSString *str = [NSString stringWithFormat:@”Device Token=%@”,deviceToken];
NSLog(@”%@”, str);


- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSString *str = [NSString stringWithFormat: @”Error: %@”, err]; NSLog(@”%@”, str);
}


- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
}
for (id key in userInfo) { NSLog(@”key: %@, value: %@”, key, [userInfo objectForKey:key]);
}
2
Sachin Kumaram

デバイストークンを取得するための最小要件:

アプリID、プロビジョニング、または証明書などを設定する必要はありませんしたがって、デリゲートメソッドを取得するコード署名は設定されていませんdidRegisterForRemoteNotificationsWithDeviceTokenが呼び出されました。

Xcode 7でデフォルト設定のシングルビュー用に新しいiOSプロジェクトを作成し、com.mycompany.pushtestのようなランダムなバンドルIDを指定しましたが、これはApple dev portal 。

次のコードを使用すると、iPadのdidRegisterForRemoteNotificationsWithDeviceTokenメソッドでinternet WIFIにアクセスしてデバイストークンを取得できます。デバイスが接続され、xcodeから直接アプリを実行し、xcodeのコンソールで値を表示しています。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions   

{  
    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)])  
    {  
        UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound);  
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes categories:nil];  
        [application registerUserNotificationSettings:settings];  
        [application registerForRemoteNotifications];  
    }  
    else  
    {  
        // Register for Push Notifications, if running iOS version < 8  
        [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];  
    }  
    return YES;  
}  


- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"Error: %@", error.description);
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSLog(@"didRegisterForRemoteNotificationsWithDeviceToken: %@", deviceToken);
}

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    NSLog(@"NotificationSettings: %@", notificationSettings);
}
2
zeeawan

アプリのプッシュメッセージをシャットダウンした場合、

appdidRegisterForRemoteNotificationsWithDeviceTokenが呼び出されることはありません

1
libai

最も厄介な3時間を無駄にした後、次の手順で問題を修正します。

  1. アプリを削除する

  2. デバイスをリセットする

  3. 再実行

うまくいった

1
ozd

最近、私もこの問題に直面しています。ドキュメントに従ってすべてを実行しましたが、デリゲートメソッドが呼び出していませんでした最後に、ネットワークに関する問題を言っている投稿を見ました。したがって、APNSをブロックできるネットワークはほとんどないため、ネットワークにも注意してください。

1
SURESH SANKE

また、Apple https://developer.Apple.com/system-status/ でシステムステータスを確認することを忘れないでください。

上記のすべてのソリューションを試してみましたが、結局、APNSサービスがダウンしたために障害が発生しました。翌日、すべてが期待どおりに再び機能しました。

また、コールバックメソッドにタイプミスがあります。

- (void)application:(UIApplication *)appdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

Rupeshが指摘したように、正しいメソッド名は次のとおりです。

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

それがおそらくあなたのケースでトークンを受け取ったことがない理由です!

0
Brett

電話ですべてのデータをリセットして削除したため、これが私に起こりました(使用する開発者の電話が必要でした)。これにより、電話機を再度セットアップした後、APNがまったく接続できなくなりました。

あらゆる種類のことを試しましたが、それを修正した唯一のことは、新しいSIMカードの下でキャリアと連携するように電話を設定することでした。

このリンクは、何が起こっていたかについてのより多くのヒントを提供します: https://developer.Apple.com/library/ios/technotes/tn2265/_index.html

APNは、wifiではなく、キャリア/タワー経由で優先的に接続しようとするという。この問題は、wifiネットワークのポート5223をブロックしているルーターで何かが起こっていたのかもしれませんが、グローバルリセットが発生する前日には正常に機能したため、疑わしいです。

0

私が含めたサードパーティのライブラリ、つまりFirebaseによってプッシュ通知コールバックがハイジャックされるという別の問題がありました。これらのライブラリは、プッシュ通知コールバックメソッドをスウィズルして、コールバックを取得します。

これが誰かを助けることを願っています。

0
jarora

私にとってそれを解決したのは、ビルド設定とコード署名セクションの下で、コード署名IDとプロビジョニングプロファイルを手動で選択することでした。どうやら自動設定は正しい設定を取得していないため、アプリは適切に認証されていません。

0
Diego Rebosio

DidFinishLaunchingWithOptionsからregisterForNotificationsメソッドを呼び出す必要があります。

 func registerForNotifications(){

        if #available(iOS 10.0, *) {

            let center = UNUserNotificationCenter.current()
            center.delegate = self
            center.requestAuthorization(options:[.alert,.sound,.badge]) { (granted, error) in
                if granted{
                    UIApplication.shared.registerForRemoteNotifications()
                }else{

                    print("Notification permission denied.")

                }
            }

        } else {

            // For iOS 9 and Below
            let type: UIUserNotificationType = [.alert,.sound,.badge];
            let setting = UIUserNotificationSettings(types: type, categories: nil);
            UIApplication.shared.registerUserNotificationSettings(setting);
            UIApplication.shared.registerForRemoteNotifications()
        }
    }

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

        let token = String(format: "%@", deviceToken as CVarArg).trimmingCharacters(in: CharacterSet(charactersIn: "<>")).replacingOccurrences(of: " ", with: "")
        print(token)

    }


extension AppDelegate : UNUserNotificationCenterDelegate{

    @available(iOS 10.0, *)

    func userNotificationCenter(_ center: UNUserNotificationCenter,  willPresent notification: UNNotification, withCompletionHandler   completionHandler: @escaping (_ options:   UNNotificationPresentationOptions) -> Void) {
        print("Handle Push from foreground”)

        let info = ((notification.request.content.userInfo as NSDictionary).value(forKey: "aps") as! NSDictionary)
        if let type = info.value(forKey: "type") as? Int{
            if type == 0 {  

         // notification received ,Handle your notification here

            }
        }
    }

    @available(iOS 10.0, *)

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

        print("Handle Push from background or closed")

        let info = ((response.notification.request.content.userInfo as NSDictionary).value(forKey: "aps") as! NSDictionary)
        if let type = info.value(forKey: "type") as? Int{
            if type == 0 {   

            // notification received ,Handle your notification here
            }
        }
    }
}
0
Ved Rauniyar