IOS7とiOS8をターゲットにしたアプリを作成しています。プッシュ通知を送信する許可をユーザーに求めます。しかし、何らかの理由で、プッシュ許可を求められたときに「いいえ」をクリックしても、iOS7もiOS8も_application:didFailToRegisterForRemoteNotificationsWithError
_ハンドラーを呼び出さない。
私の質問:ユーザーがプッシュ通知のリクエストを却下したことをiOS7とiOS8の両方でどのように知ることができますか?彼らは要求を拒否しましたか?
私はStackOverflowの回答をたくさん見て、それらが提案するものを実装しましたが、文書化されているようには機能していません。
application:didRegisterForRemoteNotificationsWithDeviceToken:
_ハンドラーを呼び出します。だから私は彼らがそれを承認したと言うことができます。しかし、ユーザーがリクエストを拒否した場合、_application:didFailToRegisterForRemoteNotificationsWithError
_へのコールバックは取得されません。これはバグのようで、ユーザーがリクエストを拒否したことはわかりません。application:didRegisterUserNotificationSettings
_ハンドラーを呼び出します。 notificationSettings
パラメーターを調べて、ユーザーが私の要求を承認または拒否したかどうかを確認できるので、便利です。 isRegisteredForRemoteNotifications()
を呼び出すと(たとえば、アプリが後でアクティブになったとき)、ユーザーがリクエストを拒否した場合でも常にtrueが返されます。だから私は誤検知を取得します。これはバグのようで、 他の人もこれに気づいています 。let settings = UIApplication.sharedApplication().currentUserNotificationSettings()
を呼び出すと、_settings.types
_をチェックしてアラートが許可されているかどうかを確認できます。つまり、iOS8の場合、準備が整ったように見えます。NSUserDefaults
ブール値を使用して、ユーザーに許可を付与するように既に要求したかどうかを追跡しています。
テストには、シミュレーターではなく、ハードウェアデバイス(iOS7を搭載したiPhone4SおよびiOS8を搭載したiPhone5)を使用しています。
私は 各テスト後にデバイスをリセットする 、リクエストアラートを再度表示するようにしています。
プッシュ通知に登録する方法は次のとおりです。 if
ブランチはiOS8で使用され、else
ブランチはiOS7で使用されます。
_ let application = UIApplication.sharedApplication()
if (application.respondsToSelector("registerUserNotificationSettings:")) {
let settings = UIUserNotificationSettings(forTypes: .Badge | .Alert | .Sound,
categories: nil )
application.registerUserNotificationSettings(settings)
} else {
application.registerForRemoteNotificationTypes(.Badge | .Alert | .Sound)
}
_
(iOS8では、_application:didRegisterUserNotificationSettings:
_が呼び出されると、application.registerForRemoteNotifications()
が呼び出されます)。
登録が失敗しなかったため、didFailToRegisterForRemoteNotificationsWithError
メソッドは呼び出されません。ユーザーがリクエストを拒否したため、メソッドは呼び出されませんでした。
IOS7では、いくつかのことができます。
didRegisterForRemoteNotificationsWithDeviceToken
が呼び出されるまでリモート通知は利用できないと想定しますenabledRemoteNotificationTypes
オブジェクトの値UIApplication
を確認してください私はこの同じ問題を回避する方法を見つけようとしていました。
プッシュ通知権限UIAlertが表示されると、アプリの外部から表示されます。ユーザーが「許可しない」または「OK」を選択すると、アプリが再びアクティブになります。
ユーザーにプッシュ権限の入力を求める前に提示しているViewControllerがあります。このビューコントローラーでは、UIApplicationDidBecomeActiveNotification
をリッスンしてから、ビューコントローラーを閉じます。
これはかなりうまく機能していますが、私が見た他のすべてのソリューションは私にはまったく機能していません。
IOS8以降に対してコンパイルしていると仮定すると、次のデリゲートメソッドを使用できます。
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
print("Notifications status: \(notificationSettings)")
}
次に、didFinishLaunching(またはニーズに適した場所)で、次を呼び出す必要があります。
let app = UIApplication.sharedApplication()
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
app.registerUserNotificationSettings(settings)
app.registerForRemoteNotifications()
この時点で、ユーザーは通常の「許可/許可しないプロンプト」メッセージでプロンプトが表示されます。ユーザーの選択に関係なく、上記のメソッドが呼び出され、アプリのきめ細かい構成が可能になります。結果は次のようになります。
Notification Status: <UIUserNotificationSettings: 0x7fa261701da0; types: (none);>
Notification Status: <UIUserNotificationSettings: 0x7ff032e21dd0; types: (UIUserNotificationTypeAlert UIUserNotificationTypeBadge UIUserNotificationTypeSound);>
最初のケースでは、ユーザーが通知を拒否したことに気付くでしょう。 2つ目は、許可オプションに関するものです。