@@ -174,6 +174,9 @@ @implementation OneSignal
174174// method can be called the moment the user provides privacy consent.
175175DelayedInitializationParameters *delayedInitParameters;
176176
177+ // Ensure we only initlize the SDK once even if the public method is called more.
178+ static BOOL initDone;
179+
177180// used to ensure registration occurs even if APNS does not respond
178181static NSDate *initializationTime;
179182static NSTimeInterval maxApnsWait = APNS_TIMEOUT;
@@ -404,6 +407,7 @@ + (void)setDelayIntervals:(NSTimeInterval)apnsMaxWait withRegistrationDelay:(NST
404407}
405408
406409+ (void )clearStatics {
410+ initDone = false ;
407411 usesAutoPrompt = false ;
408412 requestedProvisionalAuthorization = false ;
409413
@@ -496,18 +500,8 @@ + (id)initWithLaunchOptions:(NSDictionary*)launchOptions
496500
497501 [self onesignal_Log: ONE_S_LL_VERBOSE message: [NSString stringWithFormat: @" Called init with app ID: %@ " , appId]];
498502
499- initializationTime = [NSDate date ];
500-
501- [OneSignalCacheCleaner cleanCachedUserData ];
502-
503- // Outcomes init
504- _sessionManager = [[OneSignalSessionManager alloc ] init: self ];
505- _outcomeEventsController = [[OneSignalOutcomeEventsController alloc ] init: self .sessionManager];
506-
507- // Some wrapper SDK's call init multiple times and pass nil/NSNull as the appId on the first call
508- // the app ID is required to download parameters, so do not download params until the appID is provided
509- if (!didCallDownloadParameters && appId != nil && appId != (id )[NSNull null ])
510- [self downloadIOSParamsWithAppId: appId];
503+ [OneSignalHelper setNotificationActionBlock: actionCallback];
504+ [OneSignalHelper setNotificationReceivedBlock: receivedCallback];
511505
512506 if ([self requiresUserPrivacyConsent ]) {
513507 delayedInitializationForPrivacyConsent = true ;
@@ -520,83 +514,96 @@ + (id)initWithLaunchOptions:(NSDictionary*)launchOptions
520514 return self;
521515 }
522516
517+ [OneSignalCacheCleaner cleanCachedUserData ];
518+
523519 let success = [self initAppId: appId withSettings: settings];
524520 if (!success)
525521 return self;
526522
523+ if (initDone)
524+ return self;
525+ initDone = true ;
526+
527+ initializationTime = [NSDate date ];
528+
529+ // Outcomes init
530+ _sessionManager = [[OneSignalSessionManager alloc ] init: self ];
531+ _outcomeEventsController = [[OneSignalOutcomeEventsController alloc ] init: self .sessionManager];
532+
533+ // Some wrapper SDK's call init multiple times and pass nil/NSNull as the appId on the first call
534+ // the app ID is required to download parameters, so do not download params until the appID is provided
535+ if (!didCallDownloadParameters && appId != nil && appId != (id )[NSNull null ])
536+ [self downloadIOSParamsWithAppId: appId];
537+
527538 if (appId && mShareLocation)
528539 [OneSignalLocation getLocation: false ];
529540
530541 let standardUserDefaults = OneSignalUserDefaults.initStandard ;
531- if (self) {
532- [OneSignal checkIfApplicationImplementsDeprecatedMethods ];
533-
534- [OneSignalHelper notificationBlocks: receivedCallback : actionCallback];
535-
536- if ([OneSignalHelper isIOSVersionGreaterThanOrEqual: @" 8.0" ])
537- registeredWithApple = self.currentPermissionState .accepted ;
538- else
539- registeredWithApple = self.currentSubscriptionState .pushToken || [standardUserDefaults getSavedBoolForKey: REGISTERED_WITH_APPLE defaultValue: false ];
540-
541- // Check if disabled in-app launch url if passed a NO
542- if (settings[kOSSettingsKeyInAppLaunchURL ] && [settings[kOSSettingsKeyInAppLaunchURL ] isKindOfClass: [NSNumber class ]])
543- [self enableInAppLaunchURL: [settings[kOSSettingsKeyInAppLaunchURL ] boolValue ]];
544- else if (![standardUserDefaults keyExists: INAPP_LAUNCH_URL]) {
545- // Only need to default to true if the app doesn't already have this setting saved in NSUserDefaults
546- [self enableInAppLaunchURL: true ];
547- }
548-
549- if (settings[kOSSSettingsKeyPromptBeforeOpeningPushURL ] && [settings[kOSSSettingsKeyPromptBeforeOpeningPushURL ] isKindOfClass: [NSNumber class ]]) {
550- promptBeforeOpeningPushURLs = [settings[kOSSSettingsKeyPromptBeforeOpeningPushURL ] boolValue ];
551- [standardUserDefaults saveBoolForKey: PROMPT_BEFORE_OPENING_PUSH_URL withValue: promptBeforeOpeningPushURLs];
552- }
553- else
554- promptBeforeOpeningPushURLs = [standardUserDefaults getSavedBoolForKey: PROMPT_BEFORE_OPENING_PUSH_URL defaultValue: false ];
555-
556- usesAutoPrompt = YES ;
557- if (settings[kOSSettingsKeyAutoPrompt ] && [settings[kOSSettingsKeyAutoPrompt ] isKindOfClass: [NSNumber class ]])
558- usesAutoPrompt = [settings[kOSSettingsKeyAutoPrompt ] boolValue ];
559-
560- if (settings[kOSSettingsKeyProvidesAppNotificationSettings ] && [settings[kOSSettingsKeyProvidesAppNotificationSettings ] isKindOfClass: [NSNumber class ]] && [OneSignalHelper isIOSVersionGreaterThanOrEqual: @" 12.0" ])
561- providesAppNotificationSettings = [settings[kOSSettingsKeyProvidesAppNotificationSettings ] boolValue ];
562-
563- // Register with Apple's APNS server if we registed once before or if auto-prompt hasn't been disabled.
564- if (usesAutoPrompt || registeredWithApple)
565- [self registerForPushNotifications ];
566- else {
567- [self checkProvisionalAuthorizationStatus ];
568- [self registerForAPNsToken ];
569- }
542+ [OneSignal checkIfApplicationImplementsDeprecatedMethods ];
543+
544+ if ([OneSignalHelper isIOSVersionGreaterThanOrEqual: @" 8.0" ])
545+ registeredWithApple = self.currentPermissionState .accepted ;
546+ else
547+ registeredWithApple = self.currentSubscriptionState .pushToken || [standardUserDefaults getSavedBoolForKey: REGISTERED_WITH_APPLE defaultValue: false ];
548+
549+ // Check if disabled in-app launch url if passed a NO
550+ if (settings[kOSSettingsKeyInAppLaunchURL ] && [settings[kOSSettingsKeyInAppLaunchURL ] isKindOfClass: [NSNumber class ]])
551+ [self enableInAppLaunchURL: [settings[kOSSettingsKeyInAppLaunchURL ] boolValue ]];
552+ else if (![standardUserDefaults keyExists: INAPP_LAUNCH_URL]) {
553+ // Only need to default to true if the app doesn't already have this setting saved in NSUserDefaults
554+ [self enableInAppLaunchURL: true ];
555+ }
556+
557+ if (settings[kOSSSettingsKeyPromptBeforeOpeningPushURL ] && [settings[kOSSSettingsKeyPromptBeforeOpeningPushURL ] isKindOfClass: [NSNumber class ]]) {
558+ promptBeforeOpeningPushURLs = [settings[kOSSSettingsKeyPromptBeforeOpeningPushURL ] boolValue ];
559+ [standardUserDefaults saveBoolForKey: PROMPT_BEFORE_OPENING_PUSH_URL withValue: promptBeforeOpeningPushURLs];
560+ }
561+ else
562+ promptBeforeOpeningPushURLs = [standardUserDefaults getSavedBoolForKey: PROMPT_BEFORE_OPENING_PUSH_URL defaultValue: false ];
563+
564+ usesAutoPrompt = YES ;
565+ if (settings[kOSSettingsKeyAutoPrompt ] && [settings[kOSSettingsKeyAutoPrompt ] isKindOfClass: [NSNumber class ]])
566+ usesAutoPrompt = [settings[kOSSettingsKeyAutoPrompt ] boolValue ];
567+
568+ if (settings[kOSSettingsKeyProvidesAppNotificationSettings ] && [settings[kOSSettingsKeyProvidesAppNotificationSettings ] isKindOfClass: [NSNumber class ]] && [OneSignalHelper isIOSVersionGreaterThanOrEqual: @" 12.0" ])
569+ providesAppNotificationSettings = [settings[kOSSettingsKeyProvidesAppNotificationSettings ] boolValue ];
570+
571+ // Register with Apple's APNS server if we registed once before or if auto-prompt hasn't been disabled.
572+ if (usesAutoPrompt || registeredWithApple)
573+ [self registerForPushNotifications ];
574+ else {
575+ [self checkProvisionalAuthorizationStatus ];
576+ [self registerForAPNsToken ];
577+ }
570578
571- /* Check if in-app setting passed assigned
572- * LOGIC: Default - InAppAlerts enabled / InFocusDisplayOption InAppAlert.
573- * Priority for kOSSettingsKeyInFocusDisplayOption.
574- */
575- NSNumber *IAASetting = settings[kOSSettingsKeyInAppAlerts ];
576- let inAppAlertsPassed = IAASetting && (IAASetting.integerValue == 0 || IAASetting.integerValue == 1 );
577-
578- NSNumber *IFDSetting = settings[kOSSettingsKeyInFocusDisplayOption ];
579- let inFocusDisplayPassed = IFDSetting && IFDSetting.integerValue > -1 && IFDSetting.integerValue < 3 ;
580-
581- if (inAppAlertsPassed || inFocusDisplayPassed) {
582- if (!inFocusDisplayPassed)
583- self.inFocusDisplayType = (OSNotificationDisplayType)IAASetting.integerValue ;
584- else
585- self.inFocusDisplayType = (OSNotificationDisplayType)IFDSetting.integerValue ;
586- }
587-
588- if (self.currentSubscriptionState .userId )
589- [self registerUser ];
590- else {
591- [self .osNotificationSettings getNotificationPermissionState: ^(OSPermissionState *state) {
592-
593- if (state.answeredPrompt ) {
594- [self registerUser ];
595- } else {
596- [self registerUserAfterDelay ];
597- }
598- }];
599- }
579+ /* Check if in-app setting passed assigned
580+ * LOGIC: Default - InAppAlerts enabled / InFocusDisplayOption InAppAlert.
581+ * Priority for kOSSettingsKeyInFocusDisplayOption.
582+ */
583+ NSNumber *IAASetting = settings[kOSSettingsKeyInAppAlerts ];
584+ let inAppAlertsPassed = IAASetting && (IAASetting.integerValue == 0 || IAASetting.integerValue == 1 );
585+
586+ NSNumber *IFDSetting = settings[kOSSettingsKeyInFocusDisplayOption ];
587+ let inFocusDisplayPassed = IFDSetting && IFDSetting.integerValue > -1 && IFDSetting.integerValue < 3 ;
588+
589+ if (inAppAlertsPassed || inFocusDisplayPassed) {
590+ if (!inFocusDisplayPassed)
591+ self.inFocusDisplayType = (OSNotificationDisplayType)IAASetting.integerValue ;
592+ else
593+ self.inFocusDisplayType = (OSNotificationDisplayType)IFDSetting.integerValue ;
594+ }
595+
596+ if (self.currentSubscriptionState .userId )
597+ [self registerUser ];
598+ else {
599+ [self .osNotificationSettings getNotificationPermissionState: ^(OSPermissionState *state) {
600+
601+ if (state.answeredPrompt ) {
602+ [self registerUser ];
603+ } else {
604+ [self registerUserAfterDelay ];
605+ }
606+ }];
600607 }
601608
602609 /*
@@ -614,17 +621,9 @@ + (id)initWithLaunchOptions:(NSDictionary*)launchOptions
614621 [self clearBadgeCount: false ];
615622
616623 if (!trackIAPPurchase && [OneSignalTrackIAP canTrack ])
617- trackIAPPurchase = [[OneSignalTrackIAP alloc ] init ];
618-
619- if (NSClassFromString (@" UNUserNotificationCenter" ))
620- [OneSignalHelper clearCachedMedia ];
624+ trackIAPPurchase = [OneSignalTrackIAP new ];
621625
622- /*
623- * Downloads params file to see:
624- * (A) if firebase analytics should be tracked
625- * (B) if this app requires email authentication
626- */
627- if ([OneSignalTrackFirebaseAnalytics needsRemoteParams ])
626+ if ([OneSignalTrackFirebaseAnalytics libraryExists ])
628627 [OneSignalTrackFirebaseAnalytics init ];
629628
630629 return self;
@@ -664,6 +663,7 @@ + (bool)initAppId:(NSString*)appId withSettings:(NSDictionary*)settings {
664663 // Handle changes to the app id, this might happen on a developer's device when testing
665664 // Will also run the first time OneSignal is initialized
666665 if (app_id && ![app_id isEqualToString: prevAppId]) {
666+ initDone = false ;
667667 let sharedUserDefaults = OneSignalUserDefaults.initShared ;
668668
669669 // Save app_id to both standard and shared NSUserDefaults
0 commit comments