diff --git a/plugin.xml b/plugin.xml
index 5aeb3d5f8..78d1e5d31 100755
--- a/plugin.xml
+++ b/plugin.xml
@@ -117,8 +117,11 @@
+
+
+
diff --git a/src/ios/PushPlugin.m b/src/ios/PushPlugin.m
index 31078b36d..119e809a8 100644
--- a/src/ios/PushPlugin.m
+++ b/src/ios/PushPlugin.m
@@ -24,6 +24,7 @@
*/
#import "PushPlugin.h"
+#import "PushPluginSettings.h"
#import "AppDelegate+notification.h"
@import Firebase;
@@ -121,9 +122,10 @@ - (void)unsubscribe:(CDVInvokedUrlCommand *)command {
- (void)init:(CDVInvokedUrlCommand *)command {
NSMutableDictionary* options = [command.arguments objectAtIndex:0];
- NSMutableDictionary* iosOptions = [options objectForKey:@"ios"];
- id voipArg = [iosOptions objectForKey:@"voip"];
- if (([voipArg isKindOfClass:[NSString class]] && [voipArg isEqualToString:@"true"]) || [voipArg boolValue]) {
+ [[PushPluginSettings sharedInstance] updateSettingsWithOptions:[options objectForKey:@"ios"]];
+ PushPluginSettings *settings = [PushPluginSettings sharedInstance];
+
+ if ([settings voipEnabled]) {
[self.commandDelegate runInBackground:^ {
NSLog(@"[PushPlugin] VoIP set to true");
@@ -142,114 +144,34 @@ - (void)init:(CDVInvokedUrlCommand *)command {
[self.commandDelegate runInBackground:^ {
NSLog(@"[PushPlugin] register called");
self.callbackId = command.callbackId;
-
- NSArray* topics = [iosOptions objectForKey:@"topics"];
- [self setFcmTopics:topics];
+ self.isInline = NO;
+ self.fcmTopics = [settings fcmTopics];
+ self.forceShow = [settings forceShowEnabled];
+ self.clearBadge = [settings clearBadgeEnabled];
+ if (self.clearBadge) {
+ [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
+ }
UNAuthorizationOptions authorizationOptions = UNAuthorizationOptionNone;
-
- id badgeArg = [iosOptions objectForKey:@"badge"];
- id soundArg = [iosOptions objectForKey:@"sound"];
- id alertArg = [iosOptions objectForKey:@"alert"];
- id criticalArg = [iosOptions objectForKey:@"critical"];
- id clearBadgeArg = [iosOptions objectForKey:@"clearBadge"];
- id forceShowArg = [iosOptions objectForKey:@"forceShow"];
-
- if (([badgeArg isKindOfClass:[NSString class]] && [badgeArg isEqualToString:@"true"]) || [badgeArg boolValue])
- {
+ if ([settings badgeEnabled]) {
authorizationOptions |= UNAuthorizationOptionBadge;
}
-
- if (([soundArg isKindOfClass:[NSString class]] && [soundArg isEqualToString:@"true"]) || [soundArg boolValue])
- {
+ if ([settings soundEnabled]) {
authorizationOptions |= UNAuthorizationOptionSound;
}
-
- if (([alertArg isKindOfClass:[NSString class]] && [alertArg isEqualToString:@"true"]) || [alertArg boolValue])
- {
+ if ([settings alertEnabled]) {
authorizationOptions |= UNAuthorizationOptionAlert;
}
-
if (@available(iOS 12.0, *))
{
- if ((([criticalArg isKindOfClass:[NSString class]] && [criticalArg isEqualToString:@"true"]) || [criticalArg boolValue]))
- {
+ if ([settings criticalEnabled]) {
authorizationOptions |= UNAuthorizationOptionCriticalAlert;
}
}
-
- if (clearBadgeArg == nil || ([clearBadgeArg isKindOfClass:[NSString class]] && [clearBadgeArg isEqualToString:@"false"]) || ![clearBadgeArg boolValue]) {
- NSLog(@"[PushPlugin] register: setting badge to false");
- clearBadge = NO;
- } else {
- NSLog(@"[PushPlugin] register: setting badge to true");
- clearBadge = YES;
- [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
- }
- NSLog(@"[PushPlugin] register: clear badge is set to %d", clearBadge);
-
- if (forceShowArg == nil || ([forceShowArg isKindOfClass:[NSString class]] && [forceShowArg isEqualToString:@"false"]) || ![forceShowArg boolValue]) {
- NSLog(@"[PushPlugin] register: setting forceShow to false");
- forceShow = NO;
- } else {
- NSLog(@"[PushPlugin] register: setting forceShow to true");
- forceShow = YES;
- }
-
- isInline = NO;
-
- NSLog(@"[PushPlugin] register: better button setup");
- // setup action buttons
- NSMutableSet *categories = [[NSMutableSet alloc] init];
- id categoryOptions = [iosOptions objectForKey:@"categories"];
- if (categoryOptions != nil && [categoryOptions isKindOfClass:[NSDictionary class]]) {
- for (id key in categoryOptions) {
- NSLog(@"[PushPlugin] categories: key %@", key);
- id category = [categoryOptions objectForKey:key];
-
- id yesButton = [category objectForKey:@"yes"];
- UNNotificationAction *yesAction;
- if (yesButton != nil && [yesButton isKindOfClass:[NSDictionary class]]) {
- yesAction = [self createAction: yesButton];
- }
- id noButton = [category objectForKey:@"no"];
- UNNotificationAction *noAction;
- if (noButton != nil && [noButton isKindOfClass:[NSDictionary class]]) {
- noAction = [self createAction: noButton];
- }
- id maybeButton = [category objectForKey:@"maybe"];
- UNNotificationAction *maybeAction;
- if (maybeButton != nil && [maybeButton isKindOfClass:[NSDictionary class]]) {
- maybeAction = [self createAction: maybeButton];
- }
-
- // Identifier to include in your push payload and local notification
- NSString *identifier = key;
-
- NSMutableArray *actions = [[NSMutableArray alloc] init];
- if (yesButton != nil) {
- [actions addObject:yesAction];
- }
- if (noButton != nil) {
- [actions addObject:noAction];
- }
- if (maybeButton != nil) {
- [actions addObject:maybeAction];
- }
-
- UNNotificationCategory *notificationCategory = [UNNotificationCategory categoryWithIdentifier:identifier
- actions:actions
- intentIdentifiers:@[]
- options:UNNotificationCategoryOptionNone];
-
- NSLog(@"[PushPlugin] Adding category %@", key);
- [categories addObject:notificationCategory];
- }
- }
+ [self handleNotificationSettingsWithAuthorizationOptions:[NSNumber numberWithInteger:authorizationOptions]];
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
- [center setNotificationCategories:categories];
- [self handleNotificationSettingsWithAuthorizationOptions:[NSNumber numberWithInteger:authorizationOptions]];
+ [center setNotificationCategories:[settings categories]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleNotificationSettings:)
@@ -291,23 +213,6 @@ - (void)init:(CDVInvokedUrlCommand *)command {
}
}
-- (UNNotificationAction *)createAction:(NSDictionary *)dictionary {
- NSString *identifier = [dictionary objectForKey:@"callback"];
- NSString *title = [dictionary objectForKey:@"title"];
- UNNotificationActionOptions options = UNNotificationActionOptionNone;
-
- id mode = [dictionary objectForKey:@"foreground"];
- if (mode != nil && (([mode isKindOfClass:[NSString class]] && [mode isEqualToString:@"true"]) || [mode boolValue])) {
- options |= UNNotificationActionOptionForeground;
- }
- id destructive = [dictionary objectForKey:@"destructive"];
- if (destructive != nil && (([destructive isKindOfClass:[NSString class]] && [destructive isEqualToString:@"true"]) || [destructive boolValue])) {
- options |= UNNotificationActionOptionDestructive;
- }
-
- return [UNNotificationAction actionWithIdentifier:identifier title:title options:options];
-}
-
- (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
if (self.callbackId == nil) {
NSLog(@"[PushPlugin] Unexpected call to didRegisterForRemoteNotificationsWithDeviceToken, ignoring: %@", deviceToken);
diff --git a/src/ios/PushPluginSettings.h b/src/ios/PushPluginSettings.h
new file mode 100644
index 000000000..0ac12cff1
--- /dev/null
+++ b/src/ios/PushPluginSettings.h
@@ -0,0 +1,28 @@
+//
+// PushPluginSettings.h
+// cordovaTest
+//
+// Created by Erisu on 2024/09/14.
+//
+
+#import
+#import
+
+@interface PushPluginSettings : NSObject
+
+@property (nonatomic, readonly) BOOL badgeEnabled;
+@property (nonatomic, readonly) BOOL soundEnabled;
+@property (nonatomic, readonly) BOOL alertEnabled;
+@property (nonatomic, readonly) BOOL criticalEnabled;
+@property (nonatomic, readonly) BOOL clearBadgeEnabled;
+@property (nonatomic, readonly) BOOL forceShowEnabled;
+@property (nonatomic, readonly) BOOL voipEnabled;
+
+@property (nonatomic, readonly, strong) NSArray *fcmTopics;
+@property (nonatomic, readonly, strong) NSSet *categories;
+
++ (instancetype)sharedInstance;
+
+- (void)updateSettingsWithOptions:(NSDictionary *)options;
+
+@end
diff --git a/src/ios/PushPluginSettings.m b/src/ios/PushPluginSettings.m
new file mode 100644
index 000000000..a394d9764
--- /dev/null
+++ b/src/ios/PushPluginSettings.m
@@ -0,0 +1,179 @@
+//
+// PushPluginSettings.m
+// cordovaTest
+//
+// Created by Erisu on 2024/09/14.
+//
+
+#import "PushPluginSettings.h"
+
+@interface PushPluginSettings ()
+
+@property (nonatomic, strong) NSMutableDictionary *settingsDictionary;
+
+@end
+
+@implementation PushPluginSettings
+
++ (instancetype)sharedInstance {
+ static PushPluginSettings *sharedInstance = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ sharedInstance = [[self alloc] initWithDefaults];
+ });
+ return sharedInstance;
+}
+
+- (instancetype)initWithDefaults {
+ self = [super init];
+ if (self) {
+ self.settingsDictionary = [@{
+ @"badge" : @(NO),
+ @"sound" : @(NO),
+ @"alert" : @(NO),
+ @"critical" : @(NO),
+ @"clearBadge" : @(NO),
+ @"forceShow" : @(NO),
+ @"voip" : @(NO),
+ @"fcmTopics" : @[],
+ @"categories" : [NSSet set]
+ } mutableCopy];
+ }
+ return self;
+}
+
+- (void)updateSettingsWithOptions:(NSDictionary *)options {
+ for (NSString *key in options) {
+ if ([self.settingsDictionary objectForKey:key]) {
+ // Overrides the default setting if defined and apply the correct formatting based on the key.
+ if ([key isEqualToString:@"fcmTopics"]) {
+ self.settingsDictionary[key] = [self parseArrayOption:key fromOptions:options withDefault:nil];
+ } else if ([key isEqualToString:@"categories"]) {
+ self.settingsDictionary[key] = [self parseCategoriesFromOptions:options[key]];
+ } else {
+ self.settingsDictionary[key] = @([self parseOption:key fromOptions:options withDefault:NO]);
+ }
+ } else {
+ NSLog(@"[PushPlugin] Settings: Invalid option key: %@", key);
+ }
+ }
+
+ NSLog(@"[PushPlugin] Settings: %@", self.settingsDictionary);
+}
+
+- (BOOL)parseOption:(NSString *)key fromOptions:(NSDictionary *)options withDefault:(BOOL)defaultValue {
+ id option = [options objectForKey:key];
+ if ([option isKindOfClass:[NSString class]]) {
+ return [option isEqualToString:@"true"];
+ }
+ if ([option respondsToSelector:@selector(boolValue)]) {
+ return [option boolValue];
+ }
+ return defaultValue;
+}
+
+- (NSArray *)parseArrayOption:(NSString *)key fromOptions:(NSDictionary *)options withDefault:(NSArray *)defaultValue {
+ id option = [options objectForKey:key];
+ if ([option isKindOfClass:[NSArray class]]) {
+ return (NSArray *)option;
+ }
+ return defaultValue;
+}
+
+- (NSSet *)parseCategoriesFromOptions:(NSDictionary *)categoryOptions {
+ NSMutableSet *categoriesSet = [[NSMutableSet alloc] init];
+ if (categoryOptions != nil && [categoryOptions isKindOfClass:[NSDictionary class]]) {
+ for (id key in categoryOptions) {
+ NSDictionary *category = [categoryOptions objectForKey:key];
+ UNNotificationCategory *notificationCategory = [self createCategoryFromDictionary:category withIdentifier:key];
+ if (notificationCategory) {
+ [categoriesSet addObject:notificationCategory];
+ }
+ }
+ }
+ return categoriesSet;
+}
+
+- (UNNotificationCategory *)createCategoryFromDictionary:(NSDictionary *)category withIdentifier:(NSString *)identifier {
+ NSMutableArray *actions = [[NSMutableArray alloc] init];
+
+ UNNotificationAction *yesAction = [self createActionFromDictionary:[category objectForKey:@"yes"]];
+ if (yesAction)
+ [actions addObject:yesAction];
+
+ UNNotificationAction *noAction = [self createActionFromDictionary:[category objectForKey:@"no"]];
+ if (noAction)
+ [actions addObject:noAction];
+
+ UNNotificationAction *maybeAction = [self createActionFromDictionary:[category objectForKey:@"maybe"]];
+ if (maybeAction)
+ [actions addObject:maybeAction];
+
+ return [UNNotificationCategory categoryWithIdentifier:identifier actions:actions intentIdentifiers:@[] options:UNNotificationCategoryOptionNone];
+}
+
+- (UNNotificationAction *)createActionFromDictionary:(NSDictionary *)dictionary {
+ if (![dictionary isKindOfClass:[NSDictionary class]]) {
+ return nil;
+ }
+
+ NSString *identifier = [dictionary objectForKey:@"identifier"];
+ NSString *title = [dictionary objectForKey:@"title"];
+ UNNotificationActionOptions options = UNNotificationActionOptionNone;
+
+ id foreground = [dictionary objectForKey:@"foreground"];
+ if (foreground != nil && (([foreground isKindOfClass:[NSString class]] && [foreground isEqualToString:@"true"]) || [foreground boolValue])) {
+ options |= UNNotificationActionOptionForeground;
+ }
+
+ id destructive = [dictionary objectForKey:@"destructive"];
+ if (destructive != nil && (([destructive isKindOfClass:[NSString class]] && [destructive isEqualToString:@"true"]) || [destructive boolValue])) {
+ options |= UNNotificationActionOptionDestructive;
+ }
+
+ if (title && identifier) {
+ return [UNNotificationAction actionWithIdentifier:identifier title:title options:options];
+ }
+
+ return nil;
+}
+
+#pragma mark - Getters for individual settings
+
+- (BOOL)badgeEnabled {
+ return [self.settingsDictionary[@"badge"] boolValue];
+}
+
+- (BOOL)soundEnabled {
+ return [self.settingsDictionary[@"sound"] boolValue];
+}
+
+- (BOOL)alertEnabled {
+ return [self.settingsDictionary[@"alert"] boolValue];
+}
+
+- (BOOL)criticalEnabled {
+ return [self.settingsDictionary[@"critical"] boolValue];
+}
+
+- (BOOL)clearBadgeEnabled {
+ return [self.settingsDictionary[@"clearBadge"] boolValue];
+}
+
+- (BOOL)forceShowEnabled {
+ return [self.settingsDictionary[@"forceShow"] boolValue];
+}
+
+- (BOOL)voipEnabled {
+ return [self.settingsDictionary[@"voip"] boolValue];
+}
+
+- (NSArray *)fcmTopics {
+ return self.settingsDictionary[@"fcmTopics"];
+}
+
+- (NSSet *)categories {
+ return self.settingsDictionary[@"categories"];
+}
+
+@end