ฉันกำลังมองหาวิธีตรวจสอบว่าผู้ใช้มีการตั้งค่าเปิดใช้งานหรือปิดใช้งานการแจ้งเตือนแบบพุชสำหรับแอปพลิเคชันของฉันหรือไม่
ฉันกำลังมองหาวิธีตรวจสอบว่าผู้ใช้มีการตั้งค่าเปิดใช้งานหรือปิดใช้งานการแจ้งเตือนแบบพุชสำหรับแอปพลิเคชันของฉันหรือไม่
คำตอบ:
โทร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
}
RxSwift Observable Version สำหรับ 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(...)
แบบอะซิงโครนัสดังนั้นการคืนค่าภายในจะถูกละเว้น
ในการพยายามสนับสนุนทั้ง iOS8 และที่ต่ำกว่านั้นฉันไม่ได้โชคดีisRegisteredForRemoteNotifications
เท่าที่เควินแนะนำ ฉันใช้แทน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
โชคไม่ดีที่โซลูชันเหล่านี้ไม่ได้ให้การแก้ปัญหาจริงๆเพราะในตอนท้ายของวัน APIs จะขาดอย่างจริงจังเมื่อมันมาถึงการให้ข้อมูลที่เกี่ยวข้อง คุณสามารถคาดเดาได้สองสามอย่างอย่างไรก็ตามการใช้currentUserNotificationSettings
(iOS8 +) นั้นไม่เพียงพอในรูปแบบปัจจุบันเพื่อตอบคำถาม แม้ว่าคำตอบมากมายที่นี่ดูเหมือนจะแนะนำว่าอย่างใดอย่างหนึ่งหรือisRegisteredForRemoteNotifications
มากกว่าคำตอบที่ชัดเจนว่ามันไม่ได้เป็นจริง
พิจารณาสิ่งนี้:
ด้วยisRegisteredForRemoteNotifications
เอกสารประกอบสถานะ:
ส่งคืน YES หากแอปพลิเคชันลงทะเบียนสำหรับการแจ้งเตือนระยะไกลโดยคำนึงถึงการตั้งค่าทั้งระบบ ...
อย่างไรก็ตามหากคุณเพียงแค่ส่งNSLog
ตัวแทนแอพของคุณเพื่อสังเกตพฤติกรรมมันชัดเจนว่านี่จะไม่ทำงานตามที่เราคาดหวังว่ามันจะทำงาน มันเกี่ยวข้องโดยตรงกับการแจ้งเตือนระยะไกลที่เปิดใช้งานสำหรับแอพ / อุปกรณ์นี้ YES
เมื่อเปิดใช้งานเป็นครั้งแรกนี้มักจะกลับ แม้การปิดการตั้งค่า (การแจ้งเตือน) จะยังคงส่งผลให้สิ่งนี้กลับมาYES
เป็นเพราะใน iOS8 แอปอาจลงทะเบียนสำหรับการแจ้งเตือนระยะไกลและแม้แต่ส่งไปยังอุปกรณ์โดยที่ผู้ใช้ไม่ได้เปิดใช้งานการแจ้งเตือน ป้ายและเสียงโดยที่ผู้ใช้เปิดใช้งาน การแจ้งเตือนเงียบเป็นตัวอย่างที่ดีของสิ่งที่คุณอาจทำต่อไปแม้จะปิดการแจ้งเตือน
เท่าที่currentUserNotificationSettings
ระบุหนึ่งในสี่สิ่ง:
การแจ้งเตือนอยู่บนป้ายสถานะเปิดเสียงเปิดอยู่ไม่มีเปิดอยู่
สิ่งนี้ทำให้คุณไม่มีข้อบ่งชี้ใด ๆ เลยเกี่ยวกับปัจจัยอื่น ๆ หรือการแจ้งเตือนเอง
ในความเป็นจริงผู้ใช้อาจปิดป้ายเสียงและการเตือน แต่ยังคงมีการแสดงบน lockscreen หรือในศูนย์การแจ้งเตือน ผู้ใช้รายนี้ยังควรได้รับการแจ้งเตือนแบบพุชและสามารถเห็นได้ทั้งบนหน้าจอล็อคและในศูนย์การแจ้งเตือน พวกเขาเปิดสวิตช์การแจ้งเตือน แต่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
UIUserNotificationTypeNone
iOS8 + (วัตถุประสงค์ 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");
}
ที่นี่เราได้รับ UIRemoteNotificationType จาก UIApplication มันแสดงถึงสถานะของการแจ้งเตือนผลักดันของแอพนี้ในการตั้งค่ากว่าที่คุณสามารถตรวจสอบประเภทของมันได้อย่างง่ายดาย
ฉันพยายามที่จะสนับสนุน iOS 10 และข้างต้นโดยใช้วิธีการแก้ปัญหาให้โดย @Shaheen Ghiassy enabledRemoteNotificationTypes
แต่พบปัญหาการกีดกัน ดังนั้นวิธีแก้ปัญหาที่ฉันค้นหาโดยใช้isRegisteredForRemoteNotifications
แทนวิธีenabledRemoteNotificationTypes
ที่เลิกใช้ใน iOS 8 ด้านล่างเป็นโซลูชันที่อัปเดตของฉันซึ่งทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน:
- (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 มา เนื่องจากenableRemoteNotificationTypesเลิกใช้แล้วตั้งแต่ 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")
}
}
อีกครั้ง:
สิ่งนี้ถูกต้อง
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]];
}
}
}
GLHF!