Search code examples
iospush-notificationios9ios10

iOS 10 / 9 Push Notifications


I need to update an application from us to support iOS 9 and iOS 10, so my problem is to use UNUserNotificationCenter for PushNotifications.

So with iOS 9 we have a method which returns result of UIUserNotificationSettings like

- (BOOL)alertEnabled {
    UIUserNotificationSettings *theSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
    return [theSettings types] & UIUserNotificationTypeAlert;
}

With iOS 10 I did something like

- (void)userNotificationsAuthorization :(void (^)(BOOL alertIsActive))completion {
    [[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
        completion(settings.alertSetting == UNNotificationSettingEnabled);
    }];
}

Call it and get it via completion handler.

My Question: Is there some possibility to use getNotificationSettingsWithCompletionHandler and return the value instead of the completion handler that I can use it into my alertEnabled method?

Thanks a lot.

Update:

With this approach it's working

- (BOOL)alertIsEnabled {
    __block BOOL alertIsActive = NO;

    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) {
        dispatch_semaphore_t sem = dispatch_semaphore_create(0);

        [[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
            alertIsActive = settings.alertSetting == UNNotificationSettingEnabled;
            dispatch_semaphore_signal(sem);
        }];

        dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    }
    else {
        UIUserNotificationSettings *theSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
        alertIsActive = [theSettings types] & UIUserNotificationTypeAlert;    
    }
    return alertIsActive;
}

but maybe there is a better solution


Solution

  • So, after a week of tests, it's working fine for me.

    For my specific problem, I created a custom class.

    SpecicPush.h

    #import <UIKit/UIKit.h>
    
    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
    

    SpecificPush.m

    #import "SpecificPush.h"
    #import <UserNotifications/UserNotifications.h>
    
    @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 (IS_IOS10)
        {
            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
    

    I used the same NS_ENUM as UIUserNotificationType. Now I can easy use old implementation. Insted of

    - (BOOL)alertEnabled {
        UIUserNotificationSettings *theSettings = [[UIApplication sharedApplication] currentUserNotificationSettings];
        return [theSettings types] & UIUserNotificationTypeAlert;
    }
    

    I use

    - (BOOL)alertEnabled {
        return [[SpecificPush sharedInstance] types] & PushNotificationTypeAlert;
    }