Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/pre-release-qa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ jobs:
verify-cocoapods-iOS:
runs-on: macos-latest
steps:
- name: Select Xcode version
run: sudo xcode-select -s '/Applications/Xcode_16.4.app/Contents/Developer'
- name: Check out code
uses: actions/checkout@v4
- name: Install pod, build project and run tests
Expand All @@ -19,6 +21,8 @@ jobs:
verify-carthage-iOS:
runs-on: macos-15
steps:
- name: Select Xcode version
run: sudo xcode-select -s '/Applications/Xcode_16.4.app/Contents/Developer'
- name: Check out code
uses: actions/checkout@v4
- name: Create Cart File, run carthage command, build project and run tests
Expand All @@ -35,6 +39,8 @@ jobs:
verify-SPM-iOS:
runs-on: macos-latest
steps:
- name: Select Xcode version
run: sudo xcode-select -s '/Applications/Xcode_16.4.app/Contents/Developer'
- name: Check out code
uses: actions/checkout@v4
- name: build project and run tests
Expand All @@ -46,6 +52,8 @@ jobs:
verify-manually-with-xcframework-iOS:
runs-on: macos-latest
steps:
- name: Select Xcode version
run: sudo xcode-select -s '/Applications/Xcode_16.4.app/Contents/Developer'
- name: Check out code
uses: actions/checkout@v4
- name: build xcframework, then build project and run tests
Expand All @@ -58,6 +66,8 @@ jobs:
verify-manually-with-StaticFramework-iOS:
runs-on: macos-latest
steps:
- name: Select Xcode version
run: sudo xcode-select -s '/Applications/Xcode_16.4.app/Contents/Developer'
- name: Check out code
uses: actions/checkout@v4
- name: build static xcframework, then build project and run tests
Expand All @@ -70,6 +80,8 @@ jobs:
verify-cocoapods-tvOS:
runs-on: macos-latest
steps:
- name: Select Xcode version
run: sudo xcode-select -s '/Applications/Xcode_16.4.app/Contents/Developer'
- name: Check out code
uses: actions/checkout@v4
- name: Install pod, build project and run tests
Expand All @@ -82,6 +94,8 @@ jobs:
verify-carthage-tvOS:
runs-on: macos-latest
steps:
- name: Select Xcode version
run: sudo xcode-select -s '/Applications/Xcode_16.4.app/Contents/Developer'
- name: Check out code
uses: actions/checkout@v4
- name: Verify Integration using Carthage for tvOS
Expand All @@ -93,6 +107,8 @@ jobs:
verify-manually-with-xcframework-tvOS:
runs-on: macos-latest
steps:
- name: Select Xcode version
run: sudo xcode-select -s '/Applications/Xcode_16.4.app/Contents/Developer'
- name: Check out code
uses: actions/checkout@v4
- name: build xcframework, then build project and run tests
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ jobs:
runs-on: macos-15
timeout-minutes: 20
steps:
- name: Select Xcode version
run: sudo xcode-select -s '/Applications/Xcode_16.4.app/Contents/Developer'
- name: Check out code
uses: actions/checkout@v4
- name: Set up Ruby 2.7
Expand Down
97 changes: 97 additions & 0 deletions Branch-TestBed/Branch-SDK-Tests/BranchClassTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -261,5 +261,102 @@ - (void)testSetConsumerProtectionAttributionLevel {

}

- (void)testSetAnonID {
NSString *expectedAnonID = @"static-test-anon-id-12345";

[Branch setAnonID:expectedAnonID];

NSString *actualAnonID = [BNCPreferenceHelper sharedInstance].anonID;
XCTAssertEqualObjects(actualAnonID, expectedAnonID, @"setAnonID should set valid string");
}

- (void)testSetAnonID_UpdateExistingValue {
NSString *initialAnonID = @"initial-anon-id";
NSString *updatedAnonID = @"updated-anon-id";

[Branch setAnonID:initialAnonID];
XCTAssertEqualObjects([BNCPreferenceHelper sharedInstance].anonID, initialAnonID);

[Branch setAnonID:updatedAnonID];
XCTAssertEqualObjects([BNCPreferenceHelper sharedInstance].anonID, updatedAnonID);
}

- (void)testSetAnonID_NilValue {
NSString *initialAnonID = @"initial-anon-id";

[Branch setAnonID:initialAnonID];
XCTAssertEqualObjects([BNCPreferenceHelper sharedInstance].anonID, initialAnonID);

[Branch setAnonID:nil];
XCTAssertEqualObjects([BNCPreferenceHelper sharedInstance].anonID, initialAnonID);
}

- (void)testSetAnonID_EmptyString {
NSString *emptyAnonID = @"";

[Branch setAnonID:emptyAnonID];

NSString *actualAnonID = [BNCPreferenceHelper sharedInstance].anonID;
XCTAssertEqualObjects(actualAnonID, emptyAnonID, @"Static setAnonID should accept empty string");
}

- (void)testSetAnonID_NonStringObject {
NSString *initialAnonID = @"initial-anon-id";

[Branch setAnonID:initialAnonID];
XCTAssertEqualObjects([BNCPreferenceHelper sharedInstance].anonID, initialAnonID);

// Try to set with a non-string object (NSNumber)
NSNumber *nonStringValue = @123;
[Branch setAnonID:(NSString *)nonStringValue];
Comment on lines +309 to +311
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Bug Fix

Issue: Unsafe type casting of NSNumber to NSString will cause runtime crash when the method tries to validate the parameter type
Fix: Remove the explicit cast to let the method handle type validation naturally
Impact: Prevents potential crash and allows proper testing of type validation logic

Suggested change
// Try to set with a non-string object (NSNumber)
NSNumber *nonStringValue = @123;
[Branch setAnonID:(NSString *)nonStringValue];
// Try to set with a non-string object (NSNumber)
NSNumber *nonStringValue = @123;
[Branch setAnonID:nonStringValue];


XCTAssertEqualObjects([BNCPreferenceHelper sharedInstance].anonID, initialAnonID);
}

- (void)testSetAnonID_LongString {
NSString *longAnonID = @"very-long-anon-id-with-many-characters-to-test-string-handling-1234567890-abcdefghijklmnopqrstuvwxyz";

[Branch setAnonID:longAnonID];

NSString *actualAnonID = [BNCPreferenceHelper sharedInstance].anonID;
XCTAssertEqualObjects(actualAnonID, longAnonID, @"setAnonID should handle long strings");
}

- (void)testSetAnonID_SpecialCharacters {
NSString *specialCharAnonID = @"static-anon-id-with-special-chars-!@#$%^&*()_+-=[]{}|;:,.<>?";

[Branch setAnonID:specialCharAnonID];

NSString *actualAnonID = [BNCPreferenceHelper sharedInstance].anonID;
XCTAssertEqualObjects(actualAnonID, specialCharAnonID, @"setAnonID should handle special characters");
}

- (void)testSetAnonID_ThreadSafety {
NSString *anonID1 = @"thread-test-anon-id-1";
NSString *anonID2 = @"thread-test-anon-id-2";

// Test that the method is thread-safe by calling it from different queues
dispatch_group_t group = dispatch_group_create();

dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[Branch setAnonID:anonID1];
dispatch_group_leave(group);
});

dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[Branch setAnonID:anonID2];
dispatch_group_leave(group);
});

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

// Verify that one of the values was set (we can't predict which due to concurrency)
NSString *finalAnonID = [BNCPreferenceHelper sharedInstance].anonID;
XCTAssertTrue([finalAnonID isEqualToString:anonID1] || [finalAnonID isEqualToString:anonID2],
@"One of the anonID values should be set");
}


@end
10 changes: 10 additions & 0 deletions Sources/BranchSDK/Branch.m
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,16 @@ + (void)setODMInfo:(NSString *)odmInfo andFirstOpenTimestamp:(NSDate *) firstOpe

}

+ (void)setAnonID:(NSString *)anonID {
@synchronized (self) {
if (anonID && [anonID isKindOfClass:[NSString class]]) {
[BNCPreferenceHelper sharedInstance].anonID = anonID;
} else {
[[BranchLogger shared] logWarning:@"Invalid anonID provided. Must be a non-nil NSString." error:nil];
}
}
}

- (void)setConsumerProtectionAttributionLevel:(BranchAttributionLevel)level {
self.preferenceHelper.attributionLevel = level;

Expand Down
6 changes: 6 additions & 0 deletions Sources/BranchSDK/Public/Branch.h
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,12 @@ Sets a custom base safetrack URL for non-linking calls to the Branch API.

+ (void)setODMInfo:(NSString *)odmInfo andFirstOpenTimestamp:(NSDate *) firstOpenTimestamp;

/**
Sets a custom Meta Anon ID for the current user.
@param anonID The custom Meta Anon ID to be used by Branch.
*/
+ (void)setAnonID:(NSString *)anonID;

/**
* Enumeration representing different levels of consumer protection attribution levels
*/
Expand Down
Loading