From 74c40ade31ecaf0f72ac7af900e8cff03333a8cf Mon Sep 17 00:00:00 2001 From: ndixit-branch <93544270+NidhiDixit09@users.noreply.github.com> Date: Fri, 2 Aug 2024 16:05:14 -0700 Subject: [PATCH] Universal ink cold launch fix (#1421) * Fix for Universal Link Cold launch when tracking is disabled. -> Moved check isLinkingRelatedRequest to postRequest func -> Fixed isLinkingRelatedRequest to read identifiers from request post params. -> Temporarily Commented out code for retrieving archived queues - will revert later * Added property for Differentiating between archived and non-archived requests * Don't process archived Open Requests once an Open Request with link url get successful. * Added param in function initUserSessionAndCallCallback for forced session re-initialization irrespective of current SDK initializationStatus --- Sources/BranchSDK/BNCServerInterface.m | 37 ++++++++++--------- Sources/BranchSDK/BNCServerRequestQueue.m | 9 ++++- Sources/BranchSDK/Branch.m | 34 +++++++++++------ Sources/BranchSDK/BranchOpenRequest.m | 5 +++ Sources/BranchSDK/Private/BranchOpenRequest.h | 2 +- .../BranchSDK/Public/BNCServerRequestQueue.h | 2 + 6 files changed, 59 insertions(+), 30 deletions(-) diff --git a/Sources/BranchSDK/BNCServerInterface.m b/Sources/BranchSDK/BNCServerInterface.m index 89869b028..2fc2e29f8 100644 --- a/Sources/BranchSDK/BNCServerInterface.m +++ b/Sources/BranchSDK/BNCServerInterface.m @@ -65,6 +65,23 @@ - (void)postRequest:(NSDictionary *)post url:(NSString *)url retryNumber:(NSInte // TODO: confirm it's ok to send full URL instead of with the domain trimmed off self.requestEndpoint = url; + + // Drops non-linking requests when tracking is disabled + if (Branch.trackingDisabled) { + + [[BranchLogger shared] logVerbose:[NSString stringWithFormat:@"Tracking is disabled, checking if %@ is linking request.", url] error:nil]; + + if (![self isLinkingRelatedRequest:url postParams:post]) { + [[BNCPreferenceHelper sharedInstance] clearTrackingInformation]; + NSError *error = [NSError branchErrorWithCode:BNCTrackingDisabledError]; + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Dropping non-linking request"] error:error]; + if (callback) { + callback(nil, error); + } + return; + } + } + NSURLRequest *request = [self preparePostRequest:post url:url key:key retryNumber:retryNumber]; [self genericHTTPRequest:request @@ -142,21 +159,7 @@ - (void)genericHTTPRequest:(NSURLRequest *)request retryNumber:(NSInteger)retryN } }; - // Drops non-linking requests when tracking is disabled - if (Branch.trackingDisabled) { - NSString *endpoint = request.URL.absoluteString; - [[BranchLogger shared] logVerbose:[NSString stringWithFormat:@"Tracking is disabled, checking if %@ is linking request.", endpoint] error:nil]; - if (![self isLinkingRelatedRequest:endpoint]) { - [[BNCPreferenceHelper sharedInstance] clearTrackingInformation]; - NSError *error = [NSError branchErrorWithCode:BNCTrackingDisabledError]; - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Dropping non-linking request"] error:error]; - if (callback) { - callback(nil, error); - } - return; - } - } id operation = [self.networkService networkOperationWithURLRequest:request.copy completion:completionHandler]; [operation start]; @@ -172,9 +175,9 @@ - (void)genericHTTPRequest:(NSURLRequest *)request retryNumber:(NSInteger)retryN } } -- (BOOL)isLinkingRelatedRequest:(NSString *)endpoint { - BNCPreferenceHelper *prefs = [BNCPreferenceHelper sharedInstance]; - BOOL hasIdentifier = (prefs.linkClickIdentifier.length > 0 ) || (prefs.spotlightIdentifier.length > 0 ) || (prefs.universalLinkUrl.length > 0); +- (BOOL)isLinkingRelatedRequest:(NSString *)endpoint postParams:(NSDictionary *)post { + + BOOL hasIdentifier = (post[BRANCH_REQUEST_KEY_LINK_IDENTIFIER] != nil ) || (post[BRANCH_REQUEST_KEY_LINK_IDENTIFIER] != nil) || (post[BRANCH_REQUEST_KEY_UNIVERSAL_LINK_URL] != nil); // Allow install to resolve a link. if ([endpoint containsString:@"/v1/install"]) { diff --git a/Sources/BranchSDK/BNCServerRequestQueue.m b/Sources/BranchSDK/BNCServerRequestQueue.m index 28bdd988a..2fefbc419 100755 --- a/Sources/BranchSDK/BNCServerRequestQueue.m +++ b/Sources/BranchSDK/BNCServerRequestQueue.m @@ -42,6 +42,7 @@ - (instancetype)init { self.queue = [NSMutableArray new]; self.asyncQueue = dispatch_queue_create("io.branch.persist_queue", DISPATCH_QUEUE_SERIAL); + self.processArchivedOpens = YES; return self; } @@ -167,7 +168,8 @@ - (BranchOpenRequest *)findExistingInstallOrOpen { BNCServerRequest *request = [self.queue objectAtIndex:i]; // Install subclasses open, so only need to check open - if ([request isKindOfClass:[BranchOpenRequest class]]) { + // Request should not be the one added from archived queue + if ([request isKindOfClass:[BranchOpenRequest class]] && !((BranchOpenRequest *)request).isFromArchivedQueue) { return (BranchOpenRequest *)request; } } @@ -279,6 +281,11 @@ - (void)retrieve { NSData *data = [NSData dataWithContentsOfURL:self.class.URLForQueueFile options:0 error:&error]; if (!error && data) { NSMutableArray *decodedQueue = [self unarchiveQueueFromData:data]; + for (id request in decodedQueue) { + if ([request isKindOfClass:[BranchOpenRequest class]] || [request isKindOfClass:[BranchInstallRequest class]]) { + ((BranchOpenRequest *)request).isFromArchivedQueue = YES; + } + } self.queue = decodedQueue; } } diff --git a/Sources/BranchSDK/Branch.m b/Sources/BranchSDK/Branch.m index 194e03f60..f04251466 100644 --- a/Sources/BranchSDK/Branch.m +++ b/Sources/BranchSDK/Branch.m @@ -526,7 +526,7 @@ + (void)setTrackingDisabled:(BOOL)disabled { // Set the flag: [BNCPreferenceHelper sharedInstance].trackingDisabled = NO; // Initialize a Branch session: - [Branch.getInstance initUserSessionAndCallCallback:NO sceneIdentifier:nil urlString:nil]; + [Branch.getInstance initUserSessionAndCallCallback:NO sceneIdentifier:nil urlString:nil reset:NO]; } } } @@ -642,7 +642,7 @@ - (void)initSessionWithLaunchOptions:(NSDictionary *)options } #endif - [self initUserSessionAndCallCallback:YES sceneIdentifier:nil urlString:pushURL]; + [self initUserSessionAndCallCallback:YES sceneIdentifier:nil urlString:pushURL reset:NO]; } - (void)setDeepLinkDebugMode:(NSDictionary *)debugParams { @@ -693,7 +693,7 @@ - (BOOL)handleDeepLink:(NSURL *)url sceneIdentifier:(NSString *)sceneIdentifier self.preferenceHelper.externalIntentURI = pattern; self.preferenceHelper.referringURL = pattern; - [self initUserSessionAndCallCallback:YES sceneIdentifier:sceneIdentifier urlString:nil]; + [self initUserSessionAndCallCallback:YES sceneIdentifier:sceneIdentifier urlString:nil reset:YES]; return NO; } @@ -741,7 +741,7 @@ - (BOOL)handleSchemeDeepLink_private:(NSURL*)url sceneIdentifier:(NSString *)sce self.preferenceHelper.linkClickIdentifier = params[@"link_click_id"]; } } - [self initUserSessionAndCallCallback:YES sceneIdentifier:sceneIdentifier urlString:url.absoluteString]; + [self initUserSessionAndCallCallback:YES sceneIdentifier:sceneIdentifier urlString:url.absoluteString reset:YES]; return handled; } @@ -775,7 +775,7 @@ - (BOOL)handleUniversalDeepLink_private:(NSString*)urlString sceneIdentifier:(NS [[BranchLogger shared] logVerbose:[NSString stringWithFormat:@"Set universalLinkUrl and referringURL to %@", urlString] error:nil]; } - [self initUserSessionAndCallCallback:YES sceneIdentifier:sceneIdentifier urlString:urlString]; + [self initUserSessionAndCallCallback:YES sceneIdentifier:sceneIdentifier urlString:urlString reset:YES]; return [Branch isBranchLink:urlString]; } @@ -815,7 +815,7 @@ - (BOOL)continueUserActivity:(NSUserActivity *)userActivity sceneIdentifier:(NSS } #endif - [self initUserSessionAndCallCallback:YES sceneIdentifier:sceneIdentifier urlString:userActivity.webpageURL.absoluteString]; + [self initUserSessionAndCallCallback:YES sceneIdentifier:sceneIdentifier urlString:userActivity.webpageURL.absoluteString reset:YES]; return spotlightIdentifier != nil; } @@ -1716,7 +1716,7 @@ - (void)applicationDidBecomeActive { if (!Branch.trackingDisabled && self.initializationStatus != BNCInitStatusInitialized && !installOrOpenInQueue) { [[BranchLogger shared] logVerbose:[NSString stringWithFormat:@"applicationDidBecomeActive trackingDisabled %d initializationStatus %d installOrOpenInQueue %d", Branch.trackingDisabled, self.initializationStatus, installOrOpenInQueue] error:nil]; - [self initUserSessionAndCallCallback:YES sceneIdentifier:nil urlString:nil]; + [self initUserSessionAndCallCallback:YES sceneIdentifier:nil urlString:nil reset:NO]; } }); } @@ -1885,6 +1885,16 @@ - (void)processNextQueueItem { return; } } + + if ( !(((BNCServerRequestQueue*)[BNCServerRequestQueue getInstance]).processArchivedOpens) + && [req isKindOfClass:[BranchOpenRequest class]] + && ((BranchOpenRequest *)req).isFromArchivedQueue){ + [[BranchLogger shared] logVerbose:[NSString stringWithFormat:@"Removed Archived Open Request from Queue %@", [req description]] error:nil]; + [self.requestQueue remove:req]; + self.networkCount = 0; + [self processNextQueueItem]; + return; + } dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^ { @@ -1945,11 +1955,11 @@ - (void)notifyNativeToInit { - (void)initSafetyCheck { if (self.initializationStatus == BNCInitStatusUninitialized) { [[BranchLogger shared] logDebug:@"Branch avoided an error by preemptively initializing." error:nil]; - [self initUserSessionAndCallCallback:NO sceneIdentifier:nil urlString:nil]; + [self initUserSessionAndCallCallback:NO sceneIdentifier:nil urlString:nil reset:NO]; } } -- (void)initUserSessionAndCallCallback:(BOOL)callCallback sceneIdentifier:(NSString *)sceneIdentifier urlString:(NSString *)urlString { +- (void)initUserSessionAndCallCallback:(BOOL)callCallback sceneIdentifier:(NSString *)sceneIdentifier urlString:(NSString *)urlString reset:(BOOL)reset { @synchronized (self) { if (self.deferInitForPluginRuntime) { @@ -1971,8 +1981,10 @@ - (void)initUserSessionAndCallCallback:(BOOL)callCallback sceneIdentifier:(NSStr dispatch_async(self.isolationQueue, ^(){ - // If the session is not yet initialized - if (self.initializationStatus == BNCInitStatusUninitialized) { + + // If the session is not yet initialized OR + // If the session is already initialized or is initializing but we need to reset it. + if ( reset || self.initializationStatus == BNCInitStatusUninitialized) { [self initializeSessionAndCallCallback:callCallback sceneIdentifier:sceneIdentifier urlString:urlString]; } // If the session was initialized, but callCallback was specified, do so. diff --git a/Sources/BranchSDK/BranchOpenRequest.m b/Sources/BranchSDK/BranchOpenRequest.m index 96a6f7110..d817d9a07 100644 --- a/Sources/BranchSDK/BranchOpenRequest.m +++ b/Sources/BranchSDK/BranchOpenRequest.m @@ -40,6 +40,7 @@ - (id)initWithCallback:(callbackWithStatus)callback isInstall:(BOOL)isInstall { if ((self = [super init])) { _callback = callback; _isInstall = isInstall; + _isFromArchivedQueue = NO; } return self; @@ -151,6 +152,10 @@ - (void)processResponse:(BNCServerResponse *)response error:(NSError *)error { } } } + + if (referringURL.length > 0) { + ((BNCServerRequestQueue *)[BNCServerRequestQueue getInstance]).processArchivedOpens = NO; + } // Clear link identifiers so they don't get reused on the next open preferenceHelper.linkClickIdentifier = nil; diff --git a/Sources/BranchSDK/Private/BranchOpenRequest.h b/Sources/BranchSDK/Private/BranchOpenRequest.h index 5e347a178..ec5717cd6 100644 --- a/Sources/BranchSDK/Private/BranchOpenRequest.h +++ b/Sources/BranchSDK/Private/BranchOpenRequest.h @@ -13,7 +13,7 @@ // URL that triggered this install or open event @property (nonatomic, copy, readwrite) NSString *urlString; - +@property (assign, nonatomic) BOOL isFromArchivedQueue; @property (nonatomic, copy) callbackWithStatus callback; + (void) waitForOpenResponseLock; diff --git a/Sources/BranchSDK/Public/BNCServerRequestQueue.h b/Sources/BranchSDK/Public/BNCServerRequestQueue.h index 535034112..311c65a76 100755 --- a/Sources/BranchSDK/Public/BNCServerRequestQueue.h +++ b/Sources/BranchSDK/Public/BNCServerRequestQueue.h @@ -11,6 +11,8 @@ @interface BNCServerRequestQueue : NSObject +@property (assign, nonatomic) BOOL processArchivedOpens; + - (void)enqueue:(BNCServerRequest *)request; - (BNCServerRequest *)dequeue; - (BNCServerRequest *)peek;