diff --git a/Branch-TestBed/Branch-SDK-Tests/BranchConfigurationControllerTests.m b/Branch-TestBed/Branch-SDK-Tests/BranchConfigurationControllerTests.m new file mode 100644 index 000000000..0caef907e --- /dev/null +++ b/Branch-TestBed/Branch-SDK-Tests/BranchConfigurationControllerTests.m @@ -0,0 +1,100 @@ +// +// BranchConfigurationControllerTests.m +// Branch-SDK-Tests +// +// Created by Nidhi Dixit on 6/12/25. +// + + +#import +#import "BranchConfigurationController.h" +#import "BranchConstants.h" +#import "BNCRequestFactory.h" +#import "BNCEncodingUtils.h" + +@interface BranchConfigurationControllerTests : XCTestCase +@end + +@implementation BranchConfigurationControllerTests + +- (void)testSingletonInstance { + + BranchConfigurationController *instance1 = [BranchConfigurationController sharedInstance]; + XCTAssertNotNil(instance1); + + BranchConfigurationController *instance2 = [BranchConfigurationController sharedInstance]; + XCTAssertEqual(instance1, instance2); +} + +- (void)testPropertySettersAndGetters { + BranchConfigurationController *configController = [BranchConfigurationController sharedInstance]; + + NSString *keySource = BRANCH_KEY_SOURCE_GET_INSTANCE_API; + configController.branchKeySource = keySource; + XCTAssertTrue([configController.branchKeySource isEqualToString:keySource]); + + configController.deferInitForPluginRuntime = YES; + XCTAssertTrue(configController.deferInitForPluginRuntime); + configController.deferInitForPluginRuntime = NO; + XCTAssertFalse(configController.deferInitForPluginRuntime); + + configController.checkPasteboardOnInstall = YES; + XCTAssertTrue(configController.checkPasteboardOnInstall); + configController.checkPasteboardOnInstall = NO; + XCTAssertFalse(configController.checkPasteboardOnInstall); +} + +- (void)testGetConfiguration { + BranchConfigurationController *configController = [BranchConfigurationController sharedInstance]; + configController.branchKeySource = BRANCH_KEY_SOURCE_INFO_PLIST; + configController.deferInitForPluginRuntime = YES; + configController.checkPasteboardOnInstall = YES; + + NSDictionary *configDict = [configController getConfiguration]; + XCTAssertNotNil(configDict); + + XCTAssertTrue([configDict[BRANCH_REQUEST_KEY_BRANCH_KEY_SOURCE] isEqualToString:BRANCH_KEY_SOURCE_INFO_PLIST]); + XCTAssertEqualObjects(configDict[BRANCH_REQUEST_KEY_DEFER_INIT_FOR_PLUGIN_RUNTIME], @(YES)); + XCTAssertEqualObjects(configDict[BRANCH_REQUEST_KEY_CHECK_PASTEBOARD_ON_INSTALL], @(YES)); + + NSDictionary *frameworks = configDict[BRANCH_REQUEST_KEY_LINKED_FRAMEORKS]; + XCTAssertNotNil(frameworks); + + XCTAssertEqualObjects(frameworks[FRAMEWORK_AD_SUPPORT], @(YES)); + XCTAssertEqualObjects(frameworks[FRAMEWORK_ATT_TRACKING_MANAGER], @(YES)); + XCTAssertEqualObjects(frameworks[FRAMEWORK_AD_FIREBASE_CRASHLYTICS], @(YES)); + XCTAssertEqualObjects(frameworks[FRAMEWORK_AD_SAFARI_SERVICES], @(NO)); + XCTAssertEqualObjects(frameworks[FRAMEWORK_AD_APP_ADS_ONDEVICE_CONVERSION], @(NO)); + +} + +- (void)testInstallRequestParams { + BranchConfigurationController *configController = [BranchConfigurationController sharedInstance]; + configController.branchKeySource = BRANCH_KEY_SOURCE_INFO_PLIST; + configController.deferInitForPluginRuntime = YES; + configController.checkPasteboardOnInstall = YES; + + NSString* requestUUID = [[NSUUID UUID ] UUIDString]; + NSNumber* requestCreationTimeStamp = BNCWireFormatFromDate([NSDate date]); + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:requestUUID TimeStamp:requestCreationTimeStamp]; + NSDictionary *installDict = [factory dataForInstallWithURLString:@"https://branch.io"]; + + NSDictionary *configDict = installDict[BRANCH_REQUEST_KEY_OPERATIONAL_METRICS]; + XCTAssertNotNil(configDict); + + XCTAssertTrue([configDict[BRANCH_REQUEST_KEY_BRANCH_KEY_SOURCE] isEqualToString:BRANCH_KEY_SOURCE_INFO_PLIST]); + XCTAssertEqualObjects(configDict[BRANCH_REQUEST_KEY_DEFER_INIT_FOR_PLUGIN_RUNTIME], @(YES)); + XCTAssertEqualObjects(configDict[BRANCH_REQUEST_KEY_CHECK_PASTEBOARD_ON_INSTALL], @(YES)); + + NSDictionary *frameworks = configDict[BRANCH_REQUEST_KEY_LINKED_FRAMEORKS]; + XCTAssertNotNil(frameworks); + + XCTAssertEqualObjects(frameworks[FRAMEWORK_AD_SUPPORT], @(YES)); + XCTAssertEqualObjects(frameworks[FRAMEWORK_ATT_TRACKING_MANAGER], @(YES)); + XCTAssertEqualObjects(frameworks[FRAMEWORK_AD_FIREBASE_CRASHLYTICS], @(YES)); + XCTAssertEqualObjects(frameworks[FRAMEWORK_AD_SAFARI_SERVICES], @(NO)); + XCTAssertEqualObjects(frameworks[FRAMEWORK_AD_APP_ADS_ONDEVICE_CONVERSION], @(NO)); + +} + +@end diff --git a/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj b/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj index a435edb28..c55c7fb00 100644 --- a/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj +++ b/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj @@ -246,7 +246,10 @@ E7AC74752DB069B2002D8C40 /* nanopb in Frameworks */ = {isa = PBXBuildFile; productRef = E7AC74742DB069B2002D8C40 /* nanopb */; }; E7AC747B2DB0700D002D8C40 /* BranchSDK in Frameworks */ = {isa = PBXBuildFile; productRef = E7AC747A2DB0700D002D8C40 /* BranchSDK */; }; E7AC747E2DB0714B002D8C40 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = E7AC747D2DB07145002D8C40 /* libc++.tbd */; }; + E7AE4A092DFB2C4400696805 /* BranchConfigurationControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7AE4A082DFB2C4400696805 /* BranchConfigurationControllerTests.m */; }; + E7AE4A0C2DFB2D0100696805 /* BranchConfigurationController.h in Headers */ = {isa = PBXBuildFile; fileRef = E7AE4A0B2DFB2D0100696805 /* BranchConfigurationController.h */; }; E7E28ECA2DD2424C00F75D0D /* BNCInAppBrowser.m in Sources */ = {isa = PBXBuildFile; fileRef = E7E28EC82DD2424C00F75D0D /* BNCInAppBrowser.m */; }; + E7FC47732DFC7B020072B3ED /* BranchConfigurationController.m in Sources */ = {isa = PBXBuildFile; fileRef = E7FC47722DFC7B020072B3ED /* BranchConfigurationController.m */; }; F1CF14111F4CC79F00BB2694 /* CoreSpotlight.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67F270881BA9FCFF002546A7 /* CoreSpotlight.framework */; settings = {ATTRIBUTES = (Required, ); }; }; /* End PBXBuildFile section */ @@ -569,7 +572,10 @@ E7AC74772DB06D05002D8C40 /* NSError+Branch.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSError+Branch.m"; sourceTree = ""; }; E7AC74782DB06D47002D8C40 /* NSError+Branch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSError+Branch.h"; sourceTree = ""; }; E7AC747D2DB07145002D8C40 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.2.sdk/usr/lib/libc++.tbd"; sourceTree = DEVELOPER_DIR; }; + E7AE4A082DFB2C4400696805 /* BranchConfigurationControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BranchConfigurationControllerTests.m; sourceTree = ""; }; + E7AE4A0B2DFB2D0100696805 /* BranchConfigurationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BranchConfigurationController.h; sourceTree = ""; }; E7E28EC82DD2424C00F75D0D /* BNCInAppBrowser.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BNCInAppBrowser.m; sourceTree = ""; }; + E7FC47722DFC7B020072B3ED /* BranchConfigurationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = BranchConfigurationController.m; path = ../Sources/BranchSDK/BranchConfigurationController.m; sourceTree = ""; }; F1D4F9AC1F323F01002D13FF /* Branch-TestBed-UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Branch-TestBed-UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -651,6 +657,7 @@ 4D16837A2098C901008819E3 /* Branch-SDK-Tests */ = { isa = PBXGroup; children = ( + E7AE4A082DFB2C4400696805 /* BranchConfigurationControllerTests.m */, E7A728BC2AA9A112009343B7 /* BNCAPIServerTest.m */, 5FC7326F22DD1F93006E6FBC /* BNCAppleReceiptTests.m */, 4D1683972098C901008819E3 /* BNCApplicationTests.m */, @@ -838,6 +845,7 @@ 5F644B6E2B7AA810000DCD78 /* Private */ = { isa = PBXGroup; children = ( + E7AE4A0B2DFB2D0100696805 /* BranchConfigurationController.h */, E71E397A2DD3C14800110F59 /* BNCInAppBrowser.h */, 5F644B762B7AA810000DCD78 /* BNCAppGroupsData.h */, 5F644B702B7AA810000DCD78 /* BNCAppleReceipt.h */, @@ -916,6 +924,7 @@ 670016571940F51400A9E103 = { isa = PBXGroup; children = ( + E7FC47722DFC7B020072B3ED /* BranchConfigurationController.m */, E7AC74762DB06B42002D8C40 /* Reflection_ODM_Tests.xctestplan */, 6589EBA52674270100F2E28B /* Branch-TestBed-CI.xctestplan */, 033FC71025AC1E5800D8319E /* Branch-TestBed.xctestplan */, @@ -1088,6 +1097,7 @@ 5F644C062B7AA811000DCD78 /* UIViewController+Branch.h in Headers */, 5F644C022B7AA811000DCD78 /* BNCPasteboard.h in Headers */, 5F644C0F2B7AA811000DCD78 /* BranchOpenRequest.h in Headers */, + E7AE4A0C2DFB2D0100696805 /* BranchConfigurationController.h in Headers */, 5F644C2C2B7AA811000DCD78 /* BNCRequestFactory.h in Headers */, 5F644C142B7AA811000DCD78 /* BNCDeviceSystem.h in Headers */, ); @@ -1364,6 +1374,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + E7FC47732DFC7B020072B3ED /* BranchConfigurationController.m in Sources */, 5F644BB92B7AA811000DCD78 /* NSError+Branch.m in Sources */, 5F644C482B7AA811000DCD78 /* BNCCallbackMap.m in Sources */, 5F644BBE2B7AA811000DCD78 /* BNCApplication.m in Sources */, @@ -1499,6 +1510,7 @@ C12320B52808DB90007771C0 /* BranchQRCodeTests.m in Sources */, 5F3D671B233062FD00454FF1 /* BNCJsonLoader.m in Sources */, 4D1683C02098C902008819E3 /* BranchUniversalObjectTests.m in Sources */, + E7AE4A092DFB2C4400696805 /* BranchConfigurationControllerTests.m in Sources */, 5FC7327022DD1F93006E6FBC /* BNCAppleReceiptTests.m in Sources */, 4D1683C82098C902008819E3 /* NSStringBranchTests.m in Sources */, 5F892EC5236116CD0023AEC1 /* NSErrorBranchTests.m in Sources */, diff --git a/BranchSDK.xcodeproj/project.pbxproj b/BranchSDK.xcodeproj/project.pbxproj index c751c42c6..74de0d1d8 100644 --- a/BranchSDK.xcodeproj/project.pbxproj +++ b/BranchSDK.xcodeproj/project.pbxproj @@ -499,6 +499,12 @@ E71E39722DD3A92900110F59 /* BNCInAppBrowser.h in Headers */ = {isa = PBXBuildFile; fileRef = E71E396D2DD3A92900110F59 /* BNCInAppBrowser.h */; }; E71E39732DD3A92900110F59 /* BNCInAppBrowser.m in Sources */ = {isa = PBXBuildFile; fileRef = E71E396E2DD3A92900110F59 /* BNCInAppBrowser.m */; }; E71E39742DD3A92900110F59 /* BNCInAppBrowser.h in Headers */ = {isa = PBXBuildFile; fileRef = E71E396D2DD3A92900110F59 /* BNCInAppBrowser.h */; }; + E73D02812DEE8AE90076C3F1 /* BranchConfigurationController.m in Sources */ = {isa = PBXBuildFile; fileRef = E73D02802DEE8AE90076C3F1 /* BranchConfigurationController.m */; }; + E73D02822DEE8AE90076C3F1 /* BranchConfigurationController.h in Headers */ = {isa = PBXBuildFile; fileRef = E73D027F2DEE8AE90076C3F1 /* BranchConfigurationController.h */; }; + E73D02832DEE8AE90076C3F1 /* BranchConfigurationController.h in Headers */ = {isa = PBXBuildFile; fileRef = E73D027F2DEE8AE90076C3F1 /* BranchConfigurationController.h */; }; + E73D02842DEE8AE90076C3F1 /* BranchConfigurationController.m in Sources */ = {isa = PBXBuildFile; fileRef = E73D02802DEE8AE90076C3F1 /* BranchConfigurationController.m */; }; + E73D02852DEE8AE90076C3F1 /* BranchConfigurationController.m in Sources */ = {isa = PBXBuildFile; fileRef = E73D02802DEE8AE90076C3F1 /* BranchConfigurationController.m */; }; + E73D02862DEE8AE90076C3F1 /* BranchConfigurationController.h in Headers */ = {isa = PBXBuildFile; fileRef = E73D027F2DEE8AE90076C3F1 /* BranchConfigurationController.h */; }; E7F311AE2DACB4D400F824A7 /* BNCODMInfoCollector.m in Sources */ = {isa = PBXBuildFile; fileRef = E7F311AD2DACB4D400F824A7 /* BNCODMInfoCollector.m */; }; E7F311AF2DACB4D400F824A7 /* BNCODMInfoCollector.m in Sources */ = {isa = PBXBuildFile; fileRef = E7F311AD2DACB4D400F824A7 /* BNCODMInfoCollector.m */; }; E7F311B12DACB54100F824A7 /* BNCODMInfoCollector.h in Headers */ = {isa = PBXBuildFile; fileRef = E7F311B02DACB54100F824A7 /* BNCODMInfoCollector.h */; }; @@ -717,6 +723,8 @@ E52E5B092CC79E5C00F553EE /* BranchFileLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchFileLogger.m; sourceTree = ""; }; E71E396D2DD3A92900110F59 /* BNCInAppBrowser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BNCInAppBrowser.h; sourceTree = ""; }; E71E396E2DD3A92900110F59 /* BNCInAppBrowser.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BNCInAppBrowser.m; sourceTree = ""; }; + E73D027F2DEE8AE90076C3F1 /* BranchConfigurationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BranchConfigurationController.h; sourceTree = ""; }; + E73D02802DEE8AE90076C3F1 /* BranchConfigurationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BranchConfigurationController.m; sourceTree = ""; }; E7F311AD2DACB4D400F824A7 /* BNCODMInfoCollector.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BNCODMInfoCollector.m; sourceTree = ""; }; E7F311B02DACB54100F824A7 /* BNCODMInfoCollector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCODMInfoCollector.h; sourceTree = ""; }; /* End PBXFileReference section */ @@ -904,6 +912,7 @@ 5FCDD3732B7AC6A100EAF29F /* NSMutableDictionary+Branch.m */, 5FCDD37C2B7AC6A100EAF29F /* NSString+Branch.m */, 5FCDD3F52B7AC6A100EAF29F /* UIViewController+Branch.m */, + E73D02802DEE8AE90076C3F1 /* BranchConfigurationController.m */, 5FCDD3B42B7AC6A100EAF29F /* Private */, 5FCDD3982B7AC6A100EAF29F /* Public */, ); @@ -997,6 +1006,7 @@ E52E5B052CC79E4E00F553EE /* BranchFileLogger.h */, 5FCDD3BB2B7AC6A100EAF29F /* UIViewController+Branch.h */, E71E396D2DD3A92900110F59 /* BNCInAppBrowser.h */, + E73D027F2DEE8AE90076C3F1 /* BranchConfigurationController.h */, ); path = Private; sourceTree = ""; @@ -1103,6 +1113,7 @@ 5FCDD54F2B7AC6A300EAF29F /* BranchJsonConfig.h in Headers */, 5FCDD4E02B7AC6A200EAF29F /* BNCSKAdNetwork.h in Headers */, 5FCDD5102B7AC6A300EAF29F /* BNCDeviceSystem.h in Headers */, + E73D02832DEE8AE90076C3F1 /* BranchConfigurationController.h in Headers */, 5FCDD51F2B7AC6A300EAF29F /* BNCNetworkInterface.h in Headers */, 5FA71BA82B7AE6B2008009CA /* Branch.h in Headers */, ); @@ -1186,6 +1197,7 @@ 5FCDD4D82B7AC6A200EAF29F /* BNCAppleReceipt.h in Headers */, 5FCDD5502B7AC6A300EAF29F /* BranchJsonConfig.h in Headers */, 5FCDD4E12B7AC6A200EAF29F /* BNCSKAdNetwork.h in Headers */, + E73D02822DEE8AE90076C3F1 /* BranchConfigurationController.h in Headers */, 5FCDD5112B7AC6A300EAF29F /* BNCDeviceSystem.h in Headers */, 5FCDD5202B7AC6A300EAF29F /* BNCNetworkInterface.h in Headers */, ); @@ -1269,6 +1281,7 @@ 5FCDD4D92B7AC6A200EAF29F /* BNCAppleReceipt.h in Headers */, 5FCDD5512B7AC6A300EAF29F /* BranchJsonConfig.h in Headers */, 5FCDD4E22B7AC6A200EAF29F /* BNCSKAdNetwork.h in Headers */, + E73D02862DEE8AE90076C3F1 /* BranchConfigurationController.h in Headers */, 5FCDD5122B7AC6A300EAF29F /* BNCDeviceSystem.h in Headers */, 5FCDD5212B7AC6A300EAF29F /* BNCNetworkInterface.h in Headers */, ); @@ -1627,6 +1640,7 @@ 5FCDD42C2B7AC6A100EAF29F /* BranchPluginSupport.m in Sources */, 5FCDD5A62B7AC6A400EAF29F /* BNCQRCodeCache.m in Sources */, 5FCDD45C2B7AC6A100EAF29F /* BNCReachability.m in Sources */, + E73D02842DEE8AE90076C3F1 /* BranchConfigurationController.m in Sources */, 5FCDD42F2B7AC6A100EAF29F /* NSString+Branch.m in Sources */, 5FCDD5A02B7AC6A400EAF29F /* BranchShortUrlRequest.m in Sources */, 5FCDD46B2B7AC6A100EAF29F /* BNCServerInterface.m in Sources */, @@ -1734,6 +1748,7 @@ 5FCDD42D2B7AC6A100EAF29F /* BranchPluginSupport.m in Sources */, 5FCDD5A72B7AC6A400EAF29F /* BNCQRCodeCache.m in Sources */, 5FCDD45D2B7AC6A100EAF29F /* BNCReachability.m in Sources */, + E73D02812DEE8AE90076C3F1 /* BranchConfigurationController.m in Sources */, 5FCDD4302B7AC6A100EAF29F /* NSString+Branch.m in Sources */, 5FCDD5A12B7AC6A400EAF29F /* BranchShortUrlRequest.m in Sources */, 5FCDD46C2B7AC6A100EAF29F /* BNCServerInterface.m in Sources */, @@ -1829,6 +1844,7 @@ 5FCDD44C2B7AC6A100EAF29F /* BranchContentDiscoveryManifest.m in Sources */, 5FCDD46A2B7AC6A100EAF29F /* BNCCrashlyticsWrapper.m in Sources */, 5FCDD43D2B7AC6A100EAF29F /* BNCServerRequest.m in Sources */, + E73D02852DEE8AE90076C3F1 /* BranchConfigurationController.m in Sources */, 5FCDD5842B7AC6A400EAF29F /* BranchLinkProperties.m in Sources */, 5FCDD59F2B7AC6A400EAF29F /* BranchEvent.m in Sources */, 5FCDD5812B7AC6A400EAF29F /* BNCAppleReceipt.m in Sources */, diff --git a/Sources/BranchSDK/BNCRequestFactory.m b/Sources/BranchSDK/BNCRequestFactory.m index c23f34981..226d77f07 100644 --- a/Sources/BranchSDK/BNCRequestFactory.m +++ b/Sources/BranchSDK/BNCRequestFactory.m @@ -35,6 +35,7 @@ #import "BNCReferringURLUtility.h" #import "BNCPasteboard.h" #import "BNCODMInfoCollector.h" +#import "BranchConfigurationController.h" @interface BNCRequestFactory() @@ -135,6 +136,9 @@ - (NSDictionary *)dataForInstallWithURLString:(NSString *)urlString { // Add Enhanced Web UX params [self addWebUXParams:json]; + + // Add Operation Metrics for Install only. + [self addOperationalMetrics:json]; return json; } @@ -425,6 +429,12 @@ - (void)addLocalURLToOpenJSON:(NSMutableDictionary *)json { } } +// If the client uses a UIPasteControl, force a new open to fetch the payload +- (void)addOperationalMetrics:(NSMutableDictionary *)json { + [self safeSetValue:[[BranchConfigurationController sharedInstance] getConfiguration] forKey:BRANCH_REQUEST_KEY_OPERATIONAL_METRICS onDict:json]; +} + + - (void)clearLocalURLFromStorage { self.preferenceHelper.localUrl = nil; #if !TARGET_OS_TV diff --git a/Sources/BranchSDK/Branch.m b/Sources/BranchSDK/Branch.m index ccc73de1c..e0977f8df 100644 --- a/Sources/BranchSDK/Branch.m +++ b/Sources/BranchSDK/Branch.m @@ -45,6 +45,7 @@ #import "BNCServerAPI.h" #import "BranchPluginSupport.h" #import "BranchLogger.h" +#import "BranchConfigurationController.h" #if !TARGET_OS_TV #import "BNCUserAgentCollector.h" @@ -187,6 +188,7 @@ + (Branch *)getInstance { + (Branch *)getInstance:(NSString *)branchKey { self.branchKey = branchKey; + [BranchConfigurationController sharedInstance].branchKeySource = BRANCH_KEY_SOURCE_GET_INSTANCE_API; return [Branch getInstanceInternal:self.branchKey]; } @@ -246,6 +248,7 @@ - (id)initWithInterface:(BNCServerInterface *)interface BranchJsonConfig *config = BranchJsonConfig.instance; self.deferInitForPluginRuntime = config.deferInitForPluginRuntime; + [BranchConfigurationController sharedInstance].deferInitForPluginRuntime = self.deferInitForPluginRuntime; if (config.apiUrl) { [Branch setAPIUrl:config.apiUrl]; @@ -407,7 +410,7 @@ + (void)setBranchKey:(NSString*)branchKey error:(NSError **)error { [[BranchLogger shared] logError:[NSString stringWithFormat:@"Invalid Branch key format. Did you add your Branch key to your Info.plist? Passed key is '%@'.", branchKey] error:*error]; return; } - + [BranchConfigurationController sharedInstance].branchKeySource = BRANCH_KEY_SOURCE_SET_BRANCH_KEY_API; bnc_branchKey = branchKey; } } @@ -417,13 +420,16 @@ + (NSString *)branchKey { if (bnc_branchKey) return bnc_branchKey; NSString *branchKey = nil; + NSString *branchKeySource = @"Unknown"; BranchJsonConfig *config = BranchJsonConfig.instance; BOOL usingTestInstance = bnc_useTestBranchKey || config.useTestInstance; branchKey = config.branchKey ?: usingTestInstance ? config.testKey : config.liveKey; [self setUseTestBranchKey:usingTestInstance]; - if (branchKey == nil) { + if (branchKey) { + branchKeySource = BRANCH_KEY_SOURCE_CONFIG_JSON; + } else { NSDictionary *branchDictionary = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"branch_key"]; if ([branchDictionary isKindOfClass:[NSString class]]) { branchKey = (NSString*) branchDictionary; @@ -432,12 +438,15 @@ + (NSString *)branchKey { branchKey = (self.useTestBranchKey) ? branchDictionary[@"test"] : branchDictionary[@"live"]; } + if (branchKey) + branchKeySource = BRANCH_KEY_SOURCE_INFO_PLIST; } self.branchKey = branchKey; if (!bnc_branchKey) { [[BranchLogger shared] logError:@"Your Branch key is not set in your Info.plist file. See https://dev.branch.io/getting-started/sdk-integration-guide/guide/ios/#configure-xcode-project for configuration instructions." error:nil]; } + [BranchConfigurationController sharedInstance].branchKeySource = branchKeySource; return bnc_branchKey; } } @@ -890,6 +899,7 @@ - (BOOL)continueUserActivity:(NSUserActivity *)userActivity sceneIdentifier:(NSS self.preferenceHelper.initialReferrer = userActivity.referrerURL.absoluteString; } + [[BranchLogger shared] logVerbose:userActivity.debugDescription error:nil]; // Check to see if a browser activity needs to be handled if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { return [self handleDeepLink:userActivity.webpageURL sceneIdentifier:sceneIdentifier]; @@ -998,6 +1008,7 @@ - (void)startLoadingOfODMInfo { - (void)checkPasteboardOnInstall { [BNCPasteboard sharedInstance].checkOnInstall = YES; + [BranchConfigurationController sharedInstance].checkPasteboardOnInstall = YES; } - (BOOL)willShowPasteboardToast { diff --git a/Sources/BranchSDK/BranchConfigurationController.m b/Sources/BranchSDK/BranchConfigurationController.m new file mode 100644 index 000000000..e9a0f35dc --- /dev/null +++ b/Sources/BranchSDK/BranchConfigurationController.m @@ -0,0 +1,68 @@ +// +// BranchConfigurationController.m +// BranchSDK +// +// Created by Nidhi Dixit on 6/2/25. +// + +#import "BranchConfigurationController.h" +#import "BNCPreferenceHelper.h" +#import "BranchLogger.h" +#import "BranchConstants.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation BranchConfigurationController + ++ (instancetype)sharedInstance { + static BranchConfigurationController *sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[BranchConfigurationController alloc] init]; + }); + return sharedInstance; +} + +- (NSDictionary *) branchKeyInfo { + return @{ + BRANCH_REQUEST_KEY_BRANCH_KEY_SOURCE : self.branchKeySource ? self.branchKeySource: @"Unknown", + }; +} + +- (NSDictionary *)featureFlagsInfo { + return @{ + BRANCH_REQUEST_KEY_CHECK_PASTEBOARD_ON_INSTALL: @(self.checkPasteboardOnInstall), + BRANCH_REQUEST_KEY_DEFER_INIT_FOR_PLUGIN_RUNTIME: @(self.deferInitForPluginRuntime) + }; +} + +- (NSDictionary *)frameworkIntegrationInfo { + NSMutableDictionary *info = [NSMutableDictionary new]; + + info[BRANCH_REQUEST_KEY_LINKED_FRAMEORKS] = @{ + FRAMEWORK_AD_SUPPORT: @([self isClassAvailable:@"ASIdentifierManager"]), + FRAMEWORK_ATT_TRACKING_MANAGER: @([self isClassAvailable:@"ATTrackingManager"]), + FRAMEWORK_AD_FIREBASE_CRASHLYTICS: @([self isClassAvailable:@"FIRCrashlytics"]), + FRAMEWORK_AD_SAFARI_SERVICES: @([self isClassAvailable:@"SFSafariViewController"]), + FRAMEWORK_AD_APP_ADS_ONDEVICE_CONVERSION: @([self isClassAvailable:@"ODCConversionManager"]), + }; + + return [info copy]; +} + +- (NSDictionary *) getConfiguration { + NSMutableDictionary *config = [NSMutableDictionary new]; + [config addEntriesFromDictionary:[self branchKeyInfo]]; + [config addEntriesFromDictionary:[self featureFlagsInfo]]; + [config addEntriesFromDictionary:[self frameworkIntegrationInfo]]; + return [config copy]; +} + +// helper methods +- (BOOL)isClassAvailable:(NSString *)className { + return NSClassFromString(className) != nil; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/BranchSDK/BranchConstants.m b/Sources/BranchSDK/BranchConstants.m index f72209f86..d5ee04498 100644 --- a/Sources/BranchSDK/BranchConstants.m +++ b/Sources/BranchSDK/BranchConstants.m @@ -181,3 +181,21 @@ NSString * const WEB_UX_IN_APP_WEBVIEW = @"IN_APP_WEBVIEW"; NSString * const WEB_UX_EXTERNAL_BROWSER = @"EXTERNAL_BROWSER"; + +NSString * const BRANCH_REQUEST_KEY_OPERATIONAL_METRICS = @"operational_metrics"; +NSString * const BRANCH_REQUEST_KEY_DEFER_INIT_FOR_PLUGIN_RUNTIME = @"deferInitForPluginRuntime"; +NSString * const BRANCH_REQUEST_KEY_CHECK_PASTEBOARD_ON_INSTALL= @"checkPasteboardOnInstall"; + +NSString * const BRANCH_REQUEST_KEY_BRANCH_KEY_SOURCE = @"branch_key_source"; +NSString * const BRANCH_KEY_SOURCE_UNKNOWN = @"Unknown"; +NSString * const BRANCH_KEY_SOURCE_CONFIG_JSON = @"config_json"; +NSString * const BRANCH_KEY_SOURCE_INFO_PLIST = @"info_plist"; +NSString * const BRANCH_KEY_SOURCE_GET_INSTANCE_API = @"getInstance_api"; +NSString * const BRANCH_KEY_SOURCE_SET_BRANCH_KEY_API= @"setBranchKey_api"; + +NSString * const BRANCH_REQUEST_KEY_LINKED_FRAMEORKS = @"linked_frameworks"; +NSString * const FRAMEWORK_ATT_TRACKING_MANAGER = @"ATTrackingManager"; +NSString * const FRAMEWORK_AD_SUPPORT = @"AdSupport"; +NSString * const FRAMEWORK_AD_SAFARI_SERVICES = @"SafariServices"; +NSString * const FRAMEWORK_AD_APP_ADS_ONDEVICE_CONVERSION = @"AppAdsOnDeviceConversion"; +NSString * const FRAMEWORK_AD_FIREBASE_CRASHLYTICS = @"FirebaseCrashlytics"; diff --git a/Sources/BranchSDK/Private/BranchConfigurationController.h b/Sources/BranchSDK/Private/BranchConfigurationController.h new file mode 100644 index 000000000..63ed530c3 --- /dev/null +++ b/Sources/BranchSDK/Private/BranchConfigurationController.h @@ -0,0 +1,34 @@ +// +// BranchConfigurationController.h +// BranchSDK +// +// Created by Nidhi Dixit on 6/2/25. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * The BranchConfigurationController class contains SDK configuration information. + * .This information is sent to backend as `operational_metrics` with v1/install request. + */ + +@interface BranchConfigurationController : NSObject + +@property (nonatomic, copy) NSString *branchKeySource; +@property (assign, nonatomic) BOOL deferInitForPluginRuntime; +@property (assign, nonatomic) BOOL checkPasteboardOnInstall; + ++ (instancetype)sharedInstance; + +/** + * Retrieves the current SDK configuration as a dictionary. + * + * @return An `NSDictionary` containing the current configuration values. + */ +- (NSDictionary *) getConfiguration; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/BranchSDK/Private/BranchConstants.h b/Sources/BranchSDK/Private/BranchConstants.h index c0e6e1edd..b08ec65f7 100644 --- a/Sources/BranchSDK/Private/BranchConstants.h +++ b/Sources/BranchSDK/Private/BranchConstants.h @@ -183,3 +183,22 @@ extern NSString * const BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP; extern NSString * const WEB_UX_IN_APP_WEBVIEW; extern NSString * const WEB_UX_EXTERNAL_BROWSER; + +// Operational Metrics Param Keys +extern NSString * const BRANCH_REQUEST_KEY_OPERATIONAL_METRICS; +extern NSString * const BRANCH_REQUEST_KEY_DEFER_INIT_FOR_PLUGIN_RUNTIME; +extern NSString * const BRANCH_REQUEST_KEY_CHECK_PASTEBOARD_ON_INSTALL; + +extern NSString * const BRANCH_REQUEST_KEY_BRANCH_KEY_SOURCE; +extern NSString * const BRANCH_KEY_SOURCE_UNKNOWN; +extern NSString * const BRANCH_KEY_SOURCE_GET_INSTANCE_API; +extern NSString * const BRANCH_KEY_SOURCE_SET_BRANCH_KEY_API; +extern NSString * const BRANCH_KEY_SOURCE_CONFIG_JSON; +extern NSString * const BRANCH_KEY_SOURCE_INFO_PLIST; + +extern NSString * const BRANCH_REQUEST_KEY_LINKED_FRAMEORKS; +extern NSString * const FRAMEWORK_ATT_TRACKING_MANAGER; +extern NSString * const FRAMEWORK_AD_SUPPORT; +extern NSString * const FRAMEWORK_AD_SAFARI_SERVICES; +extern NSString * const FRAMEWORK_AD_APP_ADS_ONDEVICE_CONVERSION; +extern NSString * const FRAMEWORK_AD_FIREBASE_CRASHLYTICS;