ユーザーが設定を介して、アプリケーションのプッシュ通知を有効または無効にしているかどうかを判断する方法を探しています。
19 に答える
enabledRemoteNotificationsTypes
マスクを呼び出して確認します。
例えば:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone)
// blah blah blah
iOS8以降:
[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
量子ポテトの問題:
types
によって与えられる場所
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
使用できます
if (types & UIRemoteNotificationTypeAlert)
それ以外の
if (types == UIRemoteNotificationTypeNone)
通知が有効になっているかどうかのみを確認できます(サウンド、バッジ、通知センターなどについて心配する必要はありません)。コードの最初の行( )は、他の設定に関係なく、「アラートスタイル」が「バナー」または「アラート」に設定されている場合、および「アラートスタイル」が「なし」に設定されている場合types & UIRemoteNotificationTypeAlert
に返されます。YES
NO
iOSの最新バージョンでは、このメソッドは非推奨になりました。iOS7とiOS8の両方をサポートするには、次を使用します。
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;
}
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から、swift2.0UIRemoteNotificationTypeは非推奨になりました。次のコードを使用してください
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
}
以下に、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");
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以降のRxSwiftObservableバージョン:
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()
}
}
}
isRegisteredForRemoteNotifications
iOS8以下の両方をサポートしようとして、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;
}
残念ながら、提供されたこれらのソリューションはどれも実際には問題を解決しません。なぜなら、結局のところ、関連情報の提供に関してAPIが深刻に不足しているからです。いくつか推測することはできますがcurrentUserNotificationSettings
、現在の形式では(iOS8 +)を使用するだけでは、実際に質問に答えるには不十分です。isRegisteredForRemoteNotifications
ここでの解決策の多くは、それがより決定的な答えであることを示唆しているように見えますが、実際にはそうではありません。
このことを考慮:
isRegisteredForRemoteNotifications
ドキュメントの状態:
システム全体の設定を考慮して、アプリケーションが現在リモート通知に登録されている場合はYESを返します。
ただし、動作を観察するためにアプリデリゲートに単純NSLog
にスローすると、これが動作すると予想される動作をしないことは明らかです。実際には、このアプリ/デバイスに対してアクティブ化されたリモート通知に直接関係します。初めてアクティブ化されると、これは常にに戻りYES
ます。設定(通知)でオフにしても、この結果が返されます。YES
これは、iOS8以降、アプリがリモート通知に登録し、ユーザーが通知を有効にせずにデバイスに送信する場合でも、アラートを実行できない場合があるためです。ユーザーがそれをオンにせずにバッジとサウンド。サイレント通知は、通知をオフにしても引き続き実行できることの良い例です。
それが4つのことのうちの1つを示す限りcurrentUserNotificationSettings
:
アラートはオンですバッジはオンですサウンドはオンですなしはオンです。
これにより、他の要因や通知スイッチ自体についてはまったくわかりません。
ユーザーは実際にはバッジ、サウンド、アラートをオフにしても、ロック画面や通知センターに表示されている場合があります。このユーザーは引き続きプッシュ通知を受信し、ロック画面と通知センターの両方でそれらを見ることができるはずです。通知スイッチがオンになっています。しかし、currentUserNotificationSettings
戻ります:UIUserNotificationTypeNone
その場合。これは、ユーザーの実際の設定を正確に示すものではありません。
いくつかの推測ができます:
- その場合、このデバイスがリモート通知に正常に登録されたことがないと見なすことができます
isRegisteredForRemoteNotifications
。NO
- リモート通知を初めて登録した後、
application:didRegisterUserNotificationSettings:
この時点でユーザー通知設定を含むコールバックが行われます。これは、ユーザーが初めて登録されるため、設定は、許可要求に関してユーザーが選択した内容を示す必要があります。設定が次のいずれか以外の場合:UIUserNotificationTypeNone
プッシュ許可が付与され、それ以外の場合は拒否されました。これは、リモート登録プロセスを開始した瞬間から、ユーザーは承認または拒否することしかできず、承認の初期設定は登録プロセス中に設定した設定であるためです。
答えを完成させるために、それはこのように働くかもしれません...
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;
}
iOS7以前の場合は、実際にを使用enabledRemoteNotificationTypes
して、に等しい(または必要に応じて等しくない)かどうかを確認する必要がありますUIRemoteNotificationTypeNone
。
ただし、iOS8の場合、上記の状態を確認するだけでは必ずしも十分ではありませんisRegisteredForRemoteNotifications
。application.currentUserNotificationSettings.types
また、等しいかどうか(または必要に応じて等しくないかどうか)も確認する必要がありますUIUserNotificationTypeNone
。
isRegisteredForRemoteNotifications
を返してもtrueを返す場合がありcurrentUserNotificationSettings.types
ますUIUserNotificationTypeNone
。
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;
}
}];
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types & UIRemoteNotificationTypeAlert)
// blah blah blah
{
NSLog(@"Notification Enabled");
}
else
{
NSLog(@"Notification not enabled");
}
ここでは、UIApplicationからUIRemoteNotificationTypeを取得します。タイプを簡単に確認できるよりも、設定でこのアプリのプッシュ通知の状態を表します
@ShaheenGhiassyが提供するソリューションを使用してiOS10以降をサポートしようとしていますが、剥奪の問題が見つかりましたenabledRemoteNotificationTypes
。isRegisteredForRemoteNotifications
そのため、iOS 8で廃止されたソリューションの代わりに使用して見つけたソリューションを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";
それが他の人にも役立つことを願っています:)ハッピーコーディング。
Zacの答えはiOS7までは完全に正しかったが、iOS8が登場してから変わった。enabledRemoteNotificationTypesはiOS8以降で非推奨になっているためです。iOS 8以降の場合は、isRegisteredForRemoteNotificationsを使用する必要があります。
- iOS7以前の場合->enabledRemoteNotificationTypesを使用
- iOS8以降の場合->isRegisteredForRemoteNotificationsを使用します。
この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")
}
}
再:
正解です
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
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メソッドのみを使用してください。
Xamarinでは、上記のすべてのソリューションが機能しません。これは私が代わりに使用するものです:
public static bool IsRemoteNotificationsEnabled() {
return UIApplication.SharedApplication.CurrentUserNotificationSettings.Types != UIUserNotificationType.None;
}
[設定]で通知ステータスを変更した後も、ライブアップデートを取得しています。
@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!