diff --git a/iOS_SDK/OneSignalSDK/Framework/OneSignal.framework/Versions/A/OneSignal b/iOS_SDK/OneSignalSDK/Framework/OneSignal.framework/Versions/A/OneSignal index 2daed671b..138e3e569 100644 Binary files a/iOS_SDK/OneSignalSDK/Framework/OneSignal.framework/Versions/A/OneSignal and b/iOS_SDK/OneSignalSDK/Framework/OneSignal.framework/Versions/A/OneSignal differ diff --git a/iOS_SDK/OneSignalSDK/Source/OneSignal.m b/iOS_SDK/OneSignalSDK/Source/OneSignal.m index 8a3aea8f6..1fe440a13 100755 --- a/iOS_SDK/OneSignalSDK/Source/OneSignal.m +++ b/iOS_SDK/OneSignalSDK/Source/OneSignal.m @@ -160,10 +160,6 @@ @implementation OneSignal // Under Capabilities is "Background Modes" > "Remote notifications" enabled. static BOOL backgroundModesEnabled = false; -// indicates if the GetiOSParams request has completed -static BOOL downloadedParameters = false; -static BOOL didCallDownloadParameters = false; - static BOOL promptBeforeOpeningPushURLs = false; @@ -332,6 +328,24 @@ + (void)setMSubscriptionStatus:(NSNumber*)status { mSubscriptionStatus = [status intValue]; } +/* + Indicates if the iOS params request has started + Set to true when the method is called and set false if the request's failure callback is triggered + */ +static BOOL _didCallDownloadParameters = false; ++ (BOOL)didCallDownloadParameters { + return _didCallDownloadParameters; +} + +/* + Indicates if the iOS params request is complete + Set to true when the request's success callback is triggered + */ +static BOOL _downloadedParameters = false; ++ (BOOL)downloadedParameters { + return _downloadedParameters; +} + static OneSignalReceiveReceiptsController* _receiveReceiptsController; + (OneSignalReceiveReceiptsController*)receiveReceiptsController { if (!_receiveReceiptsController) @@ -428,7 +442,8 @@ + (void)clearStatics { _permissionStateChangesObserver = nil; - didCallDownloadParameters = false; + _downloadedParameters = false; + _didCallDownloadParameters = false; maxApnsWait = APNS_TIMEOUT; reattemptRegistrationInterval = REGISTRATION_DELAY_SECONDS; @@ -520,6 +535,11 @@ + (id)initWithLaunchOptions:(NSDictionary*)launchOptions if (!success) return self; + // Wrapper SDK's call init twice and pass null as the appId on the first call + // the app ID is required to download parameters, so do not download params until the appID is provided + if (!_didCallDownloadParameters && appId && appId != (id)[NSNull null]) + [self downloadIOSParamsWithAppId:appId]; + if (initDone) return self; initDone = true; @@ -529,11 +549,6 @@ + (id)initWithLaunchOptions:(NSDictionary*)launchOptions // Outcomes init _sessionManager = [[OneSignalSessionManager alloc] init:self]; _outcomeEventsController = [[OneSignalOutcomeEventsController alloc] init:self.sessionManager]; - - // Some wrapper SDK's call init multiple times and pass nil/NSNull as the appId on the first call - // the app ID is required to download parameters, so do not download params until the appID is provided - if (!didCallDownloadParameters && appId != nil && appId != (id)[NSNull null]) - [self downloadIOSParamsWithAppId:appId]; if (appId && mShareLocation) [OneSignalLocation getLocation:false]; @@ -597,7 +612,6 @@ + (id)initWithLaunchOptions:(NSDictionary*)launchOptions [self registerUser]; else { [self.osNotificationSettings getNotificationPermissionState:^(OSPermissionState *state) { - if (state.answeredPrompt) { [self registerUser]; } else { @@ -664,6 +678,8 @@ + (bool)initAppId:(NSString*)appId withSettings:(NSDictionary*)settings { // Will also run the first time OneSignal is initialized if (app_id && ![app_id isEqualToString:prevAppId]) { initDone = false; + _downloadedParameters = false; + _didCallDownloadParameters = false; let sharedUserDefaults = OneSignalUserDefaults.initShared; [standardUserDefaults saveStringForKey:NSUD_APP_ID withValue:app_id]; @@ -762,9 +778,9 @@ + (void)checkIfApplicationImplementsDeprecatedMethods { }); } -+(void)downloadIOSParamsWithAppId:(NSString *)appId { ++ (void)downloadIOSParamsWithAppId:(NSString *)appId { [self onesignal_Log:ONE_S_LL_DEBUG message:@"Downloading iOS parameters for this application"]; - didCallDownloadParameters = true; + _didCallDownloadParameters = true; [OneSignalClient.sharedClient executeRequest:[OSRequestGetIosParams withUserId:self.currentSubscriptionState.userId appId:appId] onSuccess:^(NSDictionary *result) { if (result[IOS_REQUIRES_EMAIL_AUTHENTICATION]) { @@ -777,24 +793,22 @@ +(void)downloadIOSParamsWithAppId:(NSString *)appId { } } - if (!usesAutoPrompt && - result[IOS_USES_PROVISIONAL_AUTHORIZATION] && - result[IOS_USES_PROVISIONAL_AUTHORIZATION] != [NSNull null] && - [result[IOS_USES_PROVISIONAL_AUTHORIZATION] boolValue]) { - - [OneSignalUserDefaults.initStandard saveBoolForKey:USES_PROVISIONAL_AUTHORIZATION withValue:true]; + if (!usesAutoPrompt && result[IOS_USES_PROVISIONAL_AUTHORIZATION] != (id)[NSNull null]) { + [OneSignalUserDefaults.initStandard saveBoolForKey:USES_PROVISIONAL_AUTHORIZATION withValue:[result[IOS_USES_PROVISIONAL_AUTHORIZATION] boolValue]]; [self checkProvisionalAuthorizationStatus]; } - if (result[IOS_RECEIVE_RECEIPTS_ENABLE]) - [OneSignalUserDefaults.initShared saveBoolForKey:ONESIGNAL_ENABLE_RECEIVE_RECEIPTS withValue:true]; + if (result[IOS_RECEIVE_RECEIPTS_ENABLE] != (id)[NSNull null]) + [OneSignalUserDefaults.initShared saveBoolForKey:ONESIGNAL_ENABLE_RECEIVE_RECEIPTS withValue:[result[IOS_RECEIVE_RECEIPTS_ENABLE] boolValue]]; [OSOutcomesUtils saveOutcomeParamsForApp:result]; [OneSignalTrackFirebaseAnalytics updateFromDownloadParams:result]; - downloadedParameters = true; - } onFailure:nil]; + _downloadedParameters = true; + } onFailure:^(NSError *error) { + _didCallDownloadParameters = false; + }]; } + (void)setLogLevel:(ONE_S_LOG_LEVEL)nsLogLevel visualLevel:(ONE_S_LOG_LEVEL)visualLogLevel { @@ -2290,7 +2304,7 @@ + (void)setEmail:(NSString * _Nonnull)email withEmailAuthHashToken:(NSString * _ and we do not need to delay the request */ - if (!self.currentSubscriptionState.userId || (downloadedParameters == false && emailAuthToken != nil)) { + if (!self.currentSubscriptionState.userId || (_downloadedParameters == false && emailAuthToken != nil)) { [self onesignal_Log:ONE_S_LL_VERBOSE message:@"iOS Parameters for this application has not yet been downloaded. Delaying call to setEmail: until the parameters have been downloaded."]; delayedEmailParameters = [OneSignalSetEmailParameters withEmail:email withAuthToken:emailAuthToken withSuccess:successBlock withFailure:failureBlock]; return; diff --git a/iOS_SDK/OneSignalSDK/Source/OneSignalInternal.h b/iOS_SDK/OneSignalSDK/Source/OneSignalInternal.h index 1753ce8b6..ed38b4247 100644 --- a/iOS_SDK/OneSignalSDK/Source/OneSignalInternal.h +++ b/iOS_SDK/OneSignalSDK/Source/OneSignalInternal.h @@ -66,6 +66,13 @@ + (NSDate *)sessionLaunchTime; +// Indicates if the app provides its own custom Notification customization settings UI +// To enable this, set kOSSettingsKeyProvidesAppNotificationSettings to true in init. ++ (BOOL)providesAppNotificationSettings; + +@property (class, readonly) BOOL didCallDownloadParameters; +@property (class, readonly) BOOL downloadedParameters; + @property (class) NSObject* osNotificationSettings; @property (class) OSPermissionState* currentPermissionState; @@ -75,10 +82,6 @@ @property (class) OneSignalSessionManager* sessionManager; @property (class) OneSignalOutcomeEventsController* outcomeEventsController; -// Indicates if the app provides its own custom Notification customization settings UI -// To enable this, set kOSSettingsKeyProvidesAppNotificationSettings to true in init. -+ (BOOL)providesAppNotificationSettings; - @end diff --git a/iOS_SDK/OneSignalSDK/Source/OneSignalNotificationServiceExtensionHandler.m b/iOS_SDK/OneSignalSDK/Source/OneSignalNotificationServiceExtensionHandler.m index 4664592f4..8f786aa67 100644 --- a/iOS_SDK/OneSignalSDK/Source/OneSignalNotificationServiceExtensionHandler.m +++ b/iOS_SDK/OneSignalSDK/Source/OneSignalNotificationServiceExtensionHandler.m @@ -39,6 +39,10 @@ @implementation OneSignalNotificationServiceExtensionHandler + (UNMutableNotificationContent*)didReceiveNotificationExtensionRequest:(UNNotificationRequest*)request withMutableNotificationContent:(UNMutableNotificationContent*)replacementContent { + // Set default log level of NSE to VERBOSE so we get all logs from NSE logic + [OneSignal setLogLevel:ONE_S_LL_VERBOSE visualLevel:ONE_S_LL_NONE]; + [OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:@"NSE request received, setting OneSignal log level to VERBOSE!"]; + if (!replacementContent) replacementContent = [request.content mutableCopy]; @@ -50,6 +54,7 @@ + (UNMutableNotificationContent*)didReceiveNotificationExtensionRequest:(UNNotif // Track receieved [OneSignalTrackFirebaseAnalytics trackReceivedEvent:payload]; + // Get and check the received notification id let receivedNotificationId = payload.notificationID; if (receivedNotificationId && ![receivedNotificationId isEqualToString:@""]) { // Track confirmed delivery diff --git a/iOS_SDK/OneSignalSDK/Source/OneSignalReceiveReceiptsController.m b/iOS_SDK/OneSignalSDK/Source/OneSignalReceiveReceiptsController.m index fe0849f54..779276524 100644 --- a/iOS_SDK/OneSignalSDK/Source/OneSignalReceiveReceiptsController.m +++ b/iOS_SDK/OneSignalSDK/Source/OneSignalReceiveReceiptsController.m @@ -75,7 +75,7 @@ - (void)sendReceiveReceiptWithPlayerId:(nonnull NSString *)playerId [OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:@"Receieve receipts disabled"]; return; } - + let request = [OSRequestReceiveReceipts withPlayerId:playerId notificationId:notificationId appId:appId]; [OneSignalClient.sharedClient executeRequest:request onSuccess:^(NSDictionary *result) { if (success) diff --git a/iOS_SDK/OneSignalSDK/UnitTests/UnitTests.m b/iOS_SDK/OneSignalSDK/UnitTests/UnitTests.m index 90545815a..3a1c44b67 100644 --- a/iOS_SDK/OneSignalSDK/UnitTests/UnitTests.m +++ b/iOS_SDK/OneSignalSDK/UnitTests/UnitTests.m @@ -37,6 +37,7 @@ #import "OneSignal.h" #import "OneSignalHelper.h" #import "OneSignalTracker.h" +#import "OneSignalInternal.h" #import "NSString+OneSignal.h" #import "UnitTestCommonMethods.h" #import "OneSignalSelectorHelpers.h" @@ -1820,6 +1821,31 @@ - (void) testDidReceiveNotificationExtensionRequestDontOverrideCateogory { XCTAssertEqualObjects(content.attachments[0].URL.scheme, @"file"); } +/* + Wrapper SDKs call OneSignal init method twice: + 1. App id is null + 2. App id should be valid + NOTE: The init method uses flags initDone, didCallDownloadParameters, downloadedParameters and these prevent code from executing more than once in specific cases + initDone BOOL is used to return early in the event of init being called more than once + didCallDownloadParameters BOOL is used to determine whether iOS params have started being pulled down + downloadedParameters BOOL is used to determine whether iOS params have successfully been pulled down + */ +- (void)testiOSParams_withNullAppIdInit_andValidAppIdInit { + // 1. Open app and init with null app id + [OneSignal initWithLaunchOptions:nil appId:nil]; + [UnitTestCommonMethods foregroundApp]; + + // 2. Make sure iOS params did not download, since app id was invalid + XCTAssertFalse(OneSignal.didCallDownloadParameters); + XCTAssertFalse(OneSignal.downloadedParameters); + + // 3. Init with valid app id + [OneSignal initWithLaunchOptions:nil appId:@"b2f7f966-d8cc-11e4-bed1-df8f05be55ba"]; + + // 4. Make sure iOS params have been downloaded, since app_id is valid + XCTAssertTrue(OneSignal.didCallDownloadParameters); + XCTAssertTrue(OneSignal.downloadedParameters); +} - (void)testAddingSharedKeysIfMissing { // 1. Init SDK as normal