Skip to content

Commit 4c5c569

Browse files
authored
Fixed Branch Universal Object & Update UITestBed (#768)
* Updated the UITestBed for better link testing. * Fixed expired link generation. Fixed split view. * Need to fix how BUO dictionaries are merged. * Checked BUO compatibility with Android. * Fixed unit test.
1 parent 2da77db commit 4c5c569

File tree

17 files changed

+301
-180
lines changed

17 files changed

+301
-180
lines changed

Branch-SDK/Branch-SDK/Branch.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ extern NSString * const BNCCanonicalIdList;
124124
extern NSString * const BNCPurchaseAmount;
125125
extern NSString * const BNCPurchaseCurrency;
126126
extern NSString * const BNCCanonicalIdList;
127-
extern NSString * const BNCPurchaseAmount;
128127
extern NSString * const BNCRegisterViewEvent;
129128
extern NSString * const BNCAddToWishlistEvent;
130129
extern NSString * const BNCAddToCartEvent;

Branch-SDK/Branch-SDK/Branch.m

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,7 @@ - (void)getCreditHistoryForBucket:(NSString *)bucket after:(NSString *)creditTra
11741174
- (BranchUniversalObject *)getFirstReferringBranchUniversalObject {
11751175
NSDictionary *params = [self getFirstReferringParams];
11761176
if ([[params objectForKey:BRANCH_INIT_KEY_CLICKED_BRANCH_LINK] isEqual:@1]) {
1177-
return [BranchUniversalObject getBranchUniversalObjectFromDictionary:params];
1177+
return [BranchUniversalObject objectWithDictionary:params];
11781178
}
11791179
return nil;
11801180
}
@@ -1221,7 +1221,7 @@ - (NSDictionary*) getLatestReferringParamsSynchronous {
12211221
- (BranchUniversalObject *)getLatestReferringBranchUniversalObject {
12221222
NSDictionary *params = [self getLatestReferringParams];
12231223
if ([[params objectForKey:BRANCH_INIT_KEY_CLICKED_BRANCH_LINK] isEqual:@1]) {
1224-
return [BranchUniversalObject getBranchUniversalObjectFromDictionary:params];
1224+
return [BranchUniversalObject objectWithDictionary:params];
12251225
}
12261226
return nil;
12271227
}
@@ -1670,7 +1670,7 @@ - (NSString *)generateShortUrl:(NSArray *)tags
16701670
linkCache:self.linkCache];
16711671

16721672
if (self.isInitialized) {
1673-
BNCLogDebug(@"Created a custom URL synchronously.");
1673+
BNCLogDebug(@"Creating a custom URL synchronously.");
16741674
BNCServerResponse *serverResponse = [req makeRequest:self.serverInterface key:self.class.branchKey];
16751675
shortURL = [req processResponse:serverResponse];
16761676

@@ -2205,10 +2205,8 @@ - (void) sendOpenNotificationWithLinkParameters:(NSDictionary*)linkParameters
22052205

22062206
NSNumber *isBranchLink = linkParameters[BRANCH_INIT_KEY_CLICKED_BRANCH_LINK];
22072207
if ([isBranchLink boolValue]) {
2208-
universalObject =
2209-
[BranchUniversalObject getBranchUniversalObjectFromDictionary:linkParameters];
2210-
linkProperties =
2211-
[BranchLinkProperties getBranchLinkPropertiesFromDictionary:linkParameters];
2208+
universalObject = [BranchUniversalObject objectWithDictionary:linkParameters];
2209+
linkProperties = [BranchLinkProperties getBranchLinkPropertiesFromDictionary:linkParameters];
22122210
}
22132211

22142212
if (error) {

Branch-SDK/Branch-SDK/BranchUniversalObject.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,14 +239,11 @@ FOUNDATION_EXPORT BranchCondition _Nonnull BranchConditionRefurbished;
239239

240240
- (void)removeFromSpotlightWithCallback:(void (^_Nullable)(NSError * _Nullable error))completion;
241241

242-
/// Convenience method for initSession methods that return BranchUniversalObject, but can be used safely by anyone.
243-
+ (nonnull BranchUniversalObject *)getBranchUniversalObjectFromDictionary:(nonnull NSDictionary *)dictionary;
244-
245-
- (NSDictionary*_Nonnull)getParamsForServerRequest;
246242
- (NSDictionary*_Nonnull)getDictionaryWithCompleteLinkProperties:(BranchLinkProperties*_Nonnull)linkProperties;
247243
- (NSDictionary*_Nonnull)getParamsForServerRequestWithAddedLinkProperties:(BranchLinkProperties*_Nonnull)linkProperties;
248244

249-
- (NSDictionary*_Nonnull) dictionary;
245+
/// Convenience method for initSession methods that return BranchUniversalObject, but can be used safely by anyone.
246+
- (NSMutableDictionary*_Nonnull) dictionary;
250247
+ (BranchUniversalObject*_Nonnull) objectWithDictionary:(NSDictionary*_Null_unspecified)dictionary;
251248

252249
- (NSString*_Nonnull) description;

Branch-SDK/Branch-SDK/BranchUniversalObject.m

Lines changed: 66 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ - (void)userCompletedAction:(NSString *)action withState:(NSDictionary *)state {
305305
[[BranchEvent customEventWithName:action contentItem:self] logEvent];
306306

307307
// Maybe list on spotlight --
308-
NSDictionary *linkParams = [self getParamsForServerRequest];
308+
NSDictionary *linkParams = self.dictionary;
309309
if (self.locallyIndex && self.canonicalIdentifier && linkParams) {
310310

311311
NSMutableDictionary *actionPayload = [[NSMutableDictionary alloc] init];
@@ -377,8 +377,20 @@ - (NSString *)getShortUrlWithLinkPropertiesAndIgnoreFirstClick:(BranchLinkProper
377377
forceLinkCreation:YES];
378378
}
379379

380-
- (NSString *)getLongUrlWithChannel:(NSString *)channel andTags:(NSArray *)tags andFeature:(NSString *)feature andStage:(NSString *)stage andAlias:(NSString *)alia{
381-
return [[Branch getInstance] getLongURLWithParams:[self getParamsForServerRequest] andChannel:channel andTags:tags andFeature:feature andStage:stage andAlias:alia];
380+
- (NSString *)getLongUrlWithChannel:(NSString *)channel
381+
andTags:(NSArray *)tags
382+
andFeature:(NSString *)feature
383+
andStage:(NSString *)stage
384+
andAlias:(NSString *)alias {
385+
NSString *urlString =
386+
[[Branch getInstance]
387+
getLongURLWithParams:self.dictionary
388+
andChannel:channel
389+
andTags:tags
390+
andFeature:feature
391+
andStage:stage
392+
andAlias:alias];
393+
return urlString;
382394
}
383395

384396
#pragma mark - Share Sheets
@@ -596,85 +608,13 @@ - (void) removeFromSpotlightWithCallback:(void (^_Nullable)(NSError * _Nullable
596608
}
597609
}
598610

599-
#pragma mark - Private methods
600611
#pragma mark - Dictionary Methods
601612

602-
+ (BranchUniversalObject *)getBranchUniversalObjectFromDictionary:(NSDictionary *)dictionary {
603-
BranchUniversalObject *universalObject = [[BranchUniversalObject alloc] init];
604-
605-
// Build BranchUniversalObject base properties
606-
universalObject.contentMetadata.customMetadata = [dictionary copy];
607-
if (dictionary[BRANCH_LINK_DATA_KEY_CANONICAL_IDENTIFIER]) {
608-
universalObject.canonicalIdentifier = dictionary[BRANCH_LINK_DATA_KEY_CANONICAL_IDENTIFIER];
609-
}
610-
if (dictionary[BRANCH_LINK_DATA_KEY_CANONICAL_URL]) {
611-
universalObject.canonicalUrl = dictionary[BRANCH_LINK_DATA_KEY_CANONICAL_URL];
612-
}
613-
if (dictionary[BRANCH_LINK_DATA_KEY_OG_TITLE]) {
614-
universalObject.title = dictionary[BRANCH_LINK_DATA_KEY_OG_TITLE];
615-
}
616-
if (dictionary[BRANCH_LINK_DATA_KEY_OG_DESCRIPTION]) {
617-
universalObject.contentDescription = dictionary[BRANCH_LINK_DATA_KEY_OG_DESCRIPTION];
618-
}
619-
if (dictionary[BRANCH_LINK_DATA_KEY_OG_IMAGE_URL]) {
620-
universalObject.imageUrl = dictionary[BRANCH_LINK_DATA_KEY_OG_IMAGE_URL];
621-
}
622-
universalObject.publiclyIndex = [dictionary[BRANCH_LINK_DATA_KEY_PUBLICLY_INDEXABLE] boolValue];
623-
universalObject.locallyIndex = [dictionary[BRANCH_LINK_DATA_KEY_LOCALLY_INDEXABLE] boolValue];
624-
625-
NSNumber *number = dictionary[BRANCH_LINK_DATA_KEY_CONTENT_EXPIRATION_DATE];
626-
if ([number isKindOfClass:[NSNumber class]]) {
627-
// Number is millisecondsSince1970
628-
universalObject.expirationDate = [NSDate dateWithTimeIntervalSince1970:number.integerValue/1000];
629-
}
630-
if (dictionary[BRANCH_LINK_DATA_KEY_KEYWORDS]) {
631-
universalObject.keywords = dictionary[BRANCH_LINK_DATA_KEY_KEYWORDS];
632-
}
633-
NSString *s = dictionary[BNCPurchaseAmount];
634-
if (s) {
635-
if ([s isKindOfClass:NSString.class])
636-
universalObject.contentMetadata.price = [NSDecimalNumber decimalNumberWithString:s];
637-
else
638-
if ([s isKindOfClass:NSDecimalNumber.class])
639-
universalObject.contentMetadata.price = (NSDecimalNumber*) s;
640-
else
641-
if ([s isKindOfClass:NSNumber.class]) {
642-
s = [((NSNumber*)s) stringValue];
643-
universalObject.contentMetadata.price = [NSDecimalNumber decimalNumberWithString:s];
644-
}
645-
}
646-
if (dictionary[BNCPurchaseCurrency]) {
647-
universalObject.contentMetadata.currency = dictionary[BNCPurchaseCurrency];
648-
}
649-
650-
if (dictionary[BRANCH_LINK_DATA_KEY_CONTENT_TYPE]) {
651-
universalObject.contentMetadata.contentSchema = dictionary[BRANCH_LINK_DATA_KEY_CONTENT_TYPE];
652-
}
653-
return universalObject;
654-
}
655-
656-
- (NSDictionary*_Nonnull) getParamsForServerRequest {
657-
NSMutableDictionary *temp = [[NSMutableDictionary alloc] init];
658-
[self safeSetValue:self.canonicalIdentifier forKey:BRANCH_LINK_DATA_KEY_CANONICAL_IDENTIFIER onDict:temp];
659-
[self safeSetValue:self.canonicalUrl forKey:BRANCH_LINK_DATA_KEY_CANONICAL_URL onDict:temp];
660-
[self safeSetValue:self.title forKey:BRANCH_LINK_DATA_KEY_OG_TITLE onDict:temp];
661-
[self safeSetValue:self.contentDescription forKey:BRANCH_LINK_DATA_KEY_OG_DESCRIPTION onDict:temp];
662-
[self safeSetValue:self.imageUrl forKey:BRANCH_LINK_DATA_KEY_OG_IMAGE_URL onDict:temp];
663-
temp[BRANCH_LINK_DATA_KEY_PUBLICLY_INDEXABLE] = [NSNumber numberWithBool:self.publiclyIndex];
664-
temp[BRANCH_LINK_DATA_KEY_LOCALLY_INDEXABLE] = [NSNumber numberWithBool:self.locallyIndex];
665-
[self safeSetValue:self.keywords forKey:BRANCH_LINK_DATA_KEY_KEYWORDS onDict:temp];
666-
[self safeSetValue:@(1000 * [self.expirationDate timeIntervalSince1970]) forKey:BRANCH_LINK_DATA_KEY_CONTENT_EXPIRATION_DATE onDict:temp];
667-
[self safeSetValue:self.contentMetadata.contentSchema forKey:BRANCH_LINK_DATA_KEY_CONTENT_TYPE onDict:temp];
668-
[self safeSetValue:self.contentMetadata.currency forKey:BNCPurchaseCurrency onDict:temp];
669-
temp[BNCPurchaseAmount] = self.contentMetadata.price;
670-
[temp addEntriesFromDictionary:[self.contentMetadata.customMetadata copy]];
671-
return [temp copy];
672-
}
673-
674613
- (NSDictionary *)getParamsForServerRequestWithAddedLinkProperties:(BranchLinkProperties *)linkProperties {
675-
NSMutableDictionary *temp = [[self getParamsForServerRequest] mutableCopy];
676-
[temp addEntriesFromDictionary:[linkProperties.controlParams copy]]; // TODO: Add warnings if controlParams contains non-control params
677-
return [temp copy];
614+
// TODO: Add warnings if controlParams contains non-control params
615+
NSMutableDictionary *temp = self.dictionary;
616+
[temp addEntriesFromDictionary:[linkProperties.controlParams copy]];
617+
return temp;
678618
}
679619

680620
- (NSDictionary *)getDictionaryWithCompleteLinkProperties:(BranchLinkProperties *)linkProperties {
@@ -717,14 +657,60 @@ + (BranchUniversalObject*_Nonnull) objectWithDictionary:(NSDictionary*_Null_unsp
717657

718658
BranchContentMetadata *data = [BranchContentMetadata contentMetadataWithDictionary:dictionary];
719659
object.contentMetadata = data;
720-
660+
661+
NSSet *fieldsAdded = [NSSet setWithArray:@[
662+
@"$canonical_identifier",
663+
@"$canonical_url",
664+
@"$creation_timestamp",
665+
@"$exp_date",
666+
@"$keywords",
667+
@"$locally_indexable",
668+
@"$og_description",
669+
@"$og_image_url",
670+
@"$og_title",
671+
@"$publicly_indexable",
672+
@"$content_schema",
673+
@"$quantity",
674+
@"$price",
675+
@"$currency",
676+
@"$sku",
677+
@"$product_name",
678+
@"$product_brand",
679+
@"$product_category",
680+
@"$product_variant",
681+
@"$condition",
682+
@"$rating_average",
683+
@"$rating_count",
684+
@"$rating_max",
685+
@"$address_street",
686+
@"$address_city",
687+
@"$address_region",
688+
@"$address_country",
689+
@"$address_postal_code",
690+
@"$latitude",
691+
@"$longitude",
692+
@"$image_captions",
693+
@"$custom_fields",
694+
]];
695+
696+
// Add any extra fields to the content object.contentMetadata.customMetadata
697+
698+
for (NSString* key in dictionary.keyEnumerator) {
699+
if (![fieldsAdded containsObject:key]) {
700+
object.contentMetadata.customMetadata[key] = dictionary[key];
701+
}
702+
}
703+
721704
return object;
722705
}
723706

724707
- (NSDictionary*_Nonnull) dictionary {
725708

726709
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
727710

711+
NSDictionary *contentDictionary = [self.contentMetadata dictionary];
712+
if (contentDictionary.count) [dictionary addEntriesFromDictionary:contentDictionary];
713+
728714
#define BNCFieldDefinesDictionaryFromSelf
729715
#include "BNCFieldDefines.h"
730716

@@ -741,9 +727,6 @@ - (NSDictionary*_Nonnull) dictionary {
741727

742728
#include "BNCFieldDefines.h"
743729

744-
NSDictionary *contentDictionary = [self.contentMetadata dictionary];
745-
if (contentDictionary.count) [dictionary addEntriesFromDictionary:contentDictionary];
746-
747730
return dictionary;
748731
}
749732

Branch-TestBed/Branch-SDK-Tests/BNCLog.Test.m

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -816,37 +816,6 @@ - (void) testLogByteWrapPerformanceTesting {
816816
BNCLogCloseLogFile();
817817
NSLog(@"%@: Synchronized time: %1.5f.",
818818
BNCSStringForCurrentMethod(), - startTime.timeIntervalSinceNow);
819-
820-
/* // Non-sychronized --
821-
// EBS: Non-sychronized is no longer a thing. It was slower and less safe.
822-
823-
BNCLogSetOutputToURLByteWrap(URL, kLogSize);
824-
BNCLogSetSynchronizeMessages(NO);
825-
826-
startTime = [NSDate date];
827-
waitGroup = dispatch_group_create();
828-
829-
dispatch_group_async(waitGroup,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
830-
for (long i = 0; i < 2000; i++)
831-
BNCLog(@"Message 1x%ld", i);
832-
});
833-
834-
dispatch_group_async(waitGroup,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
835-
for (long i = 0; i < 2000; i++)
836-
BNCLog(@"Message 2x%ld", i);
837-
});
838-
839-
dispatch_group_async(waitGroup,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
840-
for (long i = 0; i < 2000; i++)
841-
BNCLog(@"Message 3x%ld", i);
842-
});
843-
844-
dispatch_group_wait(waitGroup, DISPATCH_TIME_FOREVER);
845-
BNCLogCloseLogFile();
846-
BNCLogFlushMessages();
847-
NSLog(@"%@: Non-synchronized time: %1.5f",
848-
BNCSStringForCurrentMethod(), - startTime.timeIntervalSinceNow);
849-
*/
850819
}
851820

852821
- (void) testByteWrapTruncate {

Branch-TestBed/Branch-SDK-Tests/BranchDelegate.Test.m

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
#import "BNCTestCase.h"
10+
#import "BNCEncodingUtils.h"
1011

1112
@interface BranchDelegateTest : BNCTestCase <BranchDelegate>
1213
@property (assign, nonatomic) NSInteger notificationOrder;
@@ -22,10 +23,6 @@ @interface BranchDelegateTest : BNCTestCase <BranchDelegate>
2223

2324
@implementation BranchDelegateTest
2425

25-
+ (void) tearDown {
26-
[[NSNotificationCenter defaultCenter] removeObserver:self];
27-
}
28-
2926
// Test that Branch notifications work.
3027
// Test that they 1) work and 2) are sent in the right order.
3128
- (void) testNotificationsSuccess {
@@ -276,21 +273,49 @@ - (void) branchDidStartSessionNotification:(NSNotification*)notification {
276273
XCTAssertNotNil(error);
277274
XCTAssertNil(URL);
278275
XCTAssertNil(object);
279-
XCTAssertNil(object);
276+
XCTAssertNil(properties);
280277

281278
} else {
282279

283280
XCTAssertNil(error);
284281
XCTAssertNotNil(URL);
285282
XCTAssertNotNil(object);
286-
XCTAssertNotNil(object);
283+
XCTAssertNotNil(properties);
284+
285+
NSMutableDictionary *d =
286+
[NSMutableDictionary dictionaryWithDictionary:
287+
[object getDictionaryWithCompleteLinkProperties:properties]];
288+
NSMutableDictionary *truth = [NSMutableDictionary dictionaryWithDictionary:@{
289+
@"$amount": @1000,
290+
@"$canonical_identifier": @"item/12345",
291+
@"$canonical_url": @"https://dev.branch.io/getting-started/deep-link-routing/guide/ios/",
292+
@"$content_type": @"some type",
293+
@"$currency": @"$",
294+
@"$custom_fields": @"{\"+click_timestamp\":1506983962,\"+clicked_branch_link\":true,\"$identity_id\":\"423237095633725879\",\"$one_time_use\":false,\"$amount\":1000,\"~feature\":\"Sharing Feature\",\"$content_type\":\"some type\",\"~creation_source\":3,\"~channel\":\"Distribution Channel\",\"~id\":423243086454504450,\"deeplink_text\":\"This text was embedded as data in a Branch link with the following characteristics:\\n\\ncanonicalUrl: https://dev.branch.io/getting-started/deep-link-routing/guide/ios/\\n title: Content Title\\n contentDescription: My Content Description\\n imageUrl: https://pbs.twimg.com/profile_images/658759610220703744/IO1HUADP.png\\n\",\"~referring_link\":\"https://bnctestbed.app.link/izPBY2xCqF\",\"+match_guaranteed\":true,\"$desktop_url\":\"http://branch.io\",\"+is_first_session\":false,\"$ios_url\":\"https://dev.branch.io/getting-started/sdk-integration-guide/guide/ios/\",\"~campaign\":\"some campaign\"}",
295+
@"$desktop_url": @"http://branch.io",
296+
@"$exp_date": @0,
297+
@"$identity_id": @"423237095633725879",
298+
@"$ios_url": @"https://dev.branch.io/getting-started/sdk-integration-guide/guide/ios/",
299+
@"$og_description": @"My Content Description",
300+
@"$og_image_url": @"https://pbs.twimg.com/profile_images/658759610220703744/IO1HUADP.png",
301+
@"$og_title": @"Content Title",
302+
@"$one_time_use": @0,
303+
@"$publicly_indexable": @1,
304+
@"~campaign": @"some campaign",
305+
@"~channel": @"Distribution Channel",
306+
@"~duration": @0,
307+
@"~feature": @"Sharing Feature",
308+
}];
309+
310+
NSDictionary *dCustom = [BNCEncodingUtils decodeJsonStringToDictionary:d[@"$custom_fields"]];
311+
d[@"$custom_fields"] = nil;
312+
313+
NSDictionary *tCustom = [BNCEncodingUtils decodeJsonStringToDictionary:truth[@"$custom_fields"]];
314+
truth[@"$custom_fields"] = nil;
287315

288-
NSDictionary *d = [object getDictionaryWithCompleteLinkProperties:properties];
289-
NSMutableDictionary *truth = [NSMutableDictionary dictionaryWithDictionary:self.deepLinkParams];
290-
truth[@"~duration"] = @(0); // ~duration not added because zero value?
291-
truth[@"$locally_indexable"] = @(0);
292316
XCTAssertTrue(d.count == truth.count);
293317
XCTAssertTrue(!d || [d isEqualToDictionary:truth]);
318+
XCTAssertTrue(!dCustom || [dCustom isEqualToDictionary:tCustom]);
294319
}
295320

296321
[self.branchDidOpenURLNotificationExpectation fulfill];

Branch-TestBed/Branch-SDK-Tests/BranchEvent.Test.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class BranchEventTestSwift : BNCTestCase {
7373
var dictionary = self.mutableDictionaryFromBundleJSON(withKey: "V2EventProperties")
7474
XCTAssert((dictionary?.isEqual(to: testDictionary))!)
7575

76-
testDictionary = branchUniversalObject.dictionary()
76+
testDictionary = branchUniversalObject.dictionary() as! [AnyHashable : Any]
7777
dictionary = self.mutableDictionaryFromBundleJSON(withKey: "BranchUniversalObjectJSON")
7878
dictionary!["$publicly_indexable"] = nil // Remove this value since we don't add false values.
7979
XCTAssert((dictionary?.isEqual(to: testDictionary))!)

0 commit comments

Comments
 (0)