답변:
전화 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");
스위프트 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 Observable 버전 :
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
는 네 가지 중 하나를 나타냅니다
알림이 켜져 있습니다. 배지가 켜져 있습니다. 소리가 켜져 있습니다.
이것은 다른 요소 나 알림 스위치 자체에 대한 어떠한 표시도 제공하지 않습니다.
사용자는 실제로 배지, 소리 및 알림을 끌 수 있지만 여전히 잠금 화면이나 알림 센터에 표시됩니다. 이 사용자는 여전히 푸시 알림을 받고 있어야하며 잠금 화면과 알림 센터에서 모두 볼 수 있습니다. 알림 스위치가 켜져 있습니다. 그러나이 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
returns 하더라도 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은 이후 아이폰 OS 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")
}
}
레:
이것은 맞다
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]];
}
}
}
GLHF!