Skip to content

Commit 3f5f141

Browse files
authored
Merge pull request #1147 from BranchMetrics/CORE-2088
Sync with 1.39.4 maintenance release
2 parents be16e17 + 2cc23f5 commit 3f5f141

26 files changed

+374
-111
lines changed

Branch-SDK/BNCPasteboard.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// BNCPasteboard.h
3+
// Branch
4+
//
5+
// Created by Ernest Cho on 6/24/21.
6+
// Copyright © 2021 Branch, Inc. All rights reserved.
7+
//
8+
9+
#import <Foundation/Foundation.h>
10+
11+
NS_ASSUME_NONNULL_BEGIN
12+
13+
@interface BNCPasteboard : NSObject
14+
15+
/*
16+
Indicates if the client wishes to check for Branch links on install. By default, this is NO.
17+
18+
Set via Branch.checkPasteboardOnInstall
19+
Checked by BranchInstallRequest.makeRequest before checking the pasteboard for a Branch link.
20+
*/
21+
@property (nonatomic, assign) BOOL checkOnInstall;
22+
23+
- (BOOL)isUrlOnPasteboard;
24+
- (nullable NSURL *)checkForBranchLink;
25+
26+
+ (BNCPasteboard *)sharedInstance;
27+
28+
@end
29+
30+
NS_ASSUME_NONNULL_END

Branch-SDK/BNCPasteboard.m

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//
2+
// BNCPasteboard.m
3+
// Branch
4+
//
5+
// Created by Ernest Cho on 6/24/21.
6+
// Copyright © 2021 Branch, Inc. All rights reserved.
7+
//
8+
9+
#import "BNCPasteboard.h"
10+
#import <UIKit/UIKit.h>
11+
#import "Branch.h"
12+
13+
@implementation BNCPasteboard
14+
15+
+ (BNCPasteboard *)sharedInstance {
16+
static BNCPasteboard *pasteboard;
17+
static dispatch_once_t onceToken;
18+
dispatch_once(&onceToken, ^{
19+
pasteboard = [BNCPasteboard new];
20+
});
21+
return pasteboard;
22+
}
23+
24+
- (instancetype)init {
25+
self = [super init];
26+
if (self) {
27+
self.checkOnInstall = NO;
28+
}
29+
return self;
30+
}
31+
32+
- (BOOL)isUrlOnPasteboard {
33+
#if !TARGET_OS_TV
34+
if (@available(iOS 10.0, *)) {
35+
if ([UIPasteboard.generalPasteboard hasURLs]) {
36+
return YES;
37+
}
38+
}
39+
#endif
40+
return NO;
41+
}
42+
43+
- (nullable NSURL *)checkForBranchLink {
44+
if ([self isUrlOnPasteboard]) {
45+
#if !TARGET_OS_TV
46+
// triggers the end user toast message
47+
NSURL *tmp = UIPasteboard.generalPasteboard.URL;
48+
if ([Branch isBranchLink:tmp.absoluteString]) {
49+
return tmp;
50+
}
51+
#endif
52+
}
53+
return nil;
54+
}
55+
56+
@end

Branch-SDK/BNCPreferenceHelper.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ NSURL* /* _Nonnull */ BNCURLForBranchDirectory(void);
7474
- (NSString *)getAPIURL:(NSString *)endpoint;
7575
- (NSString *)getEndpointFromURL:(NSString *)url;
7676

77-
- (id)getBranchUniversalLinkDomains;
78-
7977
- (void)setRequestMetadataKey:(NSString *)key value:(NSObject *)value;
8078
- (NSMutableDictionary *)requestMetadataDictionary;
8179

Branch-SDK/BNCPreferenceHelper.m

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
static NSString * const BRANCH_PREFS_KEY_SESSION_PARAMS = @"bnc_session_params";
4040
static NSString * const BRANCH_PREFS_KEY_INSTALL_PARAMS = @"bnc_install_params";
4141
static NSString * const BRANCH_PREFS_KEY_USER_URL = @"bnc_user_url";
42-
static NSString * const BRANCH_PREFS_KEY_BRANCH_UNIVERSAL_LINK_DOMAINS = @"branch_universal_link_domains";
4342

4443
static NSString * const BRANCH_PREFS_KEY_BRANCH_VIEW_USAGE_CNT = @"bnc_branch_view_usage_cnt_";
4544
static NSString * const BRANCH_PREFS_KEY_ANALYTICAL_DATA = @"bnc_branch_analytical_data";
@@ -472,7 +471,7 @@ - (NSMutableString*) sanitizedMutableBaseURL:(NSString*)baseUrl_ {
472471
} else
473472
if ([baseUrl hasSuffix:@"&"] || [baseUrl hasSuffix:@"?"]) {
474473
} else
475-
if ([baseUrl bnc_containsString:@"?"]) {
474+
if ([baseUrl containsString:@"?"]) {
476475
[baseUrl appendString:@"&"];
477476
}
478477
else {
@@ -502,10 +501,6 @@ - (void)setCheckedFacebookAppLinks:(BOOL)checked {
502501
[self writeBoolToDefaults:BRANCH_PREFS_KEY_CHECKED_FACEBOOK_APP_LINKS value:checked];
503502
}
504503

505-
- (id)getBranchUniversalLinkDomains {
506-
return [[[NSBundle mainBundle] infoDictionary] objectForKey:BRANCH_PREFS_KEY_BRANCH_UNIVERSAL_LINK_DOMAINS];
507-
}
508-
509504
- (NSMutableDictionary *)requestMetadataDictionary {
510505
if (!_requestMetadataDictionary) {
511506
_requestMetadataDictionary = [NSMutableDictionary dictionary];

Branch-SDK/BNCServerInterface.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,17 +275,17 @@ - (BOOL)isLinkingRelatedRequest:(NSString *)endpoint {
275275
BOOL hasIdentifier = (prefs.linkClickIdentifier.length > 0 ) || (prefs.spotlightIdentifier.length > 0 ) || (prefs.universalLinkUrl.length > 0);
276276

277277
// Allow install to resolve a link.
278-
if ([endpoint bnc_containsString:@"/v1/install"] && hasIdentifier) {
278+
if ([endpoint containsString:@"/v1/install"] && hasIdentifier) {
279279
return YES;
280280
}
281281

282282
// Allow open to resolve a link.
283-
if ([endpoint bnc_containsString:@"/v1/open"] && hasIdentifier) {
283+
if ([endpoint containsString:@"/v1/open"] && hasIdentifier) {
284284
return YES;
285285
}
286286

287287
// Allow short url creation requests
288-
if ([endpoint bnc_containsString:@"/v1/url"]) {
288+
if ([endpoint containsString:@"/v1/url"]) {
289289
return YES;
290290
}
291291

Branch-SDK/Branch.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,27 @@ typedef NS_ENUM(NSUInteger, BranchCreditHistoryOrder) {
654654
*/
655655
- (void)ignoreAppleSearchAdsTestData;
656656

657+
/**
658+
Checks the pasteboard (clipboard) for a Branch Link on App Install.
659+
If found, the Branch Link is used to provide deferred deeplink data.
660+
661+
This should be called before initSession
662+
663+
Note, this may display a toast message to the end user.
664+
*/
665+
- (void)checkPasteboardOnInstall;
666+
667+
/**
668+
Let's client know if the Branch SDK will trigger a pasteboard toast to the end user.
669+
670+
All of the following conditions must be true.
671+
672+
1. Developer called checkPastboardOnInstall before initSession
673+
2. A URL is on the pasteboard
674+
3. First time app is run with Branch SDK
675+
*/
676+
- (BOOL)willShowPasteboardToast;
677+
657678
/**
658679
Set the AppGroup used to share data between the App Clip and the Full App.
659680
@@ -752,6 +773,15 @@ typedef NS_ENUM(NSUInteger, BranchCreditHistoryOrder) {
752773
*/
753774
- (void)registerPluginName:(NSString *)name version:(NSString *)version;
754775

776+
/**
777+
Checks if a url string is a probable Branch link.
778+
779+
Checks against the Info.plist and the standard Branch list.
780+
781+
@param urlString URL as an NSString
782+
*/
783+
+ (BOOL)isBranchLink:(NSString *)urlString;
784+
755785
/**
756786
Key-value pairs to be included in the metadata on every request.
757787

Branch-SDK/Branch.m

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#import "BNCAppGroupsData.h"
4343
#import "BNCPartnerParameters.h"
4444
#import "BranchEvent.h"
45+
#import "BNCPasteboard.h"
4546

4647
#if !TARGET_OS_TV
4748
#import "BNCUserAgentCollector.h"
@@ -222,6 +223,10 @@ - (id)initWithInterface:(BNCServerInterface *)interface
222223

223224
BranchJsonConfig *config = BranchJsonConfig.instance;
224225

226+
if (config.checkPasteboardOnInstall) {
227+
[self checkPasteboardOnInstall];
228+
}
229+
225230
if (config.delayInitToCheckForSearchAds) {
226231
[self delayInitToCheckForSearchAds];
227232
}
@@ -783,26 +788,7 @@ - (BOOL)handleUniversalDeepLink_private:(NSString*)urlString sceneIdentifier:(NS
783788

784789
[self initUserSessionAndCallCallback:YES sceneIdentifier:sceneIdentifier];
785790

786-
id branchUniversalLinkDomains = [self.preferenceHelper getBranchUniversalLinkDomains];
787-
if ([branchUniversalLinkDomains isKindOfClass:[NSString class]] && [urlString bnc_containsString:branchUniversalLinkDomains]) {
788-
return YES;
789-
} else if ([branchUniversalLinkDomains isKindOfClass:[NSArray class]]) {
790-
for (id oneDomain in branchUniversalLinkDomains) {
791-
if ([oneDomain isKindOfClass:[NSString class]] && [urlString bnc_containsString:oneDomain]) {
792-
return YES;
793-
}
794-
}
795-
}
796-
797-
NSString *userActivityURL = urlString;
798-
NSArray *branchDomains = [NSArray arrayWithObjects:@"bnc.lt", @"app.link", @"test-app.link", nil];
799-
for (NSString* domain in branchDomains) {
800-
if ([userActivityURL bnc_containsString:domain]) {
801-
return YES;
802-
}
803-
}
804-
805-
return NO;
791+
return [Branch isBranchLink:urlString];
806792
}
807793

808794
- (BOOL)continueUserActivity:(NSUserActivity *)userActivity {
@@ -812,7 +798,7 @@ - (BOOL)continueUserActivity:(NSUserActivity *)userActivity {
812798
- (BOOL)continueUserActivity:(NSUserActivity *)userActivity sceneIdentifier:(NSString *)sceneIdentifier {
813799
BNCLogDebugSDK(@"continueUserActivity:");
814800

815-
if (@available(iOS 11.0, *)) {
801+
if (@available(iOS 11.0, tvOS 11.0, *)) {
816802
if (userActivity.referrerURL) {
817803
self.preferenceHelper.initialReferrer = userActivity.referrerURL.absoluteString;
818804
}
@@ -830,9 +816,9 @@ - (BOOL)continueUserActivity:(NSUserActivity *)userActivity sceneIdentifier:(NSS
830816
spotlightIdentifier = [self.contentDiscoveryManager spotlightIdentifierFromActivity:userActivity];
831817
NSURL *webURL = userActivity.webpageURL;
832818

833-
if ([self isBranchLink:userActivity.userInfo[CSSearchableItemActivityIdentifier]]) {
819+
if ([Branch isBranchLink:userActivity.userInfo[CSSearchableItemActivityIdentifier]]) {
834820
return [self handleDeepLink:[NSURL URLWithString:userActivity.userInfo[CSSearchableItemActivityIdentifier]] sceneIdentifier:sceneIdentifier];
835-
} else if (webURL != nil && [self isBranchLink:[webURL absoluteString]]) {
821+
} else if (webURL != nil && [Branch isBranchLink:[webURL absoluteString]]) {
836822
return [self handleDeepLink:webURL sceneIdentifier:sceneIdentifier];
837823
} else if (spotlightIdentifier) {
838824
self.preferenceHelper.spotlightIdentifier = spotlightIdentifier;
@@ -849,25 +835,28 @@ - (BOOL)continueUserActivity:(NSUserActivity *)userActivity sceneIdentifier:(NSS
849835
return spotlightIdentifier != nil;
850836
}
851837

852-
- (BOOL)isBranchLink:(NSString*)urlString {
853-
id branchUniversalLinkDomains = [self.preferenceHelper getBranchUniversalLinkDomains];
854-
if ([branchUniversalLinkDomains isKindOfClass:[NSString class]] &&
855-
[urlString containsString:branchUniversalLinkDomains]) {
838+
// checks if URL string looks like a branch link
839+
+ (BOOL)isBranchLink:(NSString *)urlString {
840+
id branchUniversalLinkDomains = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"branch_universal_link_domains"];
841+
842+
// check url list in bundle
843+
if ([branchUniversalLinkDomains isKindOfClass:[NSString class]] && [urlString containsString:branchUniversalLinkDomains]) {
856844
return YES;
857-
}
858-
else if ([branchUniversalLinkDomains isKindOfClass:[NSArray class]]) {
845+
} else if ([branchUniversalLinkDomains isKindOfClass:[NSArray class]]) {
859846
for (id oneDomain in branchUniversalLinkDomains) {
860847
if ([oneDomain isKindOfClass:[NSString class]] && [urlString containsString:oneDomain]) {
861848
return YES;
862849
}
863850
}
864851
}
865852

853+
// check default urls
866854
NSString *userActivityURL = urlString;
867855
NSArray *branchDomains = [NSArray arrayWithObjects:@"bnc.lt", @"app.link", @"test-app.link", nil];
868856
for (NSString* domain in branchDomains) {
869-
if ([userActivityURL containsString:domain])
857+
if ([userActivityURL containsString:domain]) {
870858
return YES;
859+
}
871860
}
872861
return NO;
873862
}
@@ -939,6 +928,19 @@ - (void)ignoreAppleSearchAdsTestData {
939928
#endif
940929
}
941930

931+
- (void)checkPasteboardOnInstall {
932+
[BNCPasteboard sharedInstance].checkOnInstall = YES;
933+
}
934+
935+
- (BOOL)willShowPasteboardToast {
936+
if (!self.preferenceHelper.randomizedBundleToken &&
937+
[BNCPasteboard sharedInstance].checkOnInstall &&
938+
[BNCPasteboard sharedInstance].isUrlOnPasteboard) {
939+
return YES;
940+
}
941+
return NO;
942+
}
943+
942944
- (void)checkAppleSearchAdsAttribution {
943945
#if !TARGET_OS_TV
944946
if (![BNCAppleSearchAds sharedInstance].enableAppleSearchAdsCheck) {

Branch-SDK/BranchConstants.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ extern NSString * const BRANCH_REQUEST_KEY_CHECKED_APPLE_AD_ATTRIBUTION;
5959
extern NSString * const BRANCH_REQUEST_KEY_LINK_IDENTIFIER;
6060
extern NSString * const BRANCH_REQUEST_KEY_SPOTLIGHT_IDENTIFIER;
6161
extern NSString * const BRANCH_REQUEST_KEY_UNIVERSAL_LINK_URL;
62+
extern NSString * const BRANCH_REQUEST_KEY_LOCAL_URL;
6263
extern NSString * const BRANCH_REQUEST_KEY_INITIAL_REFERRER;
6364
extern NSString * const BRANCH_REQUEST_KEY_BRAND;
6465
extern NSString * const BRANCH_REQUEST_KEY_MODEL;

Branch-SDK/BranchConstants.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
NSString * const BRANCH_REQUEST_KEY_CHECKED_APPLE_AD_ATTRIBUTION = @"apple_ad_attribution_checked";
5656
NSString * const BRANCH_REQUEST_KEY_SPOTLIGHT_IDENTIFIER = @"spotlight_identifier";
5757
NSString * const BRANCH_REQUEST_KEY_UNIVERSAL_LINK_URL = @"universal_link_url";
58+
NSString * const BRANCH_REQUEST_KEY_LOCAL_URL = @"local_url";
5859
NSString * const BRANCH_REQUEST_KEY_INITIAL_REFERRER = @"initial_referrer";
5960
NSString * const BRANCH_REQUEST_KEY_BRAND = @"brand";
6061
NSString * const BRANCH_REQUEST_KEY_MODEL = @"model";

Branch-SDK/BranchInstallRequest.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#import "BNCAppleReceipt.h"
1616
#import "BNCAppGroupsData.h"
1717
#import "BNCPartnerParameters.h"
18+
#import "BNCPasteboard.h"
1819

1920
@implementation BranchInstallRequest
2021

@@ -67,6 +68,13 @@ - (void)makeRequest:(BNCServerInterface *)serverInterface key:(NSString *)key ca
6768
onDict:params];
6869
}
6970

71+
if ([BNCPasteboard sharedInstance].checkOnInstall) {
72+
NSURL *pasteboardURL = [[BNCPasteboard sharedInstance] checkForBranchLink];
73+
if (pasteboardURL) {
74+
[self safeSetValue:pasteboardURL.absoluteString forKey:BRANCH_REQUEST_KEY_LOCAL_URL onDict:params];
75+
}
76+
}
77+
7078
NSString *appleAttributionToken = [BNCSystemObserver appleAttributionToken];
7179
if (appleAttributionToken) {
7280
preferenceHelper.appleAttributionTokenChecked = YES;

0 commit comments

Comments
 (0)