简体   繁体   English

iOS 10 / 9 推送通知

[英]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.我需要更新我们的应用程序以支持 iOS 9 和 iOS 10,所以我的问题是将UNUserNotificationCenter用于 PushNotifications。

So with iOS 9 we have a method which returns result of UIUserNotificationSettings like因此,对于 iOS 9,我们有一个方法可以返回UIUserNotificationSettings 的结果,例如

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

With iOS 10 I did something like使用 iOS 10 我做了类似的事情

- (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?我的问题:是否有可能使用getNotificationSettingsWithCompletionHandler返回值而不是完成处理程序,以便我可以在我的alertEnabled方法中使用它?

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但也许有更好的解决方案

So, after a week of tests, it's working fine for me.所以,经过一周的测试,它对我来说效果很好。

For my specific problem, I created a custom class.对于我的具体问题,我创建了一个自定义类。

SpecicPush.h特殊推送.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具体推送.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.我使用了与 UIUserNotificationType 相同的 NS_ENUM。 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM