@@ -130,7 +130,6 @@ @interface Branch() <BranchDeepLinkingControllerCompletionDelegate> {
130130@property (strong , nonatomic ) BNCServerRequestQueue *requestQueue;
131131@property (strong , nonatomic ) dispatch_semaphore_t processing_sema;
132132@property (assign , atomic ) NSInteger networkCount;
133- @property (assign , nonatomic ) NSInteger asyncRequestCount;
134133@property (assign , nonatomic ) BNCInitStatus initializationStatus;
135134@property (assign , nonatomic ) BOOL shouldCallSessionInitCallback;
136135@property (assign , nonatomic ) BOOL shouldAutomaticallyDeepLink;
@@ -147,9 +146,16 @@ @interface Branch() <BranchDeepLinkingControllerCompletionDelegate> {
147146@property (strong , nonatomic ) NSMutableArray *whiteListedSchemeList;
148147@property (strong , nonatomic ) BNCURLBlackList *URLBlackList;
149148
150- // dedicated object for locking asyncRequestCount
149+ // tracks async setup calls required before Branch init
150+ @property (assign , nonatomic ) NSInteger asyncRequestCount;
151151@property (strong , nonatomic , readwrite ) NSObject *asyncRequestCountLock;
152152
153+ // tracks if continueUserActivity was called
154+ @property (assign , nonatomic , readwrite ) BOOL continueUserActivityCalled;
155+ @property (strong , nonatomic , readwrite ) NSObject *continueUserActivityCalledLock;
156+
157+ @property (strong , nonatomic , readwrite ) NSObject *shouldWaitForInitLock;
158+
153159@end
154160
155161@implementation Branch
@@ -241,6 +247,8 @@ - (id)initWithInterface:(BNCServerInterface *)interface
241247 if (!self) return self;
242248
243249 self.asyncRequestCountLock = [NSObject new ];
250+ self.continueUserActivityCalledLock = [NSObject new ];
251+ self.shouldWaitForInitLock = [NSObject new ];
244252
245253 // Initialize instance variables
246254
@@ -255,14 +263,19 @@ - (id)initWithInterface:(BNCServerInterface *)interface
255263 _shouldCallSessionInitCallback = YES ;
256264 _processing_sema = dispatch_semaphore_create (1 );
257265 _networkCount = 0 ;
258- @synchronized (self.asyncRequestCountLock ) {
259- _asyncRequestCount = 0 ;
260- }
261266 _deepLinkControllers = [[NSMutableDictionary alloc ] init ];
262267 _whiteListedSchemeList = [[NSMutableArray alloc ] init ];
263268 _useCookieBasedMatching = YES ;
264269 self.class .branchKey = key;
265270 self.URLBlackList = [BNCURLBlackList new ];
271+
272+ @synchronized (self.asyncRequestCountLock ) {
273+ _asyncRequestCount = 0 ;
274+ }
275+ @synchronized (self.continueUserActivityCalledLock ) {
276+ _continueUserActivityCalled = NO ;
277+ }
278+
266279 [BranchOpenRequest setWaitNeededForOpenResponseLock ];
267280
268281 // Register for notifications
@@ -508,21 +521,27 @@ - (void)setRequestMetadataKey:(NSString *)key value:(NSObject *)value {
508521}
509522
510523- (void )enableDelayedInit {
511- self.preferenceHelper .shouldWaitForInit = YES ;
524+ @synchronized (self.shouldWaitForInitLock ) {
525+ self.preferenceHelper .shouldWaitForInit = YES ;
526+ }
512527
513528 self.useCookieBasedMatching = NO ; // Developers delaying init should implement their own SFSafariViewController
514529}
515530
516531- (void )disableDelayedInit {
517- self.preferenceHelper .shouldWaitForInit = NO ;
532+ @synchronized (self.shouldWaitForInitLock ) {
533+ self.preferenceHelper .shouldWaitForInit = NO ;
534+ }
518535}
519536
520537- (NSURL *)getUrlForOnboardingWithRedirectUrl : (NSString *)redirectUrl {
521538 return [BNCStrongMatchHelper getUrlForCookieBasedMatchingWithBranchKey: self .class.branchKey redirectUrl: redirectUrl];
522539}
523540
524541- (void )resumeInit {
525- self.preferenceHelper .shouldWaitForInit = NO ;
542+ @synchronized (self.shouldWaitForInitLock ) {
543+ self.preferenceHelper .shouldWaitForInit = NO ;
544+ }
526545 if (self.initializationStatus == BNCInitStatusInitialized) {
527546 BNCLogError (@" User session has already been initialized, so resumeInit is aborting." );
528547 }
@@ -695,8 +714,18 @@ - (void)initSessionWithLaunchOptions:(NSDictionary *)options
695714 return ;
696715 }
697716 }
698- // Wait for continueUserActivity Branch AppDelegate call to come through
699- self.preferenceHelper .shouldWaitForInit = YES ;
717+ // Wait for continueUserActivity Branch AppDelegate call to come through. This may have already happened...
718+ @synchronized (self.continueUserActivityCalledLock ) {
719+ if (self.continueUserActivityCalled ) {
720+ @synchronized (self.shouldWaitForInitLock ) {
721+ self.preferenceHelper .shouldWaitForInit = NO ;
722+ }
723+ } else {
724+ @synchronized (self.shouldWaitForInitLock ) {
725+ self.preferenceHelper .shouldWaitForInit = YES ;
726+ }
727+ }
728+ }
700729 }
701730 }
702731 else if (![options.allKeys containsObject: UIApplicationLaunchOptionsURLKey]) {
@@ -844,7 +873,9 @@ - (BOOL)handleUniversalDeepLink_private:(NSString*)urlString fromSelf:(BOOL)isFr
844873 self.preferenceHelper .universalLinkUrl = urlString;
845874 self.preferenceHelper .referringURL = urlString;
846875 }
847- self.preferenceHelper .shouldWaitForInit = NO ;
876+ @synchronized (self.shouldWaitForInitLock ) {
877+ self.preferenceHelper .shouldWaitForInit = NO ;
878+ }
848879 [self initUserSessionAndCallCallback: YES ];
849880
850881 id branchUniversalLinkDomains = [self .preferenceHelper getBranchUniversalLinkDomains ];
@@ -902,9 +933,16 @@ - (BOOL)continueUserActivity:(NSUserActivity *)userActivity {
902933 self.preferenceHelper .spotlightIdentifier = nonBranchSpotlightIdentifier;
903934 }
904935 }
905- self.preferenceHelper .shouldWaitForInit = NO ;
936+ @synchronized (self.shouldWaitForInitLock ) {
937+ self.preferenceHelper .shouldWaitForInit = NO ;
938+ }
906939 [self initUserSessionAndCallCallback: YES ];
907940
941+ // update that continueUserActivity was called
942+ @synchronized (self.continueUserActivityCalledLock ) {
943+ _continueUserActivityCalled = YES ;
944+ }
945+
908946 return spotlightIdentifier != nil ;
909947}
910948
@@ -952,6 +990,8 @@ - (void)handlePushNotification:(NSDictionary *)userInfo {
952990 }
953991}
954992
993+ #pragma mark - async data collection
994+
955995- (void )loadUserAgent {
956996 @synchronized (self.asyncRequestCountLock ) {
957997 self.asyncRequestCount ++;
@@ -962,7 +1002,9 @@ - (void)loadUserAgent {
9621002 self.asyncRequestCount --;
9631003 if (self.asyncRequestCount > 0 ) return ;
9641004
965- self.preferenceHelper .shouldWaitForInit = NO ;
1005+ @synchronized (self.shouldWaitForInitLock ) {
1006+ self.preferenceHelper .shouldWaitForInit = NO ;
1007+ }
9661008 dispatch_async (dispatch_get_main_queue (), ^{
9671009 [self initUserSessionAndCallCallback: (self .initializationStatus != BNCInitStatusInitialized)];
9681010 });
@@ -979,8 +1021,10 @@ - (void)loadApplicationData {
9791021 @synchronized (self.asyncRequestCountLock ) {
9801022 self.asyncRequestCount --;
9811023 if (self.asyncRequestCount > 0 ) return ;
982-
983- self.preferenceHelper .shouldWaitForInit = NO ;
1024+
1025+ @synchronized (self.shouldWaitForInitLock ) {
1026+ self.preferenceHelper .shouldWaitForInit = NO ;
1027+ }
9841028 dispatch_async (dispatch_get_main_queue (), ^{
9851029 [self initUserSessionAndCallCallback: (self .initializationStatus != BNCInitStatusInitialized)];
9861030 });
@@ -1025,7 +1069,9 @@ - (BOOL)checkAppleSearchAdsAttribution {
10251069
10261070 id sharedClientInstance = ((id (*)(id , SEL ))[ADClientClass methodForSelector: sharedClient])(ADClientClass, sharedClient);
10271071
1028- self.preferenceHelper .shouldWaitForInit = YES ;
1072+ @synchronized (self.shouldWaitForInitLock ) {
1073+ self.preferenceHelper .shouldWaitForInit = YES ;
1074+ }
10291075 self.preferenceHelper .checkedAppleSearchAdAttribution = YES ;
10301076 @synchronized (self.asyncRequestCountLock ) {
10311077 self.asyncRequestCount ++;
@@ -1065,7 +1111,9 @@ - (BOOL)checkAppleSearchAdsAttribution {
10651111 self.asyncRequestCount --;
10661112 if (self.asyncRequestCount > 0 ) return ;
10671113
1068- self.preferenceHelper .shouldWaitForInit = NO ;
1114+ @synchronized (self.shouldWaitForInitLock ) {
1115+ self.preferenceHelper .shouldWaitForInit = NO ;
1116+ }
10691117 dispatch_async (dispatch_get_main_queue (), ^{
10701118 [self initUserSessionAndCallCallback: (self .initializationStatus != BNCInitStatusInitialized)];
10711119 });
@@ -1103,8 +1151,10 @@ - (BOOL)checkFacebookAppLinks {
11031151 self.asyncRequestCount --;
11041152
11051153 if (self.asyncRequestCount > 0 ) { return ; }
1106- self.preferenceHelper .shouldWaitForInit = NO ;
1107-
1154+
1155+ @synchronized (self.shouldWaitForInitLock ) {
1156+ self.preferenceHelper .shouldWaitForInit = NO ;
1157+ }
11081158 dispatch_async (dispatch_get_main_queue (), ^{
11091159 [self handleDeepLink: appLink];
11101160 });
@@ -1115,7 +1165,9 @@ - (BOOL)checkFacebookAppLinks {
11151165 self.asyncRequestCount ++;
11161166 }
11171167 self.preferenceHelper .checkedFacebookAppLinks = YES ;
1118- self.preferenceHelper .shouldWaitForInit = YES ;
1168+ @synchronized (self.shouldWaitForInitLock ) {
1169+ self.preferenceHelper .shouldWaitForInit = YES ;
1170+ }
11191171
11201172 ((void (*)(id , SEL , void (^ __nullable)(NSURL *__nullable appLink, NSError * __nullable error)))[self .FBSDKAppLinkUtility methodForSelector: fetchDeferredAppLink])(self.FBSDKAppLinkUtility , fetchDeferredAppLink, completionBlock);
11211173
@@ -1955,9 +2007,14 @@ - (void)registerViewWithParams:(NSDictionary *)params andCallback:(callbackWithP
19552007#pragma mark - Application State Change methods
19562008
19572009- (void )applicationDidBecomeActive {
2010+ BOOL shouldWaitForInitCopy = NO ;
2011+ @synchronized (self.shouldWaitForInitLock ) {
2012+ shouldWaitForInitCopy = self.preferenceHelper .shouldWaitForInit ;
2013+ }
2014+
19582015 if (!Branch.trackingDisabled ) {
19592016 if ((self.initializationStatus != BNCInitStatusInitialized) &&
1960- !self. preferenceHelper . shouldWaitForInit &&
2017+ !shouldWaitForInitCopy &&
19612018 ![self .requestQueue containsInstallOrOpen ]) {
19622019 [self initUserSessionAndCallCallback: YES ];
19632020 }
@@ -2137,8 +2194,13 @@ - (void) clearNetworkQueue {
21372194#pragma mark - Session Initialization
21382195
21392196- (void )initSessionIfNeededAndNotInProgress {
2197+ BOOL shouldWaitForInitCopy = NO ;
2198+ @synchronized (self.shouldWaitForInitLock ) {
2199+ shouldWaitForInitCopy = self.preferenceHelper .shouldWaitForInit ;
2200+ }
2201+
21402202 if (self.initializationStatus == BNCInitStatusUninitialized &&
2141- !self. preferenceHelper . shouldWaitForInit &&
2203+ !shouldWaitForInitCopy &&
21422204 ![self .requestQueue containsInstallOrOpen ]) {
21432205 [self initUserSessionAndCallCallback: NO ];
21442206 }
0 commit comments