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);
}
同じ問題がありました: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
を呼び出したとき、期待どおりにコールバックを受け取りました。
これで問題は解決しました。それが役に立てば幸い。
IOS 8では、一部のメソッドは廃止されました。 iOS 8との互換性については、以下の手順に従ってください
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)];
}
- (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
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
}
必ずコードを呼び出してください(サポートされている通知の種類に従って更新してください)
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
プロビジョニングプロファイルはAPNS対応です。 APNSを有効にした後、プロビジョニングプロファイルを再ダウンロードする必要がある場合があります。問題が発生してエラーが発生する場合は、Entitlements.plistを作成し、ビルドの種類に応じて値「開発」または「プロダクション」のキー「aps-environment」を追加する必要があります(通常、このキーと値のペアはプロビジョニングプロファイルに含まれていますが、Xcodeが混乱することもあります)。
シミュレーターではリモート通知がサポートされていないことに注意してください。そのため、シミュレータでアプリを実行する場合、didRegisterForRemoteNotificationsWithDeviceToken
は呼び出されません。
以前にプロビジョニングプロファイルを使用してApple Push Notificationサービスを有効化および構成する場合は、プロビジョニングプロファイルを再度ダウンロードする必要があります。
Xcode OrganizerおよびiPhone/iPadからプロビジョニングプロファイルを削除します。 Settings -> General -> Profiles -> [Your provisioning] -> Remove
に移動します。
ダウンロードした新しいプロビジョニングプロファイルをインストールします。次に、XCodeからプロジェクトを削除して実行します。ここで、didRegisterForRemoteNotificationsWithDeviceToken
を呼び出す必要があります。
既存のアプリIDにプッシュを追加した場合は、プロビジョニングプロファイルを再生成してください。そうしないと、プロファイルはアプリIDでのプッシュの有効化を認識しません。
私は間違いを犯し、ここで私を導く実装の詳細を見落としました。アプリケーションのオンボーディングプロセスの後半で、空想を得てプッシュ通知をユーザーに要求しようとしたため、registerForRemoteNotificationTypes
、didRegisterForRemoteNotificationsWithDeviceToken
、およびdidFailToRegisterForRemoteNotificationsWithError
がすべてカスタムUIViewにありました。
修正:didRegisterForRemoteNotificationsWithDeviceToken
とdidFailToRegisterForRemoteNotificationsWithError
はUIApplicationDelegate
(YourAppDelegate.m
)トリガーされます。
今は明らかだね.
インターネット接続がオンになっていることを確認してください。インターネットに接続されているため、仕事の通知を受け取るのに何時間もかかりました。
これを試してみてください、
最初のステップ
- (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 を参照してください。
これが何らかの助けになることを願っています。
-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions{ //Overridepointforcustomizationafterapplicationlaunch.
//Addtheviewcontroller’sviewtothewindowanddisplay. [windowaddSubview:viewController.view]; [windowmakeKeyAndVisible];
NSLog(@”Registering for Push notifications...”);
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes: (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound)];
returnYES;
}
- (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]);
}
デバイストークンを取得するための最小要件:
アプリ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);
}
アプリのプッシュメッセージをシャットダウンした場合、
appdidRegisterForRemoteNotificationsWithDeviceTokenが呼び出されることはありません
最も厄介な3時間を無駄にした後、次の手順で問題を修正します。
アプリを削除する
デバイスをリセットする
再実行
うまくいった
最近、私もこの問題に直面しています。ドキュメントに従ってすべてを実行しましたが、デリゲートメソッドが呼び出していませんでした最後に、ネットワークに関する問題を言っている投稿を見ました。したがって、APNSをブロックできるネットワークはほとんどないため、ネットワークにも注意してください。
また、Apple https://developer.Apple.com/system-status/ でシステムステータスを確認することを忘れないでください。
上記のすべてのソリューションを試してみましたが、結局、APNSサービスがダウンしたために障害が発生しました。翌日、すべてが期待どおりに再び機能しました。
また、コールバックメソッドにタイプミスがあります。
- (void)application:(UIApplication *)appdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
Rupeshが指摘したように、正しいメソッド名は次のとおりです。
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
それがおそらくあなたのケースでトークンを受け取ったことがない理由です!
電話ですべてのデータをリセットして削除したため、これが私に起こりました(使用する開発者の電話が必要でした)。これにより、電話機を再度セットアップした後、APNがまったく接続できなくなりました。
あらゆる種類のことを試しましたが、それを修正した唯一のことは、新しいSIMカードの下でキャリアと連携するように電話を設定することでした。
このリンクは、何が起こっていたかについてのより多くのヒントを提供します: https://developer.Apple.com/library/ios/technotes/tn2265/_index.html
APNは、wifiではなく、キャリア/タワー経由で優先的に接続しようとするという。この問題は、wifiネットワークのポート5223をブロックしているルーターで何かが起こっていたのかもしれませんが、グローバルリセットが発生する前日には正常に機能したため、疑わしいです。
私が含めたサードパーティのライブラリ、つまりFirebaseによってプッシュ通知コールバックがハイジャックされるという別の問題がありました。これらのライブラリは、プッシュ通知コールバックメソッドをスウィズルして、コールバックを取得します。
これが誰かを助けることを願っています。
私にとってそれを解決したのは、ビルド設定とコード署名セクションの下で、コード署名IDとプロビジョニングプロファイルを手動で選択することでした。どうやら自動設定は正しい設定を取得していないため、アプリは適切に認証されていません。
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
}
}
}
}