diff --git a/BranchSDK.podspec b/BranchSDK.podspec index b767079..7c1175a 100644 --- a/BranchSDK.podspec +++ b/BranchSDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "BranchSDK" - s.version = "3.5.1" + s.version = "3.6.0" s.summary = "Create an HTTP URL for any piece of content in your app" s.description = <<-DESC - Want the highest possible conversions on your sharing feature? diff --git a/BranchSDK.xcodeproj/project.pbxproj b/BranchSDK.xcodeproj/project.pbxproj index fee6212..96ffd5d 100644 --- a/BranchSDK.xcodeproj/project.pbxproj +++ b/BranchSDK.xcodeproj/project.pbxproj @@ -1974,7 +1974,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 3.5.1; + MARKETING_VERSION = 3.6.0; OTHER_LDFLAGS = ( "-weak_framework", LinkPresentation, @@ -2009,7 +2009,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 3.5.1; + MARKETING_VERSION = 3.6.0; OTHER_LDFLAGS = ( "-weak_framework", LinkPresentation, @@ -2215,7 +2215,7 @@ "@loader_path/Frameworks", ); MACH_O_TYPE = staticlib; - MARKETING_VERSION = 3.5.1; + MARKETING_VERSION = 3.6.0; OTHER_LDFLAGS = ( "-weak_framework", LinkPresentation, @@ -2254,7 +2254,7 @@ "@loader_path/Frameworks", ); MACH_O_TYPE = staticlib; - MARKETING_VERSION = 3.5.1; + MARKETING_VERSION = 3.6.0; OTHER_LDFLAGS = ( "-weak_framework", LinkPresentation, @@ -2291,7 +2291,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 3.5.1; + MARKETING_VERSION = 3.6.0; OTHER_LDFLAGS = ( "-weak_framework", LinkPresentation, @@ -2326,7 +2326,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 3.5.1; + MARKETING_VERSION = 3.6.0; OTHER_LDFLAGS = ( "-weak_framework", LinkPresentation, diff --git a/ChangeLog.md b/ChangeLog.md index 4f08749..3eb94d3 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,8 @@ Branch iOS SDK Change Log +v.3.6.0 +- Fixes intermittent issue with universal links on cold opens + v.3.5.1 - Minor logging improvement diff --git a/Sources/BranchSDK/BNCConfig.m b/Sources/BranchSDK/BNCConfig.m index 8703c26..4896c7d 100644 --- a/Sources/BranchSDK/BNCConfig.m +++ b/Sources/BranchSDK/BNCConfig.m @@ -8,7 +8,7 @@ #include "BNCConfig.h" -NSString * const BNC_SDK_VERSION = @"3.5.1"; +NSString * const BNC_SDK_VERSION = @"3.6.0"; NSString * const BNC_LINK_URL = @"https://bnc.lt"; NSString * const BNC_CDN_URL = @"https://cdn.branch.io"; diff --git a/Sources/BranchSDK/BNCServerInterface.m b/Sources/BranchSDK/BNCServerInterface.m index 89869b0..2fc2e29 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 28bdd98..2fefbc4 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 194e03f..f042514 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 96a6f71..d817d9a 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 5e347a1..ec5717c 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 5350341..311c65a 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; diff --git a/scripts/version.sh b/scripts/version.sh index bdbdce9..e7f67a9 100755 --- a/scripts/version.sh +++ b/scripts/version.sh @@ -30,7 +30,7 @@ Options: USAGE } -version=3.5.1 +version=3.6.0 prev_version="$version" if (( $# == 0 )); then