回答:
enabledRemoteNotificationsTypes
マスクを呼び出して確認します。
例えば:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone)
// blah blah blah
iOS8以降:
[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
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.
[[UIApplication sharedApplication] currentUserNotificationSettings];
量子ポテトの問題:
どこtypes
で与えられる
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
使用できる
if (types & UIRemoteNotificationTypeAlert)
の代わりに
if (types == UIRemoteNotificationTypeNone)
通知が有効になっているかどうかのみを確認できます(サウンド、バッジ、通知センターなどについては心配しないでください)。「アラートスタイル」が「バナー」または「アラート」に設定されている場合、および「アラートスタイル」が「なし」に設定されている場合、他の設定に関係なく、コードの最初の行(types & UIRemoteNotificationTypeAlert
)が返されます。YES
NO
grantedSettings.types.contains(notificationType)
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;
}
UserNotifications
。残念ながら、今のところ完全な答えはありません。
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
}
以下に、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以降の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()
}
}
}
getNotificationSettings(...)
非同期なので、内部のリターンは無視されます
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;
}
isEnabled = NO;
、if
ケースでは必要ありませんNO
残念ながら、関連する情報を提供することに関しては、結局のところAPIが非常に不足しているため、これらのソリューションはどれも実際には問題を解決しません。いくつか推測することはできますが、currentUserNotificationSettings
(iOS8以降)を使用するだけでは、現在の形式では実際に質問に答えるだけでは不十分です。ここでの多くの解決策isRegisteredForRemoteNotifications
は、それがより確実な答えであると示唆しているようですが、実際にはそうではありません。
このことを考慮:
isRegisteredForRemoteNotifications
ドキュメントの状態:
システム全体の設定を考慮して、アプリケーションが現在リモート通知用に登録されている場合はYESを返します...
ただしNSLog
、動作を観察するために単純にアプリデリゲートにスローする場合、これが機能することを予測している方法で動作しないことが明らかです。実際には、このアプリ/デバイスでアクティブ化されているリモート通知に直接関係しています。初めてアクティブ化すると、これは常に戻りYES
ます。設定(通知)でそれらをオフにしても、これが返されます。YES
これは、iOS8の時点で、アプリがリモート通知に登録し、ユーザーが通知を有効にしていない状態でデバイスに送信することもあり、アラートを実行しない場合があるためです。ユーザーがオンにしなくてもバッジとサウンド。サイレント通知は、通知がオフになっていても引き続き実行できることの良い例です。
currentUserNotificationSettings
4つのことの1つを示す限り:
アラートはオンバッジはオンサウンドはオンなしはオン
これにより、他の要因や通知スイッチ自体についてはまったく何も示されません。
ユーザーは、実際にはバッジ、サウンド、アラートをオフにしても、ロック画面または通知センターに表示されることがあります。このユーザーは引き続きプッシュ通知を受信しており、ロック画面と通知センターの両方でそれらを表示できる必要があります。通知スイッチがオンになっています。しかし、その場合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
をcurrentUserNotificationSettings.types
返してもtrueを返す場合があります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を取得しています。設定でこのアプリのプッシュ通知の状態を表していますが、その種類を簡単に確認できます
@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";
それが他の人にも役立つことを願っています:)幸せなコーディング。
Zacの答えはiOS 7まで完全に正しかったが、iOS 8の登場以来、答えは変わった。enabledRemoteNotificationTypesはiOS 8以降では非推奨となっているためです。iOS 8以降の場合は、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")
}
}
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
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メソッドのみを使用してください。
@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!