iPhoneでユーザーがプッシュ通知を有効にしているかどうかを確認する


回答:


300

enabledRemoteNotificationsTypesマスクを呼び出して確認します。

例えば:

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone) 
   // blah blah blah

iOS8以降:

[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]

19
iOS 5:これは、アプリがスマートフォンの通知センターにあるかどうかに関係なく、アプリが使用するプッシュ通知の種類をチェックします。アプリのプッシュ通知を無効にしても、タイプ== 6を取得しました。サウンドとアラートのスタイルを無効にすると、タイプ== UIRemoteNotificationTypeNoneを取得しました。
クォンタムポテト

4
Quantumpotatoが指摘したように、この回答はもはやすべてのケースを処理するわけではなく、完全なソリューションではありません。
DBD 2012

5
アップルで何が起こっているのですか?この問題に対する彼らの反応を聞かせていただければ幸いです。このような基本的な情報を知らずに優れたアプリを開発するにはどうすればよいですか?
Oded Regev 2013年

15
@ZacBowling- iOS 8ユーザーがリモート通知に登録したかどうかのみをチェックするため、それ以上のソリューションは間違っています。ドキュメントによると:This method reflects only the successful completion of the remote registration process that begins when you call the registerForRemoteNotifications method. This method does not reflect whether remote notifications are actually available due to connectivity issues. The value returned by this method takes into account the user’s preferences for receiving remote notifications.
Apan

5
だから私の意見では、あなたもチェックする必要があります[[UIApplication sharedApplication] currentUserNotificationSettings];
Apan

99

量子ポテトの問題:

どこtypesで与えられる

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];

使用できる

if (types & UIRemoteNotificationTypeAlert)

の代わりに

if (types == UIRemoteNotificationTypeNone) 

通知が有効になっているかどうかのみを確認できます(サウンド、バッジ、通知センターなどについては心配しないでください)。「アラートスタイル」が「バナー」または「アラート」に設定されている場合、および「アラートスタイル」が「なし」に設定されている場合、他の設定に関係なく、コードの最初の行(types & UIRemoteNotificationTypeAlert)が返されます。YESNO


これは、quantumpotatoの問題には対応していません。彼はアラートだけに関心があるのではなく、ユーザーが通知センターの設定をオンまたはオフに切り替えたかどうかをenabledRemoteNotificationsで識別できないことを指摘しています。
ジョーイ

8
私の答えは「アプリが通知センターにあるかどうかを判断する方法」に直接答えることはできませんが、ユーザーがアプリの通知を受け取るかどうかを確認する方法を提供します。これは質問の精神における答えだと思います。前者を確認することはできないと思います。
ティムキャンバー2013

2
「if(types&UIRemoteNotificationTypeAlert)」のトリックは非常に優れています。
nembleton 2014

トリックが機能する理由を必ず理解してください!ビット演算子は非常に便利で、ビットマスクはCocoaでは一般的です。stackoverflow.com/a/3427633/1148702を
Tim Camber 14

2
Swift2 / XCode7では、ビットごとの演算がエラーで失敗します。2 項演算子「&」は2つの「UIUserNotificationType」オペランドに適用できません。代わりにcontainsを使用できますgrantedSettings.types.contains(notificationType)
Philipp Otto

54

iOSの最新バージョンでは、このメソッドは非推奨になりました。iOS 7とiOS 8の両方をサポートするには、以下を使用します。

UIApplication *application = [UIApplication sharedApplication];

BOOL enabled;

// Try to use the newer isRegisteredForRemoteNotifications otherwise use the enabledRemoteNotificationTypes.
if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
{
    enabled = [application isRegisteredForRemoteNotifications];
}
else
{
    UIRemoteNotificationType types = [application enabledRemoteNotificationTypes];
    enabled = types & UIRemoteNotificationTypeAlert;
}

2
ローカル通知はどうですか?iOS 8では、ユーザーがそれらを許可する必要があります。しかし、これらが許可されているかどうかを後で確認するにはどうすればよいですか?
フレデリック・ダッダ

@FredA。確認してくださいUserNotifications。残念ながら、今のところ完全な答えはありません。
Mazyod 2015年

1
@FredA。これが私の主題です。
Mazyod 2015年

3
Swiftではenabled = types&UIRemoteNotificationTypeAlertを実行できません。エラー:型はブールではありません
壮大な

53

