iOS10以降の通知設定を取得する



Get Notification Settings



最近、UNUserNotification通知について通知しています。現在のAPPの通知許可を取得する必要があります。 iOS10より上の通知に使用されるAPIが大幅に変更されたため、iOS10より前の通知設定コードは次のようになります。

UIUserNotificationSettings *theSettings = [[UIApplication sharedApplication] currentUserNotificationSettings] return [theSettings types] & UIUserNotificationTypeAlert

iOS10は、元のAPIの代わりにUNUserNotificationCenterを使用します。 UNUserNotificationCenterを使用して、次のようにAPP通知設定コードを取得します。



UNUserNotificationCenter *notificationCenter=[UNUserNotificationCenter currentNotificationCenter] [notificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { switch (settings.authorizationStatus) { case UNAuthorizationStatusAuthorized: enabled = YES break default: break } }]

getNotificationSettingsWithCompletionHandler:非同期コールバックのプロセスが使用されます。両方のタイプと互換性のある関数を書くために、私のコードは次のとおりです。

__block BOOL enabled = NO if (@available(iOS 10.0, *)) { UNUserNotificationCenter *notificationCenter=[UNUserNotificationCenter currentNotificationCenter] [notificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { switch (settings.authorizationStatus) { case UNAuthorizationStatusAuthorized: enabled = YES break default: break } }] } else { UIApplication *application = [UIApplication sharedApplication] if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) { UIUserNotificationSettings *settings = [application currentUserNotificationSettings] if (settings.types != UIUserNotificationTypeNone) { enabled = YES } } }

これは完璧に思えますが、実際、このコードは非常に低レベルのエラーを引き起こしました。非同期を同期再利用と考えてください。その時に問題が発見されたとき、APPはすでにオンラインでした、そして最終的に私はリーダーにレビューを書かなければなりませんでした。悲しい太平洋(π×π)



エラーを変更する必要があります。最後に、セマフォを使用して非同期を強制的に同期させることを考えました。変更されたコードは次のとおりです。

__block BOOL enabled = NO if (@available(iOS 10.0, *)) { dispatch_semaphore_t sem sem = dispatch_semaphore_create(0) UNUserNotificationCenter *notificationCenter=[UNUserNotificationCenter currentNotificationCenter] [notificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { switch (settings.authorizationStatus) { case UNAuthorizationStatusAuthorized: enabled = YES break default: break } dispatch_semaphore_signal(sem) }] Dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER) //The process of getting the notification settings is asynchronous, here you need to wait } else { UIApplication *application = [UIApplication sharedApplication] if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) { UIUserNotificationSettings *settings = [application currentUserNotificationSettings] if (settings.types != UIUserNotificationTypeNone) { enabled = YES } } }

また、通知設定の一般化を取得するクラスであるStackOverflowをアタッチします。
住所
.hファイル

#import typedef NS_ENUM(NSInteger , PushNotificationType) { PushNotificationTypeNone = 0, // the application may not present any UI upon a notification being received PushNotificationTypeBadge = 1 << 0, // the application may badge its icon upon a notification being received PushNotificationTypeSound = 1 << 1, // the application may play a sound upon a notification being received PushNotificationTypeAlert = 1 << 2, // the application may display an alert upon a notification being received } @interface SpecificPush : NSObject @property (nonatomic, readonly) PushNotificationType currentNotificationSettings + (SpecificPush *)sharedInstance - (PushNotificationType)types @end

.mファイル



#import @interface SpecificPush() @property (nonatomic) PushNotificationType currentNotificationSettings @end @implementation SpecificPush #pragma mark - Init static SpecificPush *instance = nil + (SpecificPush *)sharedInstance { @synchronized (self) { if (instance == nil) { [SpecificPush new] } } return instance } - (instancetype)init { NSAssert(!instance, @'WARNING - Instance of SpecifishPush already exists') self = [super init] if (self) { self.currentNotificationSettings = PushNotificationTypeNone } instance = self return self } - (PushNotificationType)types { if (@available(iOS 10.0, *)) { dispatch_semaphore_t semaphore = dispatch_semaphore_create(0) [[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings *settings) { if ((settings.soundSetting == UNNotificationSettingDisabled) && (settings.alertSetting == UNNotificationSettingDisabled) && (settings.soundSetting == UNNotificationSettingDisabled)) { self.currentNotificationSettings = PushNotificationTypeNone } if (settings.badgeSetting == UNNotificationSettingEnabled) { self.currentNotificationSettings = PushNotificationTypeBadge } if (settings.soundSetting == UNNotificationSettingEnabled) { self.currentNotificationSettings = PushNotificationTypeSound } if (settings.alertStyle == UNNotificationSettingEnabled) { self.currentNotificationSettings = PushNotificationTypeAlert } dispatch_semaphore_signal(semaphore) }] dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) dispatch_release(semaphore) } else { UIUserNotificationSettings *settings = [[UIApplication sharedApplication] currentUserNotificationSettings] if (settings.types == UIUserNotificationTypeNone) { self.currentNotificationSettings = PushNotificationTypeNone } if (settings.types & UIUserNotificationTypeBadge) { self.currentNotificationSettings = PushNotificationTypeBadge } if (settings.types & UIUserNotificationTypeSound) { self.currentNotificationSettings = PushNotificationTypeSound } if (settings.types & UIUserNotificationTypeAlert) { self.currentNotificationSettings = PushNotificationTypeAlert } } return self.currentNotificationSettings } @end