Skip to content

Commit a189a66

Browse files
committed
Release 1.42.0
1 parent 91be337 commit a189a66

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1064
-202
lines changed

Branch-SDK/BNCConfig.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111
NSString * const BNC_API_BASE_URL = @"https://api2.branch.io";
1212
NSString * const BNC_API_VERSION = @"v1";
1313
NSString * const BNC_LINK_URL = @"https://bnc.lt";
14-
NSString * const BNC_SDK_VERSION = @"1.41.0";
14+
NSString * const BNC_SDK_VERSION = @"1.42.0";

Branch-SDK/BNCPreferenceHelper.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ NSURL* /* _Nonnull */ BNCURLForBranchDirectory(void);
6666
@property (assign, nonatomic) BOOL sendCloseRequests;
6767

6868
@property (assign, nonatomic) BOOL trackingDisabled;
69+
70+
@property (copy, nonatomic) NSString *referrerGBRAID;
71+
@property (assign, nonatomic) NSTimeInterval referrerGBRAIDValidityWindow;
72+
@property (strong, nonatomic) NSDate *referrerGBRAIDInitDate;
73+
6974
- (void) clearTrackingInformation;
7075

7176
+ (BNCPreferenceHelper *)sharedInstance;

Branch-SDK/BNCPreferenceHelper.m

Lines changed: 126 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
static const NSTimeInterval DEFAULT_TIMEOUT = 5.5;
1818
static const NSTimeInterval DEFAULT_RETRY_INTERVAL = 0;
1919
static const NSInteger DEFAULT_RETRY_COUNT = 3;
20+
static const NSTimeInterval DEFAULT_REFERRER_GBRAID_WINDOW = 2592000; // 30 days = 2,592,000 seconds
2021

2122
static NSString * const BRANCH_PREFS_FILE = @"BNCPreferences";
2223

@@ -43,6 +44,9 @@
4344
static NSString * const BRANCH_PREFS_KEY_BRANCH_VIEW_USAGE_CNT = @"bnc_branch_view_usage_cnt_";
4445
static NSString * const BRANCH_PREFS_KEY_ANALYTICAL_DATA = @"bnc_branch_analytical_data";
4546
static NSString * const BRANCH_PREFS_KEY_ANALYTICS_MANIFEST = @"bnc_branch_analytics_manifest";
47+
static NSString * const BRANCH_PREFS_KEY_REFERRER_GBRAID = @"bnc_referrer_gbraid";
48+
static NSString * const BRANCH_PREFS_KEY_REFERRER_GBRAID_WINDOW = @"bnc_referrer_gbraid_window";
49+
static NSString * const BRANCH_PREFS_KEY_REFERRER_GBRAID_INIT_DATE = @"bnc_referrer_gbraid_init_date";
4650

4751
NSURL* /* _Nonnull */ BNCURLForBranchDirectory_Unthreaded(void);
4852

@@ -86,7 +90,9 @@ @implementation BNCPreferenceHelper
8690
checkedAppleSearchAdAttribution = _checkedAppleSearchAdAttribution,
8791
appleSearchAdDetails = _appleSearchAdDetails,
8892
requestMetadataDictionary = _requestMetadataDictionary,
89-
instrumentationDictionary = _instrumentationDictionary;
93+
instrumentationDictionary = _instrumentationDictionary,
94+
referrerGBRAID = _referrerGBRAID,
95+
referrerGBRAIDValidityWindow = _referrerGBRAIDValidityWindow;
9096

9197
+ (BNCPreferenceHelper *)sharedInstance {
9298
static BNCPreferenceHelper *preferenceHelper;
@@ -650,6 +656,53 @@ - (void)setSendCloseRequests:(BOOL)disabled {
650656
}
651657
}
652658

659+
- (NSString *) referrerGBRAID {
660+
@synchronized(self) {
661+
if (!_referrerGBRAID) {
662+
_referrerGBRAID = [self readStringFromDefaults:BRANCH_PREFS_KEY_REFERRER_GBRAID];
663+
}
664+
return _referrerGBRAID;
665+
}
666+
}
667+
668+
- (void) setReferrerGBRAID:(NSString *)referrerGBRAID {
669+
if (![_referrerGBRAID isEqualToString:referrerGBRAID]) {
670+
_referrerGBRAID = referrerGBRAID;
671+
[self writeObjectToDefaults:BRANCH_PREFS_KEY_REFERRER_GBRAID value:referrerGBRAID];
672+
self.referrerGBRAIDInitDate = [NSDate date];
673+
}
674+
}
675+
676+
- (NSTimeInterval) referrerGBRAIDValidityWindow {
677+
@synchronized (self) {
678+
_referrerGBRAIDValidityWindow = [self readDoubleFromDefaults:BRANCH_PREFS_KEY_REFERRER_GBRAID_WINDOW];
679+
if (_referrerGBRAIDValidityWindow == NSNotFound) {
680+
_referrerGBRAIDValidityWindow = DEFAULT_REFERRER_GBRAID_WINDOW;
681+
}
682+
return _referrerGBRAIDValidityWindow;
683+
}
684+
}
685+
686+
- (void) setReferrerGBRAIDValidityWindow:(NSTimeInterval)validityWindow {
687+
@synchronized (self) {
688+
[self writeObjectToDefaults:BRANCH_PREFS_KEY_REFERRER_GBRAID_WINDOW value:@(validityWindow)];
689+
}
690+
}
691+
692+
- (NSDate*) referrerGBRAIDInitDate {
693+
@synchronized (self) {
694+
NSDate* initdate = (NSDate*)[self readObjectFromDefaults:BRANCH_PREFS_KEY_REFERRER_GBRAID_INIT_DATE];
695+
if ([initdate isKindOfClass:[NSDate class]]) return initdate;
696+
return nil;
697+
}
698+
}
699+
700+
- (void)setReferrerGBRAIDInitDate:(NSDate *)initDate {
701+
@synchronized (self) {
702+
[self writeObjectToDefaults:BRANCH_PREFS_KEY_REFERRER_GBRAID_INIT_DATE value:initDate];
703+
}
704+
}
705+
653706
- (void) clearTrackingInformation {
654707
@synchronized(self) {
655708
/*
@@ -742,24 +795,10 @@ - (void)writeObjectToDefaults:(NSString *)key value:(NSObject *)value {
742795
- (void)persistPrefsToDisk {
743796
@synchronized (self) {
744797
if (!self.persistenceDict) return;
745-
NSData *data = nil;
746-
@try {
747-
if (@available(iOS 11.0, tvOS 11.0, *)) {
748-
data = [NSKeyedArchiver archivedDataWithRootObject:self.persistenceDict requiringSecureCoding:YES error:NULL];
749-
} else {
750-
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 12000
751-
data = [NSKeyedArchiver archivedDataWithRootObject:self.persistenceDict];
752-
#endif
753-
}
754-
}
755-
@catch (id exception) {
756-
data = nil;
757-
BNCLogWarning([NSString stringWithFormat:@"Exception creating preferences data: %@.", exception]);
758-
}
759-
if (!data) {
760-
BNCLogWarning(@"Can't create preferences data.");
761-
return;
762-
}
798+
799+
NSData *data = [self serializePrefDict:self.persistenceDict];
800+
if (!data) return;
801+
763802
NSURL *prefsURL = [self.class.URLForPrefsFile copy];
764803
NSBlockOperation *newPersistOp = [NSBlockOperation blockOperationWithBlock:^ {
765804
NSError *error = nil;
@@ -772,6 +811,24 @@ - (void)persistPrefsToDisk {
772811
}
773812
}
774813

814+
- (NSData *)serializePrefDict:(NSMutableDictionary *)dict {
815+
if (dict == nil) return nil;
816+
817+
NSData *data = nil;
818+
@try {
819+
if (@available(iOS 11.0, tvOS 11.0, *)) {
820+
data = [NSKeyedArchiver archivedDataWithRootObject:dict requiringSecureCoding:YES error:NULL];
821+
} else {
822+
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 12000
823+
data = [NSKeyedArchiver archivedDataWithRootObject:dict];
824+
#endif
825+
}
826+
} @catch (id exception) {
827+
BNCLogWarning([NSString stringWithFormat:@"Exception serializing preferences dict: %@.", exception]);
828+
}
829+
return data;
830+
}
831+
775832
+ (void) clearAll {
776833
NSURL *prefsURL = [self.URLForPrefsFile copy];
777834
if (prefsURL) [[NSFileManager defaultManager] removeItemAtURL:prefsURL error:nil];
@@ -782,31 +839,50 @@ + (void) clearAll {
782839
- (NSMutableDictionary *)persistenceDict {
783840
@synchronized(self) {
784841
if (!_persistenceDict) {
785-
NSDictionary *persistenceDict = nil;
786-
@try {
787-
NSError *error = nil;
788-
NSData *data = [NSData dataWithContentsOfURL:self.class.URLForPrefsFile options:0 error:&error];
789-
if (!error && data) {
790-
// if (@available(iOS 11.0, tvOS 11.0, *)) {
791-
// persistenceDict = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSMutableDictionary class] fromData:data error:NULL];
792-
// } else {
793-
//#if __IPHONE_OS_VERSION_MIN_REQUIRED < 12000
794-
persistenceDict = [NSKeyedUnarchiver unarchiveObjectWithData:data];
795-
//#endif
796-
// }
797-
}
798-
}
799-
@catch (NSException*) {
842+
_persistenceDict = [self deserializePrefDictFromData:[self loadPrefData]];
843+
}
844+
return _persistenceDict;
845+
}
846+
}
847+
848+
- (NSData *)loadPrefData {
849+
NSData *data = nil;
850+
@try {
851+
NSError *error = nil;
852+
data = [NSData dataWithContentsOfURL:self.class.URLForPrefsFile options:0 error:&error];
853+
if (error || !data) {
854+
BNCLogWarning(@"Failed to load preferences from storage.");
855+
}
856+
} @catch (NSException *) {
857+
BNCLogWarning(@"Failed to load preferences from storage.");
858+
}
859+
return data;
860+
}
861+
862+
- (NSMutableDictionary *)deserializePrefDictFromData:(NSData *)data {
863+
NSDictionary *dict = nil;
864+
if (data) {
865+
if (@available(iOS 11.0, tvOS 11.0, *)) {
866+
NSError *error = nil;
867+
NSSet *classes = [[NSMutableSet alloc] initWithArray:@[ NSNumber.class, NSString.class, NSDate.class, NSArray.class, NSDictionary.class ]];
868+
869+
dict = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:data error:&error];
870+
if (error) {
800871
BNCLogWarning(@"Failed to load preferences from storage.");
801872
}
802873

803-
if ([persistenceDict isKindOfClass:[NSDictionary class]]) {
804-
_persistenceDict = [persistenceDict mutableCopy];
805-
} else {
806-
_persistenceDict = [[NSMutableDictionary alloc] init];
807-
}
874+
} else {
875+
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 12000
876+
dict = [NSKeyedUnarchiver unarchiveObjectWithData:data];
877+
#endif
808878
}
809-
return _persistenceDict;
879+
}
880+
881+
// NSKeyedUnarchiver returns an NSDictionary, convert to NSMutableDictionary
882+
if (dict && [dict isKindOfClass:[NSDictionary class]]) {
883+
return [dict mutableCopy];
884+
} else {
885+
return [[NSMutableDictionary alloc] init];
810886
}
811887
}
812888

@@ -858,6 +934,16 @@ - (NSInteger)readIntegerFromDefaults:(NSString *)key {
858934
}
859935
}
860936

937+
- (double)readDoubleFromDefaults:(NSString *)key {
938+
@synchronized(self) {
939+
NSNumber *number = self.persistenceDict[key];
940+
if (number != nil && [number respondsToSelector:@selector(doubleValue)]){
941+
return [number doubleValue];
942+
}
943+
return NSNotFound;
944+
}
945+
}
946+
861947
#pragma mark - Preferences File URL
862948

863949
+ (NSURL* _Nonnull) URLForPrefsFile {

Branch-SDK/BNCServerInterface.m

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#import "Branch.h"
1818
#import "NSString+Branch.h"
1919
#import "BNCApplication.h"
20+
#import "BNCSKAdNetwork.h"
2021

2122
@interface BNCServerInterface ()
2223
@property (copy, nonatomic) NSString *requestEndpoint;
@@ -132,13 +133,13 @@ - (void)postRequest:(NSDictionary *)post
132133
retryNumber:(NSInteger)retryNumber
133134
key:(NSString *)key
134135
callback:(BNCServerCallback)callback {
135-
136-
NSMutableDictionary *extendedParams = [self buildExtendedParametersForURL:url withPostDictionary:post];
137-
NSURLRequest *request = [self preparePostRequest:extendedParams url:url key:key retryNumber:retryNumber];
138136

139137
// Instrumentation metrics
140138
self.requestEndpoint = [self.preferenceHelper getEndpointFromURL:url];
141-
139+
140+
NSMutableDictionary *extendedParams = [self buildExtendedParametersForURL:url withPostDictionary:post];
141+
NSURLRequest *request = [self preparePostRequest:extendedParams url:url key:key retryNumber:retryNumber];
142+
142143
[self genericHTTPRequest:request
143144
retryNumber:retryNumber
144145
callback:callback
@@ -440,6 +441,11 @@ - (NSMutableDictionary *)prepareParamDict:(NSDictionary *)params
440441
NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init];
441442
[metadata bnc_safeAddEntriesFromDictionary:self.preferenceHelper.requestMetadataDictionary];
442443
[metadata bnc_safeAddEntriesFromDictionary:fullParamDict[BRANCH_REQUEST_KEY_STATE]];
444+
445+
if(([self.requestEndpoint containsString:@"/v1/open"]) || ([self.requestEndpoint containsString:@"/v1/install"]) || ([self.requestEndpoint containsString:@"/v2/event"])){
446+
[metadata bnc_safeSetObject:[NSString stringWithFormat:@"%f", [BNCSKAdNetwork sharedInstance].maxTimeSinceInstall] forKey:BRANCH_REQUEST_METADATA_KEY_SCANTIME_WINDOW];
447+
}
448+
443449
if (metadata.count) {
444450
fullParamDict[BRANCH_REQUEST_KEY_STATE] = metadata;
445451
}
@@ -450,6 +456,22 @@ - (NSMutableDictionary *)prepareParamDict:(NSDictionary *)params
450456
fullParamDict[BRANCH_REQUEST_KEY_INSTRUMENTATION] = instrumentationDictionary;
451457
}
452458
}
459+
// For DOWNSTREAM EVENTS v1/open & v2/events, include referrer_gbraid in request if available
460+
if(([self.requestEndpoint containsString:@"/v1/open"]) || ([self.requestEndpoint containsString:@"/v2/event"])){
461+
NSString *ref_gbraid = self.preferenceHelper.referrerGBRAID;
462+
if ((ref_gbraid != nil) && (ref_gbraid.length > 0)) {
463+
// Check if its valid or expired
464+
NSTimeInterval validityWindow = self.preferenceHelper.referrerGBRAIDValidityWindow;
465+
if (validityWindow) {
466+
NSDate *initDate = self.preferenceHelper.referrerGBRAIDInitDate ;
467+
NSDate *expirationDate = [initDate dateByAddingTimeInterval:validityWindow];
468+
NSDate *now = [NSDate date];
469+
if ([now compare:expirationDate] == NSOrderedAscending) {
470+
fullParamDict[BRANCH_REQUEST_KEY_REFERRER_GBRAID] = ref_gbraid;
471+
}
472+
}
473+
}
474+
}
453475
return fullParamDict;
454476
}
455477

Branch-SDK/Branch.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,18 @@ typedef NS_ENUM(NSUInteger, BranchCreditHistoryOrder) {
825825
///Returns the current tracking state.
826826
+ (BOOL) trackingDisabled;
827827

828+
/*
829+
830+
Sets the time window for which referrer_graid is valid starting from now.
831+
After validity window is over, its cleared from settings and will not be sent
832+
with requests anymore.
833+
834+
Default time interval is 30 days (2,592,000 seconds).
835+
836+
@param validityWindow -(NSTimeInterval) number of seconds for which referrer_gbraid will be valid starting from now.
837+
*/
838+
+ (void) setReferrerGbraidValidityWindow:(NSTimeInterval) validityWindow;
839+
828840
#pragma mark - Session Item methods
829841

830842
///--------------------
@@ -1292,6 +1304,19 @@ typedef NS_ENUM(NSUInteger, BranchCreditHistoryOrder) {
12921304
*/
12931305
- (NSString *)getLongURLWithParams:(nullable NSDictionary *)params andChannel:(nullable NSString *)channel andTags:(nullable NSArray *)tags andFeature:(nullable NSString *)feature andStage:(nullable NSString *)stage andAlias:(nullable NSString *)alias;
12941306

1307+
/**
1308+
Get a long app.link url with specified params, tags, feature, stage, and alias. The usage type will default to unlimited.
1309+
1310+
@param params Dictionary of parameters to include in the link.
1311+
@param channel The channel for the link. Examples could be Facebook, Twitter, SMS, etc, depending on where it will be shared.
1312+
@param tags An array of tags to associate with this link, useful for tracking.
1313+
@param feature The feature this is utilizing. Examples could be Sharing, Referring, Inviting, etc.
1314+
@param stage The stage used for the generated link, indicating what part of a funnel the user is in.
1315+
@param alias The alias for a link.
1316+
@warning This can fail if the alias is already taken.
1317+
*/
1318+
- (NSString *)getLongAppLinkURLWithParams:(NSDictionary *)params andChannel:(nullable NSString *)channel andTags:(NSArray *)tags andFeature:(NSString *)feature andStage:(NSString *)stage andAlias:(NSString *)alias;
1319+
12951320
#pragma mark - Short Url Async methods
12961321

12971322
///----------------------------------------

0 commit comments

Comments
 (0)