swift4.0、iOS11の更新されたコード

import UserNotifications

UNUserNotificationCenter.current().getNotificationSettings { (settings) in
   print("Notification settings: \(settings)")
   guard settings.authorizationStatus == .authorized else { return }

   //Not authorised 
   UIApplication.shared.registerForRemoteNotifications()
}

swift3.0、iOS10のコード

    let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications
    if isRegisteredForRemoteNotifications {
        // User is registered for notification
    } else {
        // Show alert user is not registered for notification
    }

iOS9から、swift 2.0 UIRemoteNotificationTypeは非推奨になりました。次のコードを使用してください

let notificationType = UIApplication.shared.currentUserNotificationSettings!.types
if notificationType == UIUserNotificationType.none {
        // Push notifications are disabled in setting by user.
    }else{
  // Push notifications are enabled in setting by user.

}

プッシュ通知が有効になっているかどうかを確認するだけです

    if notificationType == UIUserNotificationType.badge {
        // the application may badge its icon upon a notification being received
    }
    if notificationType == UIUserNotificationType.sound {
        // the application may play a sound upon a notification being received

    }
    if notificationType == UIUserNotificationType.alert {
        // the application may display an alert upon a notification being received
    }

33

以下に、iOS8とiOS7(およびそれ以前のバージョン)の両方を網羅する完全な例を示します。iOS8より前のバージョンでは、「リモート通知が無効」と「ロック画面でのみ表示が有効」を区別できないことに注意してください。

BOOL remoteNotificationsEnabled = false, noneEnabled,alertsEnabled, badgesEnabled, soundsEnabled;

if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    // iOS8+
    remoteNotificationsEnabled = [UIApplication sharedApplication].isRegisteredForRemoteNotifications;

    UIUserNotificationSettings *userNotificationSettings = [UIApplication sharedApplication].currentUserNotificationSettings;

    noneEnabled = userNotificationSettings.types == UIUserNotificationTypeNone;
    alertsEnabled = userNotificationSettings.types & UIUserNotificationTypeAlert;
    badgesEnabled = userNotificationSettings.types & UIUserNotificationTypeBadge;
    soundsEnabled = userNotificationSettings.types & UIUserNotificationTypeSound;

} else {
    // iOS7 and below
    UIRemoteNotificationType enabledRemoteNotificationTypes = [UIApplication sharedApplication].enabledRemoteNotificationTypes;

    noneEnabled = enabledRemoteNotificationTypes == UIRemoteNotificationTypeNone;
    alertsEnabled = enabledRemoteNotificationTypes & UIRemoteNotificationTypeAlert;
    badgesEnabled = enabledRemoteNotificationTypes & UIRemoteNotificationTypeBadge;
    soundsEnabled = enabledRemoteNotificationTypes & UIRemoteNotificationTypeSound;
}

if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    NSLog(@"Remote notifications enabled: %@", remoteNotificationsEnabled ? @"YES" : @"NO");
}

NSLog(@"Notification type status:");
NSLog(@"  None: %@", noneEnabled ? @"enabled" : @"disabled");
NSLog(@"  Alerts: %@", alertsEnabled ? @"enabled" : @"disabled");
NSLog(@"  Badges: %@", badgesEnabled ? @"enabled" : @"disabled");
NSLog(@"  Sounds: %@", soundsEnabled ? @"enabled" : @"disabled");

6
userNotificationSettings.types&UIUserNotificationTypeNoneは常にfalseになります。UIUserNotificationTypeNoneは空のビットマスクであるため、他のビットがないためです。Noneの場合は、等しいかどうかを確認するだけです。
dberwick 2015年

25

Swift 3以上

    if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings: UNNotificationSettings) in
            // settings.authorizationStatus == .authorized
        })
    } else {
        return UIApplication.shared.currentUserNotificationSettings?.types.contains(UIUserNotificationType.alert) ?? false
    }

iOS10以降のRxSwift監視可能バージョン:

import UserNotifications
extension UNUserNotificationCenter {
    static var isAuthorized: Observable<Bool> {
        return Observable.create { observer in
            DispatchQueue.main.async {
                current().getNotificationSettings(completionHandler: { (settings: UNNotificationSettings) in
                    if settings.authorizationStatus == .authorized {
                        observer.onNext(true)
                        observer.onCompleted()
                    } else {
                        current().requestAuthorization(options: [.badge, .alert, .sound]) { (granted, error) in
                            observer.onNext(granted)
                            observer.onCompleted()
                        }
                    }
                })
            }
            return Disposables.create()
        }
    }
}

1
あなたは私の日を救います。:)
Chetan Dobariya 2017年

1
ありがとう、私はこれを1時間探していました。
Chanchal Warde

4
getNotificationSettings(...)非同期なので、内部のリターンは無視されます
shelll

17

iOS8以下の両方をサポートしようisRegisteredForRemoteNotificationsとして、Kevinが示唆したように使用するのにあまり運がありませんでした。代わりに私はを使用しましたがcurrentUserNotificationSettings、これは私のテストでうまく機能しました。

+ (BOOL)notificationServicesEnabled {
    BOOL isEnabled = NO;

    if ([[UIApplication sharedApplication] respondsToSelector:@selector(currentUserNotificationSettings)]){
        UIUserNotificationSettings *notificationSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];

        if (!notificationSettings || (notificationSettings.types == UIUserNotificationTypeNone)) {
            isEnabled = NO;
        } else {
            isEnabled = YES;
        }
    } else {
        UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
        if (types & UIRemoteNotificationTypeAlert) {
            isEnabled = YES;
        } else{
            isEnabled = NO;
        }
    }

    return isEnabled;
}

これは、アプリケーションが新しくインストールされた場合は適用されません。このメソッドは常にNOを返し、プッシュ通知のポップアップ権限は表示されません。したがって、デバイスの設定では、そのアプリの通知設定を変更(許可/禁止)したい場合、そのアプリは表示されません。誰もがこの問題を回避する方法を知っていますか?
tyegah123

アプリが削除されても、通知設定は保持されます。したがって、アプリがまったく新しい場合は、この方法が機能します。アプリが削除された後で再インストールされた場合、権限はシステムに残っているため、Appleは権限を再度尋ねる機会を提供しません。
Shaheen Ghiassy 2015

いくつかの冗長なコードが表示されます。次のように初期化されているためisEnabled = NO;ifケースでは必要ありませんNO
Jasper

15

残念ながら、関連する情報を提供することに関しては、結局のところAPIが非常に不足しているため、これらのソリューションはどれも実際には問題を解決しません。いくつか推測することはできますが、currentUserNotificationSettings(iOS8以降)を使用するだけでは、現在の形式では実際に質問に答えるだけでは不十分です。ここでの多くの解決策isRegisteredForRemoteNotificationsは、それがより確実な答えであると示唆しているようですが、実際にはそうではありません。

このことを考慮:

isRegisteredForRemoteNotificationsドキュメントの状態:

システム全体の設定を考慮して、アプリケーションが現在リモート通知用に登録されている場合はYESを返します...

ただしNSLog、動作を観察するために単純にアプリデリゲートにスローする場合、これが機能することを予測している方法で動作しないことが明らかです。実際には、このアプリ/デバイスでアクティブ化されているリモート通知に直接関係しています。初めてアクティブ化すると、これは常に戻りYESます。設定(通知)でそれらをオフにしても、これが返されます。YESこれは、iOS8の時点で、アプリがリモート通知に登録し、ユーザーが通知を有効にしていない状態でデバイスに送信することもあり、アラートを実行しない場合があるためです。ユーザーがオンにしなくてもバッジとサウンド。サイレント通知は、通知がオフになっていても引き続き実行できることの良い例です。

currentUserNotificationSettings4つのことの1つを示す限り:

アラートはオンバッジはオンサウンドはオンなしはオン

これにより、他の要因や通知スイッチ自体についてはまったく何も示されません。

ユーザーは、実際にはバッジ、サウンド、アラートをオフにしても、ロック画面または通知センターに表示されることがあります。このユーザーは引き続きプッシュ通知を受信して​​おり、ロック画面と通知センターの両方でそれらを表示できる必要があります。通知スイッチがオンになっています。しかし、その場合currentUserNotificationSettingsは次を返しますUIUserNotificationTypeNone。これは、ユーザーの実際の設定を実際に示すものではありません。

いくつかの推測を行うことができます:

  • その場合isRegisteredForRemoteNotificationsNO、このデバイスがリモート通知に正常に登録されたことがないと想定できます。
  • 初めてリモート通知に登録した後、application:didRegisterUserNotificationSettings:この時点でユーザー通知設定を含むコールバックが行われます。これは、ユーザーが初めて登録されたため、設定、ユーザーが許可リクエストに関して選択したもの示しているはずです。設定が以下以外の場合:UIUserNotificationTypeNoneプッシュ許可が付与され、それ以外の場合は拒否されました。その理由は、リモート登録プロセスを開始した瞬間から、ユーザーは受け入れまたは拒否のみが可能であり、受け入れの初期設定は登録プロセス中に設定した設定であるためです。

8

答えを完成させるには、次のように機能します...

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
switch (types) {
   case UIRemoteNotificationTypeAlert:
   case UIRemoteNotificationTypeBadge:
       // For enabled code
       break;
   case UIRemoteNotificationTypeSound:
   case UIRemoteNotificationTypeNone:
   default:
       // For disabled code
       break;
}

編集:これは正しくありません。これらはビット単位のものであるため、スイッチでは機能しないため、これを使用して終了しました。

UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
UIRemoteNotificationType typesset = (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge);
if((types & typesset) == typesset)
{
    CeldaSwitch.chkSwitch.on = true;
}
else
{
    CeldaSwitch.chkSwitch.on = false;
}

(私の状況では)サウンド通知が無効になっていると考えました(テキストがアプリの機能で有効になっていると見なす必要があるため)
pojomx

5

iOS7以前の場合、実際に使用enabledRemoteNotificationTypesして、それが次の値と等しい(または、必要に応じて等しくない)かどうかを確認する必要があります。UIRemoteNotificationTypeNone

ただし、iOS8では、上記の状態を確認するだけで必ずしも十分ではありませんisRegisteredForRemoteNotifications。また、application.currentUserNotificationSettings.types等しいかどうか(必要に応じて等しくないかどうか)も確認する必要がありますUIUserNotificationTypeNone

isRegisteredForRemoteNotificationscurrentUserNotificationSettings.types返してもtrueを返す場合がありますUIUserNotificationTypeNone


5

iOS8 +(OBJECTIVE C)

#import <UserNotifications/UserNotifications.h>


[[UNUserNotificationCenter currentNotificationCenter]getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {

    switch (settings.authorizationStatus) {
          case UNAuthorizationStatusNotDetermined:{

            break;
        }
        case UNAuthorizationStatusDenied:{

            break;
        }
        case UNAuthorizationStatusAuthorized:{

            break;
        }
        default:
            break;
    }
}];

4
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types & UIRemoteNotificationTypeAlert)
    // blah blah blah
{
    NSLog(@"Notification Enabled");
}
else
{
    NSLog(@"Notification not enabled");
}

ここでは、UIApplicationからUIRemoteNotificationTypeを取得しています。設定でこのアプリのプッシュ通知の状態を表していますが、その種類を簡単に確認できます


3
このコードが何をするか説明してください。コードを書くことは単に質問に答えるものではありません。
バティ14

4

@Shaheen Ghiassyが提供するソリューションを使用してiOS 10以上をサポートしようとしましたが、剥奪の問題が見つかりましたenabledRemoteNotificationTypes。したがって、iOS 8で廃止されたソリューションのisRegisteredForRemoteNotifications代わりに使用して見つけたソリューションをenabledRemoteNotificationTypes以下に示します。更新されたソリューションは、私にとって完璧に機能しました。

- (BOOL)notificationServicesEnabled {
    BOOL isEnabled = NO;
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(currentUserNotificationSettings)]){
        UIUserNotificationSettings *notificationSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];

        if (!notificationSettings || (notificationSettings.types == UIUserNotificationTypeNone)) {
            isEnabled = NO;
        } else {
            isEnabled = YES;
        }
    } else {

        if ([[UIApplication sharedApplication] isRegisteredForRemoteNotifications]) {
            isEnabled = YES;
        } else{
            isEnabled = NO;
        }
    }
    return isEnabled;
}

そして、この関数を簡単に呼び出してそのBool値にアクセスし、これを文字列値に変換できます。

NSString *str = [self notificationServicesEnabled] ? @"YES" : @"NO";

それが他の人にも役立つことを願っています:)幸せなコーディング。


3

Zacの答えはiOS 7まで完全に正しかったが、iOS 8の登場以来、答えは変わった。enabledRemoteNotificationTypesはiOS 8以降では非推奨となっているためです。iOS 8以降の場合は、isRegisteredForRemoteNotificationsを使用する必要があります。

  • iOS 7以前の場合-> enabledRemoteNotificationTypesを使用
  • iOS 8以降-> isRegisteredForRemoteNotificationsを使用します。

2

このSwiftyソリューションは私(iOS8 +)にうまくいきました、

方法

func isNotificationEnabled(completion:@escaping (_ enabled:Bool)->()){
    if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings: UNNotificationSettings) in
            let status =  (settings.authorizationStatus == .authorized)
            completion(status)
        })
    } else {
        if let status = UIApplication.shared.currentUserNotificationSettings?.types{
            let status = status.rawValue != UIUserNotificationType(rawValue: 0).rawValue
            completion(status)
        }else{
            completion(false)
        }
    }
}

使用法

isNotificationEnabled { (isEnabled) in
            if isEnabled{
                print("Push notification enabled")
            }else{
                print("Push notification not enabled")
            }
        }

参照


0

re:

これは正しいです

if (types & UIRemoteNotificationTypeAlert)

しかし、以下も正しいです!(UIRemoteNotificationTypeNoneは0であるため)

if (types == UIRemoteNotificationTypeNone) 

次を参照してください

NSLog(@"log:%d",0 & 0); ///false
NSLog(@"log:%d",1 & 1); ///true
NSLog(@"log:%d",1<<1 & 1<<1); ///true
NSLog(@"log:%d",1<<2 & 1<<2); ///true
NSLog(@"log:%d",(0 & 0) && YES); ///false
NSLog(@"log:%d",(1 & 1) && YES); ///true
NSLog(@"log:%d",(1<<1 & 1<<1) && YES); ///true
NSLog(@"log:%d",(1<<2 & 1<<2) && YES); ///true

0

Xamarin.iosでこれを行う方法は次のとおりです。

public class NotificationUtils
{
    public static bool AreNotificationsEnabled ()
    {
        var settings = UIApplication.SharedApplication.CurrentUserNotificationSettings;
        var types = settings.Types;
        return types != UIUserNotificationType.None;
    }
}

iOS 10以降をサポートしている場合は、UNUserNotificationCenterメソッドのみを使用してください。


0

Xamarinでは、上記のすべてのソリューションが機能しません。これは私が代わりに使用するものです:

public static bool IsRemoteNotificationsEnabled() {
    return UIApplication.SharedApplication.CurrentUserNotificationSettings.Types != UIUserNotificationType.None;
}

[設定]で通知ステータスを変更した後も、ライブアップデートを取得しています。


-1

@ZacBowlingのソリューションから構築された完全に簡単なコピーアンドペーストコード(https://stackoverflow.com/a/1535427/2298002

これにより、ユーザーがアプリの設定に移動し、すぐに有効にできるようになります

位置情報サービスが有効になっているかどうかを確認するためのソリューションも追加しました(設定にも反映します)

// check if notification service is enabled
+ (void)checkNotificationServicesEnabled
{
    if (![[UIApplication sharedApplication] isRegisteredForRemoteNotifications])
    {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Notification Services Disabled!"
                                                            message:@"Yo don't mess around bro! Enabling your Notifications allows you to receive important updates"
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:@"Settings", nil];

        alertView.tag = 300;

        [alertView show];

        return;
    }
}

// check if location service is enabled (ref: https://stackoverflow.com/a/35982887/2298002)
+ (void)checkLocationServicesEnabled
{
    //Checking authorization status
    if (![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied)
    {

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Location Services Disabled!"
                                                            message:@"You need to enable your GPS location right now!!"
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:@"Settings", nil];

        //TODO if user has not given permission to device
        if (![CLLocationManager locationServicesEnabled])
        {
            alertView.tag = 100;
        }
        //TODO if user has not given permission to particular app
        else
        {
            alertView.tag = 200;
        }

        [alertView show];

        return;
    }
}

// handle bringing user to settings for each
+ (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{

    if(buttonIndex == 0)// Cancel button pressed
    {
        //TODO for cancel
    }
    else if(buttonIndex == 1)// Settings button pressed.
    {
        if (alertView.tag == 100)
        {
            //This will open ios devices location settings
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=LOCATION_SERVICES"]];
        }
        else if (alertView.tag == 200)
        {
            //This will open particular app location settings
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
        }
        else if (alertView.tag == 300)
        {
            //This will open particular app location settings
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
        }
    }
}

GL HF!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.