Câu trả lời:
Gọi enabledRemoteNotificationsTypes
và kiểm tra mặt nạ.
Ví dụ:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
if (types == UIRemoteNotificationTypeNone)
// blah blah blah
iOS8 trở lên:
[[UIApplication sharedApplication] isRegisteredForRemoteNotifications]
iOS 8
và cao hơn là sai vì nó chỉ kiểm tra nếu người dùng đăng ký thông báo từ xa. Theo tài liệu: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];
vấn đề của quantumpotato:
Nơi types
được đưa ra bởi
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
người ta có thể sử dụng
if (types & UIRemoteNotificationTypeAlert)
thay vì
if (types == UIRemoteNotificationTypeNone)
sẽ cho phép bạn chỉ kiểm tra xem thông báo có được bật hay không (và đừng lo lắng về âm thanh, huy hiệu, trung tâm thông báo, v.v.). Dòng mã đầu tiên ( types & UIRemoteNotificationTypeAlert
) sẽ trở lại YES
nếu "Kiểu cảnh báo" được đặt thành "Biểu ngữ" hoặc "Cảnh báo" và NO
nếu "Kiểu cảnh báo" được đặt thành "Không", bất kể các cài đặt khác.
grantedSettings.types.contains(notificationType)
Trong phiên bản iOS mới nhất, phương pháp này hiện không được chấp nhận. Để hỗ trợ cả iOS 7 và iOS 8, hãy sử dụng:
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
. Thật không may, bây giờ tôi không có câu trả lời đầy đủ.
Mã cập nhật cho 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()
}
Mã cho swift3.0, iOS10
let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications
if isRegisteredForRemoteNotifications {
// User is registered for notification
} else {
// Show alert user is not registered for notification
}
Từ iOS9, UIRemoteNotificationType không được chấp nhận, sử dụng mã sau
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.
}
chỉ cần kiểm tra xem thông báo đẩy có được bật hay không
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
}
Dưới đây bạn sẽ tìm thấy một ví dụ hoàn chỉnh bao gồm cả iOS8 và iOS7 (và các phiên bản thấp hơn). Xin lưu ý rằng trước iOS8, bạn không thể phân biệt giữa "thông báo từ xa bị tắt" và "chỉ xem trong màn hình khóa được bật".
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
}
Phiên bản quan sát RxSwift cho iOS10 +:
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(...)
không đồng bộ nên lợi nhuận bên trong sẽ bị bỏ qua
Khi cố gắng hỗ trợ cả iOS8 trở xuống, tôi đã không gặp nhiều may mắn isRegisteredForRemoteNotifications
khi sử dụng như Kevin đề xuất. Thay vào đó tôi đã sử dụng currentUserNotificationSettings
, nó đã làm việc rất tốt trong thử nghiệm của tôi.
+ (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;
trong if
trường hợp của bạn là không cần thiết vì nó đã được khởi tạo làNO
Thật không may, không có giải pháp nào trong số những giải pháp này cung cấp thực sự giải quyết được vấn đề bởi vì vào cuối ngày, các API bị thiếu nghiêm trọng khi cung cấp thông tin thích hợp. Tuy nhiên, bạn có thể đoán một số dự đoán bằng cách sử dụng currentUserNotificationSettings
(iOS8 +) không đủ ở dạng hiện tại để thực sự trả lời câu hỏi. Mặc dù rất nhiều giải pháp ở đây dường như gợi ý rằng hoặcisRegisteredForRemoteNotifications
là một câu trả lời dứt khoát nhưng thực sự không phải vậy.
Xem xét điều này:
với các isRegisteredForRemoteNotifications
tài liệu nêu:
Trả về CÓ nếu ứng dụng hiện được đăng ký cho thông báo từ xa, có tính đến mọi cài đặt trên toàn hệ thống ...
Tuy nhiên, nếu bạn ném đơn giản NSLog
vào đại biểu ứng dụng của mình để quan sát hành vi thì rõ ràng điều này không hành xử theo cách chúng ta dự đoán nó sẽ hoạt động. Nó thực sự liên quan trực tiếp đến các thông báo từ xa đã được kích hoạt cho ứng dụng / thiết bị này. Sau khi kích hoạt lần đầu tiên, điều này sẽ luôn trở lại YES
. Ngay cả việc tắt chúng trong cài đặt (thông báo) vẫn sẽ dẫn đến việc trả lại YES
điều này bởi vì, kể từ iOS8, một ứng dụng có thể đăng ký thông báo từ xa và thậm chí gửi đến thiết bị mà không có người dùng bật thông báo, họ chỉ có thể không thực hiện Cảnh báo, Phù hiệu và Âm thanh mà không cần người dùng bật nó lên. Thông báo im lặng là một ví dụ tốt về những điều bạn có thể tiếp tục thực hiện ngay cả khi thông báo bị tắt.
Theo như currentUserNotificationSettings
nó chỉ ra một trong bốn điều:
Cảnh báo là trên phù hiệu đang bật Âm thanh là Không có bật.
Điều này cung cấp cho bạn hoàn toàn không có dấu hiệu nào về các yếu tố khác hoặc chính công tắc Thông báo.
Trên thực tế, người dùng có thể tắt phù hiệu, âm thanh và cảnh báo nhưng vẫn hiển thị trên màn hình khóa hoặc trong trung tâm thông báo. Người dùng này vẫn sẽ nhận được thông báo đẩy và có thể thấy cả hai trên màn hình khóa và trong trung tâm thông báo. Họ có công tắc thông báo bật. NHƯNG currentUserNotificationSettings
sẽ trở lại: UIUserNotificationTypeNone
trong trường hợp đó. Đây không thực sự là dấu hiệu của cài đặt thực tế của người dùng.
Một vài dự đoán người ta có thể thực hiện:
isRegisteredForRemoteNotifications
có NO
thì bạn có thể cho rằng thiết bị này chưa bao giờ được đăng ký thành công cho các thông báo từ xa.application:didRegisterUserNotificationSettings:
được thực hiện có chứa cài đặt thông báo người dùng tại thời điểm này vì đây là lần đầu tiên người dùng được đăng ký, cài đặt sẽ cho biết người dùng đã chọn gì theo yêu cầu cấp phép. Nếu các cài đặt tương đương với bất cứ điều gì khác ngoài: UIUserNotificationTypeNone
thì cấp phép đẩy đã được cấp, nếu không thì nó đã bị từ chối. Lý do cho điều này là từ khi bạn bắt đầu quá trình đăng ký từ xa, người dùng chỉ có khả năng chấp nhận hoặc từ chối, với cài đặt ban đầu của sự chấp nhận là cài đặt bạn thiết lập trong quá trình đăng ký.Để hoàn thành câu trả lời, nó có thể hoạt động như thế này ...
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
switch (types) {
case UIRemoteNotificationTypeAlert:
case UIRemoteNotificationTypeBadge:
// For enabled code
break;
case UIRemoteNotificationTypeSound:
case UIRemoteNotificationTypeNone:
default:
// For disabled code
break;
}
chỉnh sửa: Điều này không đúng. vì đây là những thứ khôn ngoan, nó không hoạt động với công tắc, vì vậy tôi đã kết thúc việc này:
UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
UIRemoteNotificationType typesset = (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge);
if((types & typesset) == typesset)
{
CeldaSwitch.chkSwitch.on = true;
}
else
{
CeldaSwitch.chkSwitch.on = false;
}
Đối với iOS7 và trước đó bạn thực sự nên sử dụng enabledRemoteNotificationTypes
và kiểm tra xem nó có bằng (hoặc không bằng tùy thuộc vào những gì bạn muốn) vớiUIRemoteNotificationTypeNone
.
Tuy nhiên, đối với iOS8 không phải lúc nào cũng đủ để chỉ kiểm tra với isRegisteredForRemoteNotifications
nhiều trạng thái như trên. Bạn cũng nên kiểm tra xem application.currentUserNotificationSettings.types
bằng (hoặc không bằng tùy thuộc vào những gì bạn muốn)UIUserNotificationTypeNone
!
isRegisteredForRemoteNotifications
có thể trả về đúng mặc dù currentUserNotificationSettings.types
trả về UIUserNotificationTypeNone
.
iOS8 + (MỤC TIÊU 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");
}
Ở đây chúng tôi nhận được UIRemoteNotificationType từ UIApplication. Nó đại diện cho trạng thái thông báo đẩy của ứng dụng này trong cài đặt, hơn là bạn có thể kiểm tra loại ứng dụng một cách dễ dàng
Tôi cố gắng hỗ trợ iOS 10 trở lên bằng giải pháp do @Shaheen Ghiassy cung cấp nhưng thấy vấn đề thiếu hụt enabledRemoteNotificationTypes
. Vì vậy, giải pháp tôi tìm thấy bằng cách sử dụng isRegisteredForRemoteNotifications
thay vì enabledRemoteNotificationTypes
không dùng trong iOS 8. Dưới đây là giải pháp cập nhật của tôi hoạt động hoàn hảo với tôi:
- (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;
}
Và chúng ta có thể gọi hàm này một cách dễ dàng và đang truy cập Bool
giá trị của nó và có thể chuyển đổi nó thành giá trị chuỗi bằng cách này:
NSString *str = [self notificationServicesEnabled] ? @"YES" : @"NO";
Hy vọng nó sẽ giúp người khác quá :) Chúc mừng mã hóa.
Mặc dù câu trả lời của Zac là hoàn toàn chính xác cho đến iOS 7, nhưng nó đã thay đổi kể từ khi iOS 8 xuất hiện. Bởi vì enableRemoteNotificationTypes đã bị từ chối từ iOS 8 trở đi. Đối với iOS 8 trở lên, bạn cần sử dụng isRegisteredForRemoteNotutions .
Giải pháp Swifty này hoạt động tốt với tôi ( iOS8 + ),
Phương pháp :
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)
}
}
}
Cách sử dụng :
isNotificationEnabled { (isEnabled) in
if isEnabled{
print("Push notification enabled")
}else{
print("Push notification not enabled")
}
}
lại:
chính xác
if (types & UIRemoteNotificationTypeAlert)
nhưng sau đây là chính xác quá! (vì UIRemoteNotificationTypeNone là 0)
if (types == UIRemoteNotificationTypeNone)
xem những điều sau đây
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
Đây là cách để làm điều này trong Xamarin.ios.
public class NotificationUtils
{
public static bool AreNotificationsEnabled ()
{
var settings = UIApplication.SharedApplication.CurrentUserNotificationSettings;
var types = settings.Types;
return types != UIUserNotificationType.None;
}
}
Nếu bạn đang hỗ trợ iOS 10+, chỉ sử dụng phương thức UNUserNotificationCenter.
Trong Xamarin, tất cả các giải pháp trên không làm việc cho tôi. Đây là những gì tôi sử dụng thay thế:
public static bool IsRemoteNotificationsEnabled() {
return UIApplication.SharedApplication.CurrentUserNotificationSettings.Types != UIUserNotificationType.None;
}
Đó cũng là một bản cập nhật trực tiếp sau khi bạn thay đổi trạng thái thông báo trong Cài đặt.
Mã sao chép và dán đầy đủ dễ dàng được xây dựng từ giải pháp của @ ZacBowling ( https://stackoverflow.com/a/1535427/2298002 )
điều này cũng sẽ đưa người dùng đến cài đặt ứng dụng của bạn và cho phép họ kích hoạt ngay lập tức
Tôi cũng đã thêm vào một giải pháp để kiểm tra xem dịch vụ định vị có được bật hay không (và cũng mang đến cài đặt)
// 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!