From 3d7aa5fc5e10a4fb7546e7f75cb4601929849c11 Mon Sep 17 00:00:00 2001 From: Ernest Cho Date: Tue, 6 Jul 2021 14:22:59 -0700 Subject: [PATCH 01/11] CORE-2088 backport the pasteboard feature --- Branch-SDK/BNCPasteboard.h | 24 +++++++++ Branch-SDK/BNCPasteboard.m | 51 +++++++++++++++++++ Branch-SDK/Branch.h | 8 +++ Branch-SDK/Branch.m | 42 ++++++--------- Branch-SDK/BranchConstants.h | 1 + Branch-SDK/BranchConstants.m | 1 + Branch-SDK/BranchInstallRequest.m | 8 +++ .../Branch-TestBed.xcodeproj/project.pbxproj | 8 +++ Branch-TestBed/Branch-TestBed/AppDelegate.m | 2 + 9 files changed, 118 insertions(+), 27 deletions(-) create mode 100644 Branch-SDK/BNCPasteboard.h create mode 100644 Branch-SDK/BNCPasteboard.m diff --git a/Branch-SDK/BNCPasteboard.h b/Branch-SDK/BNCPasteboard.h new file mode 100644 index 000000000..f01e8cd9b --- /dev/null +++ b/Branch-SDK/BNCPasteboard.h @@ -0,0 +1,24 @@ +// +// BNCPasteboard.h +// Branch +// +// Created by Ernest Cho on 6/24/21. +// Copyright © 2021 Branch, Inc. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface BNCPasteboard : NSObject + +// For v1, we only allow check on install requests +@property (nonatomic,assign) BOOL checkOnInstall; + +- (nullable NSURL *)checkForBranchLink; + ++ (BNCPasteboard *)sharedInstance; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Branch-SDK/BNCPasteboard.m b/Branch-SDK/BNCPasteboard.m new file mode 100644 index 000000000..052d9238b --- /dev/null +++ b/Branch-SDK/BNCPasteboard.m @@ -0,0 +1,51 @@ +// +// BNCPasteboard.m +// Branch +// +// Created by Ernest Cho on 6/24/21. +// Copyright © 2021 Branch, Inc. All rights reserved. +// + +#import "BNCPasteboard.h" +#import + +@implementation BNCPasteboard + ++ (BNCPasteboard *)sharedInstance { + static BNCPasteboard *pasteboard; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + pasteboard = [BNCPasteboard new]; + }); + return pasteboard; +} + +- (instancetype)init { + self = [super init]; + if (self) { + self.checkOnInstall = NO; + } + return self; +} + +- (nullable NSURL *)checkForBranchLink { + // consider limiting this check to iOS 15+ + if (@available(iOS 10.0, *)) { + if ([UIPasteboard.generalPasteboard hasURLs]) { + + // triggers the end user toast message + NSURL *tmp = UIPasteboard.generalPasteboard.URL; + if ([self isProbableBranchLink:tmp]) { + return tmp; + } + } + } + return nil; +} + +- (BOOL)isProbableBranchLink:(NSURL *)url { + // TODO: check against info.plist + return YES; +} + +@end diff --git a/Branch-SDK/Branch.h b/Branch-SDK/Branch.h index 1fd49b17f..9607fcd40 100644 --- a/Branch-SDK/Branch.h +++ b/Branch-SDK/Branch.h @@ -676,6 +676,14 @@ typedef NS_ENUM(NSUInteger, BranchCreditHistoryOrder) { */ - (void)ignoreAppleSearchAdsTestData; +/** + Checks the pasteboard for a Branch Link. + This copied Branch Link in the install request and can provide deeplink data. + + Note, this will display a toast message to the end user. + */ +- (void)checkPasteboardForBranchLinkOnInstall; + /** Set the AppGroup used to share data between the App Clip and the Full App. diff --git a/Branch-SDK/Branch.m b/Branch-SDK/Branch.m index 61e5cf4f0..4c8b77594 100644 --- a/Branch-SDK/Branch.m +++ b/Branch-SDK/Branch.m @@ -45,6 +45,7 @@ #import "BNCAppGroupsData.h" #import "BNCPartnerParameters.h" #import "BranchEvent.h" +#import "BNCPasteboard.h" #if !TARGET_OS_TV #import "BNCUserAgentCollector.h" @@ -800,26 +801,7 @@ - (BOOL)handleUniversalDeepLink_private:(NSString*)urlString sceneIdentifier:(NS [self initUserSessionAndCallCallback:YES sceneIdentifier:sceneIdentifier]; - id branchUniversalLinkDomains = [self.preferenceHelper getBranchUniversalLinkDomains]; - if ([branchUniversalLinkDomains isKindOfClass:[NSString class]] && [urlString bnc_containsString:branchUniversalLinkDomains]) { - return YES; - } else if ([branchUniversalLinkDomains isKindOfClass:[NSArray class]]) { - for (id oneDomain in branchUniversalLinkDomains) { - if ([oneDomain isKindOfClass:[NSString class]] && [urlString bnc_containsString:oneDomain]) { - return YES; - } - } - } - - NSString *userActivityURL = urlString; - NSArray *branchDomains = [NSArray arrayWithObjects:@"bnc.lt", @"app.link", @"test-app.link", nil]; - for (NSString* domain in branchDomains) { - if ([userActivityURL bnc_containsString:domain]) { - return YES; - } - } - - return NO; + return [self isBranchLink:urlString]; } - (BOOL)continueUserActivity:(NSUserActivity *)userActivity { @@ -860,13 +842,13 @@ - (BOOL)continueUserActivity:(NSUserActivity *)userActivity sceneIdentifier:(NSS return spotlightIdentifier != nil; } -- (BOOL)isBranchLink:(NSString*)urlString { - id branchUniversalLinkDomains = [self.preferenceHelper getBranchUniversalLinkDomains]; - if ([branchUniversalLinkDomains isKindOfClass:[NSString class]] && - [urlString containsString:branchUniversalLinkDomains]) { +- (BOOL)isBranchLink:(NSString *)urlString { + id branchUniversalLinkDomains = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"branch_universal_link_domains"]; + + // check list in bundle + if ([branchUniversalLinkDomains isKindOfClass:[NSString class]] && [urlString containsString:branchUniversalLinkDomains]) { return YES; - } - else if ([branchUniversalLinkDomains isKindOfClass:[NSArray class]]) { + } else if ([branchUniversalLinkDomains isKindOfClass:[NSArray class]]) { for (id oneDomain in branchUniversalLinkDomains) { if ([oneDomain isKindOfClass:[NSString class]] && [urlString containsString:oneDomain]) { return YES; @@ -874,11 +856,13 @@ - (BOOL)isBranchLink:(NSString*)urlString { } } + // check default urls NSString *userActivityURL = urlString; NSArray *branchDomains = [NSArray arrayWithObjects:@"bnc.lt", @"app.link", @"test-app.link", nil]; for (NSString* domain in branchDomains) { - if ([userActivityURL containsString:domain]) + if ([userActivityURL containsString:domain]) { return YES; + } } return NO; } @@ -950,6 +934,10 @@ - (void)ignoreAppleSearchAdsTestData { #endif } +- (void)checkPasteboardForBranchLinkOnInstall { + [BNCPasteboard sharedInstance].checkOnInstall = YES; +} + - (void)checkAppleSearchAdsAttribution { #if !TARGET_OS_TV if (![BNCAppleSearchAds sharedInstance].enableAppleSearchAdsCheck) { diff --git a/Branch-SDK/BranchConstants.h b/Branch-SDK/BranchConstants.h index 3b0f2b574..6fbcea3ef 100644 --- a/Branch-SDK/BranchConstants.h +++ b/Branch-SDK/BranchConstants.h @@ -59,6 +59,7 @@ extern NSString * const BRANCH_REQUEST_KEY_CHECKED_APPLE_AD_ATTRIBUTION; extern NSString * const BRANCH_REQUEST_KEY_LINK_IDENTIFIER; extern NSString * const BRANCH_REQUEST_KEY_SPOTLIGHT_IDENTIFIER; extern NSString * const BRANCH_REQUEST_KEY_UNIVERSAL_LINK_URL; +extern NSString * const BRANCH_REQUEST_KEY_LOCAL_URL; extern NSString * const BRANCH_REQUEST_KEY_BRAND; extern NSString * const BRANCH_REQUEST_KEY_MODEL; extern NSString * const BRANCH_REQUEST_KEY_SCREEN_WIDTH; diff --git a/Branch-SDK/BranchConstants.m b/Branch-SDK/BranchConstants.m index 8775fcc2a..079f74eb3 100644 --- a/Branch-SDK/BranchConstants.m +++ b/Branch-SDK/BranchConstants.m @@ -55,6 +55,7 @@ NSString * const BRANCH_REQUEST_KEY_CHECKED_APPLE_AD_ATTRIBUTION = @"apple_ad_attribution_checked"; NSString * const BRANCH_REQUEST_KEY_SPOTLIGHT_IDENTIFIER = @"spotlight_identifier"; NSString * const BRANCH_REQUEST_KEY_UNIVERSAL_LINK_URL = @"universal_link_url"; +NSString * const BRANCH_REQUEST_KEY_LOCAL_URL = @"local_url"; NSString * const BRANCH_REQUEST_KEY_BRAND = @"brand"; NSString * const BRANCH_REQUEST_KEY_MODEL = @"model"; NSString * const BRANCH_REQUEST_KEY_SCREEN_WIDTH = @"screen_width"; diff --git a/Branch-SDK/BranchInstallRequest.m b/Branch-SDK/BranchInstallRequest.m index 9db732ce0..208d04259 100644 --- a/Branch-SDK/BranchInstallRequest.m +++ b/Branch-SDK/BranchInstallRequest.m @@ -15,6 +15,7 @@ #import "BNCAppleReceipt.h" #import "BNCAppGroupsData.h" #import "BNCPartnerParameters.h" +#import "BNCPasteboard.h" @implementation BranchInstallRequest @@ -67,6 +68,13 @@ - (void)makeRequest:(BNCServerInterface *)serverInterface key:(NSString *)key ca onDict:params]; } + if ([BNCPasteboard sharedInstance].checkOnInstall) { + NSURL *pasteboardURL = [[BNCPasteboard sharedInstance] checkForBranchLink]; + if (pasteboardURL) { + [self safeSetValue:pasteboardURL.absoluteString forKey:BRANCH_REQUEST_KEY_LOCAL_URL onDict:params]; + } + } + NSString *appleAttributionToken = [BNCSystemObserver appleAttributionToken]; if (appleAttributionToken) { preferenceHelper.appleAttributionTokenChecked = YES; diff --git a/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj b/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj index 74870213d..3c348e458 100644 --- a/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj +++ b/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj @@ -182,6 +182,8 @@ 5F3D6718233061CB00454FF1 /* BranchCrossPlatformIDTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F3D6717233061CB00454FF1 /* BranchCrossPlatformIDTests.m */; }; 5F3D671B233062FD00454FF1 /* BNCJsonLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F3D671A233062FD00454FF1 /* BNCJsonLoader.m */; }; 5F3D671C233062FD00454FF1 /* BNCJsonLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F3D671A233062FD00454FF1 /* BNCJsonLoader.m */; }; + 5F4101F526851DC7003699AD /* BNCPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F4101F326851DC7003699AD /* BNCPasteboard.h */; }; + 5F4101F626851DC7003699AD /* BNCPasteboard.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F4101F426851DC7003699AD /* BNCPasteboard.m */; }; 5F42763325DB3694005B9BBC /* AdServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F42763225DB3694005B9BBC /* AdServices.framework */; }; 5F437E35237DDF770052064B /* BNCTelephony.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F437E33237DDF770052064B /* BNCTelephony.h */; }; 5F437E36237DDF770052064B /* BNCTelephony.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F437E34237DDF770052064B /* BNCTelephony.m */; }; @@ -495,6 +497,8 @@ 5F3D6717233061CB00454FF1 /* BranchCrossPlatformIDTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BranchCrossPlatformIDTests.m; sourceTree = ""; }; 5F3D6719233062FD00454FF1 /* BNCJsonLoader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BNCJsonLoader.h; sourceTree = ""; }; 5F3D671A233062FD00454FF1 /* BNCJsonLoader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BNCJsonLoader.m; sourceTree = ""; }; + 5F4101F326851DC7003699AD /* BNCPasteboard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BNCPasteboard.h; sourceTree = ""; }; + 5F4101F426851DC7003699AD /* BNCPasteboard.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BNCPasteboard.m; sourceTree = ""; }; 5F42763225DB3694005B9BBC /* AdServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdServices.framework; path = System/Library/Frameworks/AdServices.framework; sourceTree = SDKROOT; }; 5F437E33237DDF770052064B /* BNCTelephony.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BNCTelephony.h; sourceTree = ""; }; 5F437E34237DDF770052064B /* BNCTelephony.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BNCTelephony.m; sourceTree = ""; }; @@ -989,6 +993,8 @@ 5F437E34237DDF770052064B /* BNCTelephony.m */, 5F92B2372383703700CA909B /* BNCLocale.h */, 5F92B2382383703700CA909B /* BNCLocale.m */, + 5F4101F326851DC7003699AD /* BNCPasteboard.h */, + 5F4101F426851DC7003699AD /* BNCPasteboard.m */, 5FB0AA69231875B400A0F9EA /* BNCUserAgentCollector.h */, 5FB0AA6A231875B500A0F9EA /* BNCUserAgentCollector.m */, 464EA3991ACB38EC000E4094 /* BNCEncodingUtils.h */, @@ -1114,6 +1120,7 @@ 5F38022024DCC2E800E6FAFD /* BranchLogoutRequest.h in Headers */, 5F38023124DCC2E800E6FAFD /* BNCNetworkService.h in Headers */, 5F38021624DCC2E800E6FAFD /* BranchSpotlightUrlRequest.h in Headers */, + 5F4101F526851DC7003699AD /* BNCPasteboard.h in Headers */, 4DCAC8181F426F7C00405D1D /* BranchLinkProperties.h in Headers */, 5F38022724DCC2E800E6FAFD /* BranchRedeemRewardsRequest.h in Headers */, 4DCAC81A1F426F7C00405D1D /* BranchUniversalObject.h in Headers */, @@ -1427,6 +1434,7 @@ 466B58551B17779C00A69EDE /* Branch.m in Sources */, 5F437E3E237E03C00052064B /* BNCDeviceSystem.m in Sources */, 5F38023B24DCC2E800E6FAFD /* BranchContentDiscoverer.m in Sources */, + 5F4101F626851DC7003699AD /* BNCPasteboard.m in Sources */, 4DBC88651F3A55B700E119BF /* NSString+Branch.m in Sources */, 54FF1F8E1BD1D4AE0004CE2E /* BranchUniversalObject.m in Sources */, 4DA577181E67B1D600A43BDD /* BNCLog.m in Sources */, diff --git a/Branch-TestBed/Branch-TestBed/AppDelegate.m b/Branch-TestBed/Branch-TestBed/AppDelegate.m index c4b48db3a..837f80baa 100644 --- a/Branch-TestBed/Branch-TestBed/AppDelegate.m +++ b/Branch-TestBed/Branch-TestBed/AppDelegate.m @@ -51,6 +51,8 @@ - (BOOL)application:(UIApplication *)application // partner parameter sample //[branch addFacebookPartnerParameterWithName:@"em" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; + [branch checkPasteboardForBranchLinkOnInstall]; + /* * Required: Initialize Branch, passing a deep link handler block: */ From b8f95e68269bad458d85e0fe4291d2d5846eddc4 Mon Sep 17 00:00:00 2001 From: Ernest Cho Date: Tue, 6 Jul 2021 14:48:44 -0700 Subject: [PATCH 02/11] CORE-1950 backport install referrer --- Branch-SDK/BNCPreferenceHelper.h | 1 + Branch-SDK/BNCPreferenceHelper.m | 10 ++++++++++ Branch-SDK/Branch.m | 6 ++++++ Branch-SDK/BranchConstants.h | 1 + Branch-SDK/BranchConstants.m | 1 + Branch-SDK/BranchInstallRequest.m | 2 +- Branch-SDK/BranchOpenRequest.m | 1 + 7 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Branch-SDK/BNCPreferenceHelper.h b/Branch-SDK/BNCPreferenceHelper.h index 5c6a8e58b..ba32d5e49 100644 --- a/Branch-SDK/BNCPreferenceHelper.h +++ b/Branch-SDK/BNCPreferenceHelper.h @@ -28,6 +28,7 @@ NSURL* /* _Nonnull */ BNCURLForBranchDirectory(void); @property (strong, nonatomic) NSString *linkClickIdentifier; @property (strong, nonatomic) NSString *spotlightIdentifier; @property (strong, atomic) NSString *universalLinkUrl; +@property (strong, atomic) NSString *initialReferrer; @property (strong, nonatomic) NSString *userUrl; @property (strong, nonatomic) NSString *userIdentity; @property (strong, nonatomic) NSString *sessionParams; diff --git a/Branch-SDK/BNCPreferenceHelper.m b/Branch-SDK/BNCPreferenceHelper.m index cbdc0fcb2..c43c4a1b7 100644 --- a/Branch-SDK/BNCPreferenceHelper.m +++ b/Branch-SDK/BNCPreferenceHelper.m @@ -33,6 +33,7 @@ static NSString * const BRANCH_PREFS_KEY_LINK_CLICK_IDENTIFIER = @"bnc_link_click_identifier"; static NSString * const BRANCH_PREFS_KEY_SPOTLIGHT_IDENTIFIER = @"bnc_spotlight_identifier"; static NSString * const BRANCH_PREFS_KEY_UNIVERSAL_LINK_URL = @"bnc_universal_link_url"; +static NSString * const BRANCH_PREFS_KEY_INITIAL_REFERRER = @"bnc_initial_referrer"; static NSString * const BRANCH_PREFS_KEY_SESSION_PARAMS = @"bnc_session_params"; static NSString * const BRANCH_PREFS_KEY_INSTALL_PARAMS = @"bnc_install_params"; static NSString * const BRANCH_PREFS_KEY_USER_URL = @"bnc_user_url"; @@ -75,6 +76,7 @@ @implementation BNCPreferenceHelper sessionParams = _sessionParams, installParams = _installParams, universalLinkUrl = _universalLinkUrl, + initialReferrer = _initialReferrer, externalIntentURI = _externalIntentURI, isDebug = _isDebug, retryCount = _retryCount, @@ -315,6 +317,13 @@ - (void)setUniversalLinkUrl:(NSString *)universalLinkUrl { [self writeObjectToDefaults:BRANCH_PREFS_KEY_UNIVERSAL_LINK_URL value:universalLinkUrl]; } +- (NSString *)initialReferrer { + return [self readStringFromDefaults:BRANCH_REQUEST_KEY_INITIAL_REFERRER]; +} + +- (void)setInitialReferrer:(NSString *)initialReferrer { + [self writeObjectToDefaults:BRANCH_REQUEST_KEY_INITIAL_REFERRER value:initialReferrer]; +} - (NSString *)sessionParams { @synchronized (self) { if (!_sessionParams) { @@ -659,6 +668,7 @@ - (void) clearTrackingInformation { self.spotlightIdentifier = nil; self.referringURL = nil; self.universalLinkUrl = nil; + self.initialReferrer = nil; self.installParams = nil; self.appleSearchAdDetails = nil; self.appleSearchAdNeedsSend = NO; diff --git a/Branch-SDK/Branch.m b/Branch-SDK/Branch.m index 4c8b77594..df2e62307 100644 --- a/Branch-SDK/Branch.m +++ b/Branch-SDK/Branch.m @@ -811,6 +811,12 @@ - (BOOL)continueUserActivity:(NSUserActivity *)userActivity { - (BOOL)continueUserActivity:(NSUserActivity *)userActivity sceneIdentifier:(NSString *)sceneIdentifier { BNCLogDebugSDK(@"continueUserActivity:"); + if (@available(iOS 11.0, *)) { + if (userActivity.referrerURL) { + self.preferenceHelper.initialReferrer = userActivity.referrerURL.absoluteString; + } + } + // Check to see if a browser activity needs to be handled if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { return [self handleDeepLink:userActivity.webpageURL sceneIdentifier:sceneIdentifier]; diff --git a/Branch-SDK/BranchConstants.h b/Branch-SDK/BranchConstants.h index 6fbcea3ef..4468af04b 100644 --- a/Branch-SDK/BranchConstants.h +++ b/Branch-SDK/BranchConstants.h @@ -60,6 +60,7 @@ extern NSString * const BRANCH_REQUEST_KEY_LINK_IDENTIFIER; extern NSString * const BRANCH_REQUEST_KEY_SPOTLIGHT_IDENTIFIER; extern NSString * const BRANCH_REQUEST_KEY_UNIVERSAL_LINK_URL; extern NSString * const BRANCH_REQUEST_KEY_LOCAL_URL; +extern NSString * const BRANCH_REQUEST_KEY_INITIAL_REFERRER; extern NSString * const BRANCH_REQUEST_KEY_BRAND; extern NSString * const BRANCH_REQUEST_KEY_MODEL; extern NSString * const BRANCH_REQUEST_KEY_SCREEN_WIDTH; diff --git a/Branch-SDK/BranchConstants.m b/Branch-SDK/BranchConstants.m index 079f74eb3..882283ac9 100644 --- a/Branch-SDK/BranchConstants.m +++ b/Branch-SDK/BranchConstants.m @@ -56,6 +56,7 @@ NSString * const BRANCH_REQUEST_KEY_SPOTLIGHT_IDENTIFIER = @"spotlight_identifier"; NSString * const BRANCH_REQUEST_KEY_UNIVERSAL_LINK_URL = @"universal_link_url"; NSString * const BRANCH_REQUEST_KEY_LOCAL_URL = @"local_url"; +NSString * const BRANCH_REQUEST_KEY_INITIAL_REFERRER = @"initial_referrer"; NSString * const BRANCH_REQUEST_KEY_BRAND = @"brand"; NSString * const BRANCH_REQUEST_KEY_MODEL = @"model"; NSString * const BRANCH_REQUEST_KEY_SCREEN_WIDTH = @"screen_width"; diff --git a/Branch-SDK/BranchInstallRequest.m b/Branch-SDK/BranchInstallRequest.m index 208d04259..eb6be7154 100644 --- a/Branch-SDK/BranchInstallRequest.m +++ b/Branch-SDK/BranchInstallRequest.m @@ -38,7 +38,7 @@ - (void)makeRequest:(BNCServerInterface *)serverInterface key:(NSString *)key ca [self safeSetValue:preferenceHelper.linkClickIdentifier forKey:BRANCH_REQUEST_KEY_LINK_IDENTIFIER onDict:params]; [self safeSetValue:preferenceHelper.spotlightIdentifier forKey:BRANCH_REQUEST_KEY_SPOTLIGHT_IDENTIFIER onDict:params]; [self safeSetValue:preferenceHelper.universalLinkUrl forKey:BRANCH_REQUEST_KEY_UNIVERSAL_LINK_URL onDict:params]; - + [self safeSetValue:preferenceHelper.initialReferrer forKey:BRANCH_REQUEST_KEY_INITIAL_REFERRER onDict:params]; [self safeSetValue:[[BNCAppleReceipt sharedInstance] installReceipt] forKey:BRANCH_REQUEST_KEY_APPLE_RECEIPT onDict:params]; [self safeSetValue:[NSNumber numberWithBool:[[BNCAppleReceipt sharedInstance] isTestFlight]] forKey:BRANCH_REQUEST_KEY_APPLE_TESTFLIGHT onDict:params]; diff --git a/Branch-SDK/BranchOpenRequest.m b/Branch-SDK/BranchOpenRequest.m index 12dc33811..d273ee58e 100644 --- a/Branch-SDK/BranchOpenRequest.m +++ b/Branch-SDK/BranchOpenRequest.m @@ -64,6 +64,7 @@ - (void)makeRequest:(BNCServerInterface *)serverInterface key:(NSString *)key ca [self safeSetValue:preferenceHelper.linkClickIdentifier forKey:BRANCH_REQUEST_KEY_LINK_IDENTIFIER onDict:params]; [self safeSetValue:preferenceHelper.spotlightIdentifier forKey:BRANCH_REQUEST_KEY_SPOTLIGHT_IDENTIFIER onDict:params]; [self safeSetValue:preferenceHelper.universalLinkUrl forKey:BRANCH_REQUEST_KEY_UNIVERSAL_LINK_URL onDict:params]; + [self safeSetValue:preferenceHelper.initialReferrer forKey:BRANCH_REQUEST_KEY_INITIAL_REFERRER onDict:params]; [self safeSetValue:preferenceHelper.externalIntentURI forKey:BRANCH_REQUEST_KEY_EXTERNAL_INTENT_URI onDict:params]; if (preferenceHelper.limitFacebookTracking) params[@"limit_facebook_tracking"] = (__bridge NSNumber*) kCFBooleanTrue; From 66ee26d6e25504cda0c9965188d14dfdc7641820 Mon Sep 17 00:00:00 2001 From: Ernest Cho Date: Wed, 7 Jul 2021 17:49:20 -0700 Subject: [PATCH 03/11] CORE-2088 backport the branch.json support --- Branch-SDK/Branch.m | 4 ++++ Branch-SDK/BranchJsonConfig.h | 2 ++ Branch-SDK/BranchJsonConfig.m | 7 +++++++ Branch-TestBed/Branch-TestBed/AppDelegate.m | 2 +- 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Branch-SDK/Branch.m b/Branch-SDK/Branch.m index df2e62307..d0c171d1b 100644 --- a/Branch-SDK/Branch.m +++ b/Branch-SDK/Branch.m @@ -226,6 +226,10 @@ - (id)initWithInterface:(BNCServerInterface *)interface BranchJsonConfig *config = BranchJsonConfig.instance; + if (config.checkPasteboardOnInstall) { + [self checkPasteboardOnInstall]; + } + if (config.delayInitToCheckForSearchAds) { [self delayInitToCheckForSearchAds]; } diff --git a/Branch-SDK/BranchJsonConfig.h b/Branch-SDK/BranchJsonConfig.h index f66ae42fe..1dd9cdc26 100644 --- a/Branch-SDK/BranchJsonConfig.h +++ b/Branch-SDK/BranchJsonConfig.h @@ -17,6 +17,7 @@ extern NSString * _Nonnull const BranchJsonConfigDelayInitToCheckForSearchAdsOpt extern NSString * _Nonnull const BranchJsonConfigAppleSearchAdsDebugModeOption; extern NSString * _Nonnull const BranchJsonConfigDeferInitializationForJSLoadOption; extern NSString * _Nonnull const BranchJsonConfigEnableFacebookLinkCheck; +extern NSString * _Nonnull const BranchJsonConfigCheckPasteboardOnInstall; @interface BranchJsonConfig : NSObject @@ -31,6 +32,7 @@ extern NSString * _Nonnull const BranchJsonConfigEnableFacebookLinkCheck; @property (nonatomic, readonly) BOOL appleSearchAdsDebugMode; @property (nonatomic, readonly) BOOL deferInitializationForJSLoad; @property (nonatomic, readonly) BOOL enableFacebookLinkCheck; +@property (nonatomic, readonly) BOOL checkPasteboardOnInstall; - (nullable id)objectForKey:(NSString * _Nonnull)key; - (nullable id)objectForKeyedSubscript:(NSString * _Nonnull)key; diff --git a/Branch-SDK/BranchJsonConfig.m b/Branch-SDK/BranchJsonConfig.m index 4319117ee..f5e6a674d 100644 --- a/Branch-SDK/BranchJsonConfig.m +++ b/Branch-SDK/BranchJsonConfig.m @@ -18,6 +18,7 @@ NSString * _Nonnull const BranchJsonConfigAppleSearchAdsDebugModeOption = @"appleSearchAdsDebugMode"; NSString * _Nonnull const BranchJsonConfigDeferInitializationForJSLoadOption = @"deferInitializationForJSLoad"; NSString * _Nonnull const BranchJsonConfigEnableFacebookLinkCheck = @"enableFacebookLinkCheck"; +NSString * _Nonnull const BranchJsonConfigCheckPasteboardOnInstall = @"checkPasteboardOnInstall"; @interface BranchJsonConfig() @property (nonatomic) NSDictionary *configuration; @@ -148,6 +149,12 @@ - (BOOL)enableFacebookLinkCheck return number.boolValue; } +- (BOOL)checkPasteboardOnInstall +{ + NSNumber *number = self[BranchJsonConfigCheckPasteboardOnInstall]; + return number.boolValue; +} + - (NSString *)branchKey { return self[BranchJsonConfigBranchKeyOption]; diff --git a/Branch-TestBed/Branch-TestBed/AppDelegate.m b/Branch-TestBed/Branch-TestBed/AppDelegate.m index 837f80baa..bd8fee539 100644 --- a/Branch-TestBed/Branch-TestBed/AppDelegate.m +++ b/Branch-TestBed/Branch-TestBed/AppDelegate.m @@ -51,7 +51,7 @@ - (BOOL)application:(UIApplication *)application // partner parameter sample //[branch addFacebookPartnerParameterWithName:@"em" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; - [branch checkPasteboardForBranchLinkOnInstall]; + [branch checkPasteboardOnInstall]; /* * Required: Initialize Branch, passing a deep link handler block: From 9a5a8d92b15e08f378ae3173702e72564275c27a Mon Sep 17 00:00:00 2001 From: Ernest Cho Date: Wed, 7 Jul 2021 17:53:06 -0700 Subject: [PATCH 04/11] CORE-2088 correct function name --- Branch-SDK/Branch.h | 8 ++++---- Branch-SDK/Branch.m | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Branch-SDK/Branch.h b/Branch-SDK/Branch.h index 9607fcd40..e58f668c6 100644 --- a/Branch-SDK/Branch.h +++ b/Branch-SDK/Branch.h @@ -677,12 +677,12 @@ typedef NS_ENUM(NSUInteger, BranchCreditHistoryOrder) { - (void)ignoreAppleSearchAdsTestData; /** - Checks the pasteboard for a Branch Link. - This copied Branch Link in the install request and can provide deeplink data. + Checks the pasteboard (clipboard) for a Branch Link on App Install. + If found, the Branch Link is used to provide deferred deeplink data. - Note, this will display a toast message to the end user. + Note, this may display a toast message to the end user. */ -- (void)checkPasteboardForBranchLinkOnInstall; +- (void)checkPasteboardOnInstall; /** Set the AppGroup used to share data between the App Clip and the Full App. diff --git a/Branch-SDK/Branch.m b/Branch-SDK/Branch.m index d0c171d1b..13de591d2 100644 --- a/Branch-SDK/Branch.m +++ b/Branch-SDK/Branch.m @@ -944,7 +944,7 @@ - (void)ignoreAppleSearchAdsTestData { #endif } -- (void)checkPasteboardForBranchLinkOnInstall { +- (void)checkPasteboardOnInstall { [BNCPasteboard sharedInstance].checkOnInstall = YES; } From 9d18bec2e29dde3556a978b3f25916fde0e53973 Mon Sep 17 00:00:00 2001 From: Ernest Cho Date: Thu, 8 Jul 2021 10:42:43 -0700 Subject: [PATCH 05/11] CORE-2088 tvOS does not support pasteboard --- Branch-SDK/BNCPasteboard.m | 8 ++++++-- .../BranchSDK.xcodeproj/project.pbxproj | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Branch-SDK/BNCPasteboard.m b/Branch-SDK/BNCPasteboard.m index 052d9238b..a095a67a0 100644 --- a/Branch-SDK/BNCPasteboard.m +++ b/Branch-SDK/BNCPasteboard.m @@ -6,8 +6,10 @@ // Copyright © 2021 Branch, Inc. All rights reserved. // -#import "BNCPasteboard.h" #import +#if !TARGET_OS_TV +#import "BNCPasteboard.h" +#endif @implementation BNCPasteboard @@ -29,7 +31,8 @@ - (instancetype)init { } - (nullable NSURL *)checkForBranchLink { - // consider limiting this check to iOS 15+ + +#if !TARGET_OS_TV if (@available(iOS 10.0, *)) { if ([UIPasteboard.generalPasteboard hasURLs]) { @@ -40,6 +43,7 @@ - (nullable NSURL *)checkForBranchLink { } } } +#endif return nil; } diff --git a/carthage-files/BranchSDK.xcodeproj/project.pbxproj b/carthage-files/BranchSDK.xcodeproj/project.pbxproj index 45cdf1dc7..ed41b7bfb 100644 --- a/carthage-files/BranchSDK.xcodeproj/project.pbxproj +++ b/carthage-files/BranchSDK.xcodeproj/project.pbxproj @@ -147,6 +147,12 @@ 5F3802DC24DCE90400E6FAFD /* BranchSpotlightUrlRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F38024424DCE72D00E6FAFD /* BranchSpotlightUrlRequest.m */; }; 5F3802DE24DCE90800E6FAFD /* BranchUserCompletedActionRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F38024E24DCE72E00E6FAFD /* BranchUserCompletedActionRequest.m */; }; 5F3802E024DCE90B00E6FAFD /* BranchUserCompletedActionRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F38025A24DCE73000E6FAFD /* BranchUserCompletedActionRequest.h */; }; + 5F41023526976F69003699AD /* BNCPasteboard.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F41023326976F69003699AD /* BNCPasteboard.m */; }; + 5F41023626976F69003699AD /* BNCPasteboard.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F41023326976F69003699AD /* BNCPasteboard.m */; }; + 5F41023726976F69003699AD /* BNCPasteboard.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F41023326976F69003699AD /* BNCPasteboard.m */; }; + 5F41023826976F69003699AD /* BNCPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F41023426976F69003699AD /* BNCPasteboard.h */; }; + 5F41023926976F69003699AD /* BNCPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F41023426976F69003699AD /* BNCPasteboard.h */; }; + 5F41023A26976F69003699AD /* BNCPasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F41023426976F69003699AD /* BNCPasteboard.h */; }; 5F7DB5FB237C95C30077A95F /* BNCAppleAdClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F7DB5F9237C95C30077A95F /* BNCAppleAdClient.h */; platformFilter = ios; }; 5F7DB5FC237C95C30077A95F /* BNCAppleAdClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F7DB5FA237C95C30077A95F /* BNCAppleAdClient.m */; platformFilter = ios; }; 5F85110425B11E1000D544A1 /* BNCURLFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F85110025B11E0F00D544A1 /* BNCURLFilter.m */; }; @@ -558,6 +564,8 @@ 5F38026324DCE73100E6FAFD /* BNCServerRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCServerRequest.h; sourceTree = ""; }; 5F38026424DCE73100E6FAFD /* BranchLogoutRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchLogoutRequest.m; sourceTree = ""; }; 5F38026524DCE73100E6FAFD /* BNCServerRequestQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCServerRequestQueue.h; sourceTree = ""; }; + 5F41023326976F69003699AD /* BNCPasteboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCPasteboard.m; sourceTree = ""; }; + 5F41023426976F69003699AD /* BNCPasteboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCPasteboard.h; sourceTree = ""; }; 5F7DB5F9237C95C30077A95F /* BNCAppleAdClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCAppleAdClient.h; sourceTree = ""; }; 5F7DB5FA237C95C30077A95F /* BNCAppleAdClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCAppleAdClient.m; sourceTree = ""; }; 5F85110025B11E0F00D544A1 /* BNCURLFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCURLFilter.m; sourceTree = ""; }; @@ -701,6 +709,8 @@ E230A1141D03DB9E006181D8 /* Branch-SDK */ = { isa = PBXGroup; children = ( + 5F41023426976F69003699AD /* BNCPasteboard.h */, + 5F41023326976F69003699AD /* BNCPasteboard.m */, 5F85110325B11E1000D544A1 /* BNCPartnerParameters.h */, 5F85110225B11E1000D544A1 /* BNCPartnerParameters.m */, 5F85110125B11E1000D544A1 /* BNCURLFilter.h */, @@ -911,6 +921,7 @@ 5FC4D062248614830001E701 /* BNCThreads.h in Headers */, 5FC4D09C248614850001E701 /* BranchContentPathProperties.h in Headers */, 5FC4D0A5248614860001E701 /* BNCCallbackMap.h in Headers */, + 5F41023926976F69003699AD /* BNCPasteboard.h in Headers */, 5F3802B624DCE80F00E6FAFD /* BranchLATDRequest.h in Headers */, 5FC4D07B248614840001E701 /* BNCEncodingUtils.h in Headers */, 5FC4D0192486145F0001E701 /* UIViewController+Branch.h in Headers */, @@ -989,6 +1000,7 @@ 5FD0FA5225CE46BD008200EE /* BNCLinkData.h in Headers */, 5FD0FA5325CE46BD008200EE /* BNCServerRequestQueue.h in Headers */, 5FD0FA5425CE46BD008200EE /* BNCPreferenceHelper.h in Headers */, + 5F41023A26976F69003699AD /* BNCPasteboard.h in Headers */, 5FD0FA5525CE46BD008200EE /* NSError+Branch.h in Headers */, 5FD0FA5625CE46BD008200EE /* BNCServerInterface.h in Headers */, 5FD0FA5725CE46BD008200EE /* BNCSpotlightService.h in Headers */, @@ -1076,6 +1088,7 @@ E230A1771D03DB9E006181D8 /* BNCLinkData.h in Headers */, 5F38028E24DCE73100E6FAFD /* BNCServerRequestQueue.h in Headers */, E230A1791D03DB9E006181D8 /* BNCPreferenceHelper.h in Headers */, + 5F41023826976F69003699AD /* BNCPasteboard.h in Headers */, 5FED519C236B9E12008ECAFD /* NSError+Branch.h in Headers */, 5F38026924DCE73100E6FAFD /* BNCServerInterface.h in Headers */, 4D1ED2811FB3A472007390A8 /* BNCSpotlightService.h in Headers */, @@ -1353,6 +1366,7 @@ 5FC4D0AC248614860001E701 /* BranchUniversalObject.m in Sources */, 5FC4D083248614840001E701 /* BNCLinkData.m in Sources */, 5FB38D6B2526789600E9A85A /* BranchJsonConfig.m in Sources */, + 5F41023626976F69003699AD /* BNCPasteboard.m in Sources */, 5F3802C024DCE82200E6FAFD /* BranchLogoutRequest.m in Sources */, 5FC4D07F248614840001E701 /* BNCKeyChain.m in Sources */, 5FC4D04D248614830001E701 /* BNCNetworkInterface.m in Sources */, @@ -1396,6 +1410,7 @@ 5FD0FA9D25CE46BD008200EE /* BranchCreditHistoryRequest.m in Sources */, 5FD0FA9E25CE46BD008200EE /* BNCDeviceSystem.m in Sources */, 5FD0FA9F25CE46BD008200EE /* BNCAvailability.m in Sources */, + 5F41023726976F69003699AD /* BNCPasteboard.m in Sources */, 5FD0FAA025CE46BD008200EE /* BNCLocale.m in Sources */, 5FD0FAA125CE46BD008200EE /* BranchRedeemRewardsRequest.m in Sources */, 5FD0FAA225CE46BD008200EE /* BNCAppleReceipt.m in Sources */, @@ -1479,6 +1494,7 @@ 5F38028924DCE73100E6FAFD /* BranchCreditHistoryRequest.m in Sources */, 5F92B24E2387703700CA909B /* BNCDeviceSystem.m in Sources */, 4D1ED27D1FB3A43A007390A8 /* BNCAvailability.m in Sources */, + 5F41023526976F69003699AD /* BNCPasteboard.m in Sources */, 5F92B24D2387703700CA909B /* BNCLocale.m in Sources */, 5F38028024DCE73100E6FAFD /* BranchRedeemRewardsRequest.m in Sources */, 5FB6D3D923219B48006C5094 /* BNCAppleReceipt.m in Sources */, From 31c27b890d22772f94a2c49b184d47ff4aa2f2c1 Mon Sep 17 00:00:00 2001 From: Ernest Cho Date: Thu, 8 Jul 2021 10:44:13 -0700 Subject: [PATCH 06/11] CORE-2088 add check for branch link, fix tvOS --- Branch-SDK/BNCPasteboard.m | 12 ++++-------- Branch-SDK/Branch.h | 9 +++++++++ Branch-SDK/Branch.m | 11 ++++++----- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Branch-SDK/BNCPasteboard.m b/Branch-SDK/BNCPasteboard.m index a095a67a0..eee85eb38 100644 --- a/Branch-SDK/BNCPasteboard.m +++ b/Branch-SDK/BNCPasteboard.m @@ -6,9 +6,10 @@ // Copyright © 2021 Branch, Inc. All rights reserved. // -#import -#if !TARGET_OS_TV #import "BNCPasteboard.h" +#import +#import "Branch.h" + #endif @implementation BNCPasteboard @@ -38,7 +39,7 @@ - (nullable NSURL *)checkForBranchLink { // triggers the end user toast message NSURL *tmp = UIPasteboard.generalPasteboard.URL; - if ([self isProbableBranchLink:tmp]) { + if ([Branch isBranchLink:tmp.absoluteString]) { return tmp; } } @@ -47,9 +48,4 @@ - (nullable NSURL *)checkForBranchLink { return nil; } -- (BOOL)isProbableBranchLink:(NSURL *)url { - // TODO: check against info.plist - return YES; -} - @end diff --git a/Branch-SDK/Branch.h b/Branch-SDK/Branch.h index e58f668c6..c4449e405 100644 --- a/Branch-SDK/Branch.h +++ b/Branch-SDK/Branch.h @@ -782,6 +782,15 @@ typedef NS_ENUM(NSUInteger, BranchCreditHistoryOrder) { */ - (void)registerPluginName:(NSString *)name version:(NSString *)version; +/** + Checks if a url string is a probable Branch link. + + Checks against the Info.plist and the standard Branch list. + + @param urlString URL as an NSString + */ ++ (BOOL)isBranchLink:(NSString *)urlString; + /** Key-value pairs to be included in the metadata on every request. diff --git a/Branch-SDK/Branch.m b/Branch-SDK/Branch.m index 13de591d2..5bb73b099 100644 --- a/Branch-SDK/Branch.m +++ b/Branch-SDK/Branch.m @@ -805,7 +805,7 @@ - (BOOL)handleUniversalDeepLink_private:(NSString*)urlString sceneIdentifier:(NS [self initUserSessionAndCallCallback:YES sceneIdentifier:sceneIdentifier]; - return [self isBranchLink:urlString]; + return [Branch isBranchLink:urlString]; } - (BOOL)continueUserActivity:(NSUserActivity *)userActivity { @@ -833,9 +833,9 @@ - (BOOL)continueUserActivity:(NSUserActivity *)userActivity sceneIdentifier:(NSS spotlightIdentifier = [self.contentDiscoveryManager spotlightIdentifierFromActivity:userActivity]; NSURL *webURL = userActivity.webpageURL; - if ([self isBranchLink:userActivity.userInfo[CSSearchableItemActivityIdentifier]]) { + if ([Branch isBranchLink:userActivity.userInfo[CSSearchableItemActivityIdentifier]]) { return [self handleDeepLink:[NSURL URLWithString:userActivity.userInfo[CSSearchableItemActivityIdentifier]] sceneIdentifier:sceneIdentifier]; - } else if (webURL != nil && [self isBranchLink:[webURL absoluteString]]) { + } else if (webURL != nil && [Branch isBranchLink:[webURL absoluteString]]) { return [self handleDeepLink:webURL sceneIdentifier:sceneIdentifier]; } else if (spotlightIdentifier) { self.preferenceHelper.spotlightIdentifier = spotlightIdentifier; @@ -852,10 +852,11 @@ - (BOOL)continueUserActivity:(NSUserActivity *)userActivity sceneIdentifier:(NSS return spotlightIdentifier != nil; } -- (BOOL)isBranchLink:(NSString *)urlString { +// checks if URL string looks like a branch link ++ (BOOL)isBranchLink:(NSString *)urlString { id branchUniversalLinkDomains = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"branch_universal_link_domains"]; - // check list in bundle + // check url list in bundle if ([branchUniversalLinkDomains isKindOfClass:[NSString class]] && [urlString containsString:branchUniversalLinkDomains]) { return YES; } else if ([branchUniversalLinkDomains isKindOfClass:[NSArray class]]) { From ccc8ecf0a152ca87e5807bdb8aaf2c3b975b601e Mon Sep 17 00:00:00 2001 From: Ernest Cho Date: Thu, 8 Jul 2021 10:46:00 -0700 Subject: [PATCH 07/11] CORE-2088 remove missed endif --- Branch-SDK/BNCPasteboard.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/Branch-SDK/BNCPasteboard.m b/Branch-SDK/BNCPasteboard.m index eee85eb38..c1393e3ce 100644 --- a/Branch-SDK/BNCPasteboard.m +++ b/Branch-SDK/BNCPasteboard.m @@ -10,8 +10,6 @@ #import #import "Branch.h" -#endif - @implementation BNCPasteboard + (BNCPasteboard *)sharedInstance { From 053d075ab10b16d5731a6e872a66e09036413dc8 Mon Sep 17 00:00:00 2001 From: echo-branch <43450805+echo-branch@users.noreply.github.com> Date: Mon, 12 Jul 2021 16:07:18 -0700 Subject: [PATCH 08/11] CORE-2088 add willShowPasteboardToast method --- Branch-SDK/BNCPasteboard.h | 6 +++++- Branch-SDK/BNCPasteboard.m | 22 ++++++++++++++-------- Branch-SDK/Branch.h | 10 ++++++++++ Branch-SDK/Branch.m | 9 +++++++++ 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/Branch-SDK/BNCPasteboard.h b/Branch-SDK/BNCPasteboard.h index f01e8cd9b..ce3835f1f 100644 --- a/Branch-SDK/BNCPasteboard.h +++ b/Branch-SDK/BNCPasteboard.h @@ -12,9 +12,13 @@ NS_ASSUME_NONNULL_BEGIN @interface BNCPasteboard : NSObject -// For v1, we only allow check on install requests +// For v1, we only allow check on install requests. By default, this is NO @property (nonatomic,assign) BOOL checkOnInstall; +@property (nonatomic, assign, nullable) NSURL *branchLink; + +- (BOOL)isUrlOnPasteboard; + - (nullable NSURL *)checkForBranchLink; + (BNCPasteboard *)sharedInstance; diff --git a/Branch-SDK/BNCPasteboard.m b/Branch-SDK/BNCPasteboard.m index c1393e3ce..c350deccd 100644 --- a/Branch-SDK/BNCPasteboard.m +++ b/Branch-SDK/BNCPasteboard.m @@ -29,20 +29,26 @@ - (instancetype)init { return self; } -- (nullable NSURL *)checkForBranchLink { - +- (BOOL)isUrlOnPasteboard { #if !TARGET_OS_TV if (@available(iOS 10.0, *)) { if ([UIPasteboard.generalPasteboard hasURLs]) { - - // triggers the end user toast message - NSURL *tmp = UIPasteboard.generalPasteboard.URL; - if ([Branch isBranchLink:tmp.absoluteString]) { - return tmp; - } + return YES; } } #endif + return NO; +} + +- (nullable NSURL *)checkForBranchLink { + if ([self isUrlOnPasteboard]) { + // triggers the end user toast message + NSURL *tmp = UIPasteboard.generalPasteboard.URL; + if ([Branch isBranchLink:tmp.absoluteString]) { + self.branchLink = tmp; + return tmp; + } + } return nil; } diff --git a/Branch-SDK/Branch.h b/Branch-SDK/Branch.h index c4449e405..87cb37b31 100644 --- a/Branch-SDK/Branch.h +++ b/Branch-SDK/Branch.h @@ -684,6 +684,16 @@ typedef NS_ENUM(NSUInteger, BranchCreditHistoryOrder) { */ - (void)checkPasteboardOnInstall; +/** + Let's client know if the Branch SDK will trigger a pasteboard toast to the end user. + All of the following conditions must be true. + + 1. Developer called checkPastboardOnInstall before initSession + 2. A URL is on the pasteboard + 3. First time app is run with Branch SDK + */ +- (BOOL)willShowPasteboardToast; + /** Set the AppGroup used to share data between the App Clip and the Full App. diff --git a/Branch-SDK/Branch.m b/Branch-SDK/Branch.m index 5bb73b099..e2541fd4e 100644 --- a/Branch-SDK/Branch.m +++ b/Branch-SDK/Branch.m @@ -949,6 +949,15 @@ - (void)checkPasteboardOnInstall { [BNCPasteboard sharedInstance].checkOnInstall = YES; } +- (BOOL)willShowPasteboardToast { + if (!self.preferenceHelper.identityID && + [BNCPasteboard sharedInstance].checkOnInstall && + [BNCPasteboard sharedInstance].isUrlOnPasteboard) { + return YES; + } + return NO; +} + - (void)checkAppleSearchAdsAttribution { #if !TARGET_OS_TV if (![BNCAppleSearchAds sharedInstance].enableAppleSearchAdsCheck) { From 2674dd5d3310aebae77ad364bdfe94cb0368fd94 Mon Sep 17 00:00:00 2001 From: echo-branch <43450805+echo-branch@users.noreply.github.com> Date: Thu, 22 Jul 2021 22:59:56 -0700 Subject: [PATCH 09/11] CORE-2088 add tests --- Branch-SDK/BNCPasteboard.h | 12 +- Branch-SDK/BNCPasteboard.m | 17 +- .../Branch-SDK-Tests/BNCPasteboardTests.m | 161 ++++++++++++++++++ .../Branch-TestBed.xcodeproj/project.pbxproj | 4 + 4 files changed, 186 insertions(+), 8 deletions(-) create mode 100644 Branch-TestBed/Branch-SDK-Tests/BNCPasteboardTests.m diff --git a/Branch-SDK/BNCPasteboard.h b/Branch-SDK/BNCPasteboard.h index ce3835f1f..19133e7ba 100644 --- a/Branch-SDK/BNCPasteboard.h +++ b/Branch-SDK/BNCPasteboard.h @@ -12,13 +12,15 @@ NS_ASSUME_NONNULL_BEGIN @interface BNCPasteboard : NSObject -// For v1, we only allow check on install requests. By default, this is NO -@property (nonatomic,assign) BOOL checkOnInstall; - -@property (nonatomic, assign, nullable) NSURL *branchLink; +/* + Indicates if the client wishes to check for Branch links on install. By default, this is NO. + + Set via Branch.checkPasteboardOnInstall + Checked by BranchInstallRequest.makeRequest before checking the pasteboard for a Branch link. + */ +@property (nonatomic, assign) BOOL checkOnInstall; - (BOOL)isUrlOnPasteboard; - - (nullable NSURL *)checkForBranchLink; + (BNCPasteboard *)sharedInstance; diff --git a/Branch-SDK/BNCPasteboard.m b/Branch-SDK/BNCPasteboard.m index c350deccd..2d550a788 100644 --- a/Branch-SDK/BNCPasteboard.m +++ b/Branch-SDK/BNCPasteboard.m @@ -29,25 +29,36 @@ - (instancetype)init { return self; } +- (void)clearPasteboard { + #if !TARGET_OS_TV + if (@available(iOS 10.0, *)) { + // cannot delete items from the pasteboard, but we can put something else on there + [[UIPasteboard generalPasteboard] setString:@""]; + } + #endif +} + - (BOOL)isUrlOnPasteboard { -#if !TARGET_OS_TV + #if !TARGET_OS_TV if (@available(iOS 10.0, *)) { if ([UIPasteboard.generalPasteboard hasURLs]) { return YES; } } -#endif + #endif return NO; } - (nullable NSURL *)checkForBranchLink { if ([self isUrlOnPasteboard]) { + #if !TARGET_OS_TV // triggers the end user toast message NSURL *tmp = UIPasteboard.generalPasteboard.URL; if ([Branch isBranchLink:tmp.absoluteString]) { - self.branchLink = tmp; + [self clearPasteboard]; return tmp; } + #endif } return nil; } diff --git a/Branch-TestBed/Branch-SDK-Tests/BNCPasteboardTests.m b/Branch-TestBed/Branch-SDK-Tests/BNCPasteboardTests.m new file mode 100644 index 000000000..7de1c9ea0 --- /dev/null +++ b/Branch-TestBed/Branch-SDK-Tests/BNCPasteboardTests.m @@ -0,0 +1,161 @@ +// +// BNCPasteboardTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 7/19/21. +// Copyright © 2021 Branch, Inc. All rights reserved. +// + +#import +#import "BNCPasteboard.h" + +@interface BNCPasteboardTests : XCTestCase + +@property (nonatomic, assign, readwrite) NSString *testString; +@property (nonatomic, strong, readwrite) NSURL *testBranchURL; + +@end + +@implementation BNCPasteboardTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. + self.testString = @"Pasteboard String"; + self.testBranchURL = [NSURL URLWithString:@"https://123.app.link"]; +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)addStringToPasteboard { +#if !TARGET_OS_TV + if (@available(iOS 10.0, *)) { + [UIPasteboard.generalPasteboard setString:self.testString]; + } +#endif +} + +- (void)addBranchURLToPasteboard { +#if !TARGET_OS_TV + if (@available(iOS 10.0, *)) { + [UIPasteboard.generalPasteboard setURL:self.testBranchURL]; + } +#endif +} + +- (void)addNonBranchURLToPasteboard { +#if !TARGET_OS_TV + if (@available(iOS 10.0, *)) { + [UIPasteboard.generalPasteboard setURL:[NSURL URLWithString:@"https://www.apple.com"]]; + } +#endif +} + +- (void)clearPasteboard { +#if !TARGET_OS_TV + if (@available(iOS 10.0, *)) { + // cannot delete items from the pasteboard, but we can put something else on there + [[UIPasteboard generalPasteboard] setString:@""]; + } +#endif +} + +- (NSString *)getStringFromClipboard { + NSString *string = nil; +#if !TARGET_OS_TV + if (@available(iOS 10.0, *)) { + string = [UIPasteboard.generalPasteboard string]; + } +#endif + return string; +} + +- (NSURL *)getURLFromPasteboard { + NSURL *url = nil; +#if !TARGET_OS_TV + if (@available(iOS 10.0, *)) { + url = [UIPasteboard.generalPasteboard URL]; + } +#endif + return url; +} + +- (void)testStringUtilityMethods { + + // set and retrieve a string + [self addStringToPasteboard]; + NSString *tmp = [self getStringFromClipboard]; + XCTAssert([self.testString isEqualToString:tmp]); + + // overwrite the pasteboard + [self clearPasteboard]; + tmp = [self getStringFromClipboard]; + XCTAssert([@"" isEqualToString:tmp]); +} + +- (void)testURLUtilityMethods { + + // set and retrieve a url + [self addBranchURLToPasteboard]; + NSURL *tmp = [self getURLFromPasteboard]; + XCTAssert([self.testBranchURL.absoluteString isEqualToString:tmp.absoluteString]); + + // overwrite the pasteboard + [self clearPasteboard]; + tmp = [self getURLFromPasteboard]; + XCTAssertNil(tmp); +} + +- (void)testDefaultState { + // host app sets this to true, should consider a no-op test host + XCTAssertTrue([BNCPasteboard sharedInstance].checkOnInstall); +} + +- (void)testIsUrlOnPasteboard { + XCTAssertFalse([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); + + [self addBranchURLToPasteboard]; + XCTAssertTrue([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); + + [self clearPasteboard]; + XCTAssertFalse([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); +} + +- (void)testCheckForBranchLink { + [self addBranchURLToPasteboard]; + XCTAssertTrue([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); + + NSURL *tmp = [[BNCPasteboard sharedInstance] checkForBranchLink]; + XCTAssert([self.testBranchURL.absoluteString isEqualToString:tmp.absoluteString]); + + // confirms Branch link is deleted after use + XCTAssertFalse([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); +} + +- (void)testCheckForBranchLink_nonBranchLink { + [self addNonBranchURLToPasteboard]; + XCTAssertTrue([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); + + NSURL *tmp = [[BNCPasteboard sharedInstance] checkForBranchLink]; + XCTAssertNil(tmp); + + // confirms non-Branch link is still on the pasteboard + XCTAssertTrue([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); + + // deletes non-Branch link from pasteboard + [self clearPasteboard]; + XCTAssertFalse([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); +} + +- (void)testCheckForBranchLink_noLink { + [self addStringToPasteboard]; + XCTAssertFalse([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); + + NSURL *tmp = [[BNCPasteboard sharedInstance] checkForBranchLink]; + XCTAssertNil(tmp); + + [self clearPasteboard]; +} + +@end diff --git a/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj b/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj index 3c348e458..74bd2a63e 100644 --- a/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj +++ b/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj @@ -123,6 +123,7 @@ 54FF1F921BD1DC320004CE2E /* BranchLinkProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = 54FF1F901BD1DC320004CE2E /* BranchLinkProperties.m */; }; 5F08461123480008005B17E6 /* BNCTuneUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F08460F23480008005B17E6 /* BNCTuneUtility.h */; }; 5F08461223480008005B17E6 /* BNCTuneUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F08461023480008005B17E6 /* BNCTuneUtility.m */; }; + 5F1166C626A60B91004825E3 /* BNCPasteboardTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F1166C526A60B91004825E3 /* BNCPasteboardTests.m */; }; 5F205D05231864E800C776D1 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F205D04231864E800C776D1 /* WebKit.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 5F205D062318659500C776D1 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F205D04231864E800C776D1 /* WebKit.framework */; }; 5F205D0823186AF700C776D1 /* BNCUserAgentCollectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F205D022318641700C776D1 /* BNCUserAgentCollectorTests.m */; }; @@ -440,6 +441,7 @@ 54FF1F901BD1DC320004CE2E /* BranchLinkProperties.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchLinkProperties.m; sourceTree = ""; }; 5F08460F23480008005B17E6 /* BNCTuneUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BNCTuneUtility.h; sourceTree = ""; }; 5F08461023480008005B17E6 /* BNCTuneUtility.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BNCTuneUtility.m; sourceTree = ""; }; + 5F1166C526A60B91004825E3 /* BNCPasteboardTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BNCPasteboardTests.m; sourceTree = ""; }; 5F2035CB240DDE90004FDC3E /* BNCDisableAdNetworkCalloutsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BNCDisableAdNetworkCalloutsTests.m; sourceTree = ""; }; 5F205D022318641700C776D1 /* BNCUserAgentCollectorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BNCUserAgentCollectorTests.m; sourceTree = ""; }; 5F205D04231864E800C776D1 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; @@ -763,6 +765,7 @@ 5F2035CB240DDE90004FDC3E /* BNCDisableAdNetworkCalloutsTests.m */, 5FDB04F324E6156800F2F267 /* BNCSKAdNetworkTests.m */, 5FDF91582581CDF4009BE5A3 /* BNCPartnerParametersTests.m */, + 5F1166C526A60B91004825E3 /* BNCPasteboardTests.m */, ); path = "Branch-SDK-Tests"; sourceTree = ""; @@ -1562,6 +1565,7 @@ 4D1683BD2098C902008819E3 /* BranchNetworkScenario.Test.m in Sources */, 4D7881FF209CF2D4002B750F /* BNCApplication+BNCTest.m in Sources */, 5F92B23423835FEB00CA909B /* BNCReachabilityTests.m in Sources */, + 5F1166C626A60B91004825E3 /* BNCPasteboardTests.m in Sources */, 5F3D671B233062FD00454FF1 /* BNCJsonLoader.m in Sources */, 4D1683C02098C902008819E3 /* BranchUniversalObject.Test.m in Sources */, 5F5EC4602374E96B00AAAFC7 /* BNCAppleAdClientTests.m in Sources */, From 64403da0b2a1859e61e12761d29d2a8867cd173c Mon Sep 17 00:00:00 2001 From: echo-branch <43450805+echo-branch@users.noreply.github.com> Date: Fri, 23 Jul 2021 16:54:20 -0700 Subject: [PATCH 10/11] CORE-1936 fix apple search ad tests --- .../Branch-SDK-Tests/BNCAppleAdClientTests.m | 33 +++-- .../Branch-SDK-Tests/BNCAppleSearchAdsTests.m | 127 ++++++++++++------ 2 files changed, 104 insertions(+), 56 deletions(-) diff --git a/Branch-TestBed/Branch-SDK-Tests/BNCAppleAdClientTests.m b/Branch-TestBed/Branch-SDK-Tests/BNCAppleAdClientTests.m index 7b30f5213..a9921300e 100644 --- a/Branch-TestBed/Branch-SDK-Tests/BNCAppleAdClientTests.m +++ b/Branch-TestBed/Branch-SDK-Tests/BNCAppleAdClientTests.m @@ -46,20 +46,29 @@ - (void)testRequestAttribution { BNCAppleAdClient *adClient = [BNCAppleAdClient new]; [adClient requestAttributionDetailsWithBlock:^(NSDictionary * _Nonnull attributionDetails, NSError * _Nonnull error) { - XCTAssertNil(error); - - id tmp = [attributionDetails objectForKey:@"Version3.1"]; - if ([tmp isKindOfClass:NSDictionary.class]) { - NSDictionary *tmpDict = (NSDictionary *)tmp; - XCTAssertNotNil(tmpDict); - - NSNumber *tmpBool = [tmpDict objectForKey:@"iad-attribution"]; - XCTAssertNotNil(tmpBool); + + if (@available(iOS 14.5, *)) { + // Need ATT permission to use get old Apple Search Ads info + XCTAssertNotNil(error); + XCTAssert([@"The app is not authorized for ad tracking" isEqualToString:error.localizedDescription]); + [expectation fulfill]; + } else { - XCTFail(@"Did not find Search Ads attribution"); + XCTAssertNil(error); + + id tmp = [attributionDetails objectForKey:@"Version3.1"]; + if ([tmp isKindOfClass:NSDictionary.class]) { + NSDictionary *tmpDict = (NSDictionary *)tmp; + XCTAssertNotNil(tmpDict); + + NSNumber *tmpBool = [tmpDict objectForKey:@"iad-attribution"]; + XCTAssertNotNil(tmpBool); + } else { + XCTFail(@"Did not find Search Ads attribution"); + } + + [expectation fulfill]; } - - [expectation fulfill]; }]; [self waitForExpectationsWithTimeout:5 handler:^(NSError * _Nullable error) { diff --git a/Branch-TestBed/Branch-SDK-Tests/BNCAppleSearchAdsTests.m b/Branch-TestBed/Branch-SDK-Tests/BNCAppleSearchAdsTests.m index ac63f0114..670db0c14 100644 --- a/Branch-TestBed/Branch-SDK-Tests/BNCAppleSearchAdsTests.m +++ b/Branch-TestBed/Branch-SDK-Tests/BNCAppleSearchAdsTests.m @@ -194,16 +194,24 @@ - (void)testRequestAppleSearchAds { __block XCTestExpectation *expectation = [self expectationWithDescription:@"AppleSearchAds"]; [self.appleSearchAds requestAttributionWithCompletion:^(NSDictionary * _Nullable attributionDetails, NSError * _Nullable error, NSTimeInterval elapsedSeconds) { - XCTAssertNil(error); - XCTAssertTrue(elapsedSeconds > 0); - - NSDictionary *tmpDict = [attributionDetails objectForKey:@"Version3.1"]; - XCTAssertNotNil(tmpDict); - - NSNumber *tmpBool = [tmpDict objectForKey:@"iad-attribution"]; - XCTAssertNotNil(tmpBool); - - [expectation fulfill]; + if (@available(iOS 14.5, *)) { + // Need ATT permission to use get old Apple Search Ads info + XCTAssertNotNil(error); + XCTAssertTrue(elapsedSeconds > 0); + [expectation fulfill]; + + } else { + XCTAssertNil(error); + XCTAssertTrue(elapsedSeconds > 0); + + NSDictionary *tmpDict = [attributionDetails objectForKey:@"Version3.1"]; + XCTAssertNotNil(tmpDict); + + NSNumber *tmpBool = [tmpDict objectForKey:@"iad-attribution"]; + XCTAssertNotNil(tmpBool); + + [expectation fulfill]; + } }]; [self waitForExpectationsWithTimeout:5 handler:^(NSError * _Nullable error) { @@ -216,16 +224,25 @@ - (void)testRequestAppleSearchAdsWithRetry_0 { __block XCTestExpectation *expectation = [self expectationWithDescription:@"AppleSearchAds"]; [self.appleSearchAds requestAttributionWithMaxAttempts:0 completion:^(NSDictionary * _Nullable attributionDetails, NSError * _Nullable error, NSTimeInterval elapsedSeconds) { - XCTAssertNil(error); - XCTAssertTrue(elapsedSeconds > 0); - - NSDictionary *tmpDict = [attributionDetails objectForKey:@"Version3.1"]; - XCTAssertNotNil(tmpDict); - - NSNumber *tmpBool = [tmpDict objectForKey:@"iad-attribution"]; - XCTAssertNotNil(tmpBool); - - [expectation fulfill]; + if (@available(iOS 14.5, *)) { + // Need ATT permission to use get old Apple Search Ads info + XCTAssertNotNil(error); + XCTAssert([@"The app is not authorized for ad tracking" isEqualToString:error.localizedDescription]); + XCTAssertTrue(elapsedSeconds > 0); + [expectation fulfill]; + + } else { + XCTAssertNil(error); + XCTAssertTrue(elapsedSeconds > 0); + + NSDictionary *tmpDict = [attributionDetails objectForKey:@"Version3.1"]; + XCTAssertNotNil(tmpDict); + + NSNumber *tmpBool = [tmpDict objectForKey:@"iad-attribution"]; + XCTAssertNotNil(tmpBool); + + [expectation fulfill]; + } }]; [self waitForExpectationsWithTimeout:5 handler:^(NSError * _Nullable error) { @@ -238,16 +255,25 @@ - (void)testRequestAppleSearchAdsWithRetry_1 { __block XCTestExpectation *expectation = [self expectationWithDescription:@"AppleSearchAds"]; [self.appleSearchAds requestAttributionWithMaxAttempts:1 completion:^(NSDictionary * _Nullable attributionDetails, NSError * _Nullable error, NSTimeInterval elapsedSeconds) { - XCTAssertNil(error); - XCTAssertTrue(elapsedSeconds > 0); - - NSDictionary *tmpDict = [attributionDetails objectForKey:@"Version3.1"]; - XCTAssertNotNil(tmpDict); - - NSNumber *tmpBool = [tmpDict objectForKey:@"iad-attribution"]; - XCTAssertNotNil(tmpBool); - - [expectation fulfill]; + if (@available(iOS 14.5, *)) { + // Need ATT permission to use get old Apple Search Ads info + XCTAssertNotNil(error); + XCTAssert([@"The app is not authorized for ad tracking" isEqualToString:error.localizedDescription]); + XCTAssertTrue(elapsedSeconds > 0); + [expectation fulfill]; + + } else { + XCTAssertNil(error); + XCTAssertTrue(elapsedSeconds > 0); + + NSDictionary *tmpDict = [attributionDetails objectForKey:@"Version3.1"]; + XCTAssertNotNil(tmpDict); + + NSNumber *tmpBool = [tmpDict objectForKey:@"iad-attribution"]; + XCTAssertNotNil(tmpBool); + + [expectation fulfill]; + } }]; [self waitForExpectationsWithTimeout:5 handler:^(NSError * _Nullable error) { @@ -265,7 +291,7 @@ - (void)testRequestAppleSearchAdsWithRetry_NoResponse { XCTAssertNotNil(error); XCTAssertTrue(elapsedSeconds > 0); XCTAssertNil(attributionDetails); - + [expectation fulfill]; }]; @@ -283,19 +309,32 @@ - (void)testRequestAppleSearchAdsWithRetry_3 { self.appleSearchAds.adClient = mock; [self.appleSearchAds requestAttributionWithMaxAttempts:3 completion:^(NSDictionary * _Nullable attributionDetails, NSError * _Nullable error, NSTimeInterval elapsedSeconds) { - XCTAssertNil(error); - XCTAssertTrue(elapsedSeconds > 0); - - NSDictionary *tmpDict = [attributionDetails objectForKey:@"Version3.1"]; - XCTAssertNotNil(tmpDict); - - NSNumber *tmpBool = [tmpDict objectForKey:@"iad-attribution"]; - XCTAssertNotNil(tmpBool); - - // verifies things were ignored - XCTAssert(mock.ignoreCount == 2); - - [expectation fulfill]; + if (@available(iOS 14.5, *)) { + // Need ATT permission to use get old Apple Search Ads info + XCTAssertNotNil(error); + XCTAssert([@"The app is not authorized for ad tracking" isEqualToString:error.localizedDescription]); + XCTAssertTrue(elapsedSeconds > 0); + + // verifies things were ignored + XCTAssert(mock.ignoreCount == 2); + + [expectation fulfill]; + + } else { + XCTAssertNil(error); + XCTAssertTrue(elapsedSeconds > 0); + + NSDictionary *tmpDict = [attributionDetails objectForKey:@"Version3.1"]; + XCTAssertNotNil(tmpDict); + + NSNumber *tmpBool = [tmpDict objectForKey:@"iad-attribution"]; + XCTAssertNotNil(tmpBool); + + // verifies things were ignored + XCTAssert(mock.ignoreCount == 2); + + [expectation fulfill]; + } }]; [self waitForExpectationsWithTimeout:5 handler:^(NSError * _Nullable error) { From 8a9a65b53f2e9e92ef17e34406b4b9b524c103e0 Mon Sep 17 00:00:00 2001 From: echo-branch <43450805+echo-branch@users.noreply.github.com> Date: Mon, 26 Jul 2021 17:44:51 -0700 Subject: [PATCH 11/11] CORE-2088 remove overwrite, it's confusing. Also prep maintenance release. --- Branch-SDK/BNCConfig.m | 2 +- Branch-SDK/BNCPasteboard.m | 10 ---------- Branch-TestBed/Branch-SDK-Tests/BNCPasteboardTests.m | 8 +------- Branch-TestBed/Framework-Info.plist | 4 ++-- Branch.podspec | 2 +- ChangeLog.md | 4 ++++ carthage-files/BranchSDK.xcodeproj/project.pbxproj | 12 ++++++------ carthage-files/checksum | 2 +- carthage-files/checksum_static | 2 +- scripts/version.sh | 2 +- 10 files changed, 18 insertions(+), 30 deletions(-) diff --git a/Branch-SDK/BNCConfig.m b/Branch-SDK/BNCConfig.m index 53f38a88e..91250cbe9 100644 --- a/Branch-SDK/BNCConfig.m +++ b/Branch-SDK/BNCConfig.m @@ -11,4 +11,4 @@ NSString * const BNC_API_BASE_URL = @"https://api2.branch.io"; NSString * const BNC_API_VERSION = @"v1"; NSString * const BNC_LINK_URL = @"https://bnc.lt"; -NSString * const BNC_SDK_VERSION = @"1.39.3"; +NSString * const BNC_SDK_VERSION = @"1.39.4"; diff --git a/Branch-SDK/BNCPasteboard.m b/Branch-SDK/BNCPasteboard.m index 2d550a788..b851d0024 100644 --- a/Branch-SDK/BNCPasteboard.m +++ b/Branch-SDK/BNCPasteboard.m @@ -29,15 +29,6 @@ - (instancetype)init { return self; } -- (void)clearPasteboard { - #if !TARGET_OS_TV - if (@available(iOS 10.0, *)) { - // cannot delete items from the pasteboard, but we can put something else on there - [[UIPasteboard generalPasteboard] setString:@""]; - } - #endif -} - - (BOOL)isUrlOnPasteboard { #if !TARGET_OS_TV if (@available(iOS 10.0, *)) { @@ -55,7 +46,6 @@ - (nullable NSURL *)checkForBranchLink { // triggers the end user toast message NSURL *tmp = UIPasteboard.generalPasteboard.URL; if ([Branch isBranchLink:tmp.absoluteString]) { - [self clearPasteboard]; return tmp; } #endif diff --git a/Branch-TestBed/Branch-SDK-Tests/BNCPasteboardTests.m b/Branch-TestBed/Branch-SDK-Tests/BNCPasteboardTests.m index 7de1c9ea0..22631f761 100644 --- a/Branch-TestBed/Branch-SDK-Tests/BNCPasteboardTests.m +++ b/Branch-TestBed/Branch-SDK-Tests/BNCPasteboardTests.m @@ -129,8 +129,7 @@ - (void)testCheckForBranchLink { NSURL *tmp = [[BNCPasteboard sharedInstance] checkForBranchLink]; XCTAssert([self.testBranchURL.absoluteString isEqualToString:tmp.absoluteString]); - // confirms Branch link is deleted after use - XCTAssertFalse([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); + [self clearPasteboard]; } - (void)testCheckForBranchLink_nonBranchLink { @@ -140,12 +139,7 @@ - (void)testCheckForBranchLink_nonBranchLink { NSURL *tmp = [[BNCPasteboard sharedInstance] checkForBranchLink]; XCTAssertNil(tmp); - // confirms non-Branch link is still on the pasteboard - XCTAssertTrue([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); - - // deletes non-Branch link from pasteboard [self clearPasteboard]; - XCTAssertFalse([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); } - (void)testCheckForBranchLink_noLink { diff --git a/Branch-TestBed/Framework-Info.plist b/Branch-TestBed/Framework-Info.plist index 09e0cee85..da0545248 100644 --- a/Branch-TestBed/Framework-Info.plist +++ b/Branch-TestBed/Framework-Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.39.3 + 1.39.4 CFBundleSignature ???? CFBundleVersion - 1.39.3 + 1.39.4 LSRequiresIPhoneOS NSHumanReadableCopyright diff --git a/Branch.podspec b/Branch.podspec index a886074ac..8e3ccb337 100644 --- a/Branch.podspec +++ b/Branch.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Branch" - s.version = "1.39.3" + s.version = "1.39.4" 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/ChangeLog.md b/ChangeLog.md index a574b9d03..aff720594 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,9 @@ Branch iOS SDK Change Log +v1.39.4 +CORE-2088 Add support for deferred deeplinks via pasteboard. This is not enabled by default. +CORE-1950 Record install referrer + v1.39.3 CORE-1893 Add timeout to Apple attribution token. Some users are reporting the call can hang. diff --git a/carthage-files/BranchSDK.xcodeproj/project.pbxproj b/carthage-files/BranchSDK.xcodeproj/project.pbxproj index ed41b7bfb..c53552c70 100644 --- a/carthage-files/BranchSDK.xcodeproj/project.pbxproj +++ b/carthage-files/BranchSDK.xcodeproj/project.pbxproj @@ -1605,7 +1605,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 1.39.3; + MARKETING_VERSION = 1.39.4; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -1645,7 +1645,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 1.39.3; + MARKETING_VERSION = 1.39.4; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = io.branch.Branch; @@ -1681,7 +1681,7 @@ ); MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.39.3; + MARKETING_VERSION = 1.39.4; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = io.branch.Branch; @@ -1714,7 +1714,7 @@ ); MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.39.3; + MARKETING_VERSION = 1.39.4; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = io.branch.Branch; @@ -1873,7 +1873,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.39.3; + MARKETING_VERSION = 1.39.4; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = io.branch.Branch; @@ -1904,7 +1904,7 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.39.3; + MARKETING_VERSION = 1.39.4; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = io.branch.Branch; diff --git a/carthage-files/checksum b/carthage-files/checksum index 2d44c1423..825de33b1 100644 --- a/carthage-files/checksum +++ b/carthage-files/checksum @@ -1,2 +1,2 @@ #checksum for Branch.zip on Github -b325b48cdcc2a6b7e9c0fdda22d911d1423812dd Branch.zip +8ad25b9ffb7e93c34fb75f0009b19de940828387 Branch.zip diff --git a/carthage-files/checksum_static b/carthage-files/checksum_static index 29b9c323e..54be9f58c 100644 --- a/carthage-files/checksum_static +++ b/carthage-files/checksum_static @@ -1,2 +1,2 @@ #checksum for Branch_static.zip on Github -fc80baaaa34dab5dcc2eb7c55df8f2f433d71de8 Branch_static.zip +2de15f43cd7cc6a01c377d80a8d93637bcba5a6b Branch_static.zip diff --git a/scripts/version.sh b/scripts/version.sh index 2d00c10c9..62e69fae7 100755 --- a/scripts/version.sh +++ b/scripts/version.sh @@ -31,7 +31,7 @@ Options: USAGE } -version=1.39.3 +version=1.39.4 if (( $# == 0 )); then echo $version