From 743763f365c1725befc29d195b8fc9feb68f6a8c Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Fri, 13 Jun 2025 09:36:54 -0700 Subject: [PATCH 01/27] Added class BranchConfigurationController to send operational_metrics with v1/install request. --- .../BranchConfigurationControllerTests.m | 100 ++++++++++++++++++ .../Branch-TestBed.xcodeproj/project.pbxproj | 12 +++ BranchSDK.xcodeproj/project.pbxproj | 16 +++ Sources/BranchSDK/BNCRequestFactory.m | 10 ++ Sources/BranchSDK/Branch.m | 16 ++- .../BranchSDK/BranchConfigurationController.m | 68 ++++++++++++ Sources/BranchSDK/BranchConstants.m | 18 ++++ .../Private/BranchConfigurationController.h | 34 ++++++ Sources/BranchSDK/Private/BranchConstants.h | 19 ++++ 9 files changed, 291 insertions(+), 2 deletions(-) create mode 100644 Branch-TestBed/Branch-SDK-Tests/BranchConfigurationControllerTests.m create mode 100644 Sources/BranchSDK/BranchConfigurationController.m create mode 100644 Sources/BranchSDK/Private/BranchConfigurationController.h 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..b2c3a2cbb 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" @@ -166,6 +167,7 @@ @interface Branch() { @property (nonatomic, assign, readwrite) BOOL deferInitForPluginRuntime; @property (nonatomic, copy, nullable) void (^cachedInitBlock)(void); @property (nonatomic, copy, readwrite) NSString *cachedURLString; +@property (strong, nonatomic) BranchConfigurationController *configurationController; @end @@ -187,6 +189,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 +249,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 +411,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 +421,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 +439,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 +900,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 +1009,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..8da3c73c4 --- /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: @"Unkown", + }; +} + +- (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; From fcf93444314bf03f1920a83ea9ed96d82e1587e0 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Fri, 13 Jun 2025 09:42:44 -0700 Subject: [PATCH 02/27] Removed unused property configurationController. --- Sources/BranchSDK/Branch.m | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/BranchSDK/Branch.m b/Sources/BranchSDK/Branch.m index b2c3a2cbb..e0977f8df 100644 --- a/Sources/BranchSDK/Branch.m +++ b/Sources/BranchSDK/Branch.m @@ -167,7 +167,6 @@ @interface Branch() { @property (nonatomic, assign, readwrite) BOOL deferInitForPluginRuntime; @property (nonatomic, copy, nullable) void (^cachedInitBlock)(void); @property (nonatomic, copy, readwrite) NSString *cachedURLString; -@property (strong, nonatomic) BranchConfigurationController *configurationController; @end From 53af9f89d92a952352cf7e6a66e0b414bea6cbe4 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Tue, 17 Jun 2025 08:46:08 -0700 Subject: [PATCH 03/27] Fixed typo error. --- Sources/BranchSDK/BranchConfigurationController.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BranchSDK/BranchConfigurationController.m b/Sources/BranchSDK/BranchConfigurationController.m index 8da3c73c4..e9a0f35dc 100644 --- a/Sources/BranchSDK/BranchConfigurationController.m +++ b/Sources/BranchSDK/BranchConfigurationController.m @@ -25,7 +25,7 @@ + (instancetype)sharedInstance { - (NSDictionary *) branchKeyInfo { return @{ - BRANCH_REQUEST_KEY_BRANCH_KEY_SOURCE : self.branchKeySource ? self.branchKeySource: @"Unkown", + BRANCH_REQUEST_KEY_BRANCH_KEY_SOURCE : self.branchKeySource ? self.branchKeySource: @"Unknown", }; } From 5005b0fd5b37babaa498a11ed390508c93a9f356 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Tue, 24 Jun 2025 13:26:11 -0700 Subject: [PATCH 04/27] Converted class BranchConfigurationController to Swift. --- BranchSDK.xcodeproj/project.pbxproj | 57 ++++++++++----- Framework/BranchSDK.h | 1 + Sources/BranchSDK/BNCRequestFactory.m | 4 +- Sources/BranchSDK/Branch.m | 13 ++-- .../BranchSDK/BranchConfigurationController.m | 68 ------------------ .../Private/BranchConfigurationController.h | 34 --------- Sources/BranchSDK/Public/Branch.h | 1 + .../{Private => Public}/BranchConstants.h | 0 Sources/BranchSDK/Public/BranchSDK.h | 2 + .../ConfigurationController.swift | 70 +++++++++++++++++++ 10 files changed, 121 insertions(+), 129 deletions(-) delete mode 100644 Sources/BranchSDK/BranchConfigurationController.m delete mode 100644 Sources/BranchSDK/Private/BranchConfigurationController.h rename Sources/BranchSDK/{Private => Public}/BranchConstants.h (100%) create mode 100644 Sources/BranchSDK_Swift/ConfigurationController.swift diff --git a/BranchSDK.xcodeproj/project.pbxproj b/BranchSDK.xcodeproj/project.pbxproj index 74de0d1d8..596b4d1da 100644 --- a/BranchSDK.xcodeproj/project.pbxproj +++ b/BranchSDK.xcodeproj/project.pbxproj @@ -383,7 +383,7 @@ 5FCDD5462B7AC6A300EAF29F /* BNCConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DB2B7AC6A100EAF29F /* BNCConfig.h */; }; 5FCDD5472B7AC6A300EAF29F /* BNCConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DB2B7AC6A100EAF29F /* BNCConfig.h */; }; 5FCDD5482B7AC6A300EAF29F /* BNCConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DB2B7AC6A100EAF29F /* BNCConfig.h */; }; - 5FCDD5492B7AC6A300EAF29F /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */; }; + 5FCDD5492B7AC6A300EAF29F /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5FCDD54A2B7AC6A300EAF29F /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */; }; 5FCDD54B2B7AC6A300EAF29F /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */; }; 5FCDD54C2B7AC6A300EAF29F /* BNCPartnerParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DD2B7AC6A100EAF29F /* BNCPartnerParameters.h */; }; @@ -499,12 +499,9 @@ 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 */; }; + E7931D842E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; + E7931D852E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; + E7931D862E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; 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 */; }; @@ -681,7 +678,7 @@ 5FCDD3D92B7AC6A100EAF29F /* BranchSpotlightUrlRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchSpotlightUrlRequest.h; sourceTree = ""; }; 5FCDD3DA2B7AC6A100EAF29F /* BranchContentDiscoveryManifest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchContentDiscoveryManifest.h; sourceTree = ""; }; 5FCDD3DB2B7AC6A100EAF29F /* BNCConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCConfig.h; sourceTree = ""; }; - 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchConstants.h; sourceTree = ""; }; + 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BranchConstants.h; path = ../Public/BranchConstants.h; sourceTree = ""; }; 5FCDD3DD2B7AC6A100EAF29F /* BNCPartnerParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCPartnerParameters.h; sourceTree = ""; }; 5FCDD3DE2B7AC6A100EAF29F /* BranchJsonConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchJsonConfig.h; sourceTree = ""; }; 5FCDD3DF2B7AC6A100EAF29F /* BranchLATDRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchLATDRequest.h; sourceTree = ""; }; @@ -723,8 +720,7 @@ 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 = ""; }; + E7931D832E01C8AE0007A374 /* ConfigurationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ConfigurationController.swift; path = ../BranchSDK_Swift/ConfigurationController.swift; 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 */ @@ -840,6 +836,7 @@ 5FCDD36B2B7AC6A100EAF29F /* BranchSDK */ = { isa = PBXGroup; children = ( + E7931D832E01C8AE0007A374 /* ConfigurationController.swift */, E71E396E2DD3A92900110F59 /* BNCInAppBrowser.m */, E52E5B092CC79E5C00F553EE /* BranchFileLogger.m */, 5FCDD3F62B7AC6A100EAF29F /* BNCAppGroupsData.m */, @@ -912,7 +909,6 @@ 5FCDD3732B7AC6A100EAF29F /* NSMutableDictionary+Branch.m */, 5FCDD37C2B7AC6A100EAF29F /* NSString+Branch.m */, 5FCDD3F52B7AC6A100EAF29F /* UIViewController+Branch.m */, - E73D02802DEE8AE90076C3F1 /* BranchConfigurationController.m */, 5FCDD3B42B7AC6A100EAF29F /* Private */, 5FCDD3982B7AC6A100EAF29F /* Public */, ); @@ -1006,7 +1002,6 @@ E52E5B052CC79E4E00F553EE /* BranchFileLogger.h */, 5FCDD3BB2B7AC6A100EAF29F /* UIViewController+Branch.h */, E71E396D2DD3A92900110F59 /* BNCInAppBrowser.h */, - E73D027F2DEE8AE90076C3F1 /* BranchConfigurationController.h */, ); path = Private; sourceTree = ""; @@ -1039,6 +1034,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 5FCDD5492B7AC6A300EAF29F /* BranchConstants.h in Headers */, 5FCDD52E2B7AC6A300EAF29F /* Branch+Validator.h in Headers */, 5FCDD4A42B7AC6A200EAF29F /* BNCCallbacks.h in Headers */, 5FCDD4922B7AC6A100EAF29F /* BranchLinkProperties.h in Headers */, @@ -1071,7 +1067,6 @@ 5FCDD5462B7AC6A300EAF29F /* BNCConfig.h in Headers */, 5FCDD4E62B7AC6A200EAF29F /* UIViewController+Branch.h in Headers */, 5F5FDA1A2B7DE31E00F14A43 /* BranchLogger.h in Headers */, - 5FCDD5492B7AC6A300EAF29F /* BranchConstants.h in Headers */, E7F311B22DACB54100F824A7 /* BNCODMInfoCollector.h in Headers */, 5FCDD5402B7AC6A300EAF29F /* BranchSpotlightUrlRequest.h in Headers */, 5FCDD5552B7AC6A300EAF29F /* BNCCrashlyticsWrapper.h in Headers */, @@ -1113,7 +1108,6 @@ 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 */, ); @@ -1197,7 +1191,6 @@ 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 */, ); @@ -1281,7 +1274,6 @@ 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 */, ); @@ -1411,6 +1403,7 @@ TargetAttributes = { 5F22101C2894A0DB00C5B190 = { CreatedOnToolsVersion = 13.4.1; + LastSwiftMigration = 1640; }; 5F2211672894A90500C5B190 = { CreatedOnToolsVersion = 13.4.1; @@ -1429,9 +1422,11 @@ }; 5F73EBF328ECE65400608601 = { CreatedOnToolsVersion = 14.0; + LastSwiftMigration = 1640; }; 5F79038B28B5765D003144CD = { CreatedOnToolsVersion = 13.4.1; + LastSwiftMigration = 1640; }; 5FF9DEEC28EE7C0D00D62DE1 = { CreatedOnToolsVersion = 14.0; @@ -1624,6 +1619,7 @@ 5FCDD4652B7AC6A100EAF29F /* BNCProductCategory.m in Sources */, 5FCDD56A2B7AC6A400EAF29F /* Branch.m in Sources */, 5FCDD4292B7AC6A100EAF29F /* BranchInstallRequest.m in Sources */, + E7931D862E01C8AE0007A374 /* ConfigurationController.swift in Sources */, 5FCDD4262B7AC6A100EAF29F /* Branch+Validator.m in Sources */, 5FCDD4022B7AC6A100EAF29F /* BNCUserAgentCollector.m in Sources */, 5FCDD5762B7AC6A400EAF29F /* BNCSKAdNetwork.m in Sources */, @@ -1640,7 +1636,6 @@ 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 */, @@ -1732,6 +1727,7 @@ 5FCDD4662B7AC6A100EAF29F /* BNCProductCategory.m in Sources */, 5FCDD56B2B7AC6A400EAF29F /* Branch.m in Sources */, 5FCDD42A2B7AC6A100EAF29F /* BranchInstallRequest.m in Sources */, + E7931D852E01C8AE0007A374 /* ConfigurationController.swift in Sources */, 5FCDD4272B7AC6A100EAF29F /* Branch+Validator.m in Sources */, 5FCDD4032B7AC6A100EAF29F /* BNCUserAgentCollector.m in Sources */, 5FCDD5772B7AC6A400EAF29F /* BNCSKAdNetwork.m in Sources */, @@ -1748,7 +1744,6 @@ 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 */, @@ -1842,9 +1837,9 @@ 5FCDD5A52B7AC6A400EAF29F /* BranchOpenRequest.m in Sources */, 5FCDD5692B7AC6A400EAF29F /* BNCLinkData.m in Sources */, 5FCDD44C2B7AC6A100EAF29F /* BranchContentDiscoveryManifest.m in Sources */, + E7931D842E01C8AE0007A374 /* ConfigurationController.swift 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 */, @@ -2016,6 +2011,8 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(MARKETING_VERSION)"; DEFINES_MODULE = YES; @@ -2043,6 +2040,9 @@ "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -2051,6 +2051,8 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(MARKETING_VERSION)"; DEFINES_MODULE = YES; @@ -2078,6 +2080,8 @@ "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; @@ -2255,7 +2259,9 @@ 5F73EBFD28ECE65400608601 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(MARKETING_VERSION)"; DEFINES_MODULE = YES; @@ -2285,6 +2291,7 @@ SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -2294,7 +2301,9 @@ 5F73EBFE28ECE65400608601 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(MARKETING_VERSION)"; DEFINES_MODULE = YES; @@ -2324,6 +2333,7 @@ SKIP_INSTALL = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -2333,6 +2343,8 @@ 5F79039128B5765D003144CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(MARKETING_VERSION)"; DEFINES_MODULE = YES; @@ -2360,6 +2372,9 @@ SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 12.0; }; @@ -2368,6 +2383,8 @@ 5F79039228B5765D003144CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(MARKETING_VERSION)"; DEFINES_MODULE = YES; @@ -2395,6 +2412,8 @@ SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 12.0; }; diff --git a/Framework/BranchSDK.h b/Framework/BranchSDK.h index f28711897..6f0f795e9 100644 --- a/Framework/BranchSDK.h +++ b/Framework/BranchSDK.h @@ -58,3 +58,4 @@ FOUNDATION_EXPORT const unsigned char BranchSDKVersionString[]; // BNCLinkCache.h uses BNCLinkData.h #import +#import diff --git a/Sources/BranchSDK/BNCRequestFactory.m b/Sources/BranchSDK/BNCRequestFactory.m index 226d77f07..85ee9fda4 100644 --- a/Sources/BranchSDK/BNCRequestFactory.m +++ b/Sources/BranchSDK/BNCRequestFactory.m @@ -35,7 +35,7 @@ #import "BNCReferringURLUtility.h" #import "BNCPasteboard.h" #import "BNCODMInfoCollector.h" -#import "BranchConfigurationController.h" +#import "BranchSDK/BranchSDK-Swift.h" @interface BNCRequestFactory() @@ -431,7 +431,7 @@ - (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]; + [self safeSetValue:[[ConfigurationController shared] getConfiguration] forKey:BRANCH_REQUEST_KEY_OPERATIONAL_METRICS onDict:json]; } diff --git a/Sources/BranchSDK/Branch.m b/Sources/BranchSDK/Branch.m index e0977f8df..57711292f 100644 --- a/Sources/BranchSDK/Branch.m +++ b/Sources/BranchSDK/Branch.m @@ -45,7 +45,8 @@ #import "BNCServerAPI.h" #import "BranchPluginSupport.h" #import "BranchLogger.h" -#import "BranchConfigurationController.h" +#import "BranchSDK/BranchSDK-Swift.h" + #if !TARGET_OS_TV #import "BNCUserAgentCollector.h" @@ -188,7 +189,7 @@ + (Branch *)getInstance { + (Branch *)getInstance:(NSString *)branchKey { self.branchKey = branchKey; - [BranchConfigurationController sharedInstance].branchKeySource = BRANCH_KEY_SOURCE_GET_INSTANCE_API; + [ConfigurationController shared].branchKeySource = BRANCH_KEY_SOURCE_GET_INSTANCE_API; return [Branch getInstanceInternal:self.branchKey]; } @@ -248,7 +249,7 @@ - (id)initWithInterface:(BNCServerInterface *)interface BranchJsonConfig *config = BranchJsonConfig.instance; self.deferInitForPluginRuntime = config.deferInitForPluginRuntime; - [BranchConfigurationController sharedInstance].deferInitForPluginRuntime = self.deferInitForPluginRuntime; + [ConfigurationController shared].deferInitForPluginRuntime = self.deferInitForPluginRuntime; if (config.apiUrl) { [Branch setAPIUrl:config.apiUrl]; @@ -410,7 +411,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; + [ConfigurationController shared].branchKeySource = BRANCH_KEY_SOURCE_SET_BRANCH_KEY_API; bnc_branchKey = branchKey; } } @@ -446,7 +447,7 @@ + (NSString *)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; + [ConfigurationController shared].branchKeySource = branchKeySource; return bnc_branchKey; } } @@ -1008,7 +1009,7 @@ - (void)startLoadingOfODMInfo { - (void)checkPasteboardOnInstall { [BNCPasteboard sharedInstance].checkOnInstall = YES; - [BranchConfigurationController sharedInstance].checkPasteboardOnInstall = YES; + [ConfigurationController shared].checkPasteboardOnInstall = YES; } - (BOOL)willShowPasteboardToast { diff --git a/Sources/BranchSDK/BranchConfigurationController.m b/Sources/BranchSDK/BranchConfigurationController.m deleted file mode 100644 index e9a0f35dc..000000000 --- a/Sources/BranchSDK/BranchConfigurationController.m +++ /dev/null @@ -1,68 +0,0 @@ -// -// 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/Private/BranchConfigurationController.h b/Sources/BranchSDK/Private/BranchConfigurationController.h deleted file mode 100644 index 63ed530c3..000000000 --- a/Sources/BranchSDK/Private/BranchConfigurationController.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// 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/Public/Branch.h b/Sources/BranchSDK/Public/Branch.h index 75ca5f03a..328b302b9 100644 --- a/Sources/BranchSDK/Public/Branch.h +++ b/Sources/BranchSDK/Public/Branch.h @@ -49,6 +49,7 @@ //#import "NSError+Branch.h" //#import "BranchConstants.h" //#import "UIViewController+Branch.h" +#import "BranchConstants.h" NS_ASSUME_NONNULL_BEGIN diff --git a/Sources/BranchSDK/Private/BranchConstants.h b/Sources/BranchSDK/Public/BranchConstants.h similarity index 100% rename from Sources/BranchSDK/Private/BranchConstants.h rename to Sources/BranchSDK/Public/BranchConstants.h diff --git a/Sources/BranchSDK/Public/BranchSDK.h b/Sources/BranchSDK/Public/BranchSDK.h index e4914c80a..bd9d758cd 100644 --- a/Sources/BranchSDK/Public/BranchSDK.h +++ b/Sources/BranchSDK/Public/BranchSDK.h @@ -58,3 +58,5 @@ FOUNDATION_EXPORT const unsigned char BranchSDKVersionString[]; // BNCLinkCache.h uses BNCLinkData.h #import "BNCLinkData.h" + +#import "BranchConstants.h" diff --git a/Sources/BranchSDK_Swift/ConfigurationController.swift b/Sources/BranchSDK_Swift/ConfigurationController.swift new file mode 100644 index 000000000..da6d85faa --- /dev/null +++ b/Sources/BranchSDK_Swift/ConfigurationController.swift @@ -0,0 +1,70 @@ +// +// ConfigurationController.swift +// BranchSDK +// +// Created by Nidhi Dixit on 6/17/25. +// + + +import Foundation + +@objcMembers +public class ConfigurationController: NSObject { + + // MARK: - Properties + public var branchKeySource: String? + public var deferInitForPluginRuntime: Bool = false + public var checkPasteboardOnInstall: Bool = false + + // MARK: - Singleton + @MainActor public static let shared = ConfigurationController() + + private override init() { + // Private initializer to enforce singleton usage. + super.init() + } + + public func getConfiguration() -> [String: Any] { + var config: [String: Any] = [:] + + config.merge(branchKeyInfo()) { (_, new) in new } + config.merge(featureFlagsInfo()) { (_, new) in new } + config.merge(frameworkIntegrationInfo()) { (_, new) in new } + + return config + } + + // MARK: - Private Helper Methods + private func branchKeyInfo() -> [String: String] { + return [ + BRANCH_REQUEST_KEY_BRANCH_KEY_SOURCE: self.branchKeySource ?? "Unknown" + ] + } + + private func featureFlagsInfo() -> [String: Bool] { + return [ + BRANCH_REQUEST_KEY_CHECK_PASTEBOARD_ON_INSTALL: self.checkPasteboardOnInstall, + BRANCH_REQUEST_KEY_DEFER_INIT_FOR_PLUGIN_RUNTIME: self.deferInitForPluginRuntime + ] + } + + private func frameworkIntegrationInfo() -> [String: Any] { + var info: [String: Any] = [:] + + let linkedFrameworks: [String: Bool] = [ + FRAMEWORK_AD_SUPPORT: isClassAvailable(className: "ASIdentifierManager"), + FRAMEWORK_ATT_TRACKING_MANAGER: isClassAvailable(className: "ATTrackingManager"), + FRAMEWORK_AD_FIREBASE_CRASHLYTICS: isClassAvailable(className: "FIRCrashlytics"), + FRAMEWORK_AD_SAFARI_SERVICES: isClassAvailable(className: "SFSafariViewController"), + FRAMEWORK_AD_APP_ADS_ONDEVICE_CONVERSION: isClassAvailable(className: "ODCConversionManager") + ] + + info[BRANCH_REQUEST_KEY_LINKED_FRAMEORKS] = linkedFrameworks + + return info + } + + private func isClassAvailable(className: String) -> Bool { + return NSClassFromString(className) != nil + } +} From dc2d9c7319811f9dfa22d7859bd494d4020acfe0 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Tue, 24 Jun 2025 15:48:32 -0700 Subject: [PATCH 05/27] Added target for swift code. --- Package.swift | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Package.swift b/Package.swift index 0ae916e32..2743e8572 100644 --- a/Package.swift +++ b/Package.swift @@ -1,9 +1,9 @@ -// swift-tools-version:5.3 +// swift-tools-version:5.9 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( - name: "BranchSDK", + name: "ios-branch-deep-linking-attribution", platforms: [ .iOS(.v12), .tvOS(.v12), @@ -18,16 +18,17 @@ let package = Package( targets: [ .target( name: "BranchSDK", - path: "Sources", - sources: [ - "BranchSDK/" + dependencies: [ + "BranchSDK_Swift" ], + path: "Sources/BranchSDK", resources: [ - .copy("Resources/PrivacyInfo.xcprivacy"), + .copy("../Resources/PrivacyInfo.xcprivacy"), ], - publicHeadersPath: "BranchSDK/Public/", + publicHeadersPath: "Public", cSettings: [ - .headerSearchPath("BranchSDK/Private"), + .headerSearchPath("."), + .headerSearchPath("Private") ], linkerSettings: [ .linkedFramework("CoreServices"), @@ -37,5 +38,9 @@ let package = Package( .linkedFramework("AdServices", .when(platforms: [.iOS])) ] ), + .target( + name: "BranchSDK_Swift", + path: "Sources/BranchSDK_Swift", + ), ] ) From 0ad45647ea755bec8e95085eea33b1a2b63ea767 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Tue, 24 Jun 2025 22:47:13 -0700 Subject: [PATCH 06/27] Updated swift version. --- BranchSDK.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/BranchSDK.xcodeproj/project.pbxproj b/BranchSDK.xcodeproj/project.pbxproj index 596b4d1da..0be4ece30 100644 --- a/BranchSDK.xcodeproj/project.pbxproj +++ b/BranchSDK.xcodeproj/project.pbxproj @@ -2042,7 +2042,7 @@ SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -2081,7 +2081,7 @@ SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; @@ -2374,7 +2374,7 @@ SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 12.0; }; @@ -2413,7 +2413,7 @@ SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 12.0; }; From 49022015de6d60d0698d0a7c487ee4f7a42e180b Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Tue, 24 Jun 2025 22:54:34 -0700 Subject: [PATCH 07/27] Updated GH runner OS version number. --- .github/workflows/pre-release-qa.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/pre-release-qa.yml b/.github/workflows/pre-release-qa.yml index 0a2d30548..34b0bffa1 100644 --- a/.github/workflows/pre-release-qa.yml +++ b/.github/workflows/pre-release-qa.yml @@ -4,7 +4,7 @@ on: [push] jobs: verify-cocoapods-iOS: - runs-on: macos-latest + runs-on: macos-15 steps: - name: Check out code uses: actions/checkout@v4 @@ -33,7 +33,7 @@ jobs: carthage update --use-xcframeworks xcodebuild test -scheme iOSReleaseTest -project iOSReleaseTest.xcodeproj -destination "$DESTINATION" | xcpretty && exit ${PIPESTATUS[0]} verify-SPM-iOS: - runs-on: macos-latest + runs-on: macos-15 steps: - name: Check out code uses: actions/checkout@v4 @@ -44,7 +44,7 @@ jobs: cd SDKIntegrationTestApps/iOSReleaseTest-SPM/ xcodebuild test -scheme iOSReleaseTest -project iOSReleaseTest.xcodeproj -destination "$DESTINATION" | xcpretty && exit ${PIPESTATUS[0]} verify-manually-with-xcframework-iOS: - runs-on: macos-latest + runs-on: macos-15 steps: - name: Check out code uses: actions/checkout@v4 @@ -56,7 +56,7 @@ jobs: cd SDKIntegrationTestApps/iOSReleaseTest-Manual/ xcodebuild test -scheme iOSReleaseTest -project iOSReleaseTest.xcodeproj -destination "$DESTINATION" | xcpretty && exit ${PIPESTATUS[0]} verify-manually-with-StaticFramework-iOS: - runs-on: macos-latest + runs-on: macos-15 steps: - name: Check out code uses: actions/checkout@v4 @@ -68,7 +68,7 @@ jobs: cd SDKIntegrationTestApps/iOSReleaseTest-Manual-Static/ xcodebuild test -scheme iOSReleaseTest -project iOSReleaseTest.xcodeproj -destination "$DESTINATION" | xcpretty && exit ${PIPESTATUS[0]} verify-cocoapods-tvOS: - runs-on: macos-latest + runs-on: macos-15 steps: - name: Check out code uses: actions/checkout@v4 @@ -80,7 +80,7 @@ jobs: pod install xcodebuild test -scheme tvOSReleaseTest -workspace tvOSReleaseTest.xcworkspace -destination "$DESTINATION" | xcpretty && exit ${PIPESTATUS[0]} verify-carthage-tvOS: - runs-on: macos-latest + runs-on: macos-15 steps: - name: Check out code uses: actions/checkout@v4 @@ -91,7 +91,7 @@ jobs: cd SDKIntegrationTestApps/tvOSReleaseTest-Carthage/ echo "Skipping it ... its broken" verify-manually-with-xcframework-tvOS: - runs-on: macos-latest + runs-on: macos-15 steps: - name: Check out code uses: actions/checkout@v4 From 7dbd73b90a307f2870a6ae3f7b205b8bfa437b37 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Tue, 24 Jun 2025 22:57:41 -0700 Subject: [PATCH 08/27] Removed extra comma --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 2743e8572..43976fb80 100644 --- a/Package.swift +++ b/Package.swift @@ -40,7 +40,7 @@ let package = Package( ), .target( name: "BranchSDK_Swift", - path: "Sources/BranchSDK_Swift", + path: "Sources/BranchSDK_Swift" ), ] ) From 53d322c4a8e2f26553fabb55bf9a9adcf789d0f9 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Tue, 24 Jun 2025 23:37:12 -0700 Subject: [PATCH 09/27] Revert "Updated swift version." This reverts commit 0ad45647ea755bec8e95085eea33b1a2b63ea767. --- BranchSDK.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/BranchSDK.xcodeproj/project.pbxproj b/BranchSDK.xcodeproj/project.pbxproj index 0be4ece30..596b4d1da 100644 --- a/BranchSDK.xcodeproj/project.pbxproj +++ b/BranchSDK.xcodeproj/project.pbxproj @@ -2042,7 +2042,7 @@ SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -2081,7 +2081,7 @@ SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; @@ -2374,7 +2374,7 @@ SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 12.0; }; @@ -2413,7 +2413,7 @@ SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 12.0; }; From d34fed1e8f516effcccfa3ee23323bf9a7e0c499 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Wed, 25 Jun 2025 14:46:30 -0700 Subject: [PATCH 10/27] Update Package.swift --- Package.swift | 55 ++++++++++++++++----------------------------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/Package.swift b/Package.swift index 43976fb80..eb62317ab 100644 --- a/Package.swift +++ b/Package.swift @@ -5,42 +5,21 @@ import PackageDescription let package = Package( name: "ios-branch-deep-linking-attribution", platforms: [ - .iOS(.v12), - .tvOS(.v12), - ], - products: [ - .library( - name: "BranchSDK", - targets: ["BranchSDK"]), - ], - dependencies: [ - ], - targets: [ - .target( - name: "BranchSDK", - dependencies: [ - "BranchSDK_Swift" - ], - path: "Sources/BranchSDK", - resources: [ - .copy("../Resources/PrivacyInfo.xcprivacy"), - ], - publicHeadersPath: "Public", - cSettings: [ - .headerSearchPath("."), - .headerSearchPath("Private") - ], - linkerSettings: [ - .linkedFramework("CoreServices"), - .linkedFramework("SystemConfiguration"), - .linkedFramework("WebKit", .when(platforms: [.iOS])), - .linkedFramework("CoreSpotlight", .when(platforms: [.iOS])), - .linkedFramework("AdServices", .when(platforms: [.iOS])) - ] - ), - .target( - name: "BranchSDK_Swift", - path: "Sources/BranchSDK_Swift" - ), - ] + .iOS(.v13), + .tvOS(.v13), + ], + products: [ + .library( + name: "BranchSDK", + targets: ["BranchSDKBinary"] + ), + ], + targets: [ + .binaryTarget( + name: "BranchSDKBinary", + url: "https://github.com/NidhiDixit09/nidhidixit09.github.io/raw/refs/heads/main/Branch.zip", + checksum: "ac2fe6717dda43cc2e9674f549937a6ab487447698451e4c2a823b6b26ce16ac" + ) + + ] ) From 46330e089172bcffe6ea98572ce0f7dc3e7ae921 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Wed, 25 Jun 2025 14:46:54 -0700 Subject: [PATCH 11/27] Reapply "Updated swift version." This reverts commit 53d322c4a8e2f26553fabb55bf9a9adcf789d0f9. --- BranchSDK.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/BranchSDK.xcodeproj/project.pbxproj b/BranchSDK.xcodeproj/project.pbxproj index 596b4d1da..0be4ece30 100644 --- a/BranchSDK.xcodeproj/project.pbxproj +++ b/BranchSDK.xcodeproj/project.pbxproj @@ -2042,7 +2042,7 @@ SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -2081,7 +2081,7 @@ SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; @@ -2374,7 +2374,7 @@ SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 12.0; }; @@ -2413,7 +2413,7 @@ SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_VERSION = 6.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 12.0; }; From ef025f1e853c2caadfd78ff6f776cb68e853d509 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Wed, 25 Jun 2025 14:50:15 -0700 Subject: [PATCH 12/27] Update Package.swift --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index eb62317ab..b4a005088 100644 --- a/Package.swift +++ b/Package.swift @@ -18,7 +18,7 @@ let package = Package( .binaryTarget( name: "BranchSDKBinary", url: "https://github.com/NidhiDixit09/nidhidixit09.github.io/raw/refs/heads/main/Branch.zip", - checksum: "ac2fe6717dda43cc2e9674f549937a6ab487447698451e4c2a823b6b26ce16ac" + checksum: "23f2d42a54ed9c14e4bc1ec93c8b28f5c66c68b26988692a1c154efa1710d868" ) ] From d68dd4a6f132a12085356051ed15bba8c8af4736 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Wed, 25 Jun 2025 15:02:17 -0700 Subject: [PATCH 13/27] Update Branch.h --- Sources/BranchSDK/Public/Branch.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/BranchSDK/Public/Branch.h b/Sources/BranchSDK/Public/Branch.h index 328b302b9..75ca5f03a 100644 --- a/Sources/BranchSDK/Public/Branch.h +++ b/Sources/BranchSDK/Public/Branch.h @@ -49,7 +49,6 @@ //#import "NSError+Branch.h" //#import "BranchConstants.h" //#import "UIViewController+Branch.h" -#import "BranchConstants.h" NS_ASSUME_NONNULL_BEGIN From b21728000045d3dfbfc6fbd3a79a388aa23f13b6 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Wed, 25 Jun 2025 15:12:46 -0700 Subject: [PATCH 14/27] Update project.pbxproj --- BranchSDK.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/BranchSDK.xcodeproj/project.pbxproj b/BranchSDK.xcodeproj/project.pbxproj index 0be4ece30..f811063a8 100644 --- a/BranchSDK.xcodeproj/project.pbxproj +++ b/BranchSDK.xcodeproj/project.pbxproj @@ -384,8 +384,7 @@ 5FCDD5472B7AC6A300EAF29F /* BNCConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DB2B7AC6A100EAF29F /* BNCConfig.h */; }; 5FCDD5482B7AC6A300EAF29F /* BNCConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DB2B7AC6A100EAF29F /* BNCConfig.h */; }; 5FCDD5492B7AC6A300EAF29F /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5FCDD54A2B7AC6A300EAF29F /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */; }; - 5FCDD54B2B7AC6A300EAF29F /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */; }; + 5FCDD54B2B7AC6A300EAF29F /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5FCDD54C2B7AC6A300EAF29F /* BNCPartnerParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DD2B7AC6A100EAF29F /* BNCPartnerParameters.h */; }; 5FCDD54D2B7AC6A300EAF29F /* BNCPartnerParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DD2B7AC6A100EAF29F /* BNCPartnerParameters.h */; }; 5FCDD54E2B7AC6A300EAF29F /* BNCPartnerParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DD2B7AC6A100EAF29F /* BNCPartnerParameters.h */; }; @@ -502,6 +501,7 @@ E7931D842E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; E7931D852E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; E7931D862E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; + E7A7F2922E0CAB61001FBADE /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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 */; }; @@ -1119,6 +1119,7 @@ files = ( 5FCDD52F2B7AC6A300EAF29F /* Branch+Validator.h in Headers */, 5FCDD4A52B7AC6A200EAF29F /* BNCCallbacks.h in Headers */, + E7A7F2922E0CAB61001FBADE /* BranchConstants.h in Headers */, 5FCDD4932B7AC6A100EAF29F /* BranchLinkProperties.h in Headers */, 5FCDD4C92B7AC6A200EAF29F /* BranchScene.h in Headers */, 5FCDD4A82B7AC6A200EAF29F /* BranchShareLink.h in Headers */, @@ -1151,7 +1152,6 @@ 5F5FDA1B2B7DE31E00F14A43 /* BranchLogger.h in Headers */, 5FCDD4E72B7AC6A200EAF29F /* UIViewController+Branch.h in Headers */, E7F311B12DACB54100F824A7 /* BNCODMInfoCollector.h in Headers */, - 5FCDD54A2B7AC6A300EAF29F /* BranchConstants.h in Headers */, 5FCDD5412B7AC6A300EAF29F /* BranchSpotlightUrlRequest.h in Headers */, 5FCDD5562B7AC6A300EAF29F /* BNCCrashlyticsWrapper.h in Headers */, 5FCDD52C2B7AC6A300EAF29F /* BranchInstallRequest.h in Headers */, @@ -1227,11 +1227,11 @@ 5FCDD4A32B7AC6A200EAF29F /* BNCServerResponse.h in Headers */, 5FCDD4C42B7AC6A200EAF29F /* BranchDeepLinkingController.h in Headers */, 5FCDD4A02B7AC6A200EAF29F /* Branch.h in Headers */, + 5FCDD54B2B7AC6A300EAF29F /* BranchConstants.h in Headers */, 5FCDD5092B7AC6A300EAF29F /* BNCUrlQueryParameter.h in Headers */, 5FCDD5482B7AC6A300EAF29F /* BNCConfig.h in Headers */, E563942E2CC7A8E600E18E65 /* BranchFileLogger.h in Headers */, 5FCDD4E82B7AC6A200EAF29F /* UIViewController+Branch.h in Headers */, - 5FCDD54B2B7AC6A300EAF29F /* BranchConstants.h in Headers */, 5F5FDA1C2B7DE31E00F14A43 /* BranchLogger.h in Headers */, E7F311B32DACB54100F824A7 /* BNCODMInfoCollector.h in Headers */, 5FCDD5422B7AC6A300EAF29F /* BranchSpotlightUrlRequest.h in Headers */, From fd32ed3baf48b38b202218e8704c649c7a394d6d Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Wed, 25 Jun 2025 15:20:02 -0700 Subject: [PATCH 15/27] Update BranchSDK.podspec --- BranchSDK.podspec | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/BranchSDK.podspec b/BranchSDK.podspec index 35ff4cca3..98ede3fde 100644 --- a/BranchSDK.podspec +++ b/BranchSDK.podspec @@ -18,8 +18,10 @@ Use the Branch SDK (branch.io) to create and power the links that point back to s.ios.deployment_target = '12.0' s.tvos.deployment_target = '12.0' + s.swift_versions = ['5.0', '5.1', '5.2', '5.3', '5.4', '5.5', '5.6', '5.7', '5.8', '5.9', '6.0'] + s.resource_bundles = { 'BranchSDK' => 'Sources/Resources/*.xcprivacy' } - s.ios.source_files = "Sources/BranchSDK/**/*.{h,m}" + s.ios.source_files = "Sources/BranchSDK/**/*.{h,m}", "Sources/BranchSDK_Swift/**/*.swift" s.tvos.source_files = "Sources/BranchSDK/**/*.{h,m}" s.tvos.exclude_files = "Sources/BranchSDK/**/BNCContentDiscoveryManager.{h,m}", From 11f5b060bd0d2e99cfd6243af9a4dc05b5f2b157 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Wed, 25 Jun 2025 15:24:11 -0700 Subject: [PATCH 16/27] Update BranchSDK.podspec --- BranchSDK.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BranchSDK.podspec b/BranchSDK.podspec index 98ede3fde..b5750d40c 100644 --- a/BranchSDK.podspec +++ b/BranchSDK.podspec @@ -23,7 +23,7 @@ Use the Branch SDK (branch.io) to create and power the links that point back to s.resource_bundles = { 'BranchSDK' => 'Sources/Resources/*.xcprivacy' } s.ios.source_files = "Sources/BranchSDK/**/*.{h,m}", "Sources/BranchSDK_Swift/**/*.swift" - s.tvos.source_files = "Sources/BranchSDK/**/*.{h,m}" + s.tvos.source_files = "Sources/BranchSDK/**/*.{h,m}", "Sources/BranchSDK_Swift/**/*.swift" s.tvos.exclude_files = "Sources/BranchSDK/**/BNCContentDiscoveryManager.{h,m}", "Sources/BranchSDK/**/BNCUserAgentCollector.{h,m}", "Sources/BranchSDK/**/BNCSpotlightService.{h,m}", From 1d706e3adb19f241817045327c63aba28486820f Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Wed, 25 Jun 2025 19:21:22 -0700 Subject: [PATCH 17/27] Revert "Update Package.swift" This reverts commit ef025f1e853c2caadfd78ff6f776cb68e853d509. --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index b4a005088..eb62317ab 100644 --- a/Package.swift +++ b/Package.swift @@ -18,7 +18,7 @@ let package = Package( .binaryTarget( name: "BranchSDKBinary", url: "https://github.com/NidhiDixit09/nidhidixit09.github.io/raw/refs/heads/main/Branch.zip", - checksum: "23f2d42a54ed9c14e4bc1ec93c8b28f5c66c68b26988692a1c154efa1710d868" + checksum: "ac2fe6717dda43cc2e9674f549937a6ab487447698451e4c2a823b6b26ce16ac" ) ] From 0af652cc78a60a7d63eeb84fd2e4a2ca8ed4ddfa Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Thu, 26 Jun 2025 01:49:41 -0700 Subject: [PATCH 18/27] Update Package.swift --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index eb62317ab..b4a005088 100644 --- a/Package.swift +++ b/Package.swift @@ -18,7 +18,7 @@ let package = Package( .binaryTarget( name: "BranchSDKBinary", url: "https://github.com/NidhiDixit09/nidhidixit09.github.io/raw/refs/heads/main/Branch.zip", - checksum: "ac2fe6717dda43cc2e9674f549937a6ab487447698451e4c2a823b6b26ce16ac" + checksum: "23f2d42a54ed9c14e4bc1ec93c8b28f5c66c68b26988692a1c154efa1710d868" ) ] From 08f370d3451e575971bfbe34dc43ecf24c8dd12c Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Tue, 1 Jul 2025 10:33:56 -0700 Subject: [PATCH 19/27] Test checkin POC --- BranchSDK.xcodeproj/project.pbxproj | 18 +++---- Package.swift | 54 +++++++++++++------ Sources/BranchSDK/BNCRequestFactory.m | 11 +++- Sources/BranchSDK/Branch.m | 9 +++- .../BranchConstants.m | 0 .../Public/BranchConstants.h | 0 .../ConfigurationController.swift | 4 ++ 7 files changed, 67 insertions(+), 29 deletions(-) rename Sources/{BranchSDK => BranchSDK_ObjC}/BranchConstants.m (100%) rename Sources/{BranchSDK => BranchSDK_ObjC}/Public/BranchConstants.h (100%) diff --git a/BranchSDK.xcodeproj/project.pbxproj b/BranchSDK.xcodeproj/project.pbxproj index f811063a8..e65db2426 100644 --- a/BranchSDK.xcodeproj/project.pbxproj +++ b/BranchSDK.xcodeproj/project.pbxproj @@ -383,8 +383,6 @@ 5FCDD5462B7AC6A300EAF29F /* BNCConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DB2B7AC6A100EAF29F /* BNCConfig.h */; }; 5FCDD5472B7AC6A300EAF29F /* BNCConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DB2B7AC6A100EAF29F /* BNCConfig.h */; }; 5FCDD5482B7AC6A300EAF29F /* BNCConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DB2B7AC6A100EAF29F /* BNCConfig.h */; }; - 5FCDD5492B7AC6A300EAF29F /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5FCDD54B2B7AC6A300EAF29F /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5FCDD54C2B7AC6A300EAF29F /* BNCPartnerParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DD2B7AC6A100EAF29F /* BNCPartnerParameters.h */; }; 5FCDD54D2B7AC6A300EAF29F /* BNCPartnerParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DD2B7AC6A100EAF29F /* BNCPartnerParameters.h */; }; 5FCDD54E2B7AC6A300EAF29F /* BNCPartnerParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DD2B7AC6A100EAF29F /* BNCPartnerParameters.h */; }; @@ -501,12 +499,14 @@ E7931D842E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; E7931D852E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; E7931D862E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; - E7A7F2922E0CAB61001FBADE /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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 */; }; E7F311B22DACB54100F824A7 /* BNCODMInfoCollector.h in Headers */ = {isa = PBXBuildFile; fileRef = E7F311B02DACB54100F824A7 /* BNCODMInfoCollector.h */; }; E7F311B32DACB54100F824A7 /* BNCODMInfoCollector.h in Headers */ = {isa = PBXBuildFile; fileRef = E7F311B02DACB54100F824A7 /* BNCODMInfoCollector.h */; }; + E7FBA85F2E14492700E7AAD9 /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E7FBA8602E1449D100E7AAD9 /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E7FBA8612E1449D100E7AAD9 /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -596,7 +596,7 @@ 5FCDD3812B7AC6A100EAF29F /* BNCNetworkInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCNetworkInterface.m; sourceTree = ""; }; 5FCDD3822B7AC6A100EAF29F /* BNCPreferenceHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCPreferenceHelper.m; sourceTree = ""; }; 5FCDD3832B7AC6A100EAF29F /* BNCConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCConfig.m; sourceTree = ""; }; - 5FCDD3842B7AC6A100EAF29F /* BranchConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchConstants.m; sourceTree = ""; }; + 5FCDD3842B7AC6A100EAF29F /* BranchConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BranchConstants.m; path = ../BranchSDK_ObjC/BranchConstants.m; sourceTree = ""; }; 5FCDD3852B7AC6A100EAF29F /* BranchContentDiscoveryManifest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchContentDiscoveryManifest.m; sourceTree = ""; }; 5FCDD3862B7AC6A100EAF29F /* BranchSpotlightUrlRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchSpotlightUrlRequest.m; sourceTree = ""; }; 5FCDD3882B7AC6A100EAF29F /* BranchContentDiscoverer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchContentDiscoverer.m; sourceTree = ""; }; @@ -678,7 +678,6 @@ 5FCDD3D92B7AC6A100EAF29F /* BranchSpotlightUrlRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchSpotlightUrlRequest.h; sourceTree = ""; }; 5FCDD3DA2B7AC6A100EAF29F /* BranchContentDiscoveryManifest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchContentDiscoveryManifest.h; sourceTree = ""; }; 5FCDD3DB2B7AC6A100EAF29F /* BNCConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCConfig.h; sourceTree = ""; }; - 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BranchConstants.h; path = ../Public/BranchConstants.h; sourceTree = ""; }; 5FCDD3DD2B7AC6A100EAF29F /* BNCPartnerParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCPartnerParameters.h; sourceTree = ""; }; 5FCDD3DE2B7AC6A100EAF29F /* BranchJsonConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchJsonConfig.h; sourceTree = ""; }; 5FCDD3DF2B7AC6A100EAF29F /* BranchLATDRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchLATDRequest.h; sourceTree = ""; }; @@ -723,6 +722,7 @@ E7931D832E01C8AE0007A374 /* ConfigurationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ConfigurationController.swift; path = ../BranchSDK_Swift/ConfigurationController.swift; 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 = ""; }; + E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BranchConstants.h; path = Sources/BranchSDK_ObjC/Public/BranchConstants.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -776,6 +776,7 @@ 5F2210132894A0DB00C5B190 = { isa = PBXGroup; children = ( + E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */, 5FCDD36B2B7AC6A100EAF29F /* BranchSDK */, 5F2211702894A9C000C5B190 /* TestHost */, 5F2211872894A9C100C5B190 /* TestHostTests */, @@ -985,7 +986,6 @@ 5FCDD3CA2B7AC6A100EAF29F /* BNCUserAgentCollector.h */, E7F311B02DACB54100F824A7 /* BNCODMInfoCollector.h */, 5FCDD3D32B7AC6A100EAF29F /* Branch+Validator.h */, - 5FCDD3DC2B7AC6A100EAF29F /* BranchConstants.h */, 5FCDD3D82B7AC6A100EAF29F /* BranchContentDiscoverer.h */, 5FCDD3DA2B7AC6A100EAF29F /* BranchContentDiscoveryManifest.h */, 5FCDD3B82B7AC6A100EAF29F /* BranchContentPathProperties.h */, @@ -1034,7 +1034,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 5FCDD5492B7AC6A300EAF29F /* BranchConstants.h in Headers */, + E7FBA85F2E14492700E7AAD9 /* BranchConstants.h in Headers */, 5FCDD52E2B7AC6A300EAF29F /* Branch+Validator.h in Headers */, 5FCDD4A42B7AC6A200EAF29F /* BNCCallbacks.h in Headers */, 5FCDD4922B7AC6A100EAF29F /* BranchLinkProperties.h in Headers */, @@ -1117,9 +1117,9 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + E7FBA8602E1449D100E7AAD9 /* BranchConstants.h in Headers */, 5FCDD52F2B7AC6A300EAF29F /* Branch+Validator.h in Headers */, 5FCDD4A52B7AC6A200EAF29F /* BNCCallbacks.h in Headers */, - E7A7F2922E0CAB61001FBADE /* BranchConstants.h in Headers */, 5FCDD4932B7AC6A100EAF29F /* BranchLinkProperties.h in Headers */, 5FCDD4C92B7AC6A200EAF29F /* BranchScene.h in Headers */, 5FCDD4A82B7AC6A200EAF29F /* BranchShareLink.h in Headers */, @@ -1200,6 +1200,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + E7FBA8612E1449D100E7AAD9 /* BranchConstants.h in Headers */, 5FCDD4BB2B7AC6A200EAF29F /* BranchPasteControl.h in Headers */, 5FCDD5302B7AC6A300EAF29F /* Branch+Validator.h in Headers */, 5FCDD4A62B7AC6A200EAF29F /* BNCCallbacks.h in Headers */, @@ -1227,7 +1228,6 @@ 5FCDD4A32B7AC6A200EAF29F /* BNCServerResponse.h in Headers */, 5FCDD4C42B7AC6A200EAF29F /* BranchDeepLinkingController.h in Headers */, 5FCDD4A02B7AC6A200EAF29F /* Branch.h in Headers */, - 5FCDD54B2B7AC6A300EAF29F /* BranchConstants.h in Headers */, 5FCDD5092B7AC6A300EAF29F /* BNCUrlQueryParameter.h in Headers */, 5FCDD5482B7AC6A300EAF29F /* BNCConfig.h in Headers */, E563942E2CC7A8E600E18E65 /* BranchFileLogger.h in Headers */, diff --git a/Package.swift b/Package.swift index b4a005088..3b2ee30e9 100644 --- a/Package.swift +++ b/Package.swift @@ -5,21 +5,43 @@ import PackageDescription let package = Package( name: "ios-branch-deep-linking-attribution", platforms: [ - .iOS(.v13), - .tvOS(.v13), - ], - products: [ - .library( - name: "BranchSDK", - targets: ["BranchSDKBinary"] - ), - ], - targets: [ - .binaryTarget( - name: "BranchSDKBinary", - url: "https://github.com/NidhiDixit09/nidhidixit09.github.io/raw/refs/heads/main/Branch.zip", - checksum: "23f2d42a54ed9c14e4bc1ec93c8b28f5c66c68b26988692a1c154efa1710d868" - ) + .iOS(.v13), + .tvOS(.v13), + ], + products: [ + .library( + name: "BranchSDK", + targets: ["BranchSDK", "BranchSwiftSDK", "BranchConstantsTarget"]), + ], + dependencies: [ + ], + targets: [ + .target( + name: "BranchConstantsTarget", + path: "Sources/BranchSDK_ObjC", + publicHeadersPath: "Public" + ), + .target( + name: "BranchSwiftSDK", + dependencies: ["BranchConstantsTarget"], // Swift code depends on Objective-C Constants + path: "Sources/BranchSDK_Swift" - ] + ), + .target( + name: "BranchSDK", + dependencies: ["BranchSwiftSDK"], + path: "Sources/BranchSDK", + publicHeadersPath: "Public", + cSettings: [ + .headerSearchPath("Private") + ], + linkerSettings: [ + .linkedFramework("CoreServices"), + .linkedFramework("SystemConfiguration"), + .linkedFramework("WebKit", .when(platforms: [.iOS])), + .linkedFramework("CoreSpotlight", .when(platforms: [.iOS])), + .linkedFramework("AdServices", .when(platforms: [.iOS])) + ] + ) + ] ) diff --git a/Sources/BranchSDK/BNCRequestFactory.m b/Sources/BranchSDK/BNCRequestFactory.m index 85ee9fda4..ee1518855 100644 --- a/Sources/BranchSDK/BNCRequestFactory.m +++ b/Sources/BranchSDK/BNCRequestFactory.m @@ -3,7 +3,7 @@ // Branch // // Created by Ernest Cho on 8/16/23. -// Copyright © 2023 Branch, Inc. All rights reserved. +// Copyright 2023 Branch, Inc. All rights reserved. // #import "BNCRequestFactory.h" @@ -32,10 +32,17 @@ #import "BNCAppleReceipt.h" #import "BNCAppGroupsData.h" #import "BNCSKAdNetwork.h" + +#if SWIFT_PACKAGE +@import BranchSwiftSDK; +#else +#import "BranchSDK/BranchSDK-Swift.h" +#endif + + #import "BNCReferringURLUtility.h" #import "BNCPasteboard.h" #import "BNCODMInfoCollector.h" -#import "BranchSDK/BranchSDK-Swift.h" @interface BNCRequestFactory() diff --git a/Sources/BranchSDK/Branch.m b/Sources/BranchSDK/Branch.m index 57711292f..f8384b345 100644 --- a/Sources/BranchSDK/Branch.m +++ b/Sources/BranchSDK/Branch.m @@ -45,9 +45,14 @@ #import "BNCServerAPI.h" #import "BranchPluginSupport.h" #import "BranchLogger.h" -#import "BranchSDK/BranchSDK-Swift.h" +#if SWIFT_PACKAGE +@import BranchSwiftSDK; +#else +#import "BranchSDK/BranchSDK-Swift.h" +#endif + #if !TARGET_OS_TV #import "BNCUserAgentCollector.h" #import "BNCSpotlightService.h" @@ -2420,11 +2425,11 @@ - (void)handleInitFailure:(NSError *)error callCallback:(BOOL)callCallback scene if (callCallback) { if (self.sceneSessionInitWithCallback) { BNCInitSessionResponse *response = [BNCInitSessionResponse new]; - response.error = error; response.params = [NSDictionary new]; response.universalObject = [BranchUniversalObject new]; response.linkProperties = [BranchLinkProperties new]; response.sceneIdentifier = sceneIdentifier; + response.error = error; self.sceneSessionInitWithCallback(response, error); } } diff --git a/Sources/BranchSDK/BranchConstants.m b/Sources/BranchSDK_ObjC/BranchConstants.m similarity index 100% rename from Sources/BranchSDK/BranchConstants.m rename to Sources/BranchSDK_ObjC/BranchConstants.m diff --git a/Sources/BranchSDK/Public/BranchConstants.h b/Sources/BranchSDK_ObjC/Public/BranchConstants.h similarity index 100% rename from Sources/BranchSDK/Public/BranchConstants.h rename to Sources/BranchSDK_ObjC/Public/BranchConstants.h diff --git a/Sources/BranchSDK_Swift/ConfigurationController.swift b/Sources/BranchSDK_Swift/ConfigurationController.swift index da6d85faa..206e29a78 100644 --- a/Sources/BranchSDK_Swift/ConfigurationController.swift +++ b/Sources/BranchSDK_Swift/ConfigurationController.swift @@ -8,6 +8,10 @@ import Foundation +#if SWIFT_PACKAGE +import BranchConstantsTarget +#endif + @objcMembers public class ConfigurationController: NSObject { From 3a38c1a0a0f2e93c5414a386d25607758c6e72d8 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Wed, 2 Jul 2025 18:18:45 -0700 Subject: [PATCH 20/27] Package.swift target name updates and minor refactors. --- Package.swift | 38 +++++++++++++-------------- Sources/BranchSDK/BNCRequestFactory.m | 2 +- Sources/BranchSDK/Branch.m | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Package.swift b/Package.swift index 3b2ee30e9..2b6b6bb70 100644 --- a/Package.swift +++ b/Package.swift @@ -5,43 +5,43 @@ import PackageDescription let package = Package( name: "ios-branch-deep-linking-attribution", platforms: [ - .iOS(.v13), - .tvOS(.v13), + .iOS(.v12), + .tvOS(.v12), ], products: [ .library( name: "BranchSDK", - targets: ["BranchSDK", "BranchSwiftSDK", "BranchConstantsTarget"]), + targets: ["BranchSDK", "BranchSwiftSDK", "BranchObjCSDK"]), ], dependencies: [ ], targets: [ .target( - name: "BranchConstantsTarget", + name: "BranchObjCSDK", path: "Sources/BranchSDK_ObjC", publicHeadersPath: "Public" ), .target( name: "BranchSwiftSDK", - dependencies: ["BranchConstantsTarget"], // Swift code depends on Objective-C Constants + dependencies: ["BranchObjCSDK"], // Swift code depends on Objective-C Constants path: "Sources/BranchSDK_Swift" ), .target( - name: "BranchSDK", - dependencies: ["BranchSwiftSDK"], - path: "Sources/BranchSDK", - publicHeadersPath: "Public", - cSettings: [ - .headerSearchPath("Private") - ], - linkerSettings: [ - .linkedFramework("CoreServices"), - .linkedFramework("SystemConfiguration"), - .linkedFramework("WebKit", .when(platforms: [.iOS])), - .linkedFramework("CoreSpotlight", .when(platforms: [.iOS])), - .linkedFramework("AdServices", .when(platforms: [.iOS])) - ] + name: "BranchSDK", + dependencies: ["BranchSwiftSDK"], + path: "Sources/BranchSDK", + publicHeadersPath: "Public", + cSettings: [ + .headerSearchPath("Private") + ], + linkerSettings: [ + .linkedFramework("CoreServices"), + .linkedFramework("SystemConfiguration"), + .linkedFramework("WebKit", .when(platforms: [.iOS])), + .linkedFramework("CoreSpotlight", .when(platforms: [.iOS])), + .linkedFramework("AdServices", .when(platforms: [.iOS])) + ] ) ] ) diff --git a/Sources/BranchSDK/BNCRequestFactory.m b/Sources/BranchSDK/BNCRequestFactory.m index ee1518855..4027e0015 100644 --- a/Sources/BranchSDK/BNCRequestFactory.m +++ b/Sources/BranchSDK/BNCRequestFactory.m @@ -3,7 +3,7 @@ // Branch // // Created by Ernest Cho on 8/16/23. -// Copyright 2023 Branch, Inc. All rights reserved. +// Copyright © 2023 Branch, Inc. All rights reserved. // #import "BNCRequestFactory.h" diff --git a/Sources/BranchSDK/Branch.m b/Sources/BranchSDK/Branch.m index f8384b345..ed72dd9fa 100644 --- a/Sources/BranchSDK/Branch.m +++ b/Sources/BranchSDK/Branch.m @@ -2425,11 +2425,11 @@ - (void)handleInitFailure:(NSError *)error callCallback:(BOOL)callCallback scene if (callCallback) { if (self.sceneSessionInitWithCallback) { BNCInitSessionResponse *response = [BNCInitSessionResponse new]; + response.error = error; response.params = [NSDictionary new]; response.universalObject = [BranchUniversalObject new]; response.linkProperties = [BranchLinkProperties new]; response.sceneIdentifier = sceneIdentifier; - response.error = error; self.sceneSessionInitWithCallback(response, error); } } From 132b2c9ee3353375d701a087568c7e2890cda125 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Wed, 2 Jul 2025 18:20:51 -0700 Subject: [PATCH 21/27] Added dir BranchSDK_ObjC in podspec file. --- BranchSDK.podspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BranchSDK.podspec b/BranchSDK.podspec index b5750d40c..6f83392f2 100644 --- a/BranchSDK.podspec +++ b/BranchSDK.podspec @@ -21,9 +21,9 @@ Use the Branch SDK (branch.io) to create and power the links that point back to s.swift_versions = ['5.0', '5.1', '5.2', '5.3', '5.4', '5.5', '5.6', '5.7', '5.8', '5.9', '6.0'] s.resource_bundles = { 'BranchSDK' => 'Sources/Resources/*.xcprivacy' } - s.ios.source_files = "Sources/BranchSDK/**/*.{h,m}", "Sources/BranchSDK_Swift/**/*.swift" + s.ios.source_files = "Sources/BranchSDK/**/*.{h,m}", "Sources/BranchSDK_Swift/**/*.swift, "Sources/BranchSDK_ObjC/**/*.{h,m}"" - s.tvos.source_files = "Sources/BranchSDK/**/*.{h,m}", "Sources/BranchSDK_Swift/**/*.swift" + s.tvos.source_files = "Sources/BranchSDK/**/*.{h,m}", "Sources/BranchSDK_Swift/**/*.swift, "Sources/BranchSDK_ObjC/**/*.{h,m}"" s.tvos.exclude_files = "Sources/BranchSDK/**/BNCContentDiscoveryManager.{h,m}", "Sources/BranchSDK/**/BNCUserAgentCollector.{h,m}", "Sources/BranchSDK/**/BNCSpotlightService.{h,m}", From f808caa03974f60d4eeb2254346edd37908aafb5 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Wed, 2 Jul 2025 18:30:13 -0700 Subject: [PATCH 22/27] Fixed typo. --- BranchSDK.podspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BranchSDK.podspec b/BranchSDK.podspec index 6f83392f2..31c9e28fd 100644 --- a/BranchSDK.podspec +++ b/BranchSDK.podspec @@ -21,9 +21,9 @@ Use the Branch SDK (branch.io) to create and power the links that point back to s.swift_versions = ['5.0', '5.1', '5.2', '5.3', '5.4', '5.5', '5.6', '5.7', '5.8', '5.9', '6.0'] s.resource_bundles = { 'BranchSDK' => 'Sources/Resources/*.xcprivacy' } - s.ios.source_files = "Sources/BranchSDK/**/*.{h,m}", "Sources/BranchSDK_Swift/**/*.swift, "Sources/BranchSDK_ObjC/**/*.{h,m}"" + s.ios.source_files = "Sources/BranchSDK/**/*.{h,m}", "Sources/BranchSDK_Swift/**/*.swift", "Sources/BranchSDK_ObjC/**/*.{h,m}" - s.tvos.source_files = "Sources/BranchSDK/**/*.{h,m}", "Sources/BranchSDK_Swift/**/*.swift, "Sources/BranchSDK_ObjC/**/*.{h,m}"" + s.tvos.source_files = "Sources/BranchSDK/**/*.{h,m}", "Sources/BranchSDK_Swift/**/*.swift", "Sources/BranchSDK_ObjC/**/*.{h,m}" s.tvos.exclude_files = "Sources/BranchSDK/**/BNCContentDiscoveryManager.{h,m}", "Sources/BranchSDK/**/BNCUserAgentCollector.{h,m}", "Sources/BranchSDK/**/BNCSpotlightService.{h,m}", From 90090aeaabf8676077313754c523d61fbee5af14 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Wed, 2 Jul 2025 18:31:53 -0700 Subject: [PATCH 23/27] Fixed SDK name. --- Sources/BranchSDK_Swift/ConfigurationController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BranchSDK_Swift/ConfigurationController.swift b/Sources/BranchSDK_Swift/ConfigurationController.swift index 206e29a78..9b468a048 100644 --- a/Sources/BranchSDK_Swift/ConfigurationController.swift +++ b/Sources/BranchSDK_Swift/ConfigurationController.swift @@ -9,7 +9,7 @@ import Foundation #if SWIFT_PACKAGE -import BranchConstantsTarget +import BranchObjCSDK #endif @objcMembers From 422be6bb6381bc5d8d3a2e0fa12ebfcee2143d60 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Sun, 6 Jul 2025 17:25:22 -0700 Subject: [PATCH 24/27] Added swift files. --- .../Branch-TestBed.xcodeproj/project.pbxproj | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj b/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj index c55c7fb00..dd3e784eb 100644 --- a/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj +++ b/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj @@ -151,7 +151,6 @@ 5F644C242B7AA811000DCD78 /* BranchSpotlightUrlRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F644B932B7AA811000DCD78 /* BranchSpotlightUrlRequest.h */; }; 5F644C252B7AA811000DCD78 /* BranchContentDiscoveryManifest.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F644B942B7AA811000DCD78 /* BranchContentDiscoveryManifest.h */; }; 5F644C262B7AA811000DCD78 /* BNCConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F644B952B7AA811000DCD78 /* BNCConfig.h */; }; - 5F644C272B7AA811000DCD78 /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F644B962B7AA811000DCD78 /* BranchConstants.h */; }; 5F644C282B7AA811000DCD78 /* BNCPartnerParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F644B972B7AA811000DCD78 /* BNCPartnerParameters.h */; }; 5F644C292B7AA811000DCD78 /* BranchJsonConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F644B982B7AA811000DCD78 /* BranchJsonConfig.h */; }; 5F644C2A2B7AA811000DCD78 /* BranchLATDRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F644B992B7AA811000DCD78 /* BranchLATDRequest.h */; }; @@ -247,9 +246,9 @@ 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 */; }; + E7CA74B22E1B4890002EFB40 /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E7CA74B12E1B4890002EFB40 /* BranchConstants.h */; }; + E7CA74B42E1B4944002EFB40 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7CA74B32E1B4944002EFB40 /* ConfigurationController.swift */; }; 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 */ @@ -379,7 +378,7 @@ 5F644B3B2B7AA810000DCD78 /* BNCNetworkInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCNetworkInterface.m; sourceTree = ""; }; 5F644B3C2B7AA810000DCD78 /* BNCPreferenceHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCPreferenceHelper.m; sourceTree = ""; }; 5F644B3D2B7AA810000DCD78 /* BNCConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCConfig.m; sourceTree = ""; }; - 5F644B3E2B7AA810000DCD78 /* BranchConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchConstants.m; sourceTree = ""; }; + 5F644B3E2B7AA810000DCD78 /* BranchConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BranchConstants.m; path = ../BranchSDK_ObjC/BranchConstants.m; sourceTree = ""; }; 5F644B3F2B7AA810000DCD78 /* BranchContentDiscoveryManifest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchContentDiscoveryManifest.m; sourceTree = ""; }; 5F644B402B7AA810000DCD78 /* BranchSpotlightUrlRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchSpotlightUrlRequest.m; sourceTree = ""; }; 5F644B422B7AA810000DCD78 /* BranchContentDiscoverer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchContentDiscoverer.m; sourceTree = ""; }; @@ -461,7 +460,6 @@ 5F644B932B7AA811000DCD78 /* BranchSpotlightUrlRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchSpotlightUrlRequest.h; sourceTree = ""; }; 5F644B942B7AA811000DCD78 /* BranchContentDiscoveryManifest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchContentDiscoveryManifest.h; sourceTree = ""; }; 5F644B952B7AA811000DCD78 /* BNCConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCConfig.h; sourceTree = ""; }; - 5F644B962B7AA811000DCD78 /* BranchConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchConstants.h; sourceTree = ""; }; 5F644B972B7AA811000DCD78 /* BNCPartnerParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCPartnerParameters.h; sourceTree = ""; }; 5F644B982B7AA811000DCD78 /* BranchJsonConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchJsonConfig.h; sourceTree = ""; }; 5F644B992B7AA811000DCD78 /* BranchLATDRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchLATDRequest.h; sourceTree = ""; }; @@ -573,9 +571,9 @@ 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 = ""; }; + E7CA74B12E1B4890002EFB40 /* BranchConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BranchConstants.h; path = ../Sources/BranchSDK_ObjC/Public/BranchConstants.h; sourceTree = SOURCE_ROOT; }; + E7CA74B32E1B4944002EFB40 /* ConfigurationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ConfigurationController.swift; path = ../Sources/BranchSDK_Swift/ConfigurationController.swift; sourceTree = SOURCE_ROOT; }; 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 */ @@ -727,6 +725,7 @@ 5F644B252B7AA810000DCD78 /* BranchSDK */ = { isa = PBXGroup; children = ( + E7CA74B32E1B4944002EFB40 /* ConfigurationController.swift */, E563942F2CC7AC9500E18E65 /* BranchFileLogger.m */, 5F644BB02B7AA811000DCD78 /* BNCAppGroupsData.m */, 5F644BA82B7AA811000DCD78 /* BNCAppleReceipt.m */, @@ -810,6 +809,7 @@ 5F644B522B7AA810000DCD78 /* Public */ = { isa = PBXGroup; children = ( + E7CA74B12E1B4890002EFB40 /* BranchConstants.h */, 5F644B5E2B7AA810000DCD78 /* BNCCallbacks.h */, 5F644B5A2B7AA810000DCD78 /* BNCCurrency.h */, 5F644B612B7AA810000DCD78 /* BNCInitSessionResponse.h */, @@ -845,7 +845,6 @@ 5F644B6E2B7AA810000DCD78 /* Private */ = { isa = PBXGroup; children = ( - E7AE4A0B2DFB2D0100696805 /* BranchConfigurationController.h */, E71E397A2DD3C14800110F59 /* BNCInAppBrowser.h */, 5F644B762B7AA810000DCD78 /* BNCAppGroupsData.h */, 5F644B702B7AA810000DCD78 /* BNCAppleReceipt.h */, @@ -878,7 +877,6 @@ 5F644B842B7AA811000DCD78 /* BNCUserAgentCollector.h */, E7AC74562DB0639E002D8C40 /* BNCODMInfoCollector.h */, 5F644B8D2B7AA811000DCD78 /* Branch+Validator.h */, - 5F644B962B7AA811000DCD78 /* BranchConstants.h */, 5F644B922B7AA811000DCD78 /* BranchContentDiscoverer.h */, 5F644B942B7AA811000DCD78 /* BranchContentDiscoveryManifest.h */, 5F644B722B7AA810000DCD78 /* BranchContentPathProperties.h */, @@ -924,7 +922,6 @@ 670016571940F51400A9E103 = { isa = PBXGroup; children = ( - E7FC47722DFC7B020072B3ED /* BranchConfigurationController.m */, E7AC74762DB06B42002D8C40 /* Reflection_ODM_Tests.xctestplan */, 6589EBA52674270100F2E28B /* Branch-TestBed-CI.xctestplan */, 033FC71025AC1E5800D8319E /* Branch-TestBed.xctestplan */, @@ -1062,6 +1059,7 @@ 5F644C032B7AA811000DCD78 /* BranchContentPathProperties.h in Headers */, 5F644C042B7AA811000DCD78 /* BNCSKAdNetwork.h in Headers */, 5F644C0E2B7AA811000DCD78 /* BNCQRCodeCache.h in Headers */, + E7CA74B22E1B4890002EFB40 /* BranchConstants.h in Headers */, 5F644C2E2B7AA811000DCD78 /* BNCNetworkService.h in Headers */, 5F644C1B2B7AA811000DCD78 /* BNCSystemObserver.h in Headers */, 5F644C292B7AA811000DCD78 /* BranchJsonConfig.h in Headers */, @@ -1074,7 +1072,6 @@ 5F644C052B7AA811000DCD78 /* BNCJSONUtility.h in Headers */, 5F644C2D2B7AA811000DCD78 /* BNCReferringURLUtility.h in Headers */, 5F644C0B2B7AA811000DCD78 /* BNCEventUtils.h in Headers */, - 5F644C272B7AA811000DCD78 /* BranchConstants.h in Headers */, 5F644C002B7AA811000DCD78 /* BNCKeyChain.h in Headers */, 5F644C1D2B7AA811000DCD78 /* BranchInstallRequest.h in Headers */, 5F644C0D2B7AA811000DCD78 /* BranchShortUrlSyncRequest.h in Headers */, @@ -1097,7 +1094,6 @@ 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 */, ); @@ -1238,6 +1234,7 @@ TargetAttributes = { 466B58371B17773000A69EDE = { CreatedOnToolsVersion = 6.3.2; + LastSwiftMigration = 1640; }; 5F8B7B3A21B5F5CD009CE0A6 = { CreatedOnToolsVersion = 10.1; @@ -1374,7 +1371,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E7FC47732DFC7B020072B3ED /* BranchConfigurationController.m in Sources */, + E7CA74B42E1B4944002EFB40 /* ConfigurationController.swift in Sources */, 5F644BB92B7AA811000DCD78 /* NSError+Branch.m in Sources */, 5F644C482B7AA811000DCD78 /* BNCCallbackMap.m in Sources */, 5F644BBE2B7AA811000DCD78 /* BNCApplication.m in Sources */, From 83cd1788d9dd57f588fb2fcb581763c9fd506fdf Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Mon, 14 Jul 2025 23:37:17 +0530 Subject: [PATCH 25/27] Source Code folder and project workspace restructuring. -> Removed DeepLinkDemo, TestDeepLinking and TestHost Apps for the repo. -> Removed Unit tests from Branch Test Bed App -> Added Test Host App and Unit tests to BranchSDK Workspace. --- BranchSDK.xcodeproj/project.pbxproj | 761 +++-- .../xcschemes/BranchSDKTests.xcscheme | 61 +- BranchSDKTests/BNCAPIServerTest.m | 515 ++++ BranchSDKTests/BNCAppleReceiptTests.m | 33 + BranchSDKTests/BNCApplicationTests.m | 75 + BranchSDKTests/BNCCallbackMapTests.m | 134 + BranchSDKTests/BNCClassSerializationTests.m | 120 + BranchSDKTests/BNCCrashlyticsWrapperTests.m | 68 + BranchSDKTests/BNCCurrencyTests.m | 194 ++ BranchSDKTests/BNCDeviceInfoTests.m | 190 ++ BranchSDKTests/BNCDeviceSystemTests.m | 62 + .../BNCDisableAdNetworkCalloutsTests.m | 59 + BranchSDKTests/BNCEncodingUtilsTests.m | 609 ++++ BranchSDKTests/BNCJSONUtilityTests.m | 188 ++ BranchSDKTests/BNCJsonLoader.h | 20 + BranchSDKTests/BNCJsonLoader.m | 27 + BranchSDKTests/BNCKeyChainTests.m | 121 + BranchSDKTests/BNCLinkDataTests.m | 103 + BranchSDKTests/BNCNetworkInterfaceTests.m | 82 + BranchSDKTests/BNCODMTests.m | 102 + BranchSDKTests/BNCPartnerParametersTests.m | 219 ++ BranchSDKTests/BNCPasteboardTests.m | 170 ++ BranchSDKTests/BNCPreferenceHelperTests.m | 417 +++ BranchSDKTests/BNCReachabilityTests.m | 45 + BranchSDKTests/BNCReferringURLUtilityTests.m | 538 ++++ BranchSDKTests/BNCRequestFactoryTests.m | 234 ++ BranchSDKTests/BNCSKAdNetworkTests.m | 264 ++ BranchSDKTests/BNCSystemObserverTests.m | 139 + .../BNCURLFilterSkiplistUpgradeTests.m | 273 ++ BranchSDKTests/BNCURLFilterTests.m | 168 ++ BranchSDKTests/BNCUserAgentCollectorTests.m | 111 + .../Branch-SDK-Tests-Bridging-Header.h | 5 + BranchSDKTests/BranchActivityItemTests.m | 39 + BranchSDKTests/BranchClassTests.m | 265 ++ .../BranchConfigurationControllerTests.m | 105 + .../BranchConstants.h | 0 BranchSDKTests/BranchEvent.Test.m | 575 ++++ BranchSDKTests/BranchEvent.Test.swift | 129 + .../BranchLastAttributedTouchDataTests.m | 63 + BranchSDKTests/BranchLoggerTests.m | 261 ++ BranchSDKTests/BranchPluginSupportTests.m | 91 + BranchSDKTests/BranchQRCodeTests.m | 154 + BranchSDKTests/BranchSDKTests.m | 36 + BranchSDKTests/BranchSDKTests.xctestplan | 37 + BranchSDKTests/BranchShareLinkTests.m | 38 + BranchSDKTests/BranchUniversalObjectTests.m | 446 +++ .../DispatchToIsolationQueueTests.m | 76 + .../Info.plist | 6 +- BranchSDKTests/NSErrorBranchTests.m | 54 + .../NSMutableDictionaryBranchTests.m | 389 +++ BranchSDKTests/NSStringBranchTests.m | 35 + BranchSDKTestsHostApp/AppDelegate.h | 14 + BranchSDKTestsHostApp/AppDelegate.m | 40 + .../AccentColor.colorset/Contents.json | 0 .../AppIcon.appiconset/Contents.json | 35 + .../Assets.xcassets/Contents.json | 0 .../Base.lproj/LaunchScreen.storyboard | 0 .../Base.lproj/Main.storyboard | 2 +- .../BranchSDKTestsHostAppRelease.entitlements | 8 +- .../Info.plist | 20 +- BranchSDKTestsHostApp/SceneDelegate.h | 15 + BranchSDKTestsHostApp/SceneDelegate.m | 57 + BranchSDKTestsHostApp/ViewController.h | 14 + BranchSDKTestsHostApp/ViewController.m | 22 + BranchSDKTestsHostApp/cannedData/example.json | 31 + BranchSDKTestsHostApp/cannedData/latd.json | 7 + .../cannedData/latd_empty_data.json | 4 + .../cannedData/latd_missing_data.json | 3 + .../cannedData/latd_missing_window.json | 6 + BranchSDKTestsHostApp/main.m | 18 + .../DeepLinkDemo.xcodeproj/project.pbxproj | 586 ---- .../contents.xcworkspacedata | 7 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../contents.xcworkspacedata | 10 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - DeepLinkDemo/DeepLinkDemo/AppDelegate.swift | 268 -- .../AppIcon.appiconset/Contents.json | 98 - .../back_img.imageset/Contents.json | 24 - .../back_img.imageset/icons8-left-100.png | Bin 627 -> 0 bytes .../qentelli_logo.imageset/Contents.json | 21 - .../qentelli_logo.imageset/img.png | Bin 4030 -> 0 bytes .../DeepLinkDemo/Base.lproj/Main.storyboard | 2685 ----------------- .../DeepLinkDemo/Constants/CommonAlert.swift | 22 - .../DeepLinkDemo/Constants/CommonMethod.swift | 59 - .../DeepLinkDemo/Constants/Utils.swift | 87 - .../Controllers/AddMetaDataVC.swift | 117 - .../CreateObjectReferenceObject.swift | 268 -- .../DeepLinkDemo/Controllers/DispalyVC.swift | 60 - .../Controllers/GenerateURLVC.swift | 257 -- .../Controllers/HomeViewController.swift | 452 --- .../LogFileListViewController.swift | 84 - .../Controllers/MetaDataTableViewCell.swift | 224 -- .../Controllers/NavigateContentVC.swift | 108 - .../Controllers/ParentViewController.swift | 39 - .../Controllers/ReadDeeplinkingVC.swift | 108 - .../Controllers/ReadLogViewController.swift | 41 - .../DeepLinkDemo/Controllers/ReadVC.swift | 50 - .../Controllers/ShareDynamicallyVC.swift | 10 - .../Controllers/TextViewController.swift | 101 - .../Controllers/TrackContentVC.swift | 88 - .../Controllers/ViewController.swift | 20 - .../DeepLinkDemo/Controllers/WebViewVC.swift | 59 - .../DeepLinkDemo-Bridging-Header.h | 12 - DeepLinkDemo/DeepLinkDemo/Header.h | 12 - DeepLinkDemo/DeepLinkDemo/Info.plist | 54 - .../DeepLinkDemo/NSURLSessionBranch.h | 16 - .../DeepLinkDemo/NSURLSessionBranch.m | 94 - .../DeepLinkDemo/Reachability/Reachability.h | 19 - .../Reachability/Reachability.swift | 270 -- .../SIAlertView.bundle/button-cancel-d.png | Bin 1041 -> 0 bytes .../SIAlertView.bundle/button-cancel-d@2x.png | Bin 1245 -> 0 bytes .../SIAlertView.bundle/button-cancel.png | Bin 1030 -> 0 bytes .../SIAlertView.bundle/button-cancel@2x.png | Bin 1179 -> 0 bytes .../SIAlertView.bundle/button-default-d.png | Bin 1045 -> 0 bytes .../button-default-d@2x.png | Bin 1247 -> 0 bytes .../SIAlertView.bundle/button-default.png | Bin 1035 -> 0 bytes .../SIAlertView.bundle/button-default@2x.png | Bin 1178 -> 0 bytes .../button-destructive-d.png | Bin 1057 -> 0 bytes .../button-destructive-d@2x.png | Bin 1237 -> 0 bytes .../SIAlertView.bundle/button-destructive.png | Bin 1033 -> 0 bytes .../button-destructive@2x.png | Bin 1187 -> 0 bytes .../DeepLinkDemo/SIAlertView/SIAlertView.h | 69 - .../DeepLinkDemo/SIAlertView/SIAlertView.m | 1253 -------- .../SIAlertView/UIWindow+SIUtils.h | 20 - .../SIAlertView/UIWindow+SIUtils.m | 42 - .../DeepLinkDemo/StartupOptionsData.swift | 59 - DeepLinkDemo/DeepLinkDemo/img.png | Bin 4030 -> 0 bytes DeepLinkDemo/IPA/Info.plist | 27 - DeepLinkDemo/Podfile | 12 - DeepLinkDemo/Podfile.lock | 23 - DeepLinkDemo/README.md | 2 - TestDeepLinking/Podfile | 8 - .../TestDeepLinking.xcodeproj/project.pbxproj | 733 ----- .../contents.xcworkspacedata | 7 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcschemes/TestDeepLinking.xcscheme | 104 - .../contents.xcworkspacedata | 10 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../TestDeepLinking/AppDelegate.swift | 45 - .../AccentColor.colorset/Contents.json | 11 - .../AppIcon.appiconset/Contents.json | 98 - .../Assets.xcassets/Contents.json | 6 - .../Base.lproj/LaunchScreen.storyboard | 25 - .../Base.lproj/Main.storyboard | 49 - TestDeepLinking/TestDeepLinking/Info.plist | 79 - .../TestDeepLinking/SceneDelegate.swift | 64 - .../TestDeepLinking.entitlements | 13 - .../TestDeepLinking.xctestplan | 36 - .../TestDeepLinking/ViewController.swift | 22 - .../TestDeepLinkingUITests/Info.plist | 22 - .../TestDeepLinkWithoutApp.m | 64 - .../TestDeepLinkingUITestsWithHostApp.m | 38 - TestHost/AppDelegate.swift | 37 - .../AccentColor.colorset/Contents.json | 11 - .../AppIcon.appiconset/Contents.json | 98 - TestHost/Assets.xcassets/Contents.json | 6 - TestHost/Base.lproj/LaunchScreen.storyboard | 25 - TestHost/NSURLSession+Branch.h | 17 - TestHost/NSURLSession+Branch.m | 64 - TestHost/SceneDelegate.swift | 57 - TestHost/TestHost-Bridging-Header.h | 4 - TestHost/ViewController.swift | 19 - TestHostTests/TestHostTests.swift | 36 - TestHostUITests/TestHostUITests.swift | 41 - .../TestHostUITestsLaunchTests.swift | 32 - 165 files changed, 8743 insertions(+), 10309 deletions(-) rename DeepLinkDemo/DeepLinkDemo.xcodeproj/xcshareddata/xcschemes/DeepLinkDemo.xcscheme => BranchSDK.xcodeproj/xcshareddata/xcschemes/BranchSDKTests.xcscheme (58%) create mode 100644 BranchSDKTests/BNCAPIServerTest.m create mode 100644 BranchSDKTests/BNCAppleReceiptTests.m create mode 100644 BranchSDKTests/BNCApplicationTests.m create mode 100644 BranchSDKTests/BNCCallbackMapTests.m create mode 100644 BranchSDKTests/BNCClassSerializationTests.m create mode 100644 BranchSDKTests/BNCCrashlyticsWrapperTests.m create mode 100644 BranchSDKTests/BNCCurrencyTests.m create mode 100644 BranchSDKTests/BNCDeviceInfoTests.m create mode 100644 BranchSDKTests/BNCDeviceSystemTests.m create mode 100644 BranchSDKTests/BNCDisableAdNetworkCalloutsTests.m create mode 100644 BranchSDKTests/BNCEncodingUtilsTests.m create mode 100644 BranchSDKTests/BNCJSONUtilityTests.m create mode 100644 BranchSDKTests/BNCJsonLoader.h create mode 100644 BranchSDKTests/BNCJsonLoader.m create mode 100644 BranchSDKTests/BNCKeyChainTests.m create mode 100644 BranchSDKTests/BNCLinkDataTests.m create mode 100644 BranchSDKTests/BNCNetworkInterfaceTests.m create mode 100644 BranchSDKTests/BNCODMTests.m create mode 100644 BranchSDKTests/BNCPartnerParametersTests.m create mode 100644 BranchSDKTests/BNCPasteboardTests.m create mode 100644 BranchSDKTests/BNCPreferenceHelperTests.m create mode 100644 BranchSDKTests/BNCReachabilityTests.m create mode 100644 BranchSDKTests/BNCReferringURLUtilityTests.m create mode 100644 BranchSDKTests/BNCRequestFactoryTests.m create mode 100644 BranchSDKTests/BNCSKAdNetworkTests.m create mode 100644 BranchSDKTests/BNCSystemObserverTests.m create mode 100644 BranchSDKTests/BNCURLFilterSkiplistUpgradeTests.m create mode 100644 BranchSDKTests/BNCURLFilterTests.m create mode 100644 BranchSDKTests/BNCUserAgentCollectorTests.m create mode 100644 BranchSDKTests/Branch-SDK-Tests-Bridging-Header.h create mode 100644 BranchSDKTests/BranchActivityItemTests.m create mode 100644 BranchSDKTests/BranchClassTests.m create mode 100644 BranchSDKTests/BranchConfigurationControllerTests.m rename {Sources/BranchSDK_ObjC/Public => BranchSDKTests}/BranchConstants.h (100%) create mode 100644 BranchSDKTests/BranchEvent.Test.m create mode 100644 BranchSDKTests/BranchEvent.Test.swift create mode 100644 BranchSDKTests/BranchLastAttributedTouchDataTests.m create mode 100644 BranchSDKTests/BranchLoggerTests.m create mode 100644 BranchSDKTests/BranchPluginSupportTests.m create mode 100644 BranchSDKTests/BranchQRCodeTests.m create mode 100644 BranchSDKTests/BranchSDKTests.m create mode 100644 BranchSDKTests/BranchSDKTests.xctestplan create mode 100644 BranchSDKTests/BranchShareLinkTests.m create mode 100644 BranchSDKTests/BranchUniversalObjectTests.m create mode 100644 BranchSDKTests/DispatchToIsolationQueueTests.m rename {TestDeepLinking/TestDeepLinkingUITestsWithHostApp => BranchSDKTests}/Info.plist (86%) create mode 100644 BranchSDKTests/NSErrorBranchTests.m create mode 100644 BranchSDKTests/NSMutableDictionaryBranchTests.m create mode 100644 BranchSDKTests/NSStringBranchTests.m create mode 100644 BranchSDKTestsHostApp/AppDelegate.h create mode 100644 BranchSDKTestsHostApp/AppDelegate.m rename {DeepLinkDemo/DeepLinkDemo => BranchSDKTestsHostApp}/Assets.xcassets/AccentColor.colorset/Contents.json (100%) create mode 100644 BranchSDKTestsHostApp/Assets.xcassets/AppIcon.appiconset/Contents.json rename {DeepLinkDemo/DeepLinkDemo => BranchSDKTestsHostApp}/Assets.xcassets/Contents.json (100%) rename {DeepLinkDemo/DeepLinkDemo => BranchSDKTestsHostApp}/Base.lproj/LaunchScreen.storyboard (100%) rename {TestHost => BranchSDKTestsHostApp}/Base.lproj/Main.storyboard (95%) rename DeepLinkDemo/DeepLinkDemo/DeepLinkDemo.entitlements => BranchSDKTestsHostApp/BranchSDKTestsHostAppRelease.entitlements (50%) rename {TestHost => BranchSDKTestsHostApp}/Info.plist (59%) create mode 100644 BranchSDKTestsHostApp/SceneDelegate.h create mode 100644 BranchSDKTestsHostApp/SceneDelegate.m create mode 100644 BranchSDKTestsHostApp/ViewController.h create mode 100644 BranchSDKTestsHostApp/ViewController.m create mode 100644 BranchSDKTestsHostApp/cannedData/example.json create mode 100644 BranchSDKTestsHostApp/cannedData/latd.json create mode 100644 BranchSDKTestsHostApp/cannedData/latd_empty_data.json create mode 100644 BranchSDKTestsHostApp/cannedData/latd_missing_data.json create mode 100644 BranchSDKTestsHostApp/cannedData/latd_missing_window.json create mode 100644 BranchSDKTestsHostApp/main.m delete mode 100644 DeepLinkDemo/DeepLinkDemo.xcodeproj/project.pbxproj delete mode 100644 DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 DeepLinkDemo/DeepLinkDemo.xcworkspace/contents.xcworkspacedata delete mode 100644 DeepLinkDemo/DeepLinkDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 DeepLinkDemo/DeepLinkDemo/AppDelegate.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/Contents.json delete mode 100644 DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/icons8-left-100.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/Assets.xcassets/qentelli_logo.imageset/Contents.json delete mode 100644 DeepLinkDemo/DeepLinkDemo/Assets.xcassets/qentelli_logo.imageset/img.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/Base.lproj/Main.storyboard delete mode 100644 DeepLinkDemo/DeepLinkDemo/Constants/CommonAlert.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Constants/CommonMethod.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Constants/Utils.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/AddMetaDataVC.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/CreateObjectReferenceObject.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/DispalyVC.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/GenerateURLVC.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/HomeViewController.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/LogFileListViewController.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/MetaDataTableViewCell.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/NavigateContentVC.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/ParentViewController.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/ReadDeeplinkingVC.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/ReadLogViewController.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/ReadVC.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/ShareDynamicallyVC.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/TextViewController.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/TrackContentVC.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/ViewController.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/WebViewVC.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/DeepLinkDemo-Bridging-Header.h delete mode 100644 DeepLinkDemo/DeepLinkDemo/Header.h delete mode 100644 DeepLinkDemo/DeepLinkDemo/Info.plist delete mode 100644 DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.h delete mode 100644 DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.m delete mode 100644 DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.h delete mode 100644 DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel-d.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel-d@2x.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel@2x.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default-d.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default-d@2x.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default@2x.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive-d.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive-d@2x.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive@2x.png delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.h delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.m delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.h delete mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.m delete mode 100644 DeepLinkDemo/DeepLinkDemo/StartupOptionsData.swift delete mode 100644 DeepLinkDemo/DeepLinkDemo/img.png delete mode 100644 DeepLinkDemo/IPA/Info.plist delete mode 100644 DeepLinkDemo/Podfile delete mode 100644 DeepLinkDemo/Podfile.lock delete mode 100644 DeepLinkDemo/README.md delete mode 100644 TestDeepLinking/Podfile delete mode 100644 TestDeepLinking/TestDeepLinking.xcodeproj/project.pbxproj delete mode 100644 TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 TestDeepLinking/TestDeepLinking.xcodeproj/xcshareddata/xcschemes/TestDeepLinking.xcscheme delete mode 100644 TestDeepLinking/TestDeepLinking.xcworkspace/contents.xcworkspacedata delete mode 100644 TestDeepLinking/TestDeepLinking.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 TestDeepLinking/TestDeepLinking/AppDelegate.swift delete mode 100644 TestDeepLinking/TestDeepLinking/Assets.xcassets/AccentColor.colorset/Contents.json delete mode 100644 TestDeepLinking/TestDeepLinking/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 TestDeepLinking/TestDeepLinking/Assets.xcassets/Contents.json delete mode 100644 TestDeepLinking/TestDeepLinking/Base.lproj/LaunchScreen.storyboard delete mode 100644 TestDeepLinking/TestDeepLinking/Base.lproj/Main.storyboard delete mode 100644 TestDeepLinking/TestDeepLinking/Info.plist delete mode 100644 TestDeepLinking/TestDeepLinking/SceneDelegate.swift delete mode 100644 TestDeepLinking/TestDeepLinking/TestDeepLinking.entitlements delete mode 100644 TestDeepLinking/TestDeepLinking/TestDeepLinking.xctestplan delete mode 100644 TestDeepLinking/TestDeepLinking/ViewController.swift delete mode 100644 TestDeepLinking/TestDeepLinkingUITests/Info.plist delete mode 100644 TestDeepLinking/TestDeepLinkingUITests/TestDeepLinkWithoutApp.m delete mode 100644 TestDeepLinking/TestDeepLinkingUITestsWithHostApp/TestDeepLinkingUITestsWithHostApp.m delete mode 100644 TestHost/AppDelegate.swift delete mode 100644 TestHost/Assets.xcassets/AccentColor.colorset/Contents.json delete mode 100644 TestHost/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 TestHost/Assets.xcassets/Contents.json delete mode 100644 TestHost/Base.lproj/LaunchScreen.storyboard delete mode 100644 TestHost/NSURLSession+Branch.h delete mode 100644 TestHost/NSURLSession+Branch.m delete mode 100644 TestHost/SceneDelegate.swift delete mode 100644 TestHost/TestHost-Bridging-Header.h delete mode 100644 TestHost/ViewController.swift delete mode 100644 TestHostTests/TestHostTests.swift delete mode 100644 TestHostUITests/TestHostUITests.swift delete mode 100644 TestHostUITests/TestHostUITestsLaunchTests.swift diff --git a/BranchSDK.xcodeproj/project.pbxproj b/BranchSDK.xcodeproj/project.pbxproj index e65db2426..d91b0675d 100644 --- a/BranchSDK.xcodeproj/project.pbxproj +++ b/BranchSDK.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 55; + objectVersion = 73; objects = { /* Begin PBXAggregateTarget section */ @@ -54,25 +54,12 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ - 5F2211722894A9C000C5B190 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F2211712894A9C000C5B190 /* AppDelegate.swift */; }; - 5F2211742894A9C000C5B190 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F2211732894A9C000C5B190 /* SceneDelegate.swift */; }; - 5F2211762894A9C000C5B190 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F2211752894A9C000C5B190 /* ViewController.swift */; }; - 5F2211792894A9C000C5B190 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F2211772894A9C000C5B190 /* Main.storyboard */; }; - 5F22117B2894A9C100C5B190 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F22117A2894A9C100C5B190 /* Assets.xcassets */; }; - 5F22117E2894A9C100C5B190 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F22117C2894A9C100C5B190 /* LaunchScreen.storyboard */; }; - 5F2211892894A9C100C5B190 /* TestHostTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F2211882894A9C100C5B190 /* TestHostTests.swift */; }; - 5F2211932894A9C100C5B190 /* TestHostUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F2211922894A9C100C5B190 /* TestHostUITests.swift */; }; - 5F2211952894A9C100C5B190 /* TestHostUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F2211942894A9C100C5B190 /* TestHostUITestsLaunchTests.swift */; }; 5F5FDA162B7DE2FE00F14A43 /* BranchLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5FDA152B7DE2FE00F14A43 /* BranchLogger.m */; }; 5F5FDA172B7DE2FE00F14A43 /* BranchLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5FDA152B7DE2FE00F14A43 /* BranchLogger.m */; }; 5F5FDA182B7DE2FE00F14A43 /* BranchLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5FDA152B7DE2FE00F14A43 /* BranchLogger.m */; }; 5F5FDA1A2B7DE31E00F14A43 /* BranchLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F5FDA192B7DE31E00F14A43 /* BranchLogger.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5F5FDA1B2B7DE31E00F14A43 /* BranchLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F5FDA192B7DE31E00F14A43 /* BranchLogger.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5F5FDA1C2B7DE31E00F14A43 /* BranchLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F5FDA192B7DE31E00F14A43 /* BranchLogger.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5F6DD2482894AEBD00AE9FB0 /* BranchSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */; }; - 5F6DD24C2894AF5E00AE9FB0 /* NSURLSession+Branch.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F6DD24A2894AF5E00AE9FB0 /* NSURLSession+Branch.m */; }; - 5F73EBFA28ECE65400608601 /* BranchSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F73EBF428ECE65400608601 /* BranchSDK.framework */; }; - 5F73EBFB28ECE65400608601 /* BranchSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5F73EBF428ECE65400608601 /* BranchSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 5FA71BA82B7AE6B2008009CA /* Branch.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3A22B7AC6A100EAF29F /* Branch.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5FC446652ACCB97000FF1C87 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 5FC446642ACCB96000FF1C87 /* PrivacyInfo.xcprivacy */; }; 5FC446662ACCB97100FF1C87 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 5FC446642ACCB96000FF1C87 /* PrivacyInfo.xcprivacy */; }; @@ -499,48 +486,50 @@ E7931D842E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; E7931D852E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; E7931D862E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; + E7CA74EF2E1B4F75002EFB40 /* BranchSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */; settings = {ATTRIBUTES = (Required, ); }; }; + E7CA75B92E1B994B002EFB40 /* AdServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7CA75B82E1B994B002EFB40 /* AdServices.framework */; }; + E7CA75BB2E1B9951002EFB40 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7CA75BA2E1B9951002EFB40 /* AdSupport.framework */; }; + E7CA75BC2E1B9957002EFB40 /* BranchSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */; }; + E7CA75BD2E1B9957002EFB40 /* BranchSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 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 */; }; E7F311B22DACB54100F824A7 /* BNCODMInfoCollector.h in Headers */ = {isa = PBXBuildFile; fileRef = E7F311B02DACB54100F824A7 /* BNCODMInfoCollector.h */; }; E7F311B32DACB54100F824A7 /* BNCODMInfoCollector.h in Headers */ = {isa = PBXBuildFile; fileRef = E7F311B02DACB54100F824A7 /* BNCODMInfoCollector.h */; }; - E7FBA85F2E14492700E7AAD9 /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E7FBA8602E1449D100E7AAD9 /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E7FBA8612E1449D100E7AAD9 /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 5F2211852894A9C100C5B190 /* PBXContainerItemProxy */ = { + E7CA75592E1B52F4002EFB40 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 5F2210142894A0DB00C5B190 /* Project object */; proxyType = 1; - remoteGlobalIDString = 5F22116E2894A9C000C5B190; - remoteInfo = TestHost; + remoteGlobalIDString = 5F22101C2894A0DB00C5B190; + remoteInfo = BranchSDK; }; - 5F22118F2894A9C100C5B190 /* PBXContainerItemProxy */ = { + E7CA75A62E1B79CD002EFB40 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 5F2210142894A0DB00C5B190 /* Project object */; proxyType = 1; - remoteGlobalIDString = 5F22116E2894A9C000C5B190; - remoteInfo = TestHost; + remoteGlobalIDString = E7CA755E2E1B59F5002EFB40; + remoteInfo = BranchSDKTestsHostApp; }; - 5F73EBF828ECE65400608601 /* PBXContainerItemProxy */ = { + E7CA75BE2E1B9957002EFB40 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 5F2210142894A0DB00C5B190 /* Project object */; proxyType = 1; - remoteGlobalIDString = 5F73EBF328ECE65400608601; - remoteInfo = "BranchSDK-static"; + remoteGlobalIDString = 5F22101C2894A0DB00C5B190; + remoteInfo = BranchSDK; }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - 5F73EBFF28ECE65400608601 /* Embed Frameworks */ = { + E7CA75C02E1B9957002EFB40 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - 5F73EBFB28ECE65400608601 /* BranchSDK.framework in Embed Frameworks */, + E7CA75BD2E1B9957002EFB40 /* BranchSDK.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -549,24 +538,8 @@ /* Begin PBXFileReference section */ 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BranchSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5F22116F2894A9C000C5B190 /* TestHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestHost.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 5F2211712894A9C000C5B190 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 5F2211732894A9C000C5B190 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - 5F2211752894A9C000C5B190 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 5F2211782894A9C000C5B190 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 5F22117A2894A9C100C5B190 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 5F22117D2894A9C100C5B190 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 5F22117F2894A9C100C5B190 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5F2211842894A9C100C5B190 /* TestHostTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestHostTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5F2211882894A9C100C5B190 /* TestHostTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestHostTests.swift; sourceTree = ""; }; - 5F22118E2894A9C100C5B190 /* TestHostUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestHostUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 5F2211922894A9C100C5B190 /* TestHostUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestHostUITests.swift; sourceTree = ""; }; - 5F2211942894A9C100C5B190 /* TestHostUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestHostUITestsLaunchTests.swift; sourceTree = ""; }; 5F5FDA152B7DE2FE00F14A43 /* BranchLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchLogger.m; sourceTree = ""; }; 5F5FDA192B7DE31E00F14A43 /* BranchLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchLogger.h; sourceTree = ""; }; - 5F6DD2492894AF5E00AE9FB0 /* TestHost-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TestHost-Bridging-Header.h"; sourceTree = ""; }; - 5F6DD24A2894AF5E00AE9FB0 /* NSURLSession+Branch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLSession+Branch.m"; sourceTree = ""; }; - 5F6DD24B2894AF5E00AE9FB0 /* NSURLSession+Branch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLSession+Branch.h"; sourceTree = ""; }; 5F73EBF428ECE65400608601 /* BranchSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BranchSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5F73EC0028EDEAC200608601 /* build_static_xcframework_noidfa.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build_static_xcframework_noidfa.sh; sourceTree = ""; }; 5F73EC0128EDEAC200608601 /* build_static_xcframework.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build_static_xcframework.sh; sourceTree = ""; }; @@ -720,53 +693,125 @@ 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 = ""; }; E7931D832E01C8AE0007A374 /* ConfigurationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ConfigurationController.swift; path = ../BranchSDK_Swift/ConfigurationController.swift; sourceTree = ""; }; + E7CA74EB2E1B4F75002EFB40 /* BranchSDKTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BranchSDKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + E7CA755F2E1B59F5002EFB40 /* BranchSDKTestsHostApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BranchSDKTestsHostApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + E7CA75B82E1B994B002EFB40 /* AdServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdServices.framework; path = System/Library/Frameworks/AdServices.framework; sourceTree = SDKROOT; }; + E7CA75BA2E1B9951002EFB40 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; 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 = ""; }; - E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BranchConstants.h; path = Sources/BranchSDK_ObjC/Public/BranchConstants.h; sourceTree = ""; }; /* End PBXFileReference section */ -/* Begin PBXFrameworksBuildPhase section */ - 5F22101A2894A0DB00C5B190 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + E7CA75522E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + BranchConstants.h, ); - runOnlyForDeploymentPostprocessing = 0; + publicHeaders = ( + BranchConstants.h, + ); + target = 5F22101C2894A0DB00C5B190 /* BranchSDK */; }; - 5F22116C2894A9C000C5B190 /* Frameworks */ = { + E7CA75532E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + BranchConstants.h, + ); + publicHeaders = ( + BranchConstants.h, + ); + target = 5F73EBF328ECE65400608601 /* BranchSDK-static */; + }; + E7CA75542E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + BranchConstants.h, + ); + publicHeaders = ( + BranchConstants.h, + ); + target = 5F79038B28B5765D003144CD /* BranchSDK-tvOS */; + }; + E7CA75552E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = E7CA74EA2E1B4F75002EFB40 /* BranchSDKTests */; + }; + E7CA758B2E1B59F7002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = E7CA755E2E1B59F5002EFB40 /* BranchSDKTestsHostApp */; + }; + E7CA75B12E1B7B02002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + cannedData/example.json, + cannedData/latd_empty_data.json, + cannedData/latd_missing_data.json, + cannedData/latd_missing_window.json, + cannedData/latd.json, + ); + target = E7CA74EA2E1B4F75002EFB40 /* BranchSDKTests */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet section */ + E7CA75562E1B504C002EFB40 /* PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet */ = { + isa = PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet; + buildPhase = E7CA74E72E1B4F75002EFB40 /* Sources */; + membershipExceptions = ( + BNCJsonLoader.h, + "Branch-SDK-Tests-Bridging-Header.h", + ); + }; +/* End PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + E7CA74EC2E1B4F75002EFB40 /* BranchSDKTests */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (E7CA75522E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E7CA75532E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E7CA75542E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E7CA75552E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E7CA75562E1B504C002EFB40 /* PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = BranchSDKTests; sourceTree = ""; }; + E7CA75602E1B59F5002EFB40 /* BranchSDKTestsHostApp */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (E7CA75B12E1B7B02002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E7CA758B2E1B59F7002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = BranchSDKTestsHostApp; sourceTree = ""; }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5F22101A2894A0DB00C5B190 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5F6DD2482894AEBD00AE9FB0 /* BranchSDK.framework in Frameworks */, - 5F73EBFA28ECE65400608601 /* BranchSDK.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5F2211812894A9C100C5B190 /* Frameworks */ = { + 5F73EBF128ECE65400608601 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 5F22118B2894A9C100C5B190 /* Frameworks */ = { + 5F79038928B5765D003144CD /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - 5F73EBF128ECE65400608601 /* Frameworks */ = { + E7CA74E82E1B4F75002EFB40 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + E7CA74EF2E1B4F75002EFB40 /* BranchSDK.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5F79038928B5765D003144CD /* Frameworks */ = { + E7CA755C2E1B59F5002EFB40 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + E7CA75BC2E1B9957002EFB40 /* BranchSDK.framework in Frameworks */, + E7CA75B92E1B994B002EFB40 /* AdServices.framework in Frameworks */, + E7CA75BB2E1B9951002EFB40 /* AdSupport.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -776,13 +821,12 @@ 5F2210132894A0DB00C5B190 = { isa = PBXGroup; children = ( - E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */, 5FCDD36B2B7AC6A100EAF29F /* BranchSDK */, - 5F2211702894A9C000C5B190 /* TestHost */, - 5F2211872894A9C100C5B190 /* TestHostTests */, - 5F2211912894A9C100C5B190 /* TestHostUITests */, 5FF2AFDD28E7C1F200393216 /* Framework */, 5FF2AFDB28E7BF5500393216 /* Scripts */, + E7CA74EC2E1B4F75002EFB40 /* BranchSDKTests */, + E7CA75602E1B59F5002EFB40 /* BranchSDKTestsHostApp */, + E7CA75B72E1B994B002EFB40 /* Frameworks */, 5F22101E2894A0DB00C5B190 /* Products */, ); sourceTree = ""; @@ -791,49 +835,14 @@ isa = PBXGroup; children = ( 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */, - 5F22116F2894A9C000C5B190 /* TestHost.app */, - 5F2211842894A9C100C5B190 /* TestHostTests.xctest */, - 5F22118E2894A9C100C5B190 /* TestHostUITests.xctest */, 5F79038C28B5765D003144CD /* BranchSDK.framework */, 5F73EBF428ECE65400608601 /* BranchSDK.framework */, + E7CA74EB2E1B4F75002EFB40 /* BranchSDKTests.xctest */, + E7CA755F2E1B59F5002EFB40 /* BranchSDKTestsHostApp.app */, ); name = Products; sourceTree = ""; }; - 5F2211702894A9C000C5B190 /* TestHost */ = { - isa = PBXGroup; - children = ( - 5F2211712894A9C000C5B190 /* AppDelegate.swift */, - 5F2211732894A9C000C5B190 /* SceneDelegate.swift */, - 5F2211752894A9C000C5B190 /* ViewController.swift */, - 5F6DD24B2894AF5E00AE9FB0 /* NSURLSession+Branch.h */, - 5F6DD24A2894AF5E00AE9FB0 /* NSURLSession+Branch.m */, - 5F2211772894A9C000C5B190 /* Main.storyboard */, - 5F22117A2894A9C100C5B190 /* Assets.xcassets */, - 5F22117C2894A9C100C5B190 /* LaunchScreen.storyboard */, - 5F22117F2894A9C100C5B190 /* Info.plist */, - 5F6DD2492894AF5E00AE9FB0 /* TestHost-Bridging-Header.h */, - ); - path = TestHost; - sourceTree = ""; - }; - 5F2211872894A9C100C5B190 /* TestHostTests */ = { - isa = PBXGroup; - children = ( - 5F2211882894A9C100C5B190 /* TestHostTests.swift */, - ); - path = TestHostTests; - sourceTree = ""; - }; - 5F2211912894A9C100C5B190 /* TestHostUITests */ = { - isa = PBXGroup; - children = ( - 5F2211922894A9C100C5B190 /* TestHostUITests.swift */, - 5F2211942894A9C100C5B190 /* TestHostUITestsLaunchTests.swift */, - ); - path = TestHostUITests; - sourceTree = ""; - }; 5FCDD36B2B7AC6A100EAF29F /* BranchSDK */ = { isa = PBXGroup; children = ( @@ -1027,6 +1036,15 @@ path = Framework; sourceTree = ""; }; + E7CA75B72E1B994B002EFB40 /* Frameworks */ = { + isa = PBXGroup; + children = ( + E7CA75BA2E1B9951002EFB40 /* AdSupport.framework */, + E7CA75B82E1B994B002EFB40 /* AdServices.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -1034,7 +1052,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - E7FBA85F2E14492700E7AAD9 /* BranchConstants.h in Headers */, 5FCDD52E2B7AC6A300EAF29F /* Branch+Validator.h in Headers */, 5FCDD4A42B7AC6A200EAF29F /* BNCCallbacks.h in Headers */, 5FCDD4922B7AC6A100EAF29F /* BranchLinkProperties.h in Headers */, @@ -1117,7 +1134,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - E7FBA8602E1449D100E7AAD9 /* BranchConstants.h in Headers */, 5FCDD52F2B7AC6A300EAF29F /* Branch+Validator.h in Headers */, 5FCDD4A52B7AC6A200EAF29F /* BNCCallbacks.h in Headers */, 5FCDD4932B7AC6A100EAF29F /* BranchLinkProperties.h in Headers */, @@ -1200,7 +1216,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - E7FBA8612E1449D100E7AAD9 /* BranchConstants.h in Headers */, 5FCDD4BB2B7AC6A200EAF29F /* BranchPasteControl.h in Headers */, 5FCDD5302B7AC6A300EAF29F /* Branch+Validator.h in Headers */, 5FCDD4A62B7AC6A200EAF29F /* BNCCallbacks.h in Headers */, @@ -1300,61 +1315,6 @@ productReference = 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */; productType = "com.apple.product-type.framework"; }; - 5F22116E2894A9C000C5B190 /* TestHost */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5F2211962894A9C100C5B190 /* Build configuration list for PBXNativeTarget "TestHost" */; - buildPhases = ( - 5F22116B2894A9C000C5B190 /* Sources */, - 5F22116C2894A9C000C5B190 /* Frameworks */, - 5F22116D2894A9C000C5B190 /* Resources */, - 5F73EBFF28ECE65400608601 /* Embed Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 5F73EBF928ECE65400608601 /* PBXTargetDependency */, - ); - name = TestHost; - productName = TestHost; - productReference = 5F22116F2894A9C000C5B190 /* TestHost.app */; - productType = "com.apple.product-type.application"; - }; - 5F2211832894A9C100C5B190 /* TestHostTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5F2211992894A9C100C5B190 /* Build configuration list for PBXNativeTarget "TestHostTests" */; - buildPhases = ( - 5F2211802894A9C100C5B190 /* Sources */, - 5F2211812894A9C100C5B190 /* Frameworks */, - 5F2211822894A9C100C5B190 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 5F2211862894A9C100C5B190 /* PBXTargetDependency */, - ); - name = TestHostTests; - productName = TestHostTests; - productReference = 5F2211842894A9C100C5B190 /* TestHostTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 5F22118D2894A9C100C5B190 /* TestHostUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5F22119C2894A9C100C5B190 /* Build configuration list for PBXNativeTarget "TestHostUITests" */; - buildPhases = ( - 5F22118A2894A9C100C5B190 /* Sources */, - 5F22118B2894A9C100C5B190 /* Frameworks */, - 5F22118C2894A9C100C5B190 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 5F2211902894A9C100C5B190 /* PBXTargetDependency */, - ); - name = TestHostUITests; - productName = TestHostUITests; - productReference = 5F22118E2894A9C100C5B190 /* TestHostUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; 5F73EBF328ECE65400608601 /* BranchSDK-static */ = { isa = PBXNativeTarget; buildConfigurationList = 5F73EBFC28ECE65400608601 /* Build configuration list for PBXNativeTarget "BranchSDK-static" */; @@ -1391,6 +1351,54 @@ productReference = 5F79038C28B5765D003144CD /* BranchSDK.framework */; productType = "com.apple.product-type.framework"; }; + E7CA74EA2E1B4F75002EFB40 /* BranchSDKTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = E7CA74F42E1B4F75002EFB40 /* Build configuration list for PBXNativeTarget "BranchSDKTests" */; + buildPhases = ( + E7CA74E72E1B4F75002EFB40 /* Sources */, + E7CA74E82E1B4F75002EFB40 /* Frameworks */, + E7CA74E92E1B4F75002EFB40 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E7CA755A2E1B52F4002EFB40 /* PBXTargetDependency */, + E7CA75A72E1B79CD002EFB40 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + E7CA74EC2E1B4F75002EFB40 /* BranchSDKTests */, + ); + name = BranchSDKTests; + packageProductDependencies = ( + ); + productName = BranchSDKTests; + productReference = E7CA74EB2E1B4F75002EFB40 /* BranchSDKTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + E7CA755E2E1B59F5002EFB40 /* BranchSDKTestsHostApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = E7CA758C2E1B59F7002EFB40 /* Build configuration list for PBXNativeTarget "BranchSDKTestsHostApp" */; + buildPhases = ( + E7CA755B2E1B59F5002EFB40 /* Sources */, + E7CA755C2E1B59F5002EFB40 /* Frameworks */, + E7CA755D2E1B59F5002EFB40 /* Resources */, + E7CA75C02E1B9957002EFB40 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + E7CA75BF2E1B9957002EFB40 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + E7CA75602E1B59F5002EFB40 /* BranchSDKTestsHostApp */, + ); + name = BranchSDKTestsHostApp; + packageProductDependencies = ( + ); + productName = BranchSDKTestsHostApp; + productReference = E7CA755F2E1B59F5002EFB40 /* BranchSDKTestsHostApp.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -1408,18 +1416,6 @@ 5F2211672894A90500C5B190 = { CreatedOnToolsVersion = 13.4.1; }; - 5F22116E2894A9C000C5B190 = { - CreatedOnToolsVersion = 13.4.1; - LastSwiftMigration = 1340; - }; - 5F2211832894A9C100C5B190 = { - CreatedOnToolsVersion = 13.4.1; - TestTargetID = 5F22116E2894A9C000C5B190; - }; - 5F22118D2894A9C100C5B190 = { - CreatedOnToolsVersion = 13.4.1; - TestTargetID = 5F22116E2894A9C000C5B190; - }; 5F73EBF328ECE65400608601 = { CreatedOnToolsVersion = 14.0; LastSwiftMigration = 1640; @@ -1437,10 +1433,16 @@ 5FF9DEF428EE7C3600D62DE1 = { CreatedOnToolsVersion = 14.0; }; + E7CA74EA2E1B4F75002EFB40 = { + CreatedOnToolsVersion = 16.4; + TestTargetID = E7CA755E2E1B59F5002EFB40; + }; + E7CA755E2E1B59F5002EFB40 = { + CreatedOnToolsVersion = 16.4; + }; }; }; buildConfigurationList = 5F2210172894A0DB00C5B190 /* Build configuration list for PBXProject "BranchSDK" */; - compatibilityVersion = "Xcode 13.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -1448,6 +1450,7 @@ Base, ); mainGroup = 5F2210132894A0DB00C5B190; + preferredProjectObjectVersion = 55; productRefGroup = 5F22101E2894A0DB00C5B190 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -1455,13 +1458,12 @@ 5F22101C2894A0DB00C5B190 /* BranchSDK */, 5F73EBF328ECE65400608601 /* BranchSDK-static */, 5F79038B28B5765D003144CD /* BranchSDK-tvOS */, - 5F22116E2894A9C000C5B190 /* TestHost */, - 5F2211832894A9C100C5B190 /* TestHostTests */, - 5F22118D2894A9C100C5B190 /* TestHostUITests */, 5F2211672894A90500C5B190 /* xcframework */, 5FF9DEEC28EE7C0D00D62DE1 /* xcframework-noidfa */, 5FF9DEF428EE7C3600D62DE1 /* static-xcframework */, 5FF9DEF028EE7C2200D62DE1 /* static-xcframework-noidfa */, + E7CA74EA2E1B4F75002EFB40 /* BranchSDKTests */, + E7CA755E2E1B59F5002EFB40 /* BranchSDKTestsHostApp */, ); }; /* End PBXProject section */ @@ -1475,43 +1477,33 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5F22116D2894A9C000C5B190 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5F22117E2894A9C100C5B190 /* LaunchScreen.storyboard in Resources */, - 5F22117B2894A9C100C5B190 /* Assets.xcassets in Resources */, - 5F2211792894A9C000C5B190 /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5F2211822894A9C100C5B190 /* Resources */ = { + 5F73EBF228ECE65400608601 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5FC446662ACCB97100FF1C87 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5F22118C2894A9C100C5B190 /* Resources */ = { + 5F79038A28B5765D003144CD /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5FC446672ACCB97200FF1C87 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5F73EBF228ECE65400608601 /* Resources */ = { + E7CA74E92E1B4F75002EFB40 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5FC446662ACCB97100FF1C87 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5F79038A28B5765D003144CD /* Resources */ = { + E7CA755D2E1B59F5002EFB40 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5FC446672ACCB97200FF1C87 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1673,34 +1665,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5F22116B2894A9C000C5B190 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5F2211762894A9C000C5B190 /* ViewController.swift in Sources */, - 5F6DD24C2894AF5E00AE9FB0 /* NSURLSession+Branch.m in Sources */, - 5F2211722894A9C000C5B190 /* AppDelegate.swift in Sources */, - 5F2211742894A9C000C5B190 /* SceneDelegate.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5F2211802894A9C100C5B190 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5F2211892894A9C100C5B190 /* TestHostTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5F22118A2894A9C100C5B190 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5F2211952894A9C100C5B190 /* TestHostUITestsLaunchTests.swift in Sources */, - 5F2211932894A9C100C5B190 /* TestHostUITests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 5F73EBF028ECE65400608601 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1851,45 +1815,40 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + E7CA74E72E1B4F75002EFB40 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E7CA755B2E1B59F5002EFB40 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 5F2211862894A9C100C5B190 /* PBXTargetDependency */ = { + E7CA755A2E1B52F4002EFB40 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 5F22116E2894A9C000C5B190 /* TestHost */; - targetProxy = 5F2211852894A9C100C5B190 /* PBXContainerItemProxy */; + target = 5F22101C2894A0DB00C5B190 /* BranchSDK */; + targetProxy = E7CA75592E1B52F4002EFB40 /* PBXContainerItemProxy */; }; - 5F2211902894A9C100C5B190 /* PBXTargetDependency */ = { + E7CA75A72E1B79CD002EFB40 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 5F22116E2894A9C000C5B190 /* TestHost */; - targetProxy = 5F22118F2894A9C100C5B190 /* PBXContainerItemProxy */; + target = E7CA755E2E1B59F5002EFB40 /* BranchSDKTestsHostApp */; + targetProxy = E7CA75A62E1B79CD002EFB40 /* PBXContainerItemProxy */; }; - 5F73EBF928ECE65400608601 /* PBXTargetDependency */ = { + E7CA75BF2E1B9957002EFB40 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 5F73EBF328ECE65400608601 /* BranchSDK-static */; - targetProxy = 5F73EBF828ECE65400608601 /* PBXContainerItemProxy */; + target = 5F22101C2894A0DB00C5B190 /* BranchSDK */; + targetProxy = E7CA75BE2E1B9957002EFB40 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ -/* Begin PBXVariantGroup section */ - 5F2211772894A9C000C5B190 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 5F2211782894A9C000C5B190 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 5F22117C2894A9C100C5B190 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 5F22117D2894A9C100C5B190 /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - /* Begin XCBuildConfiguration section */ 5F2210222894A0DB00C5B190 /* Debug */ = { isa = XCBuildConfiguration; @@ -2106,156 +2065,6 @@ }; name = Release; }; - 5F2211972894A9C100C5B190 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = R63EM248DP; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = TestHost/Info.plist; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 15.5; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestHost; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OBJC_BRIDGING_HEADER = "TestHost/TestHost-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 5F2211982894A9C100C5B190 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = R63EM248DP; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = TestHost/Info.plist; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 15.5; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestHost; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OBJC_BRIDGING_HEADER = "TestHost/TestHost-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 5F22119A2894A9C100C5B190 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = R63EM248DP; - GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.5; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestHostTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestHost.app/TestHost"; - }; - name = Debug; - }; - 5F22119B2894A9C100C5B190 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = R63EM248DP; - GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.5; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestHostTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestHost.app/TestHost"; - }; - name = Release; - }; - 5F22119D2894A9C100C5B190 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = R63EM248DP; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestHostUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = TestHost; - }; - name = Debug; - }; - 5F22119E2894A9C100C5B190 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = R63EM248DP; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestHostUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = TestHost; - }; - name = Release; - }; 5F73EBFD28ECE65400608601 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2479,6 +2288,123 @@ }; name = Release; }; + E7CA74F22E1B4F75002EFB40 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = R63EM248DP; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = branch.BranchSDKTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 6.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BranchSDKTestsHostApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/BranchSDKTestsHostApp"; + }; + name = Debug; + }; + E7CA74F32E1B4F75002EFB40 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = R63EM248DP; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = branch.BranchSDKTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 6.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BranchSDKTestsHostApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/BranchSDKTestsHostApp"; + }; + name = Release; + }; + E7CA758D2E1B59F7002EFB40 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = R63EM248DP; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = BranchSDKTestsHostApp/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = BranchSDKTestsHostApp; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = branch.BranchSDKTestsHostApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + E7CA758E2E1B59F7002EFB40 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_ENTITLEMENTS = BranchSDKTestsHostApp/BranchSDKTestsHostAppRelease.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = R63EM248DP; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = BranchSDKTestsHostApp/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = BranchSDKTestsHostApp; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = branch.BranchSDKTestsHostApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -2509,33 +2435,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 5F2211962894A9C100C5B190 /* Build configuration list for PBXNativeTarget "TestHost" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5F2211972894A9C100C5B190 /* Debug */, - 5F2211982894A9C100C5B190 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5F2211992894A9C100C5B190 /* Build configuration list for PBXNativeTarget "TestHostTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5F22119A2894A9C100C5B190 /* Debug */, - 5F22119B2894A9C100C5B190 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5F22119C2894A9C100C5B190 /* Build configuration list for PBXNativeTarget "TestHostUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5F22119D2894A9C100C5B190 /* Debug */, - 5F22119E2894A9C100C5B190 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 5F73EBFC28ECE65400608601 /* Build configuration list for PBXNativeTarget "BranchSDK-static" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -2581,6 +2480,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + E7CA74F42E1B4F75002EFB40 /* Build configuration list for PBXNativeTarget "BranchSDKTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E7CA74F22E1B4F75002EFB40 /* Debug */, + E7CA74F32E1B4F75002EFB40 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E7CA758C2E1B59F7002EFB40 /* Build configuration list for PBXNativeTarget "BranchSDKTestsHostApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E7CA758D2E1B59F7002EFB40 /* Debug */, + E7CA758E2E1B59F7002EFB40 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = 5F2210142894A0DB00C5B190 /* Project object */; diff --git a/DeepLinkDemo/DeepLinkDemo.xcodeproj/xcshareddata/xcschemes/DeepLinkDemo.xcscheme b/BranchSDK.xcodeproj/xcshareddata/xcschemes/BranchSDKTests.xcscheme similarity index 58% rename from DeepLinkDemo/DeepLinkDemo.xcodeproj/xcshareddata/xcschemes/DeepLinkDemo.xcscheme rename to BranchSDK.xcodeproj/xcshareddata/xcschemes/BranchSDKTests.xcscheme index a2671aeb8..6608b0a6d 100644 --- a/DeepLinkDemo/DeepLinkDemo.xcodeproj/xcshareddata/xcschemes/DeepLinkDemo.xcscheme +++ b/BranchSDK.xcodeproj/xcshareddata/xcschemes/BranchSDKTests.xcscheme @@ -1,33 +1,35 @@ + LastUpgradeVersion = "1640" + version = "1.7"> - - - - - - + buildImplicitDependencies = "YES" + buildArchitectures = "Automatic"> + + + + + + + + + BlueprintIdentifier = "E7CA755E2E1B59F5002EFB40" + BuildableName = "BranchSDKTestsHostApp.app" + BlueprintName = "BranchSDKTestsHostApp" + ReferencedContainer = "container:BranchSDK.xcodeproj"> @@ -57,16 +59,15 @@ savedToolIdentifier = "" useCustomWorkingDirectory = "NO" debugDocumentVersioning = "YES"> - + + BlueprintIdentifier = "E7CA755E2E1B59F5002EFB40" + BuildableName = "BranchSDKTestsHostApp.app" + BlueprintName = "BranchSDKTestsHostApp" + ReferencedContainer = "container:BranchSDK.xcodeproj"> - + diff --git a/BranchSDKTests/BNCAPIServerTest.m b/BranchSDKTests/BNCAPIServerTest.m new file mode 100644 index 000000000..28bb3b3b3 --- /dev/null +++ b/BranchSDKTests/BNCAPIServerTest.m @@ -0,0 +1,515 @@ +// +// BNCAPIServerTest.m +// Branch-SDK-Tests +// +// Created by Nidhi Dixit on 9/6/23. +// Copyright © 2023 Branch, Inc. All rights reserved. +// + +#import +#import "BNCServerAPI.h" +#import "BNCSystemObserver.h" +#import "BNCConfig.h" +#import "BranchConstants.h" +#import "Branch.h" + +@interface BNCAPIServerTest : XCTestCase + +@end + +@implementation BNCAPIServerTest + +- (void)testInstallServiceURL { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + + NSString *url = [serverAPI installServiceURL]; + NSString *expectedUrlStr = @"https://api3.branch.io/v1/install"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testOpenServiceURL { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + + NSString *url = [serverAPI openServiceURL]; + NSString *expectedUrlStr = @"https://api3.branch.io/v1/open"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testStandardEventServiceURL { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + + NSString *url = [serverAPI standardEventServiceURL]; + NSString *expectedUrlStr = @"https://api3.branch.io/v2/event/standard"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testCustomEventServiceURL { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + + NSString *url = [serverAPI customEventServiceURL]; + NSString *expectedUrlStr = @"https://api3.branch.io/v2/event/custom"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testLinkServiceURL { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + + NSString *url = [serverAPI linkServiceURL]; + NSString *expectedUrlStr = @"https://api3.branch.io/v1/url"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testQRCodeServiceURL { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + + NSString *url = [serverAPI qrcodeServiceURL]; + NSString *expectedUrlStr = @"https://api3.branch.io/v1/qr-code"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testLATDServiceURL { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + + NSString *url = [serverAPI latdServiceURL]; + NSString *expectedUrlStr = @"https://api3.branch.io/v1/cpid/latd"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testValidationServiceURL { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + + NSString *url = [serverAPI validationServiceURL]; + NSString *expectedUrlPrefix= @"https://api3.branch.io/v1/app-link-settings"; + + XCTAssertTrue([url hasPrefix:expectedUrlPrefix]); +} + +- (void)testInstallServiceURL_Tracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI installServiceURL]; + NSString *expectedUrlStr = @"https://api-safetrack.branch.io/v1/install"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testOpenServiceURL_Tracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI openServiceURL]; + NSString *expectedUrlStr = @"https://api-safetrack.branch.io/v1/open"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testStandardEventServiceURL_Tracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI standardEventServiceURL]; + NSString *expectedUrlStr = @"https://api-safetrack.branch.io/v2/event/standard"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testCustomEventServiceURL_Tracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI customEventServiceURL]; + NSString *expectedUrlStr = @"https://api-safetrack.branch.io/v2/event/custom"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testLinkServiceURL_Tracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI linkServiceURL]; + NSString *expectedUrlStr = @"https://api3.branch.io/v1/url"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testQRCodeServiceURL_Tracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI qrcodeServiceURL]; + NSString *expectedUrlStr = @"https://api3.branch.io/v1/qr-code"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testLATDServiceURL_Tracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI latdServiceURL]; + NSString *expectedUrlStr = @"https://api3.branch.io/v1/cpid/latd"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testValidationServiceURL_Tracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI validationServiceURL]; + NSString *expectedUrlPrefix= @"https://api3.branch.io/v1/app-link-settings"; + + XCTAssertTrue([url hasPrefix:expectedUrlPrefix]); +} + +- (void)testInstallServiceURL_EU { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + + NSString *url = [serverAPI installServiceURL]; + NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/install"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testOpenServiceURL_EU { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + + NSString *url = [serverAPI openServiceURL]; + NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/open"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testStandardEventServiceURL_EU { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + + NSString *url = [serverAPI standardEventServiceURL]; + NSString *expectedUrlStr = @"https://api3-eu.branch.io/v2/event/standard"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testCustomEventServiceURL_EU { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + + NSString *url = [serverAPI customEventServiceURL]; + NSString *expectedUrlStr = @"https://api3-eu.branch.io/v2/event/custom"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testLinkServiceURL_EU { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + + NSString *url = [serverAPI linkServiceURL]; + NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/url"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testQRCodeServiceURL_EU { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + + NSString *url = [serverAPI qrcodeServiceURL]; + NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/qr-code"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testLATDServiceURL_EU { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + + NSString *url = [serverAPI latdServiceURL]; + NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/cpid/latd"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testValidationServiceURL_EU { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + + NSString *url = [serverAPI validationServiceURL]; + NSString *expectedUrlPrefix= @"https://api3-eu.branch.io/v1/app-link-settings"; + + XCTAssertTrue([url hasPrefix:expectedUrlPrefix]); +} + +- (void)testInstallServiceURL_EUTracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI installServiceURL]; + NSString *expectedUrlStr = @"https://api-safetrack-eu.branch.io/v1/install"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testOpenServiceURL_EUTracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI openServiceURL]; + NSString *expectedUrlStr = @"https://api-safetrack-eu.branch.io/v1/open"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testStandardEventServiceURL_EUTracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI standardEventServiceURL]; + NSString *expectedUrlStr = @"https://api-safetrack-eu.branch.io/v2/event/standard"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testCustomEventServiceURL_EUTracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI customEventServiceURL]; + NSString *expectedUrlStr = @"https://api-safetrack-eu.branch.io/v2/event/custom"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testLinkServiceURL_EUTracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI linkServiceURL]; + NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/url"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testQRCodeServiceURL_EUTracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI qrcodeServiceURL]; + NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/qr-code"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testLATDServiceURL_EUTracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI latdServiceURL]; + NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/cpid/latd"; + + XCTAssertTrue([url isEqualToString:expectedUrlStr]); +} + +- (void)testValidationServiceURL_EUTracking { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useEUServers = YES; + serverAPI.useTrackingDomain = YES; + + NSString *url = [serverAPI validationServiceURL]; + NSString *expectedUrlPrefix= @"https://api3-eu.branch.io/v1/app-link-settings"; + + XCTAssertTrue([url hasPrefix:expectedUrlPrefix]); +} + +- (void)testDefaultAPIURL { + BNCServerAPI *serverAPI = [BNCServerAPI new]; + XCTAssertNil(serverAPI.customAPIURL); + + NSString *storedUrl = [[BNCServerAPI sharedInstance] installServiceURL]; + NSString *expectedUrl = [BNC_API_URL stringByAppendingString: @"/v1/install"]; + XCTAssertEqualObjects(storedUrl, expectedUrl); +} + +- (void)testSetAPIURL_Example { + NSString *url = @"https://www.example.com"; + [Branch setAPIUrl:url]; + + NSString *storedUrl = [[BNCServerAPI sharedInstance] installServiceURL]; + NSString *expectedUrl = [url stringByAppendingString: @"/v1/install"]; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + [Branch setAPIUrl:BNC_API_URL]; +} + +- (void)testSetAPIURL_InvalidHttp { + NSString *url = @"Invalid://www.example.com"; + [Branch setAPIUrl:url]; + + NSString *storedUrl = [[BNCServerAPI sharedInstance] installServiceURL]; + NSString *expectedUrl = [BNC_API_URL stringByAppendingString: @"/v1/install"]; + XCTAssertEqualObjects(storedUrl, expectedUrl); +} + +- (void)testSetAPIURL_InvalidEmpty { + NSString *url = @""; + [Branch setAPIUrl:url]; + + NSString *storedUrl = [[BNCServerAPI sharedInstance] installServiceURL]; + NSString *expectedUrl = [BNC_API_URL stringByAppendingString: @"/v1/install"]; + XCTAssertEqualObjects(storedUrl, expectedUrl); +} + + +- (void)testSetSafeTrackServiceURLWithUserTrackingDomain { + NSString *url = @"https://links.toTestDomain.com"; + NSString *safeTrackUrl = @"https://links.toTestDomain-safeTrack.com"; + + [Branch setAPIUrl:url]; + [Branch setSafetrackAPIURL:safeTrackUrl]; + + BNCServerAPI *serverAPI = [BNCServerAPI sharedInstance]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useTrackingDomain = YES; + + NSString *storedUrl = [[BNCServerAPI sharedInstance] installServiceURL]; + NSString *expectedUrl = @"https://links.toTestDomain-safeTrack.com/v1/install"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] openServiceURL]; + expectedUrl = @"https://links.toTestDomain-safeTrack.com/v1/open"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] standardEventServiceURL]; + expectedUrl = @"https://links.toTestDomain-safeTrack.com/v2/event/standard"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] customEventServiceURL]; + expectedUrl = @"https://links.toTestDomain-safeTrack.com/v2/event/custom"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] linkServiceURL]; + expectedUrl = @"https://links.toTestDomain.com/v1/url"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] qrcodeServiceURL]; + expectedUrl = @"https://links.toTestDomain.com/v1/qr-code"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] latdServiceURL]; + expectedUrl = @"https://links.toTestDomain.com/v1/cpid/latd"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] validationServiceURL]; + expectedUrl = @"https://links.toTestDomain.com/v1/app-link-settings"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + [BNCServerAPI sharedInstance].useTrackingDomain = NO; + [BNCServerAPI sharedInstance].useEUServers = NO; + [BNCServerAPI sharedInstance].automaticallyEnableTrackingDomain = YES; + [BNCServerAPI sharedInstance].customAPIURL = nil; + [BNCServerAPI sharedInstance].customSafeTrackAPIURL = nil; + +} + +- (void)testSetSafeTrackServiceURLWithOutUserTrackingDomain { + NSString *url = @"https://links.toTestDomain.com"; + NSString *safeTrackUrl = @"https://links.toTestDomain-safeTrack.com"; + + [Branch setAPIUrl:url]; + [Branch setSafetrackAPIURL:safeTrackUrl]; + + BNCServerAPI *serverAPI = [BNCServerAPI sharedInstance]; + serverAPI.automaticallyEnableTrackingDomain = NO; + serverAPI.useTrackingDomain = NO; + + NSString *storedUrl = [[BNCServerAPI sharedInstance] installServiceURL]; + NSString *expectedUrl = @"https://links.toTestDomain.com/v1/install"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] openServiceURL]; + expectedUrl = @"https://links.toTestDomain.com/v1/open"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] standardEventServiceURL]; + expectedUrl = @"https://links.toTestDomain.com/v2/event/standard"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] customEventServiceURL]; + expectedUrl = @"https://links.toTestDomain.com/v2/event/custom"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] linkServiceURL]; + expectedUrl = @"https://links.toTestDomain.com/v1/url"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] qrcodeServiceURL]; + expectedUrl = @"https://links.toTestDomain.com/v1/qr-code"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] latdServiceURL]; + expectedUrl = @"https://links.toTestDomain.com/v1/cpid/latd"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + storedUrl = [[BNCServerAPI sharedInstance] validationServiceURL]; + expectedUrl = @"https://links.toTestDomain.com/v1/app-link-settings"; + XCTAssertEqualObjects(storedUrl, expectedUrl); + + [BNCServerAPI sharedInstance].useTrackingDomain = NO; + [BNCServerAPI sharedInstance].useEUServers = NO; + [BNCServerAPI sharedInstance].automaticallyEnableTrackingDomain = YES; + [BNCServerAPI sharedInstance].customAPIURL = nil; + [BNCServerAPI sharedInstance].customSafeTrackAPIURL = nil; + +} + +@end diff --git a/BranchSDKTests/BNCAppleReceiptTests.m b/BranchSDKTests/BNCAppleReceiptTests.m new file mode 100644 index 000000000..faff0ef96 --- /dev/null +++ b/BranchSDKTests/BNCAppleReceiptTests.m @@ -0,0 +1,33 @@ +// +// BNCAppleReceiptTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 7/15/19. +// Copyright © 2019 Branch, Inc. All rights reserved. +// + +#import +#import "BNCAppleReceipt.h" + +@interface BNCAppleReceiptTests : XCTestCase + +@end + +@implementation BNCAppleReceiptTests + +- (void)setUp { + +} + +- (void)tearDown { + +} + +- (void)testReceiptOnSimulator { + BNCAppleReceipt *receipt = [[BNCAppleReceipt alloc] init]; + // Appears the simulator can have a receipt + //XCTAssertNil([receipt installReceipt]); + XCTAssertFalse([receipt isTestFlight]); +} + +@end diff --git a/BranchSDKTests/BNCApplicationTests.m b/BranchSDKTests/BNCApplicationTests.m new file mode 100644 index 000000000..147a2a665 --- /dev/null +++ b/BranchSDKTests/BNCApplicationTests.m @@ -0,0 +1,75 @@ +// +// BNCApplication.Test.m +// Branch-SDK-Tests +// +// Created by Edward on 1/10/18. +// Copyright © 2018 Branch, Inc. All rights reserved. +// + +#import +#import "BNCApplication.h" +#import "BNCKeyChain.h" + +@interface BNCApplicationTests : XCTestCase +@end + +@implementation BNCApplicationTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)testApplication { + // Test general info: + + if ([UIApplication sharedApplication] == nil) { + NSLog(@"No host application for BNCApplication testing!"); + return; + } + + BNCApplication *application = [BNCApplication currentApplication]; + XCTAssertEqualObjects(application.bundleID, @"branch.BranchSDKTestsHostApp"); + XCTAssertEqualObjects(application.displayName, @"BranchSDKTestsHostApp"); + XCTAssertEqualObjects(application.shortDisplayName, @"BranchSDKTestsHostApp"); + XCTAssertEqualObjects(application.displayVersionString, @"1.0"); + XCTAssertEqualObjects(application.versionString, @"1"); +} + +- (void) testAppDates { + // App dates. Not a great test but tests basic function: + + if ([UIApplication sharedApplication] == nil) { + NSLog(@"No host application for BNCApplication testing!"); + return; + } + + NSTimeInterval const kOneYearAgo = -365.0 * 24.0 * 60.0 * 60.0; + + BNCApplication *application = [BNCApplication currentApplication]; + XCTAssertTrue(application.firstInstallDate && [application.firstInstallDate timeIntervalSinceNow] > kOneYearAgo); + XCTAssertTrue(application.firstInstallBuildDate && [application.firstInstallBuildDate timeIntervalSinceNow] > kOneYearAgo); + XCTAssertTrue(application.currentInstallDate && [application.currentInstallDate timeIntervalSinceNow] > kOneYearAgo); + XCTAssertTrue(application.currentBuildDate && [application.currentBuildDate timeIntervalSinceNow] > kOneYearAgo); + + NSString*const kBranchKeychainService = @"BranchKeychainService"; + NSString*const kBranchKeychainFirstBuildKey = @"BranchKeychainFirstBuild"; + NSString*const kBranchKeychainFirstInstalldKey = @"BranchKeychainFirstInstall"; + + NSDate * firstBuildDate = + [BNCKeyChain retrieveDateForService:kBranchKeychainService + key:kBranchKeychainFirstBuildKey + error:nil]; + XCTAssertEqualObjects(application.firstInstallBuildDate, firstBuildDate); + + NSDate * firstInstallDate = + [BNCKeyChain retrieveDateForService:kBranchKeychainService + key:kBranchKeychainFirstInstalldKey + error:nil]; + XCTAssertEqualObjects(application.firstInstallDate, firstInstallDate); +} + +@end diff --git a/BranchSDKTests/BNCCallbackMapTests.m b/BranchSDKTests/BNCCallbackMapTests.m new file mode 100644 index 000000000..4d5482499 --- /dev/null +++ b/BranchSDKTests/BNCCallbackMapTests.m @@ -0,0 +1,134 @@ +// +// BNCCallbackMapTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 2/25/20. +// Copyright © 2020 Branch, Inc. All rights reserved. +// + +#import +#import "BNCCallbackMap.h" +#import "NSError+Branch.h" + +// expose private storage object for state checks +@interface BNCCallbackMap() +@property (nonatomic, strong, readwrite) NSMapTable *callbacks; +@end + +@interface BNCCallbackMapTests : XCTestCase + +@end + +@implementation BNCCallbackMapTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)testRequestSaveAndCallback { + BNCCallbackMap *map = [BNCCallbackMap new]; + + __block BOOL successResult = NO; + __block NSError *errorResult = nil; + + // store a request and callback block + BNCServerRequest *request = [BNCServerRequest new]; + [map storeRequest:request withCompletion:^(BOOL success, NSError * _Nullable error) { + successResult = success; + errorResult = error; + }]; + + // confirm there's one entry + XCTAssert([map containsRequest:request] != NO); + XCTAssert(map.callbacks.count == 1); + + // call callback + [map callCompletionForRequest:request withSuccessStatus:YES error:nil]; + + // check if variable was updated + XCTAssertTrue(successResult); + XCTAssertNil(errorResult); +} + +- (void)testRequestSaveAndCallbackWithError { + BNCCallbackMap *map = [BNCCallbackMap new]; + + __block BOOL successResult = YES; + __block NSError *errorResult = nil; + + // store a request and callback block + BNCServerRequest *request = [BNCServerRequest new]; + [map storeRequest:request withCompletion:^(BOOL success, NSError * _Nullable error) { + successResult = success; + errorResult = error; + }]; + + // confirm there's one entry + XCTAssert([map containsRequest:request] != NO); + XCTAssert(map.callbacks.count == 1); + + // call callback + [map callCompletionForRequest:request withSuccessStatus:NO error:[NSError branchErrorWithCode:BNCGeneralError localizedMessage:@"Test Error"]]; + + // check if variable was updated + XCTAssertFalse(successResult); + XCTAssert([@"Test Error" isEqualToString:errorResult.localizedFailureReason]); +} + +- (void)testAttemptCallbackWithUnsavedRequest { + BNCCallbackMap *map = [BNCCallbackMap new]; + + __block BOOL successResult = NO; + __block NSError *errorResult = nil; + + // store a request and callback block + BNCServerRequest *request = [BNCServerRequest new]; + [map storeRequest:request withCompletion:^(BOOL success, NSError * _Nullable error) { + successResult = success; + errorResult = error; + }]; + + // confirm there's one entry + XCTAssert([map containsRequest:request] != NO); + XCTAssert(map.callbacks.count == 1); + + // confirm a new request results in no callback + request = [BNCServerRequest new]; + XCTAssert([map containsRequest:request] == NO); + [map callCompletionForRequest:request withSuccessStatus:YES error:nil]; + + // check if variable was updated + XCTAssertFalse(successResult); + XCTAssertNil(errorResult); +} + +- (void)testRequestsGetReleasedAutomatically { + BNCCallbackMap *map = [BNCCallbackMap new]; + + __block int count = 0; + + BNCServerRequest *request = [BNCServerRequest new]; + [map storeRequest:request withCompletion:^(BOOL success, NSError * _Nullable error) { + count++; + }]; + + for (int i=0; i<100; i++) { + BNCServerRequest *tmp = [BNCServerRequest new]; + [map storeRequest:tmp withCompletion:^(BOOL success, NSError * _Nullable error) { + count++; + }]; + } + + // confirm there's less than 100 entries. By not retaining the tmp request, they should be getting ARC'd + XCTAssert(map.callbacks.count < 100); + + // confirm the one request we held does get a callback + [map callCompletionForRequest:request withSuccessStatus:YES error:nil]; + XCTAssert(count == 1); +} + +@end diff --git a/BranchSDKTests/BNCClassSerializationTests.m b/BranchSDKTests/BNCClassSerializationTests.m new file mode 100644 index 000000000..f1af287d9 --- /dev/null +++ b/BranchSDKTests/BNCClassSerializationTests.m @@ -0,0 +1,120 @@ +// +// BNCClassSerializationTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 3/28/24. +// Copyright © 2024 Branch, Inc. All rights reserved. +// + +#import +#import "BranchEvent.h" +#import "BranchOpenRequest.h" +#import "BranchInstallRequest.h" + +@interface BranchEvent() +// private BranchEvent methods used to build a BranchEventRequest +- (NSDictionary *)buildEventDictionary; +@end + +@interface BranchOpenRequest() +- (NSString *)getActionName; +@end + +@interface BNCClassSerializationTests : XCTestCase + +@end + +// Test serialization of replayable requests +@implementation BNCClassSerializationTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +// BranchEventRequest is creation is tightly coupled with the BranchEvent class +// In order to test building it, we need to expose some private methods. :( +- (BranchEventRequest *)buildBranchEventRequest { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventPurchase]; + NSURL *url = [NSURL URLWithString:@"https://api3.branch.io/v2/event/standard"]; + NSDictionary *eventDictionary = [event buildEventDictionary]; + + BranchEventRequest *request = [[BranchEventRequest alloc] initWithServerURL:url eventDictionary:eventDictionary completion:nil]; + return request; +} + +- (void)testBranchEventRequestArchive { + BranchEventRequest *request = [self buildBranchEventRequest]; + + // archive the event + NSError *error = nil; + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:request requiringSecureCoding:YES error:&error]; + XCTAssertNil(error); + XCTAssertNotNil(data); + + // unarchive the event + id object = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithArray:@[BranchEventRequest.class]] fromData:data error:&error]; + XCTAssertNil(error); + XCTAssertNotNil(object); + + // check object + XCTAssertTrue([object isKindOfClass:BranchEventRequest.class]); + BranchEventRequest *unarchivedRequest = (BranchEventRequest *)object; + + XCTAssertTrue([request.serverURL.absoluteString isEqualToString:unarchivedRequest.serverURL.absoluteString]); + XCTAssertTrue(request.eventDictionary.count == unarchivedRequest.eventDictionary.count); + XCTAssertNil(unarchivedRequest.completion); +} + +- (void)testBranchOpenRequestArchive { + BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:nil]; + request.urlString = @"https://branch.io"; + + // archive the event + NSError *error = nil; + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:request requiringSecureCoding:YES error:&error]; + XCTAssertNil(error); + XCTAssertNotNil(data); + + // unarchive the event + id object = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithArray:@[BranchOpenRequest.class]] fromData:data error:&error]; + XCTAssertNil(error); + XCTAssertNotNil(object); + + // check object + XCTAssertTrue([object isKindOfClass:BranchOpenRequest.class]); + BranchOpenRequest *unarchivedRequest = (BranchOpenRequest *)object; + + XCTAssertTrue([request.urlString isEqualToString:unarchivedRequest.urlString]); + XCTAssertNil(unarchivedRequest.callback); + XCTAssertTrue([@"open" isEqualToString:[unarchivedRequest getActionName]]); +} + +- (void)testBranchInstallRequestArchive { + BranchInstallRequest *request = [[BranchInstallRequest alloc] initWithCallback:nil]; + request.urlString = @"https://branch.io"; + + // archive the event + NSError *error = nil; + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:request requiringSecureCoding:YES error:&error]; + XCTAssertNil(error); + XCTAssertNotNil(data); + + // unarchive the event + id object = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithArray:@[BranchInstallRequest.class]] fromData:data error:&error]; + XCTAssertNil(error); + XCTAssertNotNil(object); + + // check object + XCTAssertTrue([object isKindOfClass:BranchInstallRequest.class]); + BranchInstallRequest *unarchivedRequest = (BranchInstallRequest *)object; + + XCTAssertTrue([request.urlString isEqualToString:unarchivedRequest.urlString]); + XCTAssertNil(unarchivedRequest.callback); + XCTAssertTrue([@"install" isEqualToString:[unarchivedRequest getActionName]]); +} + +@end diff --git a/BranchSDKTests/BNCCrashlyticsWrapperTests.m b/BranchSDKTests/BNCCrashlyticsWrapperTests.m new file mode 100644 index 000000000..4b9be75a4 --- /dev/null +++ b/BranchSDKTests/BNCCrashlyticsWrapperTests.m @@ -0,0 +1,68 @@ +// +// BNCCrashlyticsWrapperTest.m +// Branch-TestBed +// +// Created by Jimmy Dee on 7/18/17. +// Copyright © 2017 Branch Metrics. All rights reserved. +// + +#import +#import "BNCCrashlyticsWrapper.h" + +#pragma mark Crashlytics SDK Stand-In + +@interface FIRCrashlytics : NSObject ++ (FIRCrashlytics *)crashlytics; +@property NSMutableDictionary *values; +- (void)setCustomValue:(id)value forKey:(NSString *)key; +-(id)getCustomValueForKey:(NSString *)key; +@end + +@implementation FIRCrashlytics + ++ (FIRCrashlytics *)crashlytics { + @synchronized (self) { + static FIRCrashlytics * sharedCrashlytics = nil; + if (!sharedCrashlytics) sharedCrashlytics = [[self alloc] init]; + return sharedCrashlytics; + } +} + +- (void)setCustomValue:(id)value forKey:(NSString *)key { + if (!_values) { + _values = [[NSMutableDictionary alloc] init]; + } + [_values setObject:value forKey:key]; +} + +-(id)getCustomValueForKey:(NSString *)key { + return [_values valueForKey:key]; +} +@end + +#pragma mark - BNCCrashlyticsWrapperTest + +@interface BNCCrashlyticsWrapperTests : XCTestCase +@end + +@implementation BNCCrashlyticsWrapperTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)testSetValue { + BNCCrashlyticsWrapper *wrapper = [BNCCrashlyticsWrapper wrapper]; + NSString *value = @"TestString"; + NSString *key = @"TestKey"; + + [wrapper setCustomValue:value forKey:key]; + + XCTAssertEqual([[FIRCrashlytics crashlytics] getCustomValueForKey:key], value); +} + +@end diff --git a/BranchSDKTests/BNCCurrencyTests.m b/BranchSDKTests/BNCCurrencyTests.m new file mode 100644 index 000000000..ec24da0f8 --- /dev/null +++ b/BranchSDKTests/BNCCurrencyTests.m @@ -0,0 +1,194 @@ +// +// BNCCurrencyTests.m +// Branch-SDK-Tests +// +// Created by Nipun Singh on 9/21/23. +// Copyright © 2023 Branch, Inc. All rights reserved. +// + +#import +#import "BNCCurrency.h" + +@interface BNCCurrencyTests : XCTestCase +@end + +@implementation BNCCurrencyTests + +- (void)testEnumValues { + XCTAssertEqualObjects(BNCCurrencyAED, @"AED"); + XCTAssertEqualObjects(BNCCurrencyAFN, @"AFN"); + XCTAssertEqualObjects(BNCCurrencyALL, @"ALL"); + XCTAssertEqualObjects(BNCCurrencyAMD, @"AMD"); + XCTAssertEqualObjects(BNCCurrencyANG, @"ANG"); + XCTAssertEqualObjects(BNCCurrencyAOA, @"AOA"); + XCTAssertEqualObjects(BNCCurrencyARS, @"ARS"); + XCTAssertEqualObjects(BNCCurrencyAUD, @"AUD"); + XCTAssertEqualObjects(BNCCurrencyAWG, @"AWG"); + XCTAssertEqualObjects(BNCCurrencyAZN, @"AZN"); + XCTAssertEqualObjects(BNCCurrencyBAM, @"BAM"); + XCTAssertEqualObjects(BNCCurrencyBBD, @"BBD"); + XCTAssertEqualObjects(BNCCurrencyBDT, @"BDT"); + XCTAssertEqualObjects(BNCCurrencyBGN, @"BGN"); + XCTAssertEqualObjects(BNCCurrencyBHD, @"BHD"); + XCTAssertEqualObjects(BNCCurrencyBIF, @"BIF"); + XCTAssertEqualObjects(BNCCurrencyBMD, @"BMD"); + XCTAssertEqualObjects(BNCCurrencyBND, @"BND"); + XCTAssertEqualObjects(BNCCurrencyBOB, @"BOB"); + XCTAssertEqualObjects(BNCCurrencyBOV, @"BOV"); + XCTAssertEqualObjects(BNCCurrencyBRL, @"BRL"); + XCTAssertEqualObjects(BNCCurrencyBSD, @"BSD"); + XCTAssertEqualObjects(BNCCurrencyBTN, @"BTN"); + XCTAssertEqualObjects(BNCCurrencyBWP, @"BWP"); + XCTAssertEqualObjects(BNCCurrencyBYN, @"BYN"); + XCTAssertEqualObjects(BNCCurrencyBYR, @"BYR"); + XCTAssertEqualObjects(BNCCurrencyBZD, @"BZD"); + XCTAssertEqualObjects(BNCCurrencyCAD, @"CAD"); + XCTAssertEqualObjects(BNCCurrencyCDF, @"CDF"); + XCTAssertEqualObjects(BNCCurrencyCHE, @"CHE"); + XCTAssertEqualObjects(BNCCurrencyCHF, @"CHF"); + XCTAssertEqualObjects(BNCCurrencyCHW, @"CHW"); + XCTAssertEqualObjects(BNCCurrencyCLF, @"CLF"); + XCTAssertEqualObjects(BNCCurrencyCLP, @"CLP"); + XCTAssertEqualObjects(BNCCurrencyCNY, @"CNY"); + XCTAssertEqualObjects(BNCCurrencyCOP, @"COP"); + XCTAssertEqualObjects(BNCCurrencyCOU, @"COU"); + XCTAssertEqualObjects(BNCCurrencyCRC, @"CRC"); + XCTAssertEqualObjects(BNCCurrencyCUC, @"CUC"); + XCTAssertEqualObjects(BNCCurrencyCUP, @"CUP"); + XCTAssertEqualObjects(BNCCurrencyCVE, @"CVE"); + XCTAssertEqualObjects(BNCCurrencyCZK, @"CZK"); + XCTAssertEqualObjects(BNCCurrencyDJF, @"DJF"); + XCTAssertEqualObjects(BNCCurrencyDKK, @"DKK"); + XCTAssertEqualObjects(BNCCurrencyDOP, @"DOP"); + XCTAssertEqualObjects(BNCCurrencyDZD, @"DZD"); + XCTAssertEqualObjects(BNCCurrencyEGP, @"EGP"); + XCTAssertEqualObjects(BNCCurrencyERN, @"ERN"); + XCTAssertEqualObjects(BNCCurrencyETB, @"ETB"); + XCTAssertEqualObjects(BNCCurrencyEUR, @"EUR"); + XCTAssertEqualObjects(BNCCurrencyFJD, @"FJD"); + XCTAssertEqualObjects(BNCCurrencyFKP, @"FKP"); + XCTAssertEqualObjects(BNCCurrencyGBP, @"GBP"); + XCTAssertEqualObjects(BNCCurrencyGEL, @"GEL"); + XCTAssertEqualObjects(BNCCurrencyGHS, @"GHS"); + XCTAssertEqualObjects(BNCCurrencyGIP, @"GIP"); + XCTAssertEqualObjects(BNCCurrencyGMD, @"GMD"); + XCTAssertEqualObjects(BNCCurrencyGNF, @"GNF"); + XCTAssertEqualObjects(BNCCurrencyGTQ, @"GTQ"); + XCTAssertEqualObjects(BNCCurrencyGYD, @"GYD"); + XCTAssertEqualObjects(BNCCurrencyHKD, @"HKD"); + XCTAssertEqualObjects(BNCCurrencyHNL, @"HNL"); + XCTAssertEqualObjects(BNCCurrencyHRK, @"HRK"); + XCTAssertEqualObjects(BNCCurrencyHTG, @"HTG"); + XCTAssertEqualObjects(BNCCurrencyHUF, @"HUF"); + XCTAssertEqualObjects(BNCCurrencyIDR, @"IDR"); + XCTAssertEqualObjects(BNCCurrencyILS, @"ILS"); + XCTAssertEqualObjects(BNCCurrencyINR, @"INR"); + XCTAssertEqualObjects(BNCCurrencyIQD, @"IQD"); + XCTAssertEqualObjects(BNCCurrencyIRR, @"IRR"); + XCTAssertEqualObjects(BNCCurrencyISK, @"ISK"); + XCTAssertEqualObjects(BNCCurrencyJMD, @"JMD"); + XCTAssertEqualObjects(BNCCurrencyJOD, @"JOD"); + XCTAssertEqualObjects(BNCCurrencyJPY, @"JPY"); + XCTAssertEqualObjects(BNCCurrencyKES, @"KES"); + XCTAssertEqualObjects(BNCCurrencyKGS, @"KGS"); + XCTAssertEqualObjects(BNCCurrencyKHR, @"KHR"); + XCTAssertEqualObjects(BNCCurrencyKMF, @"KMF"); + XCTAssertEqualObjects(BNCCurrencyKPW, @"KPW"); + XCTAssertEqualObjects(BNCCurrencyKRW, @"KRW"); + XCTAssertEqualObjects(BNCCurrencyKWD, @"KWD"); + XCTAssertEqualObjects(BNCCurrencyKYD, @"KYD"); + XCTAssertEqualObjects(BNCCurrencyKZT, @"KZT"); + XCTAssertEqualObjects(BNCCurrencyLAK, @"LAK"); + XCTAssertEqualObjects(BNCCurrencyLBP, @"LBP"); + XCTAssertEqualObjects(BNCCurrencyLKR, @"LKR"); + XCTAssertEqualObjects(BNCCurrencyLRD, @"LRD"); + XCTAssertEqualObjects(BNCCurrencyLSL, @"LSL"); + XCTAssertEqualObjects(BNCCurrencyLYD, @"LYD"); + XCTAssertEqualObjects(BNCCurrencyMAD, @"MAD"); + XCTAssertEqualObjects(BNCCurrencyMDL, @"MDL"); + XCTAssertEqualObjects(BNCCurrencyMGA, @"MGA"); + XCTAssertEqualObjects(BNCCurrencyMKD, @"MKD"); + XCTAssertEqualObjects(BNCCurrencyMMK, @"MMK"); + XCTAssertEqualObjects(BNCCurrencyMNT, @"MNT"); + XCTAssertEqualObjects(BNCCurrencyMOP, @"MOP"); + XCTAssertEqualObjects(BNCCurrencyMRO, @"MRO"); + XCTAssertEqualObjects(BNCCurrencyMUR, @"MUR"); + XCTAssertEqualObjects(BNCCurrencyMVR, @"MVR"); + XCTAssertEqualObjects(BNCCurrencyMWK, @"MWK"); + XCTAssertEqualObjects(BNCCurrencyMXN, @"MXN"); + XCTAssertEqualObjects(BNCCurrencyMXV, @"MXV"); + XCTAssertEqualObjects(BNCCurrencyMYR, @"MYR"); + XCTAssertEqualObjects(BNCCurrencyMZN, @"MZN"); + XCTAssertEqualObjects(BNCCurrencyNAD, @"NAD"); + XCTAssertEqualObjects(BNCCurrencyNGN, @"NGN"); + XCTAssertEqualObjects(BNCCurrencyNIO, @"NIO"); + XCTAssertEqualObjects(BNCCurrencyNOK, @"NOK"); + XCTAssertEqualObjects(BNCCurrencyNPR, @"NPR"); + XCTAssertEqualObjects(BNCCurrencyNZD, @"NZD"); + XCTAssertEqualObjects(BNCCurrencyOMR, @"OMR"); + XCTAssertEqualObjects(BNCCurrencyPAB, @"PAB"); + XCTAssertEqualObjects(BNCCurrencyPEN, @"PEN"); + XCTAssertEqualObjects(BNCCurrencyPGK, @"PGK"); + XCTAssertEqualObjects(BNCCurrencyPHP, @"PHP"); + XCTAssertEqualObjects(BNCCurrencyPKR, @"PKR"); + XCTAssertEqualObjects(BNCCurrencyPLN, @"PLN"); + XCTAssertEqualObjects(BNCCurrencyPYG, @"PYG"); + XCTAssertEqualObjects(BNCCurrencyQAR, @"QAR"); + XCTAssertEqualObjects(BNCCurrencyRON, @"RON"); + XCTAssertEqualObjects(BNCCurrencyRSD, @"RSD"); + XCTAssertEqualObjects(BNCCurrencyRUB, @"RUB"); + XCTAssertEqualObjects(BNCCurrencyRWF, @"RWF"); + XCTAssertEqualObjects(BNCCurrencySAR, @"SAR"); + XCTAssertEqualObjects(BNCCurrencySBD, @"SBD"); + XCTAssertEqualObjects(BNCCurrencySCR, @"SCR"); + XCTAssertEqualObjects(BNCCurrencySDG, @"SDG"); + XCTAssertEqualObjects(BNCCurrencySEK, @"SEK"); + XCTAssertEqualObjects(BNCCurrencySGD, @"SGD"); + XCTAssertEqualObjects(BNCCurrencySHP, @"SHP"); + XCTAssertEqualObjects(BNCCurrencySLL, @"SLL"); + XCTAssertEqualObjects(BNCCurrencySOS, @"SOS"); + XCTAssertEqualObjects(BNCCurrencySRD, @"SRD"); + XCTAssertEqualObjects(BNCCurrencySSP, @"SSP"); + XCTAssertEqualObjects(BNCCurrencySTD, @"STD"); + XCTAssertEqualObjects(BNCCurrencySYP, @"SYP"); + XCTAssertEqualObjects(BNCCurrencySZL, @"SZL"); + XCTAssertEqualObjects(BNCCurrencyTHB, @"THB"); + XCTAssertEqualObjects(BNCCurrencyTJS, @"TJS"); + XCTAssertEqualObjects(BNCCurrencyTMT, @"TMT"); + XCTAssertEqualObjects(BNCCurrencyTND, @"TND"); + XCTAssertEqualObjects(BNCCurrencyTOP, @"TOP"); + XCTAssertEqualObjects(BNCCurrencyTRY, @"TRY"); + XCTAssertEqualObjects(BNCCurrencyTTD, @"TTD"); + XCTAssertEqualObjects(BNCCurrencyTWD, @"TWD"); + XCTAssertEqualObjects(BNCCurrencyTZS, @"TZS"); + XCTAssertEqualObjects(BNCCurrencyUAH, @"UAH"); + XCTAssertEqualObjects(BNCCurrencyUGX, @"UGX"); + XCTAssertEqualObjects(BNCCurrencyUSD, @"USD"); + XCTAssertEqualObjects(BNCCurrencyUSN, @"USN"); + XCTAssertEqualObjects(BNCCurrencyUYI, @"UYI"); + XCTAssertEqualObjects(BNCCurrencyUYU, @"UYU"); + XCTAssertEqualObjects(BNCCurrencyUZS, @"UZS"); + XCTAssertEqualObjects(BNCCurrencyVEF, @"VEF"); + XCTAssertEqualObjects(BNCCurrencyVND, @"VND"); + XCTAssertEqualObjects(BNCCurrencyVUV, @"VUV"); + XCTAssertEqualObjects(BNCCurrencyWST, @"WST"); + XCTAssertEqualObjects(BNCCurrencyXAF, @"XAF"); + XCTAssertEqualObjects(BNCCurrencyXAG, @"XAG"); + XCTAssertEqualObjects(BNCCurrencyXAU, @"XAU"); + XCTAssertEqualObjects(BNCCurrencyXCD, @"XCD"); + XCTAssertEqualObjects(BNCCurrencyXDR, @"XDR"); + XCTAssertEqualObjects(BNCCurrencyXOF, @"XOF"); + XCTAssertEqualObjects(BNCCurrencyXPD, @"XPD"); + XCTAssertEqualObjects(BNCCurrencyXPF, @"XPF"); + XCTAssertEqualObjects(BNCCurrencyXPT, @"XPT"); + XCTAssertEqualObjects(BNCCurrencyXSU, @"XSU"); + XCTAssertEqualObjects(BNCCurrencyXTS, @"XTS"); + XCTAssertEqualObjects(BNCCurrencyXUA, @"XUA"); + XCTAssertEqualObjects(BNCCurrencyXXX, @"XXX"); + XCTAssertEqualObjects(BNCCurrencyYER, @"YER"); + XCTAssertEqualObjects(BNCCurrencyZAR, @"ZAR"); + XCTAssertEqualObjects(BNCCurrencyZMW, @"ZMW"); +} + + +@end diff --git a/BranchSDKTests/BNCDeviceInfoTests.m b/BranchSDKTests/BNCDeviceInfoTests.m new file mode 100644 index 000000000..39b4ee5d8 --- /dev/null +++ b/BranchSDKTests/BNCDeviceInfoTests.m @@ -0,0 +1,190 @@ +// +// BNCDeviceInfoTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 11/21/19. +// Copyright © 2019 Branch, Inc. All rights reserved. +// + +#import +#import "BNCDeviceInfo.h" +#import "BNCUserAgentCollector.h" + +@interface BNCDeviceInfoTests : XCTestCase +@property (nonatomic, strong, readwrite) BNCDeviceInfo *deviceInfo; +@end + +@implementation BNCDeviceInfoTests + +- (void)setUp { + [self workaroundUserAgentLazyLoad]; + self.deviceInfo = [BNCDeviceInfo new]; +} + +// user agent needs to be loaded +- (void)workaroundUserAgentLazyLoad { + __block XCTestExpectation *expectation = [self expectationWithDescription:@"setup"]; + [[BNCUserAgentCollector instance] loadUserAgentWithCompletion:^(NSString * _Nullable userAgent) { + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:^(NSError * _Nullable error) { }]; +} + +- (void)tearDown { + +} + +- (void)testHardwareId { + XCTAssertNotNil(self.deviceInfo.hardwareId); + + // verify hardwareId is a valid UUID + NSUUID *hardwareId = [[NSUUID alloc] initWithUUIDString:self.deviceInfo.hardwareId]; + XCTAssertNotNil(hardwareId); +} + +- (void)testHardwareIdType { + // without ATT, this is the IDFV. Branch servers expect it as vendor_id + XCTAssert([self.deviceInfo.hardwareIdType isEqualToString:@"vendor_id"]); +} + +- (void)testIsRealHardwareId { + XCTAssert(self.deviceInfo.isRealHardwareId); +} + +- (void)testAdvertiserId { + // the testbed does not show the ATT prompt. + XCTAssertNil(self.deviceInfo.advertiserId); +} + +- (void)testVendorId { + XCTAssertNotNil(self.deviceInfo.vendorId); + + // verify vendorId is a valid UUID + NSUUID *vendorId = [[NSUUID alloc] initWithUUIDString:self.deviceInfo.vendorId]; + XCTAssertNotNil(vendorId); +} + +- (void)testAnonId { + XCTAssertNotNil(self.deviceInfo.anonId); + + // verify anonId is a valid UUID + NSUUID *anonId = [[NSUUID alloc] initWithUUIDString:self.deviceInfo.anonId]; + XCTAssertNotNil(anonId); +} + +- (void)testOptedInStatus { + // the testbed does not show the ATT prompt. + XCTAssert([self.deviceInfo.optedInStatus isEqualToString:@"not_determined"]); +} + +- (void)testIsFirstOptIn { + // the testbed does not show the ATT prompt. + XCTAssert(self.deviceInfo.isFirstOptIn == NO); +} + +- (void)testLocalIPAddress { + NSString *address = [self.deviceInfo localIPAddress]; + XCTAssertNotNil(address); + XCTAssert(address.length > 7); +} + +- (void)testConnectionType { + // simulator is on wifi + XCTAssert([[self.deviceInfo connectionType] isEqualToString:@"wifi"]); +} + +- (void)testBrandName { + XCTAssert([@"Apple" isEqualToString:self.deviceInfo.brandName]); +} + +- (void)testModelName_Simulator { + // intel processor + bool x86_64 = [@"x86_64" isEqualToString:self.deviceInfo.modelName]; + + // apple processor + bool arm64 = [@"arm64" isEqualToString:self.deviceInfo.modelName]; + + XCTAssert(x86_64 || arm64); +} + +- (void)testOSName { + XCTAssertNotNil(self.deviceInfo.osName); + XCTAssert([@"iOS" isEqualToString:self.deviceInfo.osName]); +} + +- (void)testOSVersion { + XCTAssertNotNil(self.deviceInfo.osVersion); + XCTAssert([self.deviceInfo.osVersion isEqualToString:[UIDevice currentDevice].systemVersion]); +} + +- (void)testOSBuildVersion { + XCTAssertNotNil(self.deviceInfo.osBuildVersion); +} + +- (void)testEnvironment { + // currently not running unit tests on extensions + XCTAssert([@"FULL_APP" isEqualToString:self.deviceInfo.environment]); +} + +- (void)testCpuType_Simulator { + // intel processors + bool x86 = [@"7" isEqualToString:self.deviceInfo.cpuType]; + + // apple processors + bool arm = [@"16777228" isEqualToString:self.deviceInfo.cpuType]; + + XCTAssert(x86 || arm); +} + +- (void)testScreenWidth { + XCTAssert(self.deviceInfo.screenWidth.intValue >= 320); +} + +- (void)testScreenHeight { + XCTAssert(self.deviceInfo.screenHeight.intValue >= 320); +} + +- (void)testScreenScale { + XCTAssert(self.deviceInfo.screenScale.intValue >= 1); +} + +- (void)testLocale { + NSString *locale = [NSLocale currentLocale].localeIdentifier; + XCTAssertNotNil(locale); + XCTAssert([locale isEqualToString:self.deviceInfo.locale]); +} + +- (void)testCountry { + NSString *locale = [NSLocale currentLocale].localeIdentifier; + XCTAssertNotNil(locale); + XCTAssert([locale containsString:self.deviceInfo.country]); +} + +- (void)testLanguage { + NSString *locale = [NSLocale currentLocale].localeIdentifier; + XCTAssertNotNil(locale); + XCTAssert([locale containsString:self.deviceInfo.language]); +} + +- (void)testUserAgentString { + XCTAssert([self.deviceInfo.userAgentString containsString:@"AppleWebKit"]); +} + +- (void)testApplicationVersion_TestBed { + XCTAssert([@"1.0" isEqualToString:self.deviceInfo.applicationVersion]); +} + +- (void)testRegisterPluginNameVersion { + XCTAssertNil(self.deviceInfo.pluginName); + XCTAssertNil(self.deviceInfo.pluginVersion); + + NSString *expectedName = @"react native"; + NSString *expectedVersion = @"1.0.0"; + + [self.deviceInfo registerPluginName:expectedName version:expectedVersion]; + + XCTAssert([expectedName isEqualToString:self.deviceInfo.pluginName]); + XCTAssert([expectedVersion isEqualToString:self.deviceInfo.pluginVersion]); +} + +@end diff --git a/BranchSDKTests/BNCDeviceSystemTests.m b/BranchSDKTests/BNCDeviceSystemTests.m new file mode 100644 index 000000000..0a47b73d9 --- /dev/null +++ b/BranchSDKTests/BNCDeviceSystemTests.m @@ -0,0 +1,62 @@ +// +// BNCDeviceSystemTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 11/14/19. +// Copyright © 2019 Branch, Inc. All rights reserved. +// + +#import +#import "BNCDeviceSystem.h" + +@interface BNCDeviceSystemTests : XCTestCase + +@property (nonatomic, strong, readwrite) BNCDeviceSystem *deviceSystem; + +@end + +@implementation BNCDeviceSystemTests + +- (void)setUp { + self.deviceSystem = [BNCDeviceSystem new]; +} + +- (void)tearDown { + +} + +- (void)testSystemBuildVersion { + XCTAssertNotNil(self.deviceSystem.systemBuildVersion); + XCTAssert(self.deviceSystem.systemBuildVersion.length > 0); +} + +- (void)testMachine_Simulator { + // intel processor + bool x86_64 = [@"x86_64" isEqualToString:self.deviceSystem.machine]; + + // apple processor + bool arm64 = [@"arm64" isEqualToString:self.deviceSystem.machine]; + + XCTAssert(x86_64 || arm64); +} + +- (void)testCPUType_Simulator { + // intel processor + bool x86 = [@(7) isEqualToNumber:self.deviceSystem.cpuType]; + bool x86_sub = [@(8) isEqualToNumber:self.deviceSystem.cpuSubType]; + + // apple processor + bool arm = [@(16777228) isEqualToNumber:self.deviceSystem.cpuType]; + bool arm_sub = [@(2) isEqualToNumber:self.deviceSystem.cpuSubType]; + + XCTAssert(x86 || arm); + +// cpu subtype is different on cloud runners +// if (x86) { +// XCTAssert(x86_sub); +// } else { +// XCTAssert(arm_sub); +// } +} + +@end diff --git a/BranchSDKTests/BNCDisableAdNetworkCalloutsTests.m b/BranchSDKTests/BNCDisableAdNetworkCalloutsTests.m new file mode 100644 index 000000000..ea277ac39 --- /dev/null +++ b/BranchSDKTests/BNCDisableAdNetworkCalloutsTests.m @@ -0,0 +1,59 @@ +// +// BNCDisableAdNetworkCalloutsTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 3/2/20. +// Copyright © 2020 Branch, Inc. All rights reserved. +// + +#import +#import "BNCPreferenceHelper.h" +#import "BNCDeviceInfo.h" +#import "BNCServerInterface.h" +@import BranchSDK; + +@interface BNCServerInterface() +- (void)updateDeviceInfoToMutableDictionary:(NSMutableDictionary *)dict; +@end + +@interface BNCDisableAdNetworkCalloutsTests : XCTestCase + +@end + +// These tests are not parallelizable and therefore disabled by default +// This is due to the tight coupling between BNCPreferenceHelper and BNCDeviceInfo +@implementation BNCDisableAdNetworkCalloutsTests +/* +- (void)setUp { + [BNCPreferenceHelper preferenceHelper].disableAdNetworkCallouts = YES; +} + +- (void)tearDown { + [BNCPreferenceHelper preferenceHelper].disableAdNetworkCallouts = NO; +} + +// check on the V2 dictionary +- (void)testV2Dictionary { + NSDictionary *dict = [[BNCDeviceInfo getInstance] v2dictionary]; + XCTAssertNotNil(dict); + XCTAssertNotNil(dict[@"brand"]); + XCTAssertNotNil(dict[@"os"]); + XCTAssertNotNil(dict[@"sdk"]); + XCTAssertNotNil(dict[@"sdk_version"]); + + XCTAssertTrue(dict[@"disable_ad_network_callouts"]); +} + +// check on V1 payload +- (void)testV1Payload { + BNCServerInterface *interface = [BNCServerInterface new]; + interface.preferenceHelper = [BNCPreferenceHelper preferenceHelper]; + + NSMutableDictionary *tmp = [NSMutableDictionary new]; + [interface updateDeviceInfoToMutableDictionary:tmp]; + + XCTAssertNotNil(tmp); + XCTAssertTrue(tmp[@"disable_ad_network_callouts"]); +} +*/ +@end diff --git a/BranchSDKTests/BNCEncodingUtilsTests.m b/BranchSDKTests/BNCEncodingUtilsTests.m new file mode 100644 index 000000000..0b18fe51a --- /dev/null +++ b/BranchSDKTests/BNCEncodingUtilsTests.m @@ -0,0 +1,609 @@ +// +// BNCEncodingUtils.m +// Branch +// +// Created by Graham Mueller on 4/1/15. +// Copyright (c) 2015 Branch Metrics. All rights reserved. +// + +#import +#import "BNCEncodingUtils.h" + +@interface BNCEncodingUtilsTests : XCTestCase +@end + +@implementation BNCEncodingUtilsTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +#pragma mark - EncodeDictionaryToJsonString tests + +- (void)testEncodeDictionaryToJsonStringWithExpectedParams { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; + [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"]; + NSDate *date = [dateFormatter dateFromString:@"2015-04-01T00:00:00-05:00"]; + NSString *formattedDateString = [dateFormatter stringFromDate:date]; + + NSURL *someUrl = [NSURL URLWithString:@"https://branch.io"]; + NSDictionary *dataDict = @{ + @"foo": @"bar", + @"num": @1, + @"array": @[ @"array", @"items" ], + @"dict": @{ @"sub": @1 }, + @"url": someUrl, + @"date": date + }; + NSString *expectedEncodedString = [NSString stringWithFormat: + @"{\"foo\":\"bar\",\"num\":1,\"array\":[\"array\",\"items\"],\"dict\":{\"sub\":1},\"url\":\"https://branch.io\",\"date\":\"%@\"}", + formattedDateString]; + NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonString:dataDict]; + + XCTAssertEqualObjects(expectedEncodedString, encodedValue); +} + +- (void)testEncodeDictionaryToJsonStringWithUnexpectedParams { + NSObject *arbitraryObj = [[NSObject alloc] init]; + NSDictionary *dataDict = @{ @"foo": @"bar", @"random": arbitraryObj }; + NSString *expectedEncodedString = @"{\"foo\":\"bar\"}"; + + NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonString:dataDict]; + + XCTAssertEqualObjects(expectedEncodedString, encodedValue); +} + +- (void)testEncodeDictionaryToJsonStringStringWithNull { + NSDictionary *dataDict = @{ @"foo": [NSNull null] }; + NSString *expectedEncodedString = @"{\"foo\":null}"; + + NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonString:dataDict]; + + XCTAssertEqualObjects(expectedEncodedString, encodedValue); +} + +- (void)testEncodingNilDictionaryToJsonString { + NSDictionary *dataDict = nil; + NSString *expectedEncodedString = @"{}"; + + NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonString:dataDict]; + + XCTAssertEqualObjects(expectedEncodedString, encodedValue); +} + +- (void)testEncodeDictionaryToJsonStringWithNoKeys { + NSDictionary *emptyDict = @{ }; + NSString *expectedEncodedString = @"{}"; + + NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonString:emptyDict]; + + XCTAssertEqualObjects(expectedEncodedString, encodedValue); +} + +- (void)testEncodeDictionaryToJsonStringWithQuotes { + NSDictionary *dictionaryWithQuotes = @{ @"my\"cool\"key": @"my\"cool\"value" }; + NSString *expectedEncodedString = @"{\"my\\\"cool\\\"key\":\"my\\\"cool\\\"value\"}"; + + NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonString:dictionaryWithQuotes]; + + XCTAssertEqualObjects(expectedEncodedString, encodedValue); +} + +- (void)testSimpleEncodeDictionaryToJsonData { + NSDictionary *dataDict = @{ @"foo": @"bar" }; + NSData *expectedEncodedData = [@"{\"foo\":\"bar\"}" dataUsingEncoding:NSUTF8StringEncoding]; + + NSData *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonData:dataDict]; + + XCTAssertEqualObjects(expectedEncodedData, encodedValue); +} + +- (void)testEncodeDictionaryToQueryString { + NSDictionary *dataDict = @{ @"foo": @"bar", @"something": @"something & something" }; + NSString *expectedEncodedString = @"?foo=bar&something=something%20%26%20something"; + + NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToQueryString:dataDict]; + + XCTAssertEqualObjects(expectedEncodedString, encodedValue); +} + + +#pragma mark - EncodeArrayToJsonString + +- (void)testEncodeArrayToJsonStringWithExpectedParams { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; + [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"]; + NSDate *date = [dateFormatter dateFromString:@"2015-04-01T00:00:00Z"]; + NSString *formattedDateString = [dateFormatter stringFromDate:date]; + + NSURL *someUrl = [NSURL URLWithString:@"https://branch.io"]; + NSArray *dataArray = @[ @"bar", @1, @[ @"array", @"items" ], @{ @"sub": @1 }, someUrl, date ]; + NSString *expectedEncodedString = [NSString stringWithFormat:@"[\"bar\",1,[\"array\",\"items\"],{\"sub\":1},\"https://branch.io\",\"%@\"]", formattedDateString]; + + NSString *encodedValue = [BNCEncodingUtils encodeArrayToJsonString:dataArray]; + + XCTAssertEqualObjects(expectedEncodedString, encodedValue); +} + +- (void)testEncodeArrayToJsonStringWithUnexpectedParams { + NSObject *arbitraryObj = [[NSObject alloc] init]; + NSArray *dataArray = @[ @"bar", arbitraryObj ]; + NSString *expectedEncodedString = @"[\"bar\"]"; + + NSString *encodedValue = [BNCEncodingUtils encodeArrayToJsonString:dataArray]; + + XCTAssertEqualObjects(expectedEncodedString, encodedValue); +} + +- (void)testEncodeArrayToJsonStringStringWithNull { + NSArray *dataArray = @[ [NSNull null] ]; + NSString *expectedEncodedString = @"[null]"; + + NSString *encodedValue = [BNCEncodingUtils encodeArrayToJsonString:dataArray]; + + XCTAssertEqualObjects(expectedEncodedString, encodedValue); +} + +- (void)testEncodeArrayToJsonStringWithNoValues { + NSArray *emptyArray = @[ ]; + NSString *expectedEncodedString = @"[]"; + + NSString *encodedValue = [BNCEncodingUtils encodeArrayToJsonString:emptyArray]; + + XCTAssertEqualObjects(expectedEncodedString, encodedValue); +} + +- (void)testEncodingEmptyArrayToJsonString { + NSArray *emptyArray = nil; + NSString *expectedEncodedString = @"[]"; + + NSString *encodedValue = [BNCEncodingUtils encodeArrayToJsonString:emptyArray]; + + XCTAssertEqualObjects(expectedEncodedString, encodedValue); +} + +- (void)testEncodeArrayToJsonStringWithQuotes { + NSArray *arrayWithQuotes = @[ @"my\"cool\"value1", @"my\"cool\"value2" ]; + NSString *expectedEncodedString = @"[\"my\\\"cool\\\"value1\",\"my\\\"cool\\\"value2\"]"; + + NSString *encodedValue = [BNCEncodingUtils encodeArrayToJsonString:arrayWithQuotes]; + + XCTAssertEqualObjects(expectedEncodedString, encodedValue); +} + + +#pragma mark - Character Length tests + +- (void)testChineseCharactersWithLengthGreaterThanOne { + NSString *multiCharacterString = @"𥑮"; + NSDictionary *jsonDict = @{ @"foo": multiCharacterString }; + NSString *expectedEncoding = @"{\"foo\":\"𥑮\"}"; + NSInteger expectedLength = [expectedEncoding lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + NSData *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonData:jsonDict]; + + XCTAssertEqual(expectedLength, [encodedValue length]); +} + + +#pragma mark - DecodeToDictionary tests + +- (void)testDecodeJsonDataToDictionary { + NSData *encodedData = [@"{\"foo\":\"bar\"}" dataUsingEncoding:NSUTF8StringEncoding]; + NSDictionary *expectedDataDict = @{ @"foo": @"bar" }; + + NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonDataToDictionary:encodedData]; + + XCTAssertEqualObjects(decodedValue, expectedDataDict); +} + +- (void)testDecodeJsonStringToDictionary { + NSString *encodedString = @"{\"foo\":\"bar\"}"; + NSDictionary *expectedDataDict = @{ @"foo": @"bar" }; + + NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonStringToDictionary:encodedString]; + + XCTAssertEqualObjects(decodedValue, expectedDataDict); +} + +#if 0 + +// From Ed: See note below +- (void)testDecodeJsonStringToDictionaryWithNilDecodedString { + char badCStr[5] = { '{', 'f', ':', 'o', '}' }; // not nil terminated + NSString *encodedString = [NSString stringWithUTF8String:badCStr]; + NSDictionary *expectedDataDict = @{ }; + + NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonStringToDictionary:encodedString]; + + XCTAssertEqualObjects(decodedValue, expectedDataDict); +} + +#else + +- (void)testDecodeJsonStringToDictionaryWithNilDecodedString { + NSString *encodedString = nil; + NSDictionary *expectedDataDict = @{ }; + NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonStringToDictionary:encodedString]; + XCTAssertEqualObjects(decodedValue, expectedDataDict); +} + +#endif + +- (void)testDecodeBase64EncodedJsonStringToDictionary { + NSString *encodedString = [BNCEncodingUtils base64EncodeStringToString:@"{\"foo\":\"bar\"}"]; + NSDictionary *expectedDataDict = @{ @"foo": @"bar" }; + + NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonStringToDictionary:encodedString]; + + XCTAssertEqualObjects(decodedValue, expectedDataDict); +} + +- (void)testDecodeNonASCIIString { + // Should fail, but not crash. + NSString* result = [BNCEncodingUtils base64DecodeStringToString:@"𝄞"]; + XCTAssertNil(result); +} + +#if 0 + +// From Ed: I don't get the point of this test. +// It reads memory from the stack as a C string and decodes it as an NSString? +// The test itself won't run consistently and may fault sometimes. +- (void)testDecodeBase64JsonStringToDictionaryWithNilDecodedString { + char badCStr[5] = { '{', 'f', ':', 'o', '}' }; // not nil terminated + NSString *encodedString = [NSString stringWithUTF8String:badCStr]; + NSString *base64EncodedString = [BNCEncodingUtils base64EncodeStringToString:encodedString]; + NSDictionary *expectedDataDict = @{ }; + + NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonStringToDictionary:base64EncodedString]; + + XCTAssertEqualObjects(decodedValue, expectedDataDict); +} + +#else + +// This should do the same thing without faulting during the test. +- (void)testDecodeBase64JsonStringToDictionaryWithNilDecodedString { + NSString *base64EncodedString = nil; + NSDictionary *expectedDataDict = @{ }; + NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonStringToDictionary:base64EncodedString]; + XCTAssertEqualObjects(decodedValue, expectedDataDict); +} + +#endif + +- (void)testDecodeQueryStringToDictionary { + NSString *encodedString = @"foo=bar&baz=1&quux=&quo=Hi%20there"; + NSDictionary *expectedDataDict = @{ @"foo": @"bar", @"baz": @"1", @"quo": @"Hi there" }; // always goes to string + + NSDictionary *decodedValue = [BNCEncodingUtils decodeQueryStringToDictionary:encodedString]; + + XCTAssertEqualObjects(decodedValue, expectedDataDict); +} + +#pragma mark - Test Util methods + +- (NSString *)stringForDate:(NSDate *)date { + static NSDateFormatter *dateFormatter = nil; + static dispatch_once_t onceToken = 0; + + dispatch_once(&onceToken, ^{ + dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; // POSIX to avoid weird issues + [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"]; + }); + + return [dateFormatter stringFromDate:date]; +} + +#pragma mark - Base64EncodeData Tests + +#define _countof(array) (sizeof(array)/sizeof(array[0])) + +- (void)testBase64EncodeData { + NSData *data = nil; + NSString *truth = nil; + NSString *string = nil; + + string = [BNCEncodingUtils base64EncodeData:nil]; + XCTAssertEqualObjects(string, @""); + + string = [BNCEncodingUtils base64EncodeData:[NSData new]]; + XCTAssertEqualObjects(string, @""); + + uint8_t b1[] = {0, 1, 2, 3, 4, 5}; + data = [[NSData alloc] initWithBytes:b1 length:_countof(b1)]; + truth = @"AAECAwQF"; + string = [BNCEncodingUtils base64EncodeData:data]; + XCTAssertEqualObjects(string, truth); + + // Test that 1, 2, 3, 4, 5 length data encode correctly. + + data = [[NSData alloc] initWithBytes:b1 length:1]; + truth = @"AA=="; + string = [BNCEncodingUtils base64EncodeData:data]; + XCTAssertEqualObjects(string, truth); + + data = [[NSData alloc] initWithBytes:b1 length:2]; + truth = @"AAE="; + string = [BNCEncodingUtils base64EncodeData:data]; + XCTAssertEqualObjects(string, truth); + + data = [[NSData alloc] initWithBytes:b1 length:3]; + truth = @"AAEC"; + string = [BNCEncodingUtils base64EncodeData:data]; + XCTAssertEqualObjects(string, truth); + + data = [[NSData alloc] initWithBytes:b1 length:4]; + truth = @"AAECAw=="; + string = [BNCEncodingUtils base64EncodeData:data]; + XCTAssertEqualObjects(string, truth); + + data = [[NSData alloc] initWithBytes:b1 length:5]; + truth = @"AAECAwQ="; + string = [BNCEncodingUtils base64EncodeData:data]; + XCTAssertEqualObjects(string, truth); + + uint8_t b2[] = { + 0x00, 0x10, 0x83, 0x10, 0x51, 0x87, 0x20, 0x92, 0x8B, 0x30, 0xD3, 0x8F, 0x41, 0x14, 0x93, 0x51, + 0x55, 0x97, 0x61, 0x96, 0x9B, 0x71, 0xD7, 0x9F, 0x82, 0x18, 0xA3, 0x92, 0x59, 0xA7, 0xA2, 0x9A, + 0xAB, 0xB2, 0xDB, 0xAF, 0xC3, 0x1C, 0xB3, 0xD3, 0x5D, 0xB7, 0xE3, 0x9E, 0xBB, 0xF3, 0xDF, 0xBF, + }; + data = [[NSData alloc] initWithBytes:b2 length:_countof(b2)]; + truth = @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + string = [BNCEncodingUtils base64EncodeData:data]; + XCTAssertEqualObjects(string, truth); +} + +- (void)testBase64DecodeString { + NSData *data = nil; + + data = [BNCEncodingUtils base64DecodeString:nil]; + XCTAssertEqual(data, nil); + + data = [BNCEncodingUtils base64DecodeString:@""]; + XCTAssertEqualObjects(data, [NSData new]); + + uint8_t truth[] = {0, 1, 2, 3, 4, 5}; + + data = [BNCEncodingUtils base64DecodeString:@"AAECAwQF"]; + XCTAssertTrue( data.length == 6 && memcmp(data.bytes, truth, 6) == 0 ); + + // Test that 1, 2, 3, 4, 5 length data encode correctly. + + #define testDecode(string, dataLength) { \ + data = [BNCEncodingUtils base64DecodeString:string]; \ + XCTAssertTrue( data.length == dataLength && memcmp(data.bytes, truth, dataLength) == 0 ); \ + } + + testDecode(@"AA==", 1); + testDecode(@"AAE=", 2); + testDecode(@"AAEC", 3); + testDecode(@"AAECAw==", 4); + testDecode(@"AAECAwQ=", 5); + + uint8_t b2[] = { + 0x00, 0x10, 0x83, 0x10, 0x51, 0x87, 0x20, 0x92, 0x8B, 0x30, 0xD3, 0x8F, 0x41, 0x14, 0x93, 0x51, + 0x55, 0x97, 0x61, 0x96, 0x9B, 0x71, 0xD7, 0x9F, 0x82, 0x18, 0xA3, 0x92, 0x59, 0xA7, 0xA2, 0x9A, + 0xAB, 0xB2, 0xDB, 0xAF, 0xC3, 0x1C, 0xB3, 0xD3, 0x5D, 0xB7, 0xE3, 0x9E, 0xBB, 0xF3, 0xDF, 0xBF, + }; + data = [BNCEncodingUtils base64DecodeString: + @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"]; + XCTAssertTrue( data.length == _countof(b2) && memcmp(data.bytes, b2, _countof(b2)) == 0 ); + + // Test decode invalid data + data = [BNCEncodingUtils base64DecodeString: + @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcde (Junk:%&*^**) fghijklmnopqrstuvwxyz0123456789+/"]; + XCTAssertEqual(data, nil); +} + +#pragma mark - Hex String Tests + +- (void) testHexStringFromData { + + NSString *s = nil; + + s = [BNCEncodingUtils hexStringFromData:[NSData data]]; + XCTAssertEqualObjects(s, @""); + + unsigned char bytes1[] = { 0x01 }; + s = [BNCEncodingUtils hexStringFromData:[NSData dataWithBytes:bytes1 length:1]]; + XCTAssertEqualObjects(s, @"01"); + + unsigned char bytes2[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef + }; + NSString *truth = + @"000102030405060708090A0B0C0D0E0F" + "E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"; + + s = [BNCEncodingUtils hexStringFromData:[NSData dataWithBytes:bytes2 length:sizeof(bytes2)]]; + XCTAssertEqualObjects(s, truth); +} + +- (void) testDataFromHexString { + + NSData *data = nil; + + // nil + data = [BNCEncodingUtils dataFromHexString:nil]; + XCTAssertEqual(data, nil); + + // empty string + data = [BNCEncodingUtils dataFromHexString:@""]; + XCTAssertEqualObjects(data, [NSData data]); + + // upper string + unsigned char bytes[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef + }; + + NSString *stringUpper = + @"000102030405060708090A0B0C0D0E0F" + "E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"; + + data = [BNCEncodingUtils dataFromHexString:stringUpper]; + XCTAssertEqualObjects(data, [NSData dataWithBytes:bytes length:sizeof(bytes)]); + + // lower string + + NSString *stringLower = + @"000102030405060708090a0b0c0d0e0f" + "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"; + + data = [BNCEncodingUtils dataFromHexString:stringLower]; + XCTAssertEqualObjects(data, [NSData dataWithBytes:bytes length:sizeof(bytes)]); + + // white space + + NSString *stringWS = + @" 000102030405060708090a0b0c0d0e0f\n" + "e0e1e2e3e4e5e6\t\t\te7e8e9eaebeced\vee\ref"; + + data = [BNCEncodingUtils dataFromHexString:stringWS]; + XCTAssertEqualObjects(data, [NSData dataWithBytes:bytes length:sizeof(bytes)]); + + // odd number of charaters + + NSString *stringShort = + @"000102030405060708090a0b0c0d0e0f" + "e0e1e2e3e4e5e6e7e8e9eaebecedeee"; + + data = [BNCEncodingUtils dataFromHexString:stringShort]; + XCTAssertEqual(data, nil); + + // invalid characters + + NSString *stringInvalid = + @"000102030405060708090a0b0c0d0e0fInvalid" + "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"; + + data = [BNCEncodingUtils dataFromHexString:stringInvalid]; + XCTAssertEqual(data, nil); + + // singles + + NSString *stringShortShort1 = @"A"; + data = [BNCEncodingUtils dataFromHexString:stringShortShort1]; + XCTAssertEqual(data, nil); + + NSString *stringShortShort2 = @"af"; + unsigned char stringShortShort2Bytes[] = { 0xaf }; + data = [BNCEncodingUtils dataFromHexString:stringShortShort2]; + XCTAssertEqualObjects(data, [NSData dataWithBytes:stringShortShort2Bytes length:1]); +} + +- (void) testPercentDecoding { + + NSString *s = nil; + s = [BNCEncodingUtils stringByPercentDecodingString:nil]; + XCTAssert(s == nil); + + NSArray* tests = @[ + @"", + @"", + + @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", + @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", + + @"-._~", + @"-._~", + + @"one%20two", + @"one two", + + // @"one+two", + // @"one two", + + @"one%2Btwo", + @"one+two", + + @"%21%23%24%26%27%28%29%2A%2B%2C%3A%3B%3D%40%5B%5D", + @"!#$&'()*+,:;=@[]", + ]; + + for (int i = 0; i < tests.count; i+=2) { + NSString *result = [BNCEncodingUtils stringByPercentDecodingString:tests[i]]; + XCTAssertEqualObjects(result, tests[i+1]); + } +} + +- (void) testQueryItems { + + NSURL *URL = nil; + NSArray* items = nil; + NSArray* expected = nil; + + items = [BNCEncodingUtils queryItems:URL]; + XCTAssert(items != nil && items.count == 0); + + URL = [NSURL URLWithString:@"http://example.com/thus?a=1&a=2&b=3"]; + items = [BNCEncodingUtils queryItems:URL]; + expected = @[ [BNCKeyValue key:@"a" value:@"1"], [BNCKeyValue key:@"a" value:@"2"], [BNCKeyValue key:@"b" value:@"3"] ]; + XCTAssertEqualObjects(items, expected); + + URL = [NSURL URLWithString:@"http://example.com/thus"]; + items = [BNCEncodingUtils queryItems:URL]; + expected = @[ ]; + XCTAssertEqualObjects(items, expected); + + URL = [NSURL URLWithString:@"http://example.com/thus?"]; + items = [BNCEncodingUtils queryItems:URL]; + expected = @[ ]; + XCTAssertEqualObjects(items, expected); + + URL = [NSURL URLWithString:@"http://example.com/thus?="]; + items = [BNCEncodingUtils queryItems:URL]; + expected = @[ ]; + XCTAssertEqualObjects(items, expected); + + URL = [NSURL URLWithString:@"http://example.com/thus?a="]; + items = [BNCEncodingUtils queryItems:URL]; + expected = @[ [BNCKeyValue key:@"a" value:@""] ]; + XCTAssertEqualObjects(items, expected); + + URL = [NSURL URLWithString:@"http://example.com/thus?=1"]; + items = [BNCEncodingUtils queryItems:URL]; + expected = @[ [BNCKeyValue key:@"" value:@"1"] ]; + XCTAssertEqualObjects(items, expected); + + URL = [NSURL URLWithString:@"http://example.com/thus?a=1&"]; + items = [BNCEncodingUtils queryItems:URL]; + expected = @[ [BNCKeyValue key:@"a" value:@"1"] ]; + XCTAssertEqualObjects(items, expected); + + URL = [NSURL URLWithString:@"http://example.com/thus?a=1&&b=2"]; + items = [BNCEncodingUtils queryItems:URL]; + expected = @[ [BNCKeyValue key:@"a" value:@"1"], [BNCKeyValue key:@"b" value:@"2"] ]; + XCTAssertEqualObjects(items, expected); + + URL = [NSURL URLWithString:@"http://example.com/thus?a=1&b==2"]; + items = [BNCEncodingUtils queryItems:URL]; + expected = @[ [BNCKeyValue key:@"a" value:@"1"], [BNCKeyValue key:@"b" value:@"=2"] ]; + XCTAssertEqualObjects(items, expected); +} + +- (void) testSanitzeString { + NSString*test = @"\b\f\n\r\t\"`\\"; + NSString*truth = @"\\b\\f\\n\\r\\t\\\"'\\\\"; + NSString*result = [BNCEncodingUtils sanitizedStringFromString:test]; + XCTAssertEqualObjects(result, truth); +} + +// Branch servers never return a json array at the top level. However, our parser should enforce it. +- (void)testArrayJSON { + NSString *test = @"[\"helloworld\"]"; + NSDictionary *tmp = [BNCEncodingUtils decodeJsonStringToDictionary:test]; + XCTAssert([tmp isKindOfClass:[NSDictionary class]]); +} + +@end diff --git a/BranchSDKTests/BNCJSONUtilityTests.m b/BranchSDKTests/BNCJSONUtilityTests.m new file mode 100644 index 000000000..7f5f1c1cf --- /dev/null +++ b/BranchSDKTests/BNCJSONUtilityTests.m @@ -0,0 +1,188 @@ +// +// BNCJSONUtilityTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 9/17/19. +// Copyright © 2019 Branch, Inc. All rights reserved. +// + +#import +#import "BNCJSONUtility.h" +#import "BNCJsonLoader.h" + +@interface BNCJSONUtilityTests : XCTestCase +@property (nonatomic, strong, readwrite) NSDictionary *json; +@end + +@implementation BNCJSONUtilityTests + +- (void)setUp { + self.json = [BNCJsonLoader dictionaryFromJSONFileNamed:@"example"]; + XCTAssertNotNil(self.json); +} + +- (void)tearDown { + +} + +- (void)testIsNumber { + NSNumber *number = [NSNumber numberWithInt:314]; + XCTAssertTrue([BNCJSONUtility isNumber:number]); +} + +- (void)testIsNumber_Boxed { + XCTAssertTrue([BNCJSONUtility isNumber:@(1.0)]); +} + +- (void)testIsNumber_Nil { + XCTAssertFalse([BNCJSONUtility isNumber:nil]); +} + +- (void)testIsNumber_String { + XCTAssertFalse([BNCJSONUtility isNumber:@"1.0"]); +} + +- (void)testIsString { + XCTAssertTrue([BNCJSONUtility isString:@"1.0"]); +} + +- (void)testIsString_MutableString { + NSMutableString *string = [NSMutableString new]; + XCTAssertTrue([BNCJSONUtility isString:string]); +} + +- (void)testIsString_EmptyString { + XCTAssertTrue([BNCJSONUtility isString:@""]); +} + +- (void)testIsString_Nil { + XCTAssertFalse([BNCJSONUtility isString:nil]); +} + +- (void)testIsString_Number { + XCTAssertFalse([BNCJSONUtility isString:@(1.0)]); +} + +- (void)testIsArray { + NSArray *tmp = @[@1, @2]; + XCTAssertTrue([BNCJSONUtility isArray:tmp]); +} + +- (void)testIsArray_MutableArray { + NSMutableArray *tmp = [NSMutableArray new]; + XCTAssertTrue([BNCJSONUtility isArray:tmp]); +} + +- (void)testIsArray_EmptyArray { + XCTAssertTrue([BNCJSONUtility isArray:@[]]); +} + +- (void)testIsArray_Nil { + XCTAssertFalse([BNCJSONUtility isArray:nil]); +} + +- (void)testIsArray_Dictionary { + XCTAssertFalse([BNCJSONUtility isArray:[NSDictionary new]]); +} + +// successful call on untyped dictionary +- (void)testUntypedDictionary_CorrectType { + NSString *string = self.json[@"user_string"]; + XCTAssertNotNil(string); + XCTAssertTrue(([string isKindOfClass:[NSString class]] || [string isKindOfClass:[NSMutableString class]])); +} + +// demonstrates that an untyped dictionary can lead to type mismatches cause it always returns id +- (void)testUntypedDictionary_IncorrectType { + NSString *string = self.json[@"user_number"]; + XCTAssertNotNil(string); + XCTAssertTrue(([string isKindOfClass:[NSNumber class]])); +} + +- (void)testStringForKey_InvalidKey { + id key = @(1); + NSString *string = [BNCJSONUtility stringForKey:key json:self.json]; + XCTAssertNil(string); +} + +- (void)testStringForKey { + NSString *string = [BNCJSONUtility stringForKey:@"user_string" json:self.json]; + XCTAssertNotNil(string); + XCTAssertTrue(([string isKindOfClass:[NSString class]] || [string isKindOfClass:[NSMutableString class]])); +} + +- (void)testStringForKey_IncorrectType { + NSString *string = [BNCJSONUtility stringForKey:@"user_number" json:self.json]; + XCTAssertNil(string); +} + +- (void)testNumberForKey { + NSNumber *number = [BNCJSONUtility numberForKey:@"user_number" json:self.json]; + XCTAssertNotNil(number); + XCTAssertTrue([number isKindOfClass:[NSNumber class]]); +} + +- (void)testNumberForKey_IncorrectType { + NSNumber *number = [BNCJSONUtility numberForKey:@"user_string" json:self.json]; + XCTAssertNil(number); +} + +- (void)testDictionaryForKey { + NSDictionary *dict = [BNCJSONUtility dictionaryForKey:@"user_dict" json:self.json]; + XCTAssertNotNil(dict); + XCTAssertTrue(([dict isKindOfClass:NSDictionary.class] || [dict isKindOfClass:NSMutableDictionary.class])); +} + +- (void)testDictionaryForKey_IncorrectType { + NSDictionary *dict = [BNCJSONUtility dictionaryForKey:@"user_array" json:self.json]; + XCTAssertNil(dict); +} + +- (void)testArrayForKey { + NSArray *array = [BNCJSONUtility arrayForKey:@"user_array" json:self.json]; + XCTAssertNotNil(array); + XCTAssertTrue(([array isKindOfClass:[NSArray class]] || [array isKindOfClass:[NSMutableArray class]])); +} + +- (void)testArrayForKey_IncorrectType { + NSArray *array = [BNCJSONUtility arrayForKey:@"user_dict" json:self.json]; + XCTAssertNil(array); +} + +- (void)testStringArrayForKey { + NSArray *array = [BNCJSONUtility stringArrayForKey:@"user_array" json:self.json]; + XCTAssertNotNil(array); + XCTAssertTrue(array.count > 0); +} + +- (void)testStringArrayForKey_MixedTypes { + NSArray *array = [BNCJSONUtility stringArrayForKey:@"user_array_mixed" json:self.json]; + XCTAssertNotNil(array); + XCTAssertTrue(array.count > 0); +} + +- (void)testStringArrayForKey_Numbers { + NSArray *array = [BNCJSONUtility stringArrayForKey:@"user_array_numbers" json:self.json]; + XCTAssertNotNil(array); + XCTAssertTrue(array.count == 0); +} + +- (void)testStringDictionaryForKey { + NSDictionary *dict = [BNCJSONUtility stringDictionaryForKey:@"user_dict" json:self.json]; + XCTAssertNotNil(dict); + XCTAssertTrue(dict.count > 0); +} + +- (void)testStringDictionaryForKey_MixedTypes { + NSDictionary *dict = [BNCJSONUtility stringDictionaryForKey:@"user_dict_mixed" json:self.json]; + XCTAssertNotNil(dict); + XCTAssertTrue(dict.count > 0); +} + +- (void)testStringDictionaryForKey_Numbers { + NSDictionary *dict = [BNCJSONUtility stringDictionaryForKey:@"user_dict_numbers" json:self.json]; + XCTAssertNotNil(dict); + XCTAssertTrue(dict.count == 0); +} + +@end diff --git a/BranchSDKTests/BNCJsonLoader.h b/BranchSDKTests/BNCJsonLoader.h new file mode 100644 index 000000000..6df022300 --- /dev/null +++ b/BranchSDKTests/BNCJsonLoader.h @@ -0,0 +1,20 @@ +// +// BNCJsonLoader.h +// Branch-TestBed +// +// Created by Ernest Cho on 9/16/19. +// Copyright © 2019 Branch, Inc. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface BNCJsonLoader : NSObject + +// test utility that loads json files from the Test Bundle. only works on hosted tests ++ (NSDictionary *)dictionaryFromJSONFileNamed:(NSString *)fileName; + +@end + +NS_ASSUME_NONNULL_END diff --git a/BranchSDKTests/BNCJsonLoader.m b/BranchSDKTests/BNCJsonLoader.m new file mode 100644 index 000000000..098798ba8 --- /dev/null +++ b/BranchSDKTests/BNCJsonLoader.m @@ -0,0 +1,27 @@ +// +// BNCJsonLoader.m +// Branch-TestBed +// +// Created by Ernest Cho on 9/16/19. +// Copyright © 2019 Branch, Inc. All rights reserved. +// + +#import "BNCJsonLoader.h" + +@implementation BNCJsonLoader + ++ (NSDictionary *)dictionaryFromJSONFileNamed:(NSString *)fileName { + + // Since this class is part of the Test target, [self class] returns the Test Bundle + NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"json"]; + + NSString *jsonString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL]; + + id dict = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; + if ([dict isKindOfClass:NSDictionary.class]) { + return dict; + } + return nil; +} + +@end diff --git a/BranchSDKTests/BNCKeyChainTests.m b/BranchSDKTests/BNCKeyChainTests.m new file mode 100644 index 000000000..07af91a22 --- /dev/null +++ b/BranchSDKTests/BNCKeyChainTests.m @@ -0,0 +1,121 @@ +// +// BNCKeyChainTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 1/6/22. +// Copyright © 2022 Branch, Inc. All rights reserved. +// + +#import +#import "BNCKeyChain.h" + +@interface BNCKeyChainTests : XCTestCase +@property (nonatomic, copy, readwrite) NSString *serviceName; +@end + +@implementation BNCKeyChainTests + +- (void)setUp { + self.serviceName = @"Service"; +} + +- (void)tearDown { + +} + +- (void)testEnvironment { + // Keychain tests must be hosted in an app, otherwise it won't have security access. + XCTAssertFalse([UIApplication sharedApplication] == nil); + + NSString *group = [BNCKeyChain securityAccessGroup]; + XCTAssertTrue(group.length > 0); +} + +- (void)testRemoveValues_Empty { + NSError *error = [BNCKeyChain removeValuesForService:nil key:nil]; + XCTAssertTrue(error == nil); +} + +- (void)testRetrieveDate_Empty { + NSError *error; + NSDate *date = [BNCKeyChain retrieveDateForService:self.serviceName key:@"testKey" error:&error]; + XCTAssertTrue(date == nil && error.code == errSecItemNotFound); +} + +- (void)testStoreAndRetrieveDate { + NSError *error; + NSString *key = @"testKey"; + NSDate *date = [NSDate date]; + + [BNCKeyChain storeDate:date forService:self.serviceName key:key cloudAccessGroup:nil]; + NSDate *tmp = [BNCKeyChain retrieveDateForService:self.serviceName key:key error:&error]; + XCTAssertNil(error); + XCTAssertTrue([date isEqualToDate:tmp]); + + // cleanup + error = [BNCKeyChain removeValuesForService:self.serviceName key:key]; + XCTAssertNil(error); +} + +- (void)testStore_Nil { + NSError *error; + NSString *key = @"testKey"; + NSDate *date = nil; + + error = [BNCKeyChain storeDate:date forService:self.serviceName key:key cloudAccessGroup:nil]; + XCTAssertTrue(error.code == errSecParam); + + NSDate *tmp = [BNCKeyChain retrieveDateForService:self.serviceName key:key error:&error]; + XCTAssertNil(tmp); + XCTAssertTrue(error.code == errSecItemNotFound); +} + +- (void)testStoreAndRetrieveMultipleDates { + NSError *error; + NSString *keyA = @"testKeyA"; + NSString *keyB = @"testKeyB"; + + NSDate *dateA = [NSDate date]; + NSDate *dateB = [NSDate dateWithTimeIntervalSinceNow:1]; + XCTAssertFalse([dateA isEqualToDate:dateB]); + + [BNCKeyChain storeDate:dateA forService:self.serviceName key:keyA cloudAccessGroup:nil]; + [BNCKeyChain storeDate:dateB forService:self.serviceName key:keyB cloudAccessGroup:nil]; + + NSDate *tmpA = [BNCKeyChain retrieveDateForService:self.serviceName key:keyA error:&error]; + XCTAssertNil(error); + XCTAssertTrue([dateA isEqualToDate:tmpA]); + + NSDate *tmpB = [BNCKeyChain retrieveDateForService:self.serviceName key:keyB error:&error]; + XCTAssertNil(error); + XCTAssertTrue([dateB isEqualToDate:tmpB]); + + XCTAssertFalse([tmpA isEqualToDate:tmpB]); + + // cleanup + error = [BNCKeyChain removeValuesForService:self.serviceName key:keyA]; + XCTAssertNil(error); + error = [BNCKeyChain removeValuesForService:self.serviceName key:keyB]; + XCTAssertNil(error); +} + +- (void)testStoreAndRetrieveDate_retrieveWrongKey { + NSError *error; + NSString *keyA = @"testKeyA"; + NSString *keyB = @"testKeyB"; + NSDate *date = [NSDate date]; + + [BNCKeyChain storeDate:date forService:self.serviceName key:keyA cloudAccessGroup:nil]; + NSDate *tmp = [BNCKeyChain retrieveDateForService:self.serviceName key:keyB error:&error]; + XCTAssertNil(tmp); + XCTAssertTrue(error.code == errSecItemNotFound); + + // cleanup + error = [BNCKeyChain removeValuesForService:self.serviceName key:keyA]; + XCTAssertNil(error); + error = [BNCKeyChain removeValuesForService:self.serviceName key:keyB]; + XCTAssertNil(error); +} + + +@end diff --git a/BranchSDKTests/BNCLinkDataTests.m b/BranchSDKTests/BNCLinkDataTests.m new file mode 100644 index 000000000..10eb3cb25 --- /dev/null +++ b/BranchSDKTests/BNCLinkDataTests.m @@ -0,0 +1,103 @@ +// +// BNCLinkDataTests.m +// Branch-TestBed +// +// Created by Graham Mueller on 6/15/15. +// Copyright (c) 2015 Branch Metrics. All rights reserved. +// + +#import +#import "BNCLinkData.h" + +@interface BNCLinkDataTests : XCTestCase +@end + +@implementation BNCLinkDataTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)testBasicObjectHash { + BNCLinkData *a = [[BNCLinkData alloc] init]; + BNCLinkData *b = [[BNCLinkData alloc] init]; + + XCTAssertEqual([a hash], [b hash]); +} + +- (void)testObjectHashWithSameValuesForKeys { + NSArray * const TAGS = @[ @"foo-tag" ]; + NSString * const ALIAS = @"foo-alias"; + BranchLinkType const LINK_TYPE = BranchLinkTypeOneTimeUse; + NSString * const CHANNEL = @"foo-channel"; + NSString * const FEATURE = @"foo-feature"; + NSString * const STAGE = @"foo-stage"; + NSDictionary * const PARAMS = @{ @"foo-key": @"foo-value" }; + NSInteger const DURATION = 1; + NSString * const IGNORE_UA = @"foo-ua"; + + BNCLinkData *a = [[BNCLinkData alloc] init]; + [a setupTags:TAGS]; + [a setupAlias:ALIAS]; + [a setupType:LINK_TYPE]; + [a setupChannel:CHANNEL]; + [a setupFeature:FEATURE]; + [a setupStage:STAGE]; + [a setupParams:PARAMS]; + [a setupMatchDuration:DURATION]; + [a setupIgnoreUAString:IGNORE_UA]; + + BNCLinkData *b = [[BNCLinkData alloc] init]; + [b setupTags:TAGS]; + [b setupAlias:ALIAS]; + [b setupType:LINK_TYPE]; + [b setupChannel:CHANNEL]; + [b setupFeature:FEATURE]; + [b setupStage:STAGE]; + [b setupParams:PARAMS]; + [b setupMatchDuration:DURATION]; + [b setupIgnoreUAString:IGNORE_UA]; + + XCTAssertEqual([a hash], [b hash]); +} + +- (void)testObjectHashWithDifferentValuesForSameKeys { + BNCLinkData *a = [[BNCLinkData alloc] init]; + [a setupTags:@[ @"foo-tags" ]]; + [a setupAlias:@"foo-alias"]; + [a setupType:BranchLinkTypeOneTimeUse]; + [a setupChannel:@"foo-channel"]; + [a setupFeature:@"foo-feature"]; + [a setupStage:@"foo-stage"]; + [a setupParams:@{ @"foo-key": @"foo-value" }]; + [a setupMatchDuration:1]; + [a setupIgnoreUAString:@"foo-ua"]; + + BNCLinkData *b = [[BNCLinkData alloc] init]; + [b setupTags:@[ @"bar-tag" ]]; + [b setupAlias:@"bar-alias"]; + [b setupType:BranchLinkTypeUnlimitedUse]; + [b setupChannel:@"bar-channel"]; + [b setupFeature:@"bar-feature"]; + [b setupStage:@"bar-stage"]; + [b setupParams:@{ @"bar-key": @"bar-value" }]; + [b setupMatchDuration:2]; + [b setupIgnoreUAString:@"bar-ua"]; + + XCTAssertNotEqual([a hash], [b hash]); +} + +- (void)testObjectHashWithDifferentCasedValues { + BNCLinkData *a = [[BNCLinkData alloc] init]; + [a setupAlias:@"foo-alias"]; + BNCLinkData *b = [[BNCLinkData alloc] init]; + [b setupAlias:@"FOO-ALIAS"]; + + XCTAssertNotEqual([a hash], [b hash]); +} + +@end diff --git a/BranchSDKTests/BNCNetworkInterfaceTests.m b/BranchSDKTests/BNCNetworkInterfaceTests.m new file mode 100644 index 000000000..8869ecc37 --- /dev/null +++ b/BranchSDKTests/BNCNetworkInterfaceTests.m @@ -0,0 +1,82 @@ +// +// BNCNetworkInterfaceTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 3/10/23. +// Copyright © 2023 Branch, Inc. All rights reserved. +// + +#import +#import +#import "BNCNetworkInterface.h" + +// Category using inet_pton to validate +@implementation NSString (Test) + +- (BOOL)isValidIPAddress { + const char *utf8 = [self UTF8String]; + int success; + + struct in_addr dst; + success = inet_pton(AF_INET, utf8, &dst); + if (success != 1) { + struct in6_addr dst6; + success = inet_pton(AF_INET6, utf8, &dst6); + } + + return success == 1; +} + +@end + +@interface BNCNetworkInterfaceTests : XCTestCase + +@end + +@implementation BNCNetworkInterfaceTests + +- (void)setUp { + +} + +- (void)tearDown { + +} + +// verify tooling method works +- (void)testIPValidationCategory { + XCTAssert(![@"" isValidIPAddress]); + + // ipv4 + XCTAssert([@"0.0.0.0" isValidIPAddress]); + XCTAssert([@"127.0.0.1" isValidIPAddress]); + XCTAssert([@"10.1.2.3" isValidIPAddress]); + XCTAssert([@"172.0.0.0" isValidIPAddress]); + XCTAssert([@"192.0.0.0" isValidIPAddress]); + XCTAssert([@"255.255.255.255" isValidIPAddress]); + + // invalid ipv4 + XCTAssert(![@"-1.0.0.0" isValidIPAddress]); + XCTAssert(![@"256.0.0.0" isValidIPAddress]); + + // ipv6 + XCTAssert([@"2001:0db8:0000:0000:0000:8a2e:0370:7334" isValidIPAddress]); + XCTAssert([@"2001:db8::8a2e:370:7334" isValidIPAddress]); + + // invalid ipv6 + XCTAssert(![@"2001:0db8:0000:0000:0000:8a2e:0370:733g" isValidIPAddress]); + XCTAssert(![@"2001:0db8:0000:0000:0000:8a2e:0370:7330:1234" isValidIPAddress]); +} + +- (void)testLocalIPAddress { + XCTAssert([[BNCNetworkInterface localIPAddress] isValidIPAddress]); +} + +- (void)testAllIPAddresses { + // All IP addresses is a debug method that returns object descriptions + for (NSString *address in BNCNetworkInterface.allIPAddresses) { + XCTAssert([address containsString:@"BNCNetworkInterface"]); + } +} + +@end diff --git a/BranchSDKTests/BNCODMTests.m b/BranchSDKTests/BNCODMTests.m new file mode 100644 index 000000000..38d1b0cc2 --- /dev/null +++ b/BranchSDKTests/BNCODMTests.m @@ -0,0 +1,102 @@ +// +// BNCODMTests.m +// Branch-SDK-Tests +// +// Created by Nidhi Dixit on 4/16/25. +// Copyright © 2025 Branch, Inc. All rights reserved. +// + +#import +#import "Branch.h" +#import "BNCPreferenceHelper.h" +#import "BNCRequestFactory.h" +#import "BNCEncodingUtils.h" +#import "BNCODMInfoCollector.h" +#import "NSError+Branch.h" + +@interface BNCODMTests : XCTestCase +@property (nonatomic, strong, readwrite) BNCPreferenceHelper *prefHelper; +@end + +@implementation BNCODMTests + +- (void)setUp { + _prefHelper = [BNCPreferenceHelper sharedInstance]; +} + +- (void)testSetODM { + NSString *odm = @"testODMString"; + NSDate *firstOpenTS = [NSDate date]; + [Branch setODMInfo:odm andFirstOpenTimestamp:firstOpenTS]; + XCTAssertTrue([_prefHelper.odmInfo isEqualToString:odm]); + XCTAssertTrue([_prefHelper.odmInfoInitDate isEqualToDate:firstOpenTS]); + +} + +- (void)testSetODMandSDKRequests { + NSString* requestUUID = [[NSUUID UUID ] UUIDString]; + NSNumber* requestCreationTimeStamp = BNCWireFormatFromDate([NSDate date]); + NSString *odm = @"testODMString"; + NSDate *firstOpenTS = [NSDate date]; + + [Branch setODMInfo:odm andFirstOpenTimestamp:firstOpenTS]; + + [[Branch getInstance] setConsumerProtectionAttributionLevel:BranchAttributionLevelFull]; + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:requestUUID TimeStamp:requestCreationTimeStamp]; + NSDictionary *jsonInstall = [factory dataForInstallWithURLString:@"https://branch.io"]; + XCTAssertTrue([odm isEqualToString:[jsonInstall objectForKey:@"odm_info"]]); + + NSDictionary *jsonOpen = [factory dataForOpenWithURLString:@"https://branch.io"]; + XCTAssertTrue([odm isEqualToString:[jsonOpen objectForKey:@"odm_info"]]); + + NSDictionary *event = @{@"name": @"ADD_TO_CART"}; + NSDictionary *jsonEvent = [factory dataForEventWithEventDictionary:[event mutableCopy]]; + XCTAssertTrue([jsonEvent objectForKey:@"odm_info"] == nil); + + [[Branch getInstance] setConsumerProtectionAttributionLevel:BranchAttributionLevelReduced]; + jsonInstall = [factory dataForInstallWithURLString:@"https://branch.io"]; + XCTAssertTrue([jsonInstall objectForKey:@"odm_info"] == nil); + + jsonOpen = [factory dataForOpenWithURLString:@"https://branch.io"]; + XCTAssertTrue([jsonOpen objectForKey:@"odm_info"] == nil); + + self.prefHelper.odmInfo = nil; + self.prefHelper.odmInfoInitDate = nil; +} + +- (void)testODMTimeOut { + + NSString* requestUUID = [[NSUUID UUID ] UUIDString]; + NSNumber* requestCreationTimeStamp = BNCWireFormatFromDate([NSDate date]); + NSString *odm = @"testODMString"; + NSDate *firstOpenTS = [[NSDate date] dateByAddingTimeInterval:-((180*24*3600) - 5)]; + + [Branch setODMInfo:odm andFirstOpenTimestamp:firstOpenTS]; + + [[Branch getInstance] setConsumerProtectionAttributionLevel:BranchAttributionLevelFull]; + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:requestUUID TimeStamp:requestCreationTimeStamp]; + NSDictionary *jsonInstall = [factory dataForInstallWithURLString:@"https://branch.io"]; + XCTAssertTrue([odm isEqualToString:[jsonInstall objectForKey:@"odm_info"]]); + + sleep(10); + + NSDictionary *jsonOpen = [factory dataForOpenWithURLString:@"https://branch.io"]; + XCTAssertTrue(![odm isEqualToString:[jsonOpen objectForKey:@"odm_info"]]); + + self.prefHelper.odmInfo = nil; + self.prefHelper.odmInfoInitDate = nil; + +} + + +- (void) testODMAPIsNotLoaded { + XCTestExpectation *expectation = [self expectationWithDescription:@"Check if ODCManager class is loaded."]; + [[BNCODMInfoCollector instance ] loadODMInfoWithTimeOut:DISPATCH_TIME_FOREVER andCompletionHandler:^(NSString * _Nullable odmInfo, NSError * _Nullable error) { + if (error.code == BNCClassNotFoundError){ + [expectation fulfill]; + } + }]; + [self waitForExpectationsWithTimeout:15 handler:nil]; +} + +@end diff --git a/BranchSDKTests/BNCPartnerParametersTests.m b/BranchSDKTests/BNCPartnerParametersTests.m new file mode 100644 index 000000000..7fad38ac2 --- /dev/null +++ b/BranchSDKTests/BNCPartnerParametersTests.m @@ -0,0 +1,219 @@ +// +// BNCPartnerParametersTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 12/9/20. +// Copyright © 2020 Branch, Inc. All rights reserved. +// + +#import +#import "BNCPartnerParameters.h" + +// expose private methods for testing +@interface BNCPartnerParameters() +- (BOOL)sha256HashSanityCheckValue:(NSString *)value; +- (BOOL)isStringHex:(NSString *)string; +@end + +@interface BNCPartnerParametersTests : XCTestCase +@property (nonatomic, strong, readwrite) BNCPartnerParameters *partnerParams; +@end + +@implementation BNCPartnerParametersTests + +- (void)setUp { + self.partnerParams = [BNCPartnerParameters new]; +} + +- (void)tearDown { + +} + +- (void)testStringHexNil { + XCTAssertFalse([self.partnerParams isStringHex:nil]); +} + +- (void)testStringHexEmpty { + XCTAssertTrue([self.partnerParams isStringHex:@""]); +} + +- (void)testStringHexDash { + XCTAssertFalse([self.partnerParams isStringHex:@"-1"]); +} + +- (void)testStringHexDecimal { + XCTAssertFalse([self.partnerParams isStringHex:@"1.0"]); +} + +- (void)testStringHexFraction { + XCTAssertFalse([self.partnerParams isStringHex:@"2/4"]); +} + +- (void)testStringHexAt { + XCTAssertFalse([self.partnerParams isStringHex:@"test@12345"]); +} + +- (void)testStringHexUpperG { + XCTAssertFalse([self.partnerParams isStringHex:@"0123456789ABCDEFG"]); +} + +- (void)testStringHexLowerG { + XCTAssertFalse([self.partnerParams isStringHex:@"0123456789abcdefg"]); +} + +- (void)testStringHexUpperCase { + XCTAssertTrue([self.partnerParams isStringHex:@"0123456789ABCDEF"]); +} + +- (void)testStringHexLowerCase { + XCTAssertTrue([self.partnerParams isStringHex:@"0123456789abcdef"]); +} + +- (void)testSha256HashSanityCheckValueNil { + XCTAssertFalse([self.partnerParams sha256HashSanityCheckValue:nil]); +} + +- (void)testSha256HashSanityCheckValueEmpty { + XCTAssertFalse([self.partnerParams sha256HashSanityCheckValue:@""]); +} + +- (void)testSha256HashSanityCheckValueTooShort { + // 63 char string + XCTAssertFalse([self.partnerParams sha256HashSanityCheckValue:@"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcde"]); +} + +- (void)testSha256HashSanityCheckValueTooLong { + // 65 char string + XCTAssertFalse([self.partnerParams sha256HashSanityCheckValue:@"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdeff"]); +} + +- (void)testSha256HashSanityCheckValueLowerCase { + // 64 char string + XCTAssertTrue([self.partnerParams sha256HashSanityCheckValue:@"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"]); +} + +- (void)testSha256HashSanityCheckValueUpperCase { + // 64 char string + XCTAssertTrue([self.partnerParams sha256HashSanityCheckValue:@"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"]); +} + +- (void)testSha256HashSanityCheckValueMixedCase { + // 64 char string + XCTAssertTrue([self.partnerParams sha256HashSanityCheckValue:@"0123456789ABCDEF0123456789ABCDEF1234567890abcdef1234567890abcdef"]); +} + +- (void)testJsonEmpty { + NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; + XCTAssertTrue([@"{}" isEqualToString:jsonString]); +} + +- (void)testJsonFBParameterEmpty { + [self.partnerParams addFacebookParameterWithName:@"em" value:@""]; + NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; + XCTAssertTrue([@"{}" isEqualToString:jsonString]); +} + +- (void)testJsonFBParameterShort { + [self.partnerParams addFacebookParameterWithName:@"em" value:@"0123456789ABCDEF0123456789ABCDEF1234567890abcdef1234567890abcde"]; + NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; + XCTAssertTrue([@"{}" isEqualToString:jsonString]); +} + +- (void)testJsonFBParameterPhoneNumberIsIgnored { + [self.partnerParams addFacebookParameterWithName:@"em" value:@"1-555-555-5555"]; + NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; + XCTAssertTrue([@"{}" isEqualToString:jsonString]); +} + +- (void)testJsonFBParameterEmailIsIgnored { + [self.partnerParams addFacebookParameterWithName:@"em" value:@"test@branch.io"]; + NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; + XCTAssertTrue([@"{}" isEqualToString:jsonString]); +} + +- (void)testJsonFBParameterBase64EncodedIsIgnored { + // 123456789012345678901234567890123456789012345678 -> MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4 + [self.partnerParams addFacebookParameterWithName:@"em" value:@"MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4"]; + NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; + XCTAssertTrue([@"{}" isEqualToString:jsonString]); +} + +- (void)testJsonFBParameterHashedValue { + [self.partnerParams addFacebookParameterWithName:@"em" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; + NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; + XCTAssertTrue([@"{\"fb\":{\"em\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\"}}" isEqualToString:jsonString]); +} + +- (void)testJsonFBParameterExample { + [self.partnerParams addFacebookParameterWithName:@"em" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; + [self.partnerParams addFacebookParameterWithName:@"ph" value:@"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b"]; + NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; + + XCTAssertTrue([@"{\"fb\":{\"ph\":\"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b\",\"em\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\"}}" isEqualToString:jsonString]); +} + +- (void)testJsonSnapParameterExample { + [self.partnerParams addSnapParameterWithName:@"hashed_email_address" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; + [self.partnerParams addSnapParameterWithName:@"hashed_phone_number" value:@"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b"]; + NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; + + XCTAssertTrue([@"{\"snap\":{\"hashed_phone_number\":\"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b\",\"hashed_email_address\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\"}}" isEqualToString:jsonString]); +} + + +- (void)testJsonMultipleParameterExample { + [self.partnerParams addFacebookParameterWithName:@"em" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; + [self.partnerParams addFacebookParameterWithName:@"ph" value:@"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b"]; + [self.partnerParams addSnapParameterWithName:@"hashed_email_address" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; + [self.partnerParams addSnapParameterWithName:@"hashed_phone_number" value:@"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b"]; + NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; + + NSString *expectedJsonString = @"{\"snap\":{\"hashed_phone_number\":\"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b\",\"hashed_email_address\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\"},\"fb\":{\"ph\":\"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b\",\"em\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\"}}"; + + XCTAssertTrue([expectedJsonString isEqualToString:jsonString]); +} + +- (void)testParameterClear { + [self.partnerParams addFacebookParameterWithName:@"em" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; + [self.partnerParams addFacebookParameterWithName:@"ph" value:@"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b"]; + [self.partnerParams addSnapParameterWithName:@"hashed_email_address" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; + [self.partnerParams addSnapParameterWithName:@"hashed_phone_number" value:@"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b"]; + [self.partnerParams clearAllParameters]; + + NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; + XCTAssertTrue([@"{}" isEqualToString:jsonString]); +} + +// sanity check test func on an empty dictionary +- (void)testEmptyJson { + NSString *jsonString = [self jsonStringFromDictionary:@{}]; + XCTAssertTrue([@"{}" isEqualToString:jsonString]); +} + +// sanity check test func on the sample json dictionary +- (void)testSampleJson { + NSString *jsonString = [self jsonStringFromDictionary:@{ + @"fb": @{ + @"ph": @"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b", + @"em": @"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088" + } + }]; + + XCTAssertTrue([@"{\"fb\":{\"ph\":\"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b\",\"em\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\"}}" isEqualToString:jsonString] || [@"{\"fb\":{\"em\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\",\"ph\":\"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b\"}}" isEqualToString:jsonString]); +} + +// There is an assumption that this code always results in the same string for the same json data. +// This appears to be true, but I haven't found documentation to confirm it. +- (NSString *)jsonStringFromDictionary:(NSDictionary *)dictionary { + NSError *error; + NSData *json = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error]; + + if (!error) { + NSString *tmp = [[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding]; + return tmp; + } else { + return @""; + } +} + +@end diff --git a/BranchSDKTests/BNCPasteboardTests.m b/BranchSDKTests/BNCPasteboardTests.m new file mode 100644 index 000000000..6a3a4d69c --- /dev/null +++ b/BranchSDKTests/BNCPasteboardTests.m @@ -0,0 +1,170 @@ +// +// BNCPasteboardTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 7/19/21. +// Copyright © 2021 Branch, Inc. All rights reserved. +// + +#import +#import "BNCPasteboard.h" +#import "Branch.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 + [UIPasteboard.generalPasteboard setString:self.testString]; +#endif +} + +- (void)addBranchURLToPasteboard { +#if !TARGET_OS_TV + [UIPasteboard.generalPasteboard setURL:self.testBranchURL]; +#endif +} + +- (void)addNonBranchURLToPasteboard { +#if !TARGET_OS_TV + [UIPasteboard.generalPasteboard setURL:[NSURL URLWithString:@"https://www.apple.com"]]; +#endif +} + +- (void)clearPasteboard { +#if !TARGET_OS_TV + // 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 + string = [UIPasteboard.generalPasteboard string]; +#endif + return string; +} + +- (NSURL *)getURLFromPasteboard { + NSURL *url = nil; +#if !TARGET_OS_TV + 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 + XCTAssertFalse([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]); + + [self clearPasteboard]; +} + +- (void)testCheckForBranchLink_nonBranchLink { + [self addNonBranchURLToPasteboard]; + XCTAssertTrue([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); + + NSURL *tmp = [[BNCPasteboard sharedInstance] checkForBranchLink]; + XCTAssertNil(tmp); + + [self clearPasteboard]; +} + +- (void)testCheckForBranchLink_noLink { + [self addStringToPasteboard]; + XCTAssertFalse([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); + + NSURL *tmp = [[BNCPasteboard sharedInstance] checkForBranchLink]; + XCTAssertNil(tmp); + + [self clearPasteboard]; +} + +#if 0 +// This test fails intermittently when executed with other tests - depending upon the order in which its executed +- (void) testPassPasteControl { +#if !TARGET_OS_TV + if (@available(iOS 16.0, macCatalyst 16.0, *)) { + + long long timeStamp = ([[NSDate date] timeIntervalSince1970] - 5*60)*1000; // 5 minute earlier timestamp + NSString *urlString = [NSString stringWithFormat:@"https://bnctestbed-alternate.app.link/9R7MbTmnRtb?__branch_flow_type=viewapp&__branch_flow_id=1105940563590163783&__branch_mobile_deepview_type=1&nl_opt_in=1&_cpts=%lld", timeStamp]; + NSURL *testURL = [[NSURL alloc] initWithString:urlString]; + + NSArray *itemProviders = @[[[NSItemProvider alloc] initWithItem:testURL typeIdentifier:UTTypeURL.identifier]]; + XCTestExpectation *openExpectation = [self expectationWithDescription:@"Test open"]; + + [[Branch getInstance] initSessionWithLaunchOptions:@{} andRegisterDeepLinkHandler:^(NSDictionary *params, NSError *error) { + [openExpectation fulfill]; + XCTAssertNil(error); + }]; + + [[Branch getInstance] passPasteItemProviders:itemProviders]; + [self waitForExpectationsWithTimeout:5.0 handler:NULL]; + + } +#endif +} +#endif + +@end diff --git a/BranchSDKTests/BNCPreferenceHelperTests.m b/BranchSDKTests/BNCPreferenceHelperTests.m new file mode 100644 index 000000000..5269501b3 --- /dev/null +++ b/BranchSDKTests/BNCPreferenceHelperTests.m @@ -0,0 +1,417 @@ +// +// BNCPreferenceHelperTests.m +// Branch-TestBed +// +// Created by Graham Mueller on 4/2/15. +// Copyright (c) 2015 Branch Metrics. All rights reserved. +// + +#import +#import "BNCPreferenceHelper.h" +#import "BNCEncodingUtils.h" +#import "Branch.h" +#import "BNCConfig.h" + +@interface BNCPreferenceHelper() + +// expose private methods for testing +- (NSMutableDictionary *)deserializePrefDictFromData:(NSData *)data; +- (NSData *)serializePrefDict:(NSMutableDictionary *)dict; + +@end + +@interface BNCPreferenceHelperTests : XCTestCase +@property (nonatomic, strong, readwrite) BNCPreferenceHelper *prefHelper; +@end + +@implementation BNCPreferenceHelperTests + +- (void)setUp { + self.prefHelper = [BNCPreferenceHelper new]; +} + +- (void)tearDown { + +} + +- (void)testPreferenceDefaults { + XCTAssertEqual(self.prefHelper.timeout, 5.5); + XCTAssertEqual(self.prefHelper.retryInterval, 0); + XCTAssertEqual(self.prefHelper.retryCount, 3); + XCTAssertFalse(self.prefHelper.disableAdNetworkCallouts); +} + +- (void)testPreferenceSets { + self.prefHelper.retryCount = NSIntegerMax; + self.prefHelper.retryInterval = NSIntegerMax; + self.prefHelper.timeout = NSIntegerMax; + + XCTAssertEqual(self.prefHelper.retryCount, NSIntegerMax); + XCTAssertEqual(self.prefHelper.retryInterval, NSIntegerMax); + XCTAssertEqual(self.prefHelper.timeout, NSIntegerMax); +} + +// This test is not reliable when run concurrently with other tests that set the patterListURL +- (void)testURLFilter { + XCTAssertTrue([@"https://cdn.branch.io" isEqualToString:self.prefHelper.patternListURL]); + + NSString *customURL = @"https://banned.branch.io"; + self.prefHelper.patternListURL = customURL; + XCTAssertTrue([customURL isEqualToString:self.prefHelper.patternListURL]); +} + +- (void)testSerializeDict_Nil { + NSMutableDictionary *dict = nil; + NSData *data = [self.prefHelper serializePrefDict:dict]; + XCTAssert(data == nil); +} + +- (void)testSerializeDict_Empty { + NSMutableDictionary *dict = [NSMutableDictionary new]; + NSData *data = [self.prefHelper serializePrefDict:dict]; + NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; + + XCTAssert(tmp != nil); + XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); + XCTAssert(tmp.count == 0); +} + +- (void)testSerializeDict_String { + NSMutableDictionary *dict = [NSMutableDictionary new]; + NSString *value = @"the quick brown fox jumps over the lazy dog"; + NSString *key = @"test"; + [dict setObject:value forKey:key]; + + NSData *data = [self.prefHelper serializePrefDict:dict]; + NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; + + XCTAssert(tmp != nil); + XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); + XCTAssert(tmp.count == 1); + + XCTAssert([[tmp objectForKey:key] isEqualToString:value]); +} + +- (void)testSerializeDict_Date { + NSMutableDictionary *dict = [NSMutableDictionary new]; + NSDate *value = [NSDate date]; + NSString *key = @"test"; + [dict setObject:value forKey:key]; + + NSData *data = [self.prefHelper serializePrefDict:dict]; + NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; + + XCTAssert(tmp != nil); + XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); + XCTAssert(tmp.count == 1); + + XCTAssert([[tmp objectForKey:key] isEqual:value]); +} + +- (void)testSerializeDict_Bool { + NSMutableDictionary *dict = [NSMutableDictionary new]; + bool value = YES; + NSString *key = @"test"; + [dict setObject:@(value) forKey:key]; + + NSData *data = [self.prefHelper serializePrefDict:dict]; + NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; + + XCTAssert(tmp != nil); + XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); + XCTAssert(tmp.count == 1); + + XCTAssert([[tmp objectForKey:key] isEqual:@(value)]); +} + +- (void)testSerializeDict_Integer { + NSMutableDictionary *dict = [NSMutableDictionary new]; + NSInteger value = 1234; + NSString *key = @"test"; + [dict setObject:@(value) forKey:key]; + + NSData *data = [self.prefHelper serializePrefDict:dict]; + NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; + + XCTAssert(tmp != nil); + XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); + XCTAssert(tmp.count == 1); + + XCTAssert([[tmp objectForKey:key] isEqual:@(value)]); +} + +- (void)testSerializeDict_All { + NSMutableDictionary *dict = [NSMutableDictionary new]; + + NSString *value1 = @"the quick brown fox jumps over the lazy dog"; + NSString *key1 = @"test1"; + [dict setObject:value1 forKey:key1]; + + NSDate *value2 = [NSDate date]; + NSString *key2 = @"test2"; + [dict setObject:value2 forKey:key2]; + + bool value3 = YES; + NSString *key3 = @"test3"; + [dict setObject:@(value3) forKey:key3]; + + NSInteger value4 = 1234; + NSString *key4 = @"test4"; + [dict setObject:@(value4) forKey:key4]; + + NSData *data = [self.prefHelper serializePrefDict:dict]; + NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; + + XCTAssert(tmp != nil); + XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); + XCTAssert(tmp.count == 4); + + XCTAssert([[tmp objectForKey:key1] isEqualToString:value1]); + XCTAssert([[tmp objectForKey:key2] isEqual:value2]); + XCTAssert([[tmp objectForKey:key3] isEqual:@(value3)]); + XCTAssert([[tmp objectForKey:key4] isEqual:@(value4)]); +} + +- (void)testURLSkipList { + NSMutableDictionary *dict = [NSMutableDictionary new]; + NSString *key = @"test"; + NSArray *value = @[ + @"^fb\\d+:", + @"^li\\d+:", + @"^pdk\\d+:", + @"^twitterkit-.*:", + @"^com\\.googleusercontent\\.apps\\.\\d+-.*:\\/oauth", + @"^(?i)(?!(http|https):).*(:|:.*\\b)(password|o?auth|o?auth.?token|access|access.?token)\\b", + @"^(?i)((http|https):\\/\\/).*[\\/|?|#].*\\b(password|o?auth|o?auth.?token|access|access.?token)\\b", + ]; + [dict setObject:value forKey:key]; + NSData *data = [self.prefHelper serializePrefDict:dict]; + + NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; + + XCTAssert(tmp != nil); + XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); + + NSArray *filter = [tmp objectForKey:key]; + + NSString *filterDesc = filter.description; + NSString *valueDesc = value.description; + XCTAssert([filterDesc isEqualToString:valueDesc]); +} + +- (void)testSetCDNBaseURL_Example { + + NSString *url = @"https://www.example.com/"; + [self.prefHelper setPatternListURL:url]; + + NSString *urlStored = self.prefHelper.patternListURL ; + XCTAssert([url isEqualToString:urlStored]); +} + +- (void)testSetCDNBaseURL_InvalidHttp { + + NSString *url = @"Invalid://www.example.com/"; + [self.prefHelper setPatternListURL:url] ; + + NSString *urlStored = self.prefHelper.patternListURL ; + XCTAssert(![url isEqualToString:urlStored]); + XCTAssert([urlStored isEqualToString:BNC_CDN_URL]); +} + +- (void)testSetCDNBaseURL_InvalidEmpty { + + [self.prefHelper setPatternListURL:@""] ; + + NSString *urlStored = self.prefHelper.patternListURL ; + XCTAssert(![urlStored isEqualToString:@""]); + XCTAssert([urlStored isEqualToString:BNC_CDN_URL]); +} + +- (void)testSetPatternListURL { + NSString *expectedURL = @"https://example.com"; + [self.prefHelper setPatternListURL:expectedURL]; + + NSString *patternListURL = self.prefHelper.patternListURL; + XCTAssert([patternListURL isEqualToString: expectedURL]); +} + +- (void)testSetLastStrongMatchDate { + NSDate *expectedDate = [NSDate date]; + [self.prefHelper setLastStrongMatchDate: expectedDate]; + + NSDate *actualDate = [self.prefHelper lastStrongMatchDate]; + XCTAssertEqualObjects(expectedDate, actualDate); +} + +- (void)testSetAppVersion { + NSString *expectedVersion = @"1.0.0"; + [self.prefHelper setAppVersion: expectedVersion]; + + NSString *actualVersion = [self.prefHelper appVersion]; + XCTAssertEqualObjects(expectedVersion, actualVersion); +} + +- (void)testSetLocalUrl { + NSString *expectedLocalURL = @"https://local.example.com"; + [self.prefHelper setLocalUrl:expectedLocalURL]; + + NSString *localURL = [self.prefHelper localUrl]; + XCTAssertEqualObjects(localURL, expectedLocalURL); +} + +- (void)testSetInitialReferrer { + NSString *expectedReferrer = @"referrer.example.com"; + [self.prefHelper setInitialReferrer:expectedReferrer]; + + NSString *actualReferrer = [self.prefHelper initialReferrer]; + XCTAssertEqualObjects(actualReferrer, expectedReferrer); +} + +- (void)testSetAppleAttributionTokenChecked { + BOOL expectedValue = YES; + [self.prefHelper setAppleAttributionTokenChecked:expectedValue]; + + BOOL actualValue = [self.prefHelper appleAttributionTokenChecked]; + XCTAssertEqual(expectedValue, actualValue); +} + +- (void)testSetHasOptedInBefore { + BOOL expectedValue = YES; + [self.prefHelper setHasOptedInBefore:expectedValue]; + + BOOL actualValue = [self.prefHelper hasOptedInBefore]; + XCTAssertEqual(expectedValue, actualValue); +} + +- (void)testSetHasCalledHandleATTAuthorizationStatus { + BOOL expectedValue = YES; + [self.prefHelper setHasCalledHandleATTAuthorizationStatus:expectedValue]; + + BOOL actualValue = [self.prefHelper hasCalledHandleATTAuthorizationStatus]; + XCTAssertEqual(expectedValue, actualValue); +} + +- (void)testSetRequestMetadataKeyValidKeyValue { + NSString *key = @"testKey"; + NSString *value = @"testValue"; + + [self.prefHelper setRequestMetadataKey:key value:value]; + + NSObject *retrievedValue = [self.prefHelper.requestMetadataDictionary objectForKey:key]; + XCTAssertEqualObjects(retrievedValue, value); +} + +- (void)testSetRequestMetadataKeyValidKeyNilValue { + NSString *key = @"testKey"; + NSString *value = @"testValue"; + + [self.prefHelper.requestMetadataDictionary setObject:value forKey:key]; + + [self.prefHelper setRequestMetadataKey:key value:nil]; + + NSObject *retrievedValue = [self.prefHelper.requestMetadataDictionary objectForKey:key]; + XCTAssertNil(retrievedValue); +} + +- (void)testSetRequestMetadataKeyValidKeyNilValueKeyNotExists { + NSString *key = @"testKeyNotExists"; + + NSUInteger initialDictCount = [self.prefHelper.requestMetadataDictionary count]; + + [self.prefHelper setRequestMetadataKey:key value:nil]; + + NSUInteger postActionDictCount = [self.prefHelper.requestMetadataDictionary count]; + XCTAssertEqual(initialDictCount, postActionDictCount); +} + +- (void)testSetRequestMetadataKeyNilKey { + NSString *value = @"testValue"; + NSUInteger initialDictCount = [self.prefHelper.requestMetadataDictionary count]; + + [self.prefHelper setRequestMetadataKey:nil value:value]; + + NSUInteger postActionDictCount = [self.prefHelper.requestMetadataDictionary count]; + XCTAssertEqual(initialDictCount, postActionDictCount); +} + +- (void)testSetLimitFacebookTracking { + BOOL expectedValue = YES; + + [self.prefHelper setLimitFacebookTracking:expectedValue]; + + BOOL storedValue = [self.prefHelper limitFacebookTracking]; + + XCTAssertEqual(expectedValue, storedValue); +} + +- (void)testSetTrackingDisabled_YES { + [self.prefHelper setTrackingDisabled:YES]; + + BOOL storedValue = [self.prefHelper trackingDisabled]; + XCTAssertTrue(storedValue); + [self.prefHelper setTrackingDisabled:NO]; +} + +- (void)testSetTrackingDisabled_NO { + [self.prefHelper setTrackingDisabled:NO]; + + BOOL storedValue = [self.prefHelper trackingDisabled]; + XCTAssertFalse(storedValue); +} + +// TODO: rethink this test as these values are not set in a freshly instantiated prefHelper +- (void)testClearTrackingInformation { + [self.prefHelper clearTrackingInformation]; + + XCTAssertNil(self.prefHelper.sessionID); + XCTAssertNil(self.prefHelper.linkClickIdentifier); + XCTAssertNil(self.prefHelper.spotlightIdentifier); + XCTAssertNil(self.prefHelper.referringURL); + XCTAssertNil(self.prefHelper.universalLinkUrl); + XCTAssertNil(self.prefHelper.initialReferrer); + XCTAssertNil(self.prefHelper.installParams); + XCTAssertNil(self.prefHelper.sessionParams); + XCTAssertNil(self.prefHelper.externalIntentURI); + XCTAssertNil(self.prefHelper.savedAnalyticsData); + XCTAssertNil(self.prefHelper.previousAppBuildDate); + XCTAssertEqual(self.prefHelper.requestMetadataDictionary.count, 0); + XCTAssertNil(self.prefHelper.lastStrongMatchDate); + XCTAssertNil(self.prefHelper.userIdentity); + XCTAssertNil(self.prefHelper.referringURLQueryParameters); + XCTAssertNil(self.prefHelper.anonID); +} + +- (void)testSaveBranchAnalyticsData { + NSString *dummySessionID = @"testSession123"; + NSDictionary *dummyAnalyticsData = @{ @"key1": @"value1", @"key2": @"value2" }; + + self.prefHelper.sessionID = dummySessionID; + + [self.prefHelper saveBranchAnalyticsData:dummyAnalyticsData]; + + NSMutableDictionary *retrievedData = [self.prefHelper getBranchAnalyticsData]; + + NSArray *viewDataArray = [retrievedData objectForKey:dummySessionID]; + XCTAssertNotNil(viewDataArray); + XCTAssertEqual(viewDataArray.count, 1); + XCTAssertEqualObjects(viewDataArray.firstObject, dummyAnalyticsData); +} + +- (void)testClearBranchAnalyticsData { + [self.prefHelper clearBranchAnalyticsData]; + + NSMutableDictionary *retrievedData = [self.prefHelper getBranchAnalyticsData]; + XCTAssertEqual(retrievedData.count, 0); +} + +- (void)testSaveContentAnalyticsManifest { + NSDictionary *dummyManifest = @{ @"manifestKey1": @"manifestValue1", @"manifestKey2": @"manifestValue2" }; + + [self.prefHelper saveContentAnalyticsManifest:dummyManifest]; + + NSDictionary *retrievedManifest = [self.prefHelper getContentAnalyticsManifest]; + + XCTAssertEqualObjects(retrievedManifest, dummyManifest); +} + +@end diff --git a/BranchSDKTests/BNCReachabilityTests.m b/BranchSDKTests/BNCReachabilityTests.m new file mode 100644 index 000000000..3f159c1e3 --- /dev/null +++ b/BranchSDKTests/BNCReachabilityTests.m @@ -0,0 +1,45 @@ +// +// BNCReachabilityTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 11/18/19. +// Copyright © 2019 Branch, Inc. All rights reserved. +// + +#import +#import "BNCReachability.h" + +@interface BNCReachabilityTests : XCTestCase +@property (nonatomic, strong, readwrite) BNCReachability *reachability; +@end + +@implementation BNCReachabilityTests + +- (void)setUp { + self.reachability = [BNCReachability new]; +} + +- (void)tearDown { + +} + +- (void)testSimulator_WIFI { + NSString *status = [self.reachability reachabilityStatus]; + XCTAssertNotNil(status); + XCTAssert([@"wifi" isEqualToString:status]); +} + +// Only works on a device with cell +//- (void)testDevice_Cell { +// NSString *status = [self.reachability reachabilityStatus]; +// XCTAssertNotNil(status); +// XCTAssert([@"mobile" isEqualToString:status]); +//} + +// Only works on a device in Airplane mode +//- (void)testDevice_AirplaneMode { +// NSString *status = [self.reachability reachabilityStatus]; +// XCTAssertNil(status); +//} + +@end diff --git a/BranchSDKTests/BNCReferringURLUtilityTests.m b/BranchSDKTests/BNCReferringURLUtilityTests.m new file mode 100644 index 000000000..b76f91b4d --- /dev/null +++ b/BranchSDKTests/BNCReferringURLUtilityTests.m @@ -0,0 +1,538 @@ +// +// BNCReferringURLUtilityTests.m +// Branch-SDK-Tests +// +// Created by Nipun Singh on 3/9/23. +// Copyright © 2023 Branch, Inc. All rights reserved. +// + +#import +#import "BNCReferringURLUtility.h" +#import "BNCUrlQueryParameter.h" +#import "BNCPreferenceHelper.h" + +@interface BNCReferringURLUtility(Test) +// expose the private data structure so tests can clear it +@property (strong, readwrite, nonatomic) NSMutableDictionary *urlQueryParameters; + +// expose private methods to test data migration +- (void)checkForAndMigrateOldGbraid; +@end + +@interface BNCReferringURLUtilityTests : XCTestCase + +@end + +@implementation BNCReferringURLUtilityTests + +// test constants +static NSString *openEndpoint = @"/v1/open"; +static NSString *eventEndpoint = @"/v2/event"; + ++ (void)tearDown { + // clear test data from global storage + [BNCPreferenceHelper sharedInstance].referringURLQueryParameters = nil; + [BNCPreferenceHelper sharedInstance].referrerGBRAID = nil; + [BNCPreferenceHelper sharedInstance].referrerGBRAIDValidityWindow = 0; + [BNCPreferenceHelper sharedInstance].referrerGBRAIDInitDate = nil; +} + +// workaround for BNCPreferenceHelper being persistent across tests and not currently mockable +- (BNCReferringURLUtility *)referringUtilityForTests { + BNCReferringURLUtility *utility = [BNCReferringURLUtility new]; + utility.urlQueryParameters = [NSMutableDictionary new]; + return utility; +} + +// make gbraid equality check simpler by excluding timestamp +- (NSDictionary *)removeTimestampFromParams:(NSDictionary *)params { + NSMutableDictionary *paramsWithoutTimestamp = [params mutableCopy]; + paramsWithoutTimestamp[@"gbraid_timestamp"] = nil; + return paramsWithoutTimestamp; +} + +// gbraid timestamp is a string representing time in millis +- (void)validateGbraidTimestampInReferringParameters:(NSDictionary *)params { + id timestamp = params[@"gbraid_timestamp"]; + XCTAssert(timestamp != nil); + XCTAssert([timestamp isKindOfClass:NSString.class]); +} + +- (void)expireValidityWindowsInUtility:(BNCReferringURLUtility *)utility { + for (NSString *paramName in utility.urlQueryParameters.allKeys) { + BNCUrlQueryParameter *param = utility.urlQueryParameters[paramName]; + + // currently the longest validity window is 30 days + NSTimeInterval sixtyDaysAgo = -1 * 60 * 24 * 60 * 60; + param.timestamp = [NSDate dateWithTimeIntervalSinceNow:sixtyDaysAgo]; + } +} + +- (void)testReferringURLWithNoParams { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link"]; + NSDictionary *expected = @{}; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testNilReferringURL { + NSURL *url = nil; + NSDictionary *expected = @{}; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLIgnoredParam { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?other=12345"]; + NSDictionary *expected = @{ }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithGclid { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=12345"]; + NSDictionary *expected = @{ + @"gclid": @"12345" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +// NSURL treats URI schemes in a consistent manner with Universal Links +- (void)testReferringURLWithURISchemeSanityCheck{ + NSURL *url = [NSURL URLWithString:@"branchtest://?gclid=12345"]; + NSDictionary *expected = @{ + @"gclid": @"12345" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithGclidCapitalized { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?GCLID=12345"]; + NSDictionary *expected = @{ + @"gclid": @"12345" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithGclidMixedCase { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?GcLiD=12345"]; + NSDictionary *expected = @{ + @"gclid": @"12345" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithGclidNoValue { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid="]; + NSDictionary *expected = @{ + @"gclid": @"" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithGclidValueCasePreserved { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=aAbBcC"]; + NSDictionary *expected = @{ + @"gclid": @"aAbBcC" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithGclidIgnoredParam { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=12345&other=abcde"]; + NSDictionary *expected = @{ + @"gclid": @"12345" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithGclidFragment{ + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=12345#header"]; + NSDictionary *expected = @{ + @"gclid": @"12345" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithGclidAsFragment{ + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?other=abcde#gclid=12345"]; + NSDictionary *expected = @{ }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithGclidOverwritesValue { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=12345"]; + NSDictionary *expected = @{ + @"gclid": @"12345" + }; + + NSURL *url2 = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=abcde"]; + NSDictionary *expected2 = @{ + @"gclid": @"abcde" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + XCTAssert([expected isEqualToDictionary:params]); + + [utility parseReferringURL:url2]; + NSDictionary *params2 = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected2 isEqualToDictionary:params2]); +} + +- (void)testReferringURLWithMetaCampaignIdsAndInvalidURL { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?al_applink_data=[]#target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D"]; + NSDictionary *expected = @{}; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithMetaCampaignIds { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D"]; + NSDictionary *expected = @{ + @"meta_campaign_ids": @"ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithMetaCampaignIdsExpired { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D"]; + NSDictionary *expected = @{ }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + [self expireValidityWindowsInUtility:utility]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithMetaNoCampaignIds { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22test_deeplink%22%3A1%7D"]; + NSDictionary *expected = @{ }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithGbraid { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gbraid=abcde"]; + NSDictionary *expected = @{ + @"gbraid": @"abcde", + @"is_deeplink_gbraid": @(true) + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + [self validateGbraidTimestampInReferringParameters:params]; + NSDictionary *paramsWithoutTimestamp = [self removeTimestampFromParams:params]; + XCTAssert([expected isEqualToDictionary:paramsWithoutTimestamp]); +} + +- (void)testReferringURLWithGbraidOnEvent { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gbraid=abcde"]; + NSDictionary *expected = @{ + @"gbraid": @"abcde" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:eventEndpoint]; + + [self validateGbraidTimestampInReferringParameters:params]; + NSDictionary *paramsWithoutTimestamp = [self removeTimestampFromParams:params]; + XCTAssert([expected isEqualToDictionary:paramsWithoutTimestamp]); +} + +- (void)testReferringURLWithGbraidExpired { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gbraid=abcde"]; + NSDictionary *expected = @{ }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + [self expireValidityWindowsInUtility:utility]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLPreservesNonZeroValidityWindowForGbraid { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gbraid=12345"]; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + + // pretend this object was loaded from disk + // this simulates setting a custom non-zero validity window, only supported for gbraid + BNCUrlQueryParameter *existingParam = [BNCUrlQueryParameter new]; + existingParam.name = @"gbraid"; + existingParam.value = @""; + existingParam.timestamp = [NSDate date]; + existingParam.validityWindow = 5; // not the default gbraid window + utility.urlQueryParameters[@"gbraid"] = existingParam; + + [utility parseReferringURL:url]; + + // verify validity window was not changed + XCTAssert(utility.urlQueryParameters[@"gbraid"].validityWindow == 5); +} + +- (void)testReferringURLOverwritesZeroValidityWindowForGbraid { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gbraid=12345"]; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + + // pretend this object was loaded from disk + // for gbraid, or any param, we overwrite the 0 validity windows with the default + BNCUrlQueryParameter *existingParam = [BNCUrlQueryParameter new]; + existingParam.name = @"gbraid"; + existingParam.value = @""; + existingParam.timestamp = [NSDate date]; + existingParam.validityWindow = 0; + utility.urlQueryParameters[@"gbraid"] = existingParam; + + [utility parseReferringURL:url]; + + // verify validity window was changed + XCTAssert(utility.urlQueryParameters[@"gbraid"].validityWindow != 0); +} + +- (void)testReferringURLWithGclidGbraid { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=12345&gbraid=abcde"]; + NSDictionary *expected = @{ + @"gclid": @"12345", + @"gbraid": @"abcde", + @"is_deeplink_gbraid": @(true) + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + [self validateGbraidTimestampInReferringParameters:params]; + NSDictionary *paramsWithoutTimestamp = [self removeTimestampFromParams:params]; + XCTAssert([expected isEqualToDictionary:paramsWithoutTimestamp]); +} + +- (void)testGbraidDataMigration { + // Manipulates the global BNCPreferenceHelper. + // This is not safe for concurrent unit tests, so only the happy path is tested. + [self clearCurrentQueryParameters]; + [self addOldGbraidData]; + + NSDictionary *expected = @{ + @"gbraid": @"abcde", + @"is_deeplink_gbraid": @(false) + }; + + BNCReferringURLUtility *utility = [BNCReferringURLUtility new]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + [self validateGbraidTimestampInReferringParameters:params]; + NSDictionary *paramsWithoutTimestamp = [self removeTimestampFromParams:params]; + XCTAssert([expected isEqualToDictionary:paramsWithoutTimestamp]); + + [self verifyOldGbraidDataIsCleared]; +} + +- (void)clearCurrentQueryParameters { + [BNCPreferenceHelper sharedInstance].referringURLQueryParameters = nil; +} + +- (void)addOldGbraidData { + [BNCPreferenceHelper sharedInstance].referrerGBRAID = @"abcde"; + [BNCPreferenceHelper sharedInstance].referrerGBRAIDValidityWindow = 2592000; + [BNCPreferenceHelper sharedInstance].referrerGBRAIDInitDate = [NSDate date]; +} + +- (void)verifyOldGbraidDataIsCleared { + XCTAssertNil([BNCPreferenceHelper sharedInstance].referrerGBRAID); + XCTAssert([BNCPreferenceHelper sharedInstance].referrerGBRAIDValidityWindow == 0); + XCTAssertNil([BNCPreferenceHelper sharedInstance].referrerGBRAIDInitDate); +} + +- (void)testReferringURLWithSccid { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid=12345"]; + NSDictionary *expected = @{ + @"sccid": @"12345" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithSccidMixedCase { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?ScCiD=12345"]; + NSDictionary *expected = @{ + @"sccid": @"12345" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithSccidNoValue { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid="]; + NSDictionary *expected = @{ + @"sccid": @"" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithSccidValueCasePreserved { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid=aAbBcC"]; + NSDictionary *expected = @{ + @"sccid": @"aAbBcC" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithSccidIgnoredParam { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid=12345&other=abcde"]; + NSDictionary *expected = @{ + @"sccid": @"12345" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithSccidFragment{ + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid=12345#header"]; + NSDictionary *expected = @{ + @"sccid": @"12345" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithSccidAsFragment{ + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?other=abcde#sccid=12345"]; + NSDictionary *expected = @{ }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected isEqualToDictionary:params]); +} + +- (void)testReferringURLWithSccidOverwritesValue { + NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid=12345"]; + NSDictionary *expected = @{ + @"sccid": @"12345" + }; + + NSURL *url2 = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid=abcde"]; + NSDictionary *expected2 = @{ + @"sccid": @"abcde" + }; + + BNCReferringURLUtility *utility = [self referringUtilityForTests]; + [utility parseReferringURL:url]; + NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + XCTAssert([expected isEqualToDictionary:params]); + + [utility parseReferringURL:url2]; + NSDictionary *params2 = [utility referringURLQueryParamsForEndpoint:openEndpoint]; + + XCTAssert([expected2 isEqualToDictionary:params2]); +} + + +@end diff --git a/BranchSDKTests/BNCRequestFactoryTests.m b/BranchSDKTests/BNCRequestFactoryTests.m new file mode 100644 index 000000000..c28d3b6e0 --- /dev/null +++ b/BranchSDKTests/BNCRequestFactoryTests.m @@ -0,0 +1,234 @@ +// +// BNCRequestFactoryTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 8/21/23. +// Copyright © 2023 Branch, Inc. All rights reserved. +// + +#import +#import "BNCRequestFactory.h" +#import "BranchConstants.h" +#import "BNCEncodingUtils.h" + +@interface BNCRequestFactoryTests : XCTestCase +@property (nonatomic, copy, readwrite) NSString *requestUUID; +@property (nonatomic, copy, readwrite) NSNumber *requestCreationTimeStamp; +@end + +@implementation BNCRequestFactoryTests + +- (void)setUp { + _requestUUID = [[NSUUID UUID ] UUIDString]; + _requestCreationTimeStamp = BNCWireFormatFromDate([NSDate date]); +} + +- (void)tearDown { + +} + +- (void)testInitWithBranchKeyNil { + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:nil UUID:_requestUUID TimeStamp:_requestCreationTimeStamp]; + NSDictionary *json = [factory dataForInstallWithURLString:@"https://branch.io"]; + XCTAssertNotNil(json); + + // key is omitted when nil + XCTAssertNil([json objectForKey:@"branch_key"]); + XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); + XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); +} + +- (void)testInitWithBranchKeyEmpty { + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; + NSDictionary *json = [factory dataForInstallWithURLString:@"https://branch.io"]; + XCTAssertNotNil(json); + + // empty string is allowed + XCTAssertTrue([@"" isEqualToString:[json objectForKey:@"branch_key"]]); + + XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); + XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); +} + +- (void)testInitWithBranchKey { + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; + NSDictionary *json = [factory dataForInstallWithURLString:@"https://branch.io"]; + XCTAssertNotNil(json); + XCTAssertTrue([@"key_abcd" isEqualToString:[json objectForKey:@"branch_key"]]); + + XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); + XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); +} + +- (void)testDataForInstall { + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; + NSDictionary *json = [factory dataForInstallWithURLString:@"https://branch.io"]; + XCTAssertNotNil(json); + + XCTAssertTrue([@"key_abcd" isEqualToString:[json objectForKey:@"branch_key"]]); + XCTAssertNotNil([json objectForKey:@"sdk"]); + XCTAssertTrue([@"Apple" isEqualToString:[json objectForKey:@"brand"]]); + XCTAssertNotNil([json objectForKey:@"ios_vendor_id"]); + + // not present on installs + XCTAssertNil([json objectForKey:@"randomized_bundle_token"]); + + XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); + XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); +} + +- (void)testDataForOpen { + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; + NSDictionary *json = [factory dataForOpenWithURLString:@"https://branch.io"]; + XCTAssertNotNil(json); + + XCTAssertTrue([@"key_abcd" isEqualToString:[json objectForKey:@"branch_key"]]); + XCTAssertNotNil([json objectForKey:@"sdk"]); + XCTAssertTrue([@"Apple" isEqualToString:[json objectForKey:@"brand"]]); + XCTAssertNotNil([json objectForKey:@"ios_vendor_id"]); + + // Present only on opens. Assumes test runs after the host app completes an install. + // This is not a reliable assumption on test runners + //XCTAssertNotNil([json objectForKey:@"randomized_bundle_token"]); + + XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); + XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); +} + +- (void)testDataForEvent { + NSDictionary *event = @{@"name": @"ADD_TO_CART"}; + + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; + NSDictionary *json = [factory dataForEventWithEventDictionary:[event mutableCopy]]; + XCTAssertNotNil(json); + + XCTAssertTrue([@"ADD_TO_CART" isEqualToString:[json objectForKey:@"name"]]); + + NSDictionary *userData = [json objectForKey:@"user_data"]; + XCTAssertNotNil(userData); + XCTAssertNotNil([userData objectForKey:@"idfv"]); + + XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); + XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); +} + +- (void)testDataForEventWithContentItem { + NSDictionary *event = @{ + @"name": @"ADD_TO_CART", + @"content_items": @[ + @{ + @"$og_title": @"TestTitle", + @"$quantity": @(2), + @"$product_name": @"TestProduct", + @"$price": @(10) + } + ] + }; + + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; + NSDictionary *json = [factory dataForEventWithEventDictionary:[event mutableCopy]]; + XCTAssertNotNil(json); + + XCTAssertTrue([@"ADD_TO_CART" isEqualToString:[json objectForKey:@"name"]]); + + NSDictionary *contentItems = [json objectForKey:@"content_items"]; + XCTAssertNotNil(contentItems); + XCTAssertTrue(contentItems.count == 1); + + NSDictionary *userData = [json objectForKey:@"user_data"]; + XCTAssertNotNil(userData); + XCTAssertNotNil([userData objectForKey:@"idfv"]); + + XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); + XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); +} + +- (void)testDataForEventWithTwoContentItem { + NSDictionary *event = @{ + @"name": @"ADD_TO_CART", + @"content_items": @[ + @{ + @"$og_title": @"TestTitle1", + @"$quantity": @(2), + @"$product_name": @"TestProduct1", + @"$price": @(10) + }, + @{ + @"$og_title": @"TestTitle2", + @"$quantity": @(3), + @"$product_name": @"TestProduct2", + @"$price": @(20) + } + ] + }; + + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; + NSDictionary *json = [factory dataForEventWithEventDictionary:[event mutableCopy]]; + XCTAssertNotNil(json); + + XCTAssertTrue([@"ADD_TO_CART" isEqualToString:[json objectForKey:@"name"]]); + + NSDictionary *contentItems = [json objectForKey:@"content_items"]; + XCTAssertNotNil(contentItems); + XCTAssertTrue(contentItems.count == 2); + + NSDictionary *userData = [json objectForKey:@"user_data"]; + XCTAssertNotNil(userData); + XCTAssertNotNil([userData objectForKey:@"idfv"]); + + XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); + XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); +} + +- (void)testDataForEventEmpty { + NSDictionary *event = @{}; + + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; + NSDictionary *json = [factory dataForEventWithEventDictionary:[event mutableCopy]]; + XCTAssertNotNil(json); + + XCTAssertNil([json objectForKey:@"name"]); + + NSDictionary *userData = [json objectForKey:@"user_data"]; + XCTAssertNotNil(userData); + XCTAssertNotNil([userData objectForKey:@"idfv"]); + + XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); + XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); +} + +- (void)testDataForEventNil { + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; + NSDictionary *json = [factory dataForEventWithEventDictionary:nil]; + XCTAssertNotNil(json); + + XCTAssertNil([json objectForKey:@"name"]); + + NSDictionary *userData = [json objectForKey:@"user_data"]; + XCTAssertNotNil(userData); + XCTAssertNotNil([userData objectForKey:@"idfv"]); + + XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); + XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); +} + + +- (void)testDataForShortURL { + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; + NSDictionary *json = [factory dataForShortURLWithLinkDataDictionary:@{}.mutableCopy isSpotlightRequest:NO]; + XCTAssertNotNil(json); + + XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); + XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); +} + +- (void)testDataForLATD { + BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; + NSDictionary *json = [factory dataForLATDWithDataDictionary:@{}.mutableCopy]; + XCTAssertNotNil(json); + + XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); + XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); +} + +@end diff --git a/BranchSDKTests/BNCSKAdNetworkTests.m b/BranchSDKTests/BNCSKAdNetworkTests.m new file mode 100644 index 000000000..d71cf203a --- /dev/null +++ b/BranchSDKTests/BNCSKAdNetworkTests.m @@ -0,0 +1,264 @@ +// +// BNCSKAdNetworkTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 8/13/20. +// Copyright © 2020 Branch, Inc. All rights reserved. +// + +#import +#import "BNCSKAdNetwork.h" +#import "BranchEvent.h" + +// Expose private methods for testing +@interface BNCSKAdNetwork() + +@property (nonatomic, copy, readwrite) NSDate *installDate; + +- (BOOL)shouldAttemptSKAdNetworkCallout; + +@end + +@interface BranchEvent() + +// private BranchEvent methods used to check data before sending to network service. +- (NSDictionary *)buildEventDictionary; +- (BranchEventRequest *)buildRequestWithEventDictionary:(NSDictionary *)eventDictionary; + +@end + + +@interface BNCSKAdNetworkTests : XCTestCase + +@property (nonatomic, strong, readwrite) BNCSKAdNetwork *skAdNetwork; + +@end + +@implementation BNCSKAdNetworkTests + +- (void)setUp { + self.skAdNetwork = [BNCSKAdNetwork new]; + self.skAdNetwork.installDate = [NSDate date]; +} + +- (void)tearDown { + +} + +- (void)testDefaultMaxTimeout { + NSTimeInterval days; + if (@available(iOS 16.1, macCatalyst 16.1, *)) { + days = 3600.0 * 24.0 * 60.0; // one day + } else { + days = 3600.0 * 24.0; // one day + } + XCTAssertTrue(self.skAdNetwork.maxTimeSinceInstall == days); +} + +- (void)testShouldAttemptSKAdNetworkCallout { + XCTAssertTrue([self.skAdNetwork shouldAttemptSKAdNetworkCallout]); +} + +- (void)testShouldAttemptSKAdNetworkCalloutFalse { + self.skAdNetwork.maxTimeSinceInstall = 0.0; + XCTAssertFalse([self.skAdNetwork shouldAttemptSKAdNetworkCallout]); +} + +- (void)testPostbackCall { + + if (@available(iOS 16.1, macCatalyst 16.1, *)) { + self.skAdNetwork.maxTimeSinceInstall = 3600.0 * 24.0 * 60.0; + } else { + self.skAdNetwork.maxTimeSinceInstall = 3600.0 * 24.0; // one day + } + + XCTAssertTrue([self.skAdNetwork shouldAttemptSKAdNetworkCallout]); + + [[BNCSKAdNetwork sharedInstance] registerAppForAdNetworkAttribution]; + + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventInvite]; + NSDictionary *eventDictionary = [event buildEventDictionary]; + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"TestPostback"]; + BNCServerResponse *openInstallResponse = [[BNCServerResponse alloc] init]; + + openInstallResponse.data = @{ @"update_conversion_value": @60 }; + request.completion = ^(NSDictionary*_Nullable response, NSError*_Nullable error){ + [expectation fulfill]; + }; + [request processResponse:openInstallResponse error:Nil]; + + [self waitForExpectationsWithTimeout:5.0 handler:nil]; +} + +- (void)testSKAN4ParamsDefaultValues { + + if (@available(iOS 16.1, macCatalyst 16.1, *)) { + NSString *coarseValue = [[BNCSKAdNetwork sharedInstance] getCoarseConversionValueFromDataResponse:@{}]; + XCTAssertTrue([coarseValue isEqualToString:@"low"]); + + BOOL isLocked = [[BNCSKAdNetwork sharedInstance] getLockedStatusFromDataResponse:@{}]; + XCTAssertFalse(isLocked); + + BOOL ascendingOnly = [[BNCSKAdNetwork sharedInstance] getAscendingOnlyFromDataResponse:@{}]; + XCTAssertTrue(ascendingOnly); + } +} + +- (void)testSKAN4ParamsValues { + + if (@available(iOS 16.1, macCatalyst 16.1, *)) { + + NSDictionary *response = @{@"update_conversion_value": @16, @"coarse_key": @"high", @"locked": @YES, @"ascending_only":@NO }; + BNCSKAdNetwork *adNetwork = [BNCSKAdNetwork sharedInstance]; + + NSString *coarseValue = [adNetwork getCoarseConversionValueFromDataResponse:response]; + XCTAssertTrue([coarseValue isEqualToString:@"high"]); + + BOOL isLocked = [adNetwork getLockedStatusFromDataResponse:response]; + XCTAssertTrue(isLocked); + + BOOL ascendingOnly = [adNetwork getAscendingOnlyFromDataResponse:response]; + XCTAssertFalse(ascendingOnly); + } +} + +- (void)testSKAN4CurrentWindow { + + BNCSKAdNetwork *adNetwork = [BNCSKAdNetwork sharedInstance]; + BNCPreferenceHelper *prefs = [BNCPreferenceHelper sharedInstance]; + + NSDate *currentDateAndTime = [NSDate date]; + prefs.firstAppLaunchTime = [currentDateAndTime dateByAddingTimeInterval:-30]; + NSInteger win = [adNetwork calculateSKANWindowForTime:currentDateAndTime]; + XCTAssertTrue(win == 1); + + win = [adNetwork calculateSKANWindowForTime: [ currentDateAndTime dateByAddingTimeInterval:24*3600*3 ]]; + XCTAssertTrue(win == 2); + + win = [adNetwork calculateSKANWindowForTime: [ currentDateAndTime dateByAddingTimeInterval:24*3600*10 ]]; + XCTAssertTrue(win == 3); + + win = [adNetwork calculateSKANWindowForTime: [ currentDateAndTime dateByAddingTimeInterval:24*3600*36 ]]; + XCTAssertTrue(win == 0); + + prefs.firstAppLaunchTime = nil; + [prefs synchronize]; + win = [adNetwork calculateSKANWindowForTime: currentDateAndTime]; + XCTAssertTrue(win == 0); +} + +- (void)testSKAN4HighestConversionValue { + + BNCSKAdNetwork *adNetwork = [BNCSKAdNetwork sharedInstance]; + BNCPreferenceHelper *prefs = [BNCPreferenceHelper sharedInstance]; + + prefs.highestConversionValueSent = 0; + prefs.skanCurrentWindow = 0; + NSDate *currentDateAndTime = [NSDate date]; + prefs.invokeRegisterApp = YES; + + prefs.firstAppLaunchTime = [currentDateAndTime dateByAddingTimeInterval:-30 ]; + [adNetwork shouldCallPostbackForDataResponse:@{}]; + XCTAssertTrue(prefs.highestConversionValueSent == 0); + + [adNetwork shouldCallPostbackForDataResponse:@{@"update_conversion_value": @6}]; + XCTAssertTrue(prefs.highestConversionValueSent == 6); + + [adNetwork shouldCallPostbackForDataResponse:@{@"update_conversion_value": @3}]; + XCTAssertTrue(prefs.highestConversionValueSent == 6); + + + prefs.firstAppLaunchTime = [currentDateAndTime dateByAddingTimeInterval:-24*3600*3 ]; + [adNetwork shouldCallPostbackForDataResponse:@{}]; + XCTAssertTrue(prefs.highestConversionValueSent == 0); +} + +- (void)testSKAN4ShouldCallPostback { + + BNCSKAdNetwork *adNetwork = [BNCSKAdNetwork sharedInstance]; + BNCPreferenceHelper *prefs = [BNCPreferenceHelper sharedInstance]; + + prefs.firstAppLaunchTime = nil; + [prefs synchronize]; + + NSDictionary *response = @{@"update_conversion_value": @16, @"coarse_key": @"high", @"locked": @YES, @"ascending_only":@NO }; + + BOOL shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; + XCTAssertFalse(shouldCall); + +} + +- (void)testSKAN4ShouldCallPostback2 { + + BNCSKAdNetwork *adNetwork = [BNCSKAdNetwork sharedInstance]; + BNCPreferenceHelper *prefs = [BNCPreferenceHelper sharedInstance]; + + prefs.invokeRegisterApp = YES; + prefs.highestConversionValueSent = 0; + prefs.firstAppLaunchTime = [NSDate date]; + prefs.skanCurrentWindow = 0; + [prefs synchronize]; + + NSMutableDictionary *response = [[NSMutableDictionary alloc] initWithDictionary: + @{@"update_conversion_value": @16, @"coarse_key": @"high", @"locked": @YES, @"ascending_only":@YES }]; + + BOOL shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; + XCTAssertTrue(shouldCall); + + shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; + XCTAssertFalse(shouldCall); + + response[@"update_conversion_value"] = @14; + shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; + XCTAssertFalse(shouldCall); + + response[@"update_conversion_value"] = @18; + shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; + XCTAssertTrue(shouldCall); + + prefs.firstAppLaunchTime = nil; + prefs.firstAppLaunchTime = [[NSDate date] dateByAddingTimeInterval:-24*3600*3]; + shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; + NSLog(@"Conv : %ld", prefs.highestConversionValueSent); + XCTAssertTrue(shouldCall); + + shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; + XCTAssertFalse(shouldCall); +} + +- (void)testSKAN4ShouldCallPostback3 { + BNCSKAdNetwork *adNetwork = [BNCSKAdNetwork sharedInstance]; + BNCPreferenceHelper *prefs = [BNCPreferenceHelper sharedInstance]; + + prefs.invokeRegisterApp = YES; + prefs.highestConversionValueSent = 0; + prefs.firstAppLaunchTime = [NSDate date]; + [prefs synchronize]; + + NSMutableDictionary *response = [[NSMutableDictionary alloc] initWithDictionary: + @{@"update_conversion_value": @16, @"coarse_key": @"high", @"locked": @YES, @"ascending_only":@NO }]; + + BOOL shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; + XCTAssertTrue(shouldCall); + + shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; + XCTAssertTrue(shouldCall); + + response[@"update_conversion_value"] = @14; + shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; + XCTAssertTrue(shouldCall); + + response[@"update_conversion_value"] = @18; + shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; + XCTAssertTrue(shouldCall); + + prefs.firstAppLaunchTime = [[NSDate date] dateByAddingTimeInterval:-24*3600*3]; + //NSLog(@"Conv : %ld", (long)prefs.highestConversionValueSent); + shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; + NSLog(@"Conv : %ld", prefs.highestConversionValueSent); + XCTAssertTrue(shouldCall); +} + +@end diff --git a/BranchSDKTests/BNCSystemObserverTests.m b/BranchSDKTests/BNCSystemObserverTests.m new file mode 100644 index 000000000..8cc54f632 --- /dev/null +++ b/BranchSDKTests/BNCSystemObserverTests.m @@ -0,0 +1,139 @@ +// +// BNCSystemObserverTests.m +// Branch-TestBed +// +// Created by Graham Mueller on 4/22/15. +// Copyright (c) 2015 Branch Metrics. All rights reserved. +// + +#import +#import "BNCSystemObserver.h" + +@interface BNCSystemObserver () ++ (BOOL)compareUriSchemes:(NSString *)serverUriScheme With:(NSArray *)urlTypes; +@end + +@interface BNCSystemObserverTests : XCTestCase + +@end + +@implementation BNCSystemObserverTests + +- (void)testDefaultURIScheme_TestBed { + //ND XCTAssert([[BNCSystemObserver defaultURIScheme] isEqualToString:@"branchtest"]); +} + +- (void)testAppVersion_TestBed { + XCTAssert([[BNCSystemObserver applicationVersion] isEqualToString:@"1.0"]); +} + +- (void)testBundleIdentifier_TestBed { + NSString *bundleId = [BNCSystemObserver bundleIdentifier]; + XCTAssert([bundleId isEqualToString:@"branch.BranchSDKTestsHostApp"]); +} + +- (void)testBrand { + XCTAssert([[BNCSystemObserver brand] isEqualToString:@"Apple"]); +} + +- (void)testModel_Simulator { + // simulator models + NSString *tmp = [BNCSystemObserver model]; + XCTAssert([tmp containsString:@"arm64"] || [tmp containsString:@"x86_64"]); +} + +//- (void)testModelName_iPhone7 { +// XCTAssert([@"iPhone9,3" isEqualToString:[BNCSystemObserver model]]); +//} + +- (void)testOSName { + XCTAssertNotNil([BNCSystemObserver osName]); + + // This is not the system name, but rather the name Branch server expects + // XCTAssert([self.deviceInfo.osName isEqualToString:[UIDevice currentDevice].systemName]); + XCTAssert([@"iOS" isEqualToString:[BNCSystemObserver osName]] || [@"tv_OS" isEqualToString:[BNCSystemObserver osName]]); +} + +- (void)testOSVersion { + XCTAssertNotNil([BNCSystemObserver osVersion]); + XCTAssert([[BNCSystemObserver osVersion] isEqualToString:[UIDevice currentDevice].systemVersion]); +} + +/* + * Sample device screens + * original iPhone 320x480 1 + * iPad Pro (6th gen 12.9") 2048x2732 2 + * iPhone 14 Pro max 1290x2796 3 + */ + +- (void)testScreenWidth { + XCTAssert([BNCSystemObserver screenWidth].intValue >= 320 && [BNCSystemObserver screenWidth].intValue <= 2796); +} + +- (void)testScreenHeight { + XCTAssert([BNCSystemObserver screenHeight].intValue >= 320 && [BNCSystemObserver screenWidth].intValue <= 2796); +} + +- (void)testScreenScale { + XCTAssert([BNCSystemObserver screenScale].intValue >= 1 && [BNCSystemObserver screenScale].intValue <= 3); +} + +- (void)testIsSimulator_Simulator { + XCTAssert([BNCSystemObserver isSimulator]); +} + +- (void)testAdvertiserIdentifier_NoATTPrompt { + XCTAssertNil([BNCSystemObserver advertiserIdentifier]); +} + +- (void)testOptedInStatus_NoATTPrompt { + XCTAssert([[BNCSystemObserver attOptedInStatus] isEqualToString:@"not_determined"]); +} + +- (void)testAppleAttributionToken_Simulator { + NSString *token = [BNCSystemObserver appleAttributionToken]; + XCTAssertNil(token); +} + +- (void)testEnvironment { + // currently not running unit tests on extensions + XCTAssert([@"FULL_APP" isEqualToString:[BNCSystemObserver environment]]); +} + +- (void)testIsAppClip { + // currently not running unit tests on extensions + XCTAssert(![BNCSystemObserver isAppClip]); +} + +- (void)testCompareURIScemes { + + NSString *serverUriScheme = @"bnctest://"; + NSArray *urlTypes = @[@{@"CFBundleURLSchemes" : @[@""]}, @{@"CFBundleURLSchemes" : @[@"bnctest", @"xyzs"]}]; + + XCTAssertTrue([BNCSystemObserver compareUriSchemes:serverUriScheme With:urlTypes]); + + XCTAssertFalse([BNCSystemObserver compareUriSchemes:serverUriScheme With:nil]); + + XCTAssertFalse([BNCSystemObserver compareUriSchemes:nil With:nil]); + + XCTAssertFalse([BNCSystemObserver compareUriSchemes:nil With:urlTypes]); + + serverUriScheme = @":/"; + XCTAssertFalse([BNCSystemObserver compareUriSchemes:serverUriScheme With:urlTypes]); + + serverUriScheme = @"bnctest"; + XCTAssertTrue([BNCSystemObserver compareUriSchemes:serverUriScheme With:urlTypes]); + + serverUriScheme = @"bnctest://"; + urlTypes = @[ @{@"CFBundleURLSchemes" : @[@"bnctestX", @"xyzs"]}]; + XCTAssertFalse([BNCSystemObserver compareUriSchemes:serverUriScheme With:urlTypes]); + + serverUriScheme = @"://"; + XCTAssertFalse([BNCSystemObserver compareUriSchemes:serverUriScheme With:urlTypes]); + + XCTAssertFalse([BNCSystemObserver compareUriSchemes:@"" With:urlTypes]); + + XCTAssertFalse([BNCSystemObserver compareUriSchemes:@"" With:@[@{}]]); +} + +@end diff --git a/BranchSDKTests/BNCURLFilterSkiplistUpgradeTests.m b/BranchSDKTests/BNCURLFilterSkiplistUpgradeTests.m new file mode 100644 index 000000000..ad7d5b029 --- /dev/null +++ b/BranchSDKTests/BNCURLFilterSkiplistUpgradeTests.m @@ -0,0 +1,273 @@ +// +// BNCURLFilterSkiplistUpgradeTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 4/4/23. +// Copyright © 2023 Branch, Inc. All rights reserved. +// + +#import +#import "BNCURLFilter.h" + +@interface BNCURLFilterSkiplistUpgradeTests : XCTestCase + +@end + +@implementation BNCURLFilterSkiplistUpgradeTests + +- (void)setUp { + +} + +- (void)tearDown { + +} + + // v0 list + // https://cdn.branch.io/sdk/uriskiplist_v0.json +- (NSArray *)v0PatternList { + NSArray *patternList = @[ + @"^fb\\d+:", + @"^li\\d+:", + @"^pdk\\d+:", + @"^twitterkit-.*:", + @"^com\\.googleusercontent\\.apps\\.\\d+-.*:\\/oauth", + @"^(?i)(?!(http|https):).*(:|:.*\\b)(password|o?auth|o?auth.?token|access|access.?token)\\b", + @"^(?i)((http|https):\\/\\/).*[\\/|?|#].*\\b(password|o?auth|o?auth.?token|access|access.?token)\\b" + ]; + return patternList; +} + +// v1 list +// https://cdn.branch.io/sdk/uriskiplist_v1.json +- (NSArray *)v1PatternList { + NSArray *patternList = @[ + @"^fb\\d+:", + @"^li\\d+:", + @"^pdk\\d+:", + @"^twitterkit-.*:", + @"^com\\.googleusercontent\\.apps\\.\\d+-.*:\\/oauth", + @"^(?i)(?!(http|https):).*(:|:.*\\b)(password|o?auth|o?auth.?token|access|access.?token)\\b", + @"^(?i)((http|https):\\/\\/).*[\\/|?|#].*\\b(password|o?auth|o?auth.?token|access|access.?token)\\b" + ]; + return patternList; +} + +// v2 list +// https://cdn.branch.io/sdk/uriskiplist_v2.json +- (NSArray *)v2PatternList { + NSArray *patternList = @[ + @"^fb\\d+:((?!campaign_ids).)*$", + @"^li\\d+:", + @"^pdk\\d+:", + @"^twitterkit-.*:", + @"^com\\.googleusercontent\\.apps\\.\\d+-.*:\\/oauth", + @"^(?i)(?!(http|https):).*(:|:.*\\b)(password|o?auth|o?auth.?token|access|access.?token)\\b", + @"^(?i)((http|https):\\/\\/).*[\\/|?|#].*\\b(password|o?auth|o?auth.?token|access|access.?token)\\b" + ]; + return patternList; +} + +- (BNCURLFilter *)filterWithV0List { + BNCURLFilter *filter = [BNCURLFilter new]; + [self migrateFilter:filter patternList:[self v1PatternList]]; + return filter; +} + +- (BNCURLFilter *)filterWithV1List { + BNCURLFilter *filter = [BNCURLFilter new]; + [self migrateFilter:filter patternList:[self v1PatternList]]; + return filter; +} + +- (BNCURLFilter *)filterWithV2List { + BNCURLFilter *filter = [BNCURLFilter new]; + [self migrateFilter:filter patternList:[self v2PatternList]]; + return filter; +} + +- (void)migrateFilter:(BNCURLFilter *)filter patternList:(NSArray *)patternList { + [filter useCustomPatternList:patternList]; +} + +- (NSArray *)badURLs { + NSArray *kBadURLs = @[ + @"fb123456:login/464646", + @"twitterkit-.4545:", + @"shsh:oauth/login", + @"https://myapp.app.link/oauth_token=fred", + @"https://myapp.app.link/auth_token=fred", + @"https://myapp.app.link/authtoken=fred", + @"https://myapp.app.link/auth=fred", + @"fb1234:", + @"fb1234:/", + @"fb1234:/this-is-some-extra-info/?whatever", + @"fb1234:/this-is-some-extra-info/?whatever:andstuff", + @"myscheme:path/to/resource?oauth=747474", + @"myscheme:oauth=747474", + @"myscheme:/oauth=747474", + @"myscheme://oauth=747474", + @"myscheme://path/oauth=747474", + @"myscheme://path/:oauth=747474", + @"https://google.com/userprofile/devonbanks=oauth?", + ]; + return kBadURLs; +} + +- (NSArray *)goodURLs { + NSArray *kGoodURLs = @[ + @"shshs:/content/path", + @"shshs:content/path", + @"https://myapp.app.link/12345/link", + @"fb123x:/", + @"https://myapp.app.link?authentic=true&tokemonsta=false", + @"myscheme://path/brauth=747474", + ]; + return kGoodURLs; +} + +- (void)testOldBadURLsWithV0 { + BNCURLFilter *filter = [self filterWithV0List]; + NSArray *list = [self badURLs]; + for (NSString *string in list) { + NSURL *url = [NSURL URLWithString:string]; + if (url) { + XCTAssertTrue([filter shouldIgnoreURL:url], @"Checking '%@'.", url); + } + } +} + +- (void)testOldGoodURLsWithV0 { + BNCURLFilter *filter = [self filterWithV0List]; + NSArray *list = [self goodURLs]; + for (NSString *string in list) { + NSURL *url = [NSURL URLWithString:string]; + if (url) { + XCTAssertFalse([filter shouldIgnoreURL:url], @"Checking '%@'.", url); + } + } +} + +- (void)testOldBadURLsWithV2 { + BNCURLFilter *filter = [self filterWithV2List]; + NSArray *list = [self badURLs]; + for (NSString *string in list) { + NSURL *url = [NSURL URLWithString:string]; + if (url) { + XCTAssertTrue([filter shouldIgnoreURL:url], @"Checking '%@'.", url); + } + } +} + +- (void)testOldGoodURLsWithV2 { + BNCURLFilter *filter = [self filterWithV2List]; + NSArray *list = [self goodURLs]; + for (NSString *string in list) { + NSURL *url = [NSURL URLWithString:string]; + if (url) { + XCTAssertFalse([filter shouldIgnoreURL:url], @"Checking '%@'.", url); + } + } +} + +- (void)testMetaAEMWithV0 { + NSString *string = @"fb1://?campaign_ids=a"; + NSURL *url = [NSURL URLWithString:string]; + if (url) { + BNCURLFilter *filter = [self filterWithV0List]; + XCTAssertTrue([filter shouldIgnoreURL:url]); + } +} + +- (void)testMetaAEMWithV2 { + NSString *string = @"fb1://?campaign_ids=a"; + NSURL *url = [NSURL URLWithString:string]; + if (url) { + BNCURLFilter *filter = [self filterWithV2List]; + XCTAssertFalse([filter shouldIgnoreURL:url]); + } +} + +- (void)testMetaAEMWithV2WithTrailingParameters { + NSString *string = @"fb1://?campaign_ids=a&token=abcde"; + NSURL *url = [NSURL URLWithString:string]; + if (url) { + BNCURLFilter *filter = [self filterWithV2List]; + XCTAssertFalse([filter shouldIgnoreURL:url]); + } +} + +- (void)testMetaAEMWithV2WithPrecedingParameters { + NSString *string = @"fb1://?brand=abcde&campaign_ids=a"; + NSURL *url = [NSURL URLWithString:string]; + if (url) { + BNCURLFilter *filter = [self filterWithV2List]; + XCTAssertFalse([filter shouldIgnoreURL:url]); + } +} + +- (void)testMetaAEMWithV2WithPrecedingAndTrailingParameters { + NSString *string = @"fb1://?brand=abcde&campaign_ids=a&link=12345"; + NSURL *url = [NSURL URLWithString:string]; + if (url) { + BNCURLFilter *filter = [self filterWithV2List]; + XCTAssertFalse([filter shouldIgnoreURL:url]); + } +} + +- (void)testSampleMetaAEMWithV0 { + NSString *string = @"fb123456789://products/next?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D"; + NSURL *url = [NSURL URLWithString:string]; + if (url) { + BNCURLFilter *filter = [self filterWithV0List]; + XCTAssertTrue([filter shouldIgnoreURL:url]); + } +} + +- (void)testSampleMetaAEMWithV1 { + NSString *string = @"fb123456789://products/next?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D"; + NSURL *url = [NSURL URLWithString:string]; + if (url) { + BNCURLFilter *filter = [self filterWithV1List]; + XCTAssertTrue([filter shouldIgnoreURL:url]); + } +} + +// This one is not filtered! +- (void)testSampleMetaAEMWithV2 { + NSString *string = @"fb123456789://products/next?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D"; + NSURL *url = [NSURL URLWithString:string]; + if (url) { + BNCURLFilter *filter = [self filterWithV2List]; + XCTAssertFalse([filter shouldIgnoreURL:url]); + } +} + +- (void)testSampleMetaAEMNoCampignIDsWithV0 { + NSString *string = @"fb123456789://products/next?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22test_deeplink%22%3A1%7D"; + NSURL *url = [NSURL URLWithString:string]; + if (url) { + BNCURLFilter *filter = [self filterWithV0List]; + XCTAssertTrue([filter shouldIgnoreURL:url]); + } +} + +- (void)testSampleMetaAEMNoCampignIDsWithV1 { + NSString *string = @"fb123456789://products/next?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22test_deeplink%22%3A1%7D"; + NSURL *url = [NSURL URLWithString:string]; + if (url) { + BNCURLFilter *filter = [self filterWithV1List]; + XCTAssertTrue([filter shouldIgnoreURL:url]); + } +} + +- (void)testSampleMetaAEMNoCampignIDsWithV2 { + NSString *string = @"fb123456789://products/next?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22test_deeplink%22%3A1%7D"; + NSURL *url = [NSURL URLWithString:string]; + if (url) { + BNCURLFilter *filter = [self filterWithV2List]; + XCTAssertTrue([filter shouldIgnoreURL:url]); + } +} + +@end diff --git a/BranchSDKTests/BNCURLFilterTests.m b/BranchSDKTests/BNCURLFilterTests.m new file mode 100644 index 000000000..1573bc36e --- /dev/null +++ b/BranchSDKTests/BNCURLFilterTests.m @@ -0,0 +1,168 @@ +/** + @file BNCURLFilterTests.m + @package Branch-SDK-Tests + @brief BNCURLFilter tests. + + @author Edward Smith + @date February 14, 2018 + @copyright Copyright © 2018 Branch. All rights reserved. +*/ + +#import +#import "BNCURLFilter.h" + +@interface BNCURLFilterTests : XCTestCase +@end + +@implementation BNCURLFilterTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)testPatternMatchingURL_nil { + BNCURLFilter *filter = [BNCURLFilter new]; + NSURL *url = nil; + NSString *matchingRegex = [filter patternMatchingURL:url]; + XCTAssertNil(matchingRegex); +} + +- (void)testPatternMatchingURL_emptyString { + BNCURLFilter *filter = [BNCURLFilter new]; + NSURL *url = [NSURL URLWithString:@""]; + NSString *matchingRegex = [filter patternMatchingURL:url]; + XCTAssertNil(matchingRegex); +} + +- (void)testPatternMatchingURL_fbRegexMatches { + NSString *pattern = @"^fb\\d+:((?!campaign_ids).)*$"; + NSString *sampleURL = @"fb12345://"; + + BNCURLFilter *filter = [BNCURLFilter new]; + NSURL *url = [NSURL URLWithString:sampleURL]; + NSString *matchingRegex = [filter patternMatchingURL:url]; + XCTAssertTrue([pattern isEqualToString:matchingRegex]); +} + +- (void)testPatternMatchingURL_fbRegexDoesNotMatch { + NSString *pattern = @"^fb\\d+:((?!campaign_ids).)*$"; + NSString *sampleURL = @"fb12345://campaign_ids"; + + BNCURLFilter *filter = [BNCURLFilter new]; + NSURL *url = [NSURL URLWithString:sampleURL]; + NSString *matchingRegex = [filter patternMatchingURL:url]; + XCTAssertFalse([pattern isEqualToString:matchingRegex]); +} + + +- (void)testIgnoredSuspectedAuthURLs { + NSArray *urls = @[ + @"fb123456:login/464646", + @"shsh:oauth/login", + @"https://myapp.app.link/oauth_token=fred", + @"https://myapp.app.link/auth_token=fred", + @"https://myapp.app.link/authtoken=fred", + @"https://myapp.app.link/auth=fred", + @"myscheme:path/to/resource?oauth=747474", + @"myscheme:oauth=747474", + @"myscheme:/oauth=747474", + @"myscheme://oauth=747474", + @"myscheme://path/oauth=747474", + @"myscheme://path/:oauth=747474", + @"https://google.com/userprofile/devonbanks=oauth?" + ]; + + BNCURLFilter *filter = [BNCURLFilter new]; + for (NSString *string in urls) { + NSURL *URL = [NSURL URLWithString:string]; + XCTAssertTrue([filter shouldIgnoreURL:URL], @"Checking '%@'.", URL); + } +} + +- (void)testAllowedURLsSimilarToAuthURLs { + NSArray *urls = @[ + @"shshs:/content/path", + @"shshs:content/path", + @"https://myapp.app.link/12345/link", + @"https://myapp.app.link?authentic=true&tokemonsta=false", + @"myscheme://path/brauth=747474" + ]; + + BNCURLFilter *filter = [BNCURLFilter new]; + for (NSString *string in urls) { + NSURL *URL = [NSURL URLWithString:string]; + XCTAssertFalse([filter shouldIgnoreURL:URL], @"Checking '%@'", URL); + } +} + +- (void)testIgnoredFacebookURLs { + // Most FB URIs are ignored + NSArray *urls = @[ + @"fb123456://login/464646", + @"fb1234:", + @"fb1234:/", + @"fb1234:/this-is-some-extra-info/?whatever", + @"fb1234:/this-is-some-extra-info/?whatever:andstuff" + ]; + + BNCURLFilter *filter = [BNCURLFilter new]; + for (NSString *string in urls) { + NSURL *URL = [NSURL URLWithString:string]; + XCTAssertTrue([filter shouldIgnoreURL:URL], @"Checking '%@'.", URL); + } +} + +- (void)testAllowedFacebookURLs { + NSArray *urls = @[ + // Facebook URIs do not contain letters other than an fb prefix + @"fb123x://", + // FB URIs with campaign ids are allowed + @"fb1234://helloworld?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D" + ]; + + BNCURLFilter *filter = [BNCURLFilter new]; + for (NSString *string in urls) { + NSURL *URL = [NSURL URLWithString:string]; + XCTAssertFalse([filter shouldIgnoreURL:URL], @"Checking '%@'", URL); + } +} + +- (void)testCustomPatternList { + BNCURLFilter *filter = [BNCURLFilter new]; + + // sanity check default pattern list + XCTAssertTrue([filter shouldIgnoreURL:[NSURL URLWithString:@"fb123://"]]); + XCTAssertFalse([filter shouldIgnoreURL:[NSURL URLWithString:@"branch123://"]]); + + // confirm new pattern list is enforced + [filter useCustomPatternList:@[@"^branch\\d+:"]]; + XCTAssertFalse([filter shouldIgnoreURL:[NSURL URLWithString:@"fb123://"]]); + XCTAssertTrue([filter shouldIgnoreURL:[NSURL URLWithString:@"branch123://"]]); +} + +// This is an end to end test and relies on a server call +- (void)testUpdatePatternListFromServer { + BNCURLFilter *filter = [BNCURLFilter new]; + + // confirm new pattern list is enforced + [filter useCustomPatternList:@[@"^branch\\d+:"]]; + XCTAssertFalse([filter shouldIgnoreURL:[NSURL URLWithString:@"fb123://"]]); + XCTAssertTrue([filter shouldIgnoreURL:[NSURL URLWithString:@"branch123://"]]); + + __block XCTestExpectation *expectation = [self expectationWithDescription:@"List updated"]; + [filter updatePatternListFromServerWithCompletion:^{ + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:5.0 handler:^(NSError * _Nullable error) { }]; + + // the retrieved list should match default pattern list + XCTAssertTrue([filter shouldIgnoreURL:[NSURL URLWithString:@"fb123://"]]); + XCTAssertFalse([filter shouldIgnoreURL:[NSURL URLWithString:@"branch123://"]]); +} + +@end diff --git a/BranchSDKTests/BNCUserAgentCollectorTests.m b/BranchSDKTests/BNCUserAgentCollectorTests.m new file mode 100644 index 000000000..e54cca1bc --- /dev/null +++ b/BranchSDKTests/BNCUserAgentCollectorTests.m @@ -0,0 +1,111 @@ +// +// BNCUserAgentCollectorTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 8/29/19. +// Copyright © 2019 Branch, Inc. All rights reserved. +// + +#import +#import "BNCPreferenceHelper.h" +#import "BNCDeviceSystem.h" +#import "BNCUserAgentCollector.h" + +// expose private methods for unit testing +@interface BNCUserAgentCollector() + +- (NSString *)loadUserAgentForSystemBuildVersion:(NSString *)systemBuildVersion; +- (void)saveUserAgent:(NSString *)userAgent forSystemBuildVersion:(NSString *)systemBuildVersion; +- (void)collectUserAgentWithCompletion:(void (^)(NSString * _Nullable userAgent))completion; + +@end + +@interface BNCUserAgentCollectorTests : XCTestCase + +@end + +@implementation BNCUserAgentCollectorTests + ++ (void)setUp { + [BNCUserAgentCollectorTests resetPersistentData]; +} + +- (void)setUp { + +} + +- (void)tearDown { + [BNCUserAgentCollectorTests resetPersistentData]; +} + ++ (void)resetPersistentData { + BNCPreferenceHelper *preferences = [BNCPreferenceHelper sharedInstance]; + preferences.browserUserAgentString = nil; + preferences.lastSystemBuildVersion = nil; +} + +- (void)testResetPersistentData { + BNCPreferenceHelper *preferences = [BNCPreferenceHelper sharedInstance]; + XCTAssertNil(preferences.browserUserAgentString); + XCTAssertNil(preferences.lastSystemBuildVersion); +} + +- (void)testSaveAndLoadUserAgent { + NSString *systemBuildVersion = @"test"; + NSString *userAgent = @"UserAgent"; + + BNCUserAgentCollector *collector = [BNCUserAgentCollector new]; + [collector saveUserAgent:userAgent forSystemBuildVersion:systemBuildVersion]; + NSString *expected = [collector loadUserAgentForSystemBuildVersion:systemBuildVersion]; + XCTAssertTrue([userAgent isEqualToString:expected]); +} + +- (void)testCollectUserAgent { + XCTestExpectation *expectation = [self expectationWithDescription:@"expectation"]; + + BNCUserAgentCollector *collector = [BNCUserAgentCollector new]; + [collector collectUserAgentWithCompletion:^(NSString * _Nullable userAgent) { + XCTAssertNotNil(userAgent); + XCTAssertTrue([userAgent containsString:@"AppleWebKit"]); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:4.0 handler:^(NSError * _Nullable error) { + + }]; +} + +- (void)testLoadUserAgent_EmptyDataStore { + XCTestExpectation *expectation = [self expectationWithDescription:@"expectation"]; + + BNCUserAgentCollector *collector = [BNCUserAgentCollector new]; + [collector loadUserAgentWithCompletion:^(NSString * _Nullable userAgent) { + XCTAssertNotNil(userAgent); + XCTAssertTrue([userAgent containsString:@"AppleWebKit"]); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:2.0 handler:^(NSError * _Nullable error) { + + }]; +} + +- (void)testLoadUserAgent_FilledDataStore { + XCTestExpectation *expectation = [self expectationWithDescription:@"expectation"]; + NSString *savedUserAgent = @"UserAgent"; + + BNCUserAgentCollector *collector = [BNCUserAgentCollector new]; + [collector saveUserAgent:savedUserAgent forSystemBuildVersion:[BNCDeviceSystem new].systemBuildVersion]; + [collector loadUserAgentWithCompletion:^(NSString * _Nullable userAgent) { + XCTAssertNotNil(userAgent); + XCTAssertTrue([userAgent isEqualToString:savedUserAgent]); + XCTAssertFalse([userAgent containsString:@"AppleWebKit"]); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:2.0 handler:^(NSError * _Nullable error) { + + }]; +} + +@end diff --git a/BranchSDKTests/Branch-SDK-Tests-Bridging-Header.h b/BranchSDKTests/Branch-SDK-Tests-Bridging-Header.h new file mode 100644 index 000000000..169bd50f3 --- /dev/null +++ b/BranchSDKTests/Branch-SDK-Tests-Bridging-Header.h @@ -0,0 +1,5 @@ +// +// Module headers for Branch SDK unit testing. +// + +#import "Branch.h" diff --git a/BranchSDKTests/BranchActivityItemTests.m b/BranchSDKTests/BranchActivityItemTests.m new file mode 100644 index 000000000..f117859f7 --- /dev/null +++ b/BranchSDKTests/BranchActivityItemTests.m @@ -0,0 +1,39 @@ +// +// BranchActivityItemTests.m +// Branch-SDK-Tests +// +// Created by Nipun Singh on 9/21/23. +// Copyright © 2023 Branch, Inc. All rights reserved. +// + +#import +#import "Branch.h" + +@interface BranchActivityItemTests: XCTestCase +@end + +@implementation BranchActivityItemTests + +// Rework this test, it's not reliable. +//- (void)testGetBranchActivityItemWithAllParams { +// NSDictionary *params = @{@"key": @"value"}; +// NSString *feature = @"feature4"; +// NSString *stage = @"stage3"; +// NSArray *tags = @[@"tag3", @"tag4"]; +// NSString *campaign = @"campaign1"; +// NSString *alias = [[NSUUID UUID] UUIDString]; +// BranchActivityItemProvider *provider = [Branch getBranchActivityItemWithParams:params feature:feature stage:stage campaign:campaign tags:tags alias:alias]; +// sleep(2000); +// if ([[provider item] isKindOfClass:[NSURL class]]) { +// NSURL *urlObject = (NSURL *)[provider item]; +// NSString *url = [urlObject absoluteString]; +// +// NSLog(@"Provider URL as String: %@", url); +// +// XCTAssertTrue([url isEqualToString:[@"https://bnctestbed.app.link/" stringByAppendingString:alias]]); +// } else { +// XCTFail("Provider Data is not of type NSURL"); +// } +//} + +@end diff --git a/BranchSDKTests/BranchClassTests.m b/BranchSDKTests/BranchClassTests.m new file mode 100644 index 000000000..d1e7713f1 --- /dev/null +++ b/BranchSDKTests/BranchClassTests.m @@ -0,0 +1,265 @@ +// +// BranchClassTests.m +// Branch-SDK-Tests +// +// Created by Nipun Singh on 9/25/23. +// Copyright © 2023 Branch, Inc. All rights reserved. +// + +#import +#import "Branch.h" +#import "BranchConstants.h" +#import "BNCPasteboard.h" +#import "BNCAppGroupsData.h" +#import "BNCPartnerParameters.h" + +@interface BNCPreferenceHelper(Test) +// Expose internal private method to clear EEA data +- (void)writeObjectToDefaults:(NSString *)key value:(NSObject *)value; +@end + +@interface BranchClassTests : XCTestCase +@property (nonatomic, strong) Branch *branch; +@end + +@implementation BranchClassTests + +- (void)setUp { + [super setUp]; + self.branch = [Branch getInstance]; +} + +- (void)tearDown { + self.branch = nil; + [super tearDown]; +} + +- (void)testIsUserIdentified { + [self.branch setIdentity: @"userId"]; + XCTAssertTrue([self.branch isUserIdentified], @"User should be identified"); +} + +- (void)testDisableAdNetworkCallouts { + [self.branch disableAdNetworkCallouts:YES]; + XCTAssertTrue([BNCPreferenceHelper sharedInstance].disableAdNetworkCallouts, @"AdNetwork callouts should be disabled"); +} + +- (void)testSetNetworkTimeout { + [self.branch setNetworkTimeout:5.0]; + XCTAssertEqual([BNCPreferenceHelper sharedInstance].timeout, 5.0, @"Network timeout should be set to 5.0"); +} + +//- (void)testSetMaxRetries { +// [self.branch setMaxRetries:3]; +// XCTAssertEqual([BNCPreferenceHelper sharedInstance].retryCount, 3, @"Max retries should be set to 3"); +//} + +- (void)testSetRetryInterval { + [self.branch setRetryInterval:2.0]; + XCTAssertEqual([BNCPreferenceHelper sharedInstance].retryInterval, 2.0, @"Retry interval should be set to 2.0"); +} + +- (void)testSetRequestMetadataKeyAndValue { + [self.branch setRequestMetadataKey:@"key" value:@"value"]; + NSDictionary *metadata = [BNCPreferenceHelper sharedInstance].requestMetadataDictionary; + XCTAssertEqualObjects(metadata[@"key"], @"value"); +} + +- (void)testSetTrackingDisabled { + XCTAssertFalse([BNCPreferenceHelper sharedInstance].trackingDisabled); + + [Branch setTrackingDisabled:YES]; + XCTAssertTrue([BNCPreferenceHelper sharedInstance].trackingDisabled); + + [Branch setTrackingDisabled:NO]; + XCTAssertFalse([BNCPreferenceHelper sharedInstance].trackingDisabled); +} + +- (void)testCheckPasteboardOnInstall { + [self.branch checkPasteboardOnInstall]; + BOOL checkOnInstall = [BNCPasteboard sharedInstance].checkOnInstall; + XCTAssertTrue(checkOnInstall); +} + +- (void)testWillShowPasteboardToast_ShouldReturnYes { + [BNCPreferenceHelper sharedInstance].randomizedBundleToken = nil; + [BNCPasteboard sharedInstance].checkOnInstall = YES; + UIPasteboard.generalPasteboard.URL = [NSURL URLWithString:@"https://example.com"]; + + BOOL result = [self.branch willShowPasteboardToast]; + XCTAssertTrue(result); +} + +- (void)testWillShowPasteboardToast_ShouldReturnNo { + [BNCPreferenceHelper sharedInstance].randomizedBundleToken = @"some_token"; + [BNCPasteboard sharedInstance].checkOnInstall = NO; + + BOOL result = [self.branch willShowPasteboardToast]; + XCTAssertFalse(result); +} + +- (void)testSetAppClipAppGroup { + NSString *testAppGroup = @"testAppGroup"; + [self.branch setAppClipAppGroup:testAppGroup]; + NSString *actualAppGroup = [BNCAppGroupsData shared].appGroup; + + XCTAssertEqualObjects(testAppGroup, actualAppGroup); +} + +- (void)testClearPartnerParameters { + [self.branch addFacebookPartnerParameterWithName:@"ph" value:@"123456789"]; + [[BNCPartnerParameters shared] clearAllParameters]; + + NSDictionary *result = [[BNCPartnerParameters shared] parameterJson]; + XCTAssertEqual([result count], 0, @"Parameters should be empty after calling clearAllParameters"); +} + +- (void)testAddFacebookParameterWithName_Value { + [self.branch addFacebookPartnerParameterWithName:@"name" value:@"3D4F2BF07DC1BE38B20C653EE9A7E446158F84E525BBB98FEDF721CB5A40A346"]; + + NSDictionary *result = [[BNCPartnerParameters shared] parameterJson][@"fb"]; + XCTAssertEqualObjects(result[@"name"], @"3D4F2BF07DC1BE38B20C653EE9A7E446158F84E525BBB98FEDF721CB5A40A346", @"Should add parameter for Facebook"); +} + +- (void)testAddSnapParameterWithName_Value { + [self.branch addSnapPartnerParameterWithName:@"name" value:@"3D4F2BF07DC1BE38B20C653EE9A7E446158F84E525BBB98FEDF721CB5A40A346"]; + + NSDictionary *result = [[BNCPartnerParameters shared] parameterJson][@"snap"]; + XCTAssertEqualObjects(result[@"name"], @"3D4F2BF07DC1BE38B20C653EE9A7E446158F84E525BBB98FEDF721CB5A40A346", @"Should add parameter for Snap"); +} + +- (void)testGetFirstReferringBranchUniversalObject_ClickedBranchLink { + NSString *installParamsString = @"{\"$canonical_identifier\":\"content/12345\",\"$creation_timestamp\":1694557342247,\"$desktop_url\":\"https://example.com/home\",\"$og_description\":\"My Content Description\",\"$og_title\":\"My Content Title\",\"+click_timestamp\":1695749249,\"+clicked_branch_link\":1,\"+is_first_session\":1,\"+match_guaranteed\":1,\"custom\":\"data\",\"key1\":\"value1\",\"~campaign\":\"content 123 launch\",\"~channel\":\"facebook\",\"~creation_source\":3,\"~feature\":\"sharing\",\"~id\":1230269548213984984,\"~referring_link\":\"https://bnctestbed.app.link/uSPHktjO2Cb\"}"; + [[BNCPreferenceHelper sharedInstance] setInstallParams: installParamsString]; + + BranchUniversalObject *result = [self.branch getFirstReferringBranchUniversalObject];\ + XCTAssertNotNil(result); + XCTAssertEqualObjects(result.title, @"My Content Title"); + XCTAssertEqualObjects(result.canonicalIdentifier, @"content/12345"); +} + +- (void)testGetFirstReferringBranchUniversalObject_NotClickedBranchLink { + NSString *installParamsString = @"{\"+clicked_branch_link\":false,\"+is_first_session\":true}"; + [[BNCPreferenceHelper sharedInstance] setInstallParams: installParamsString]; + + BranchUniversalObject *result = [self.branch getFirstReferringBranchUniversalObject]; + XCTAssertNil(result); +} + +- (void)testGetFirstReferringBranchLinkProperties_ClickedBranchLink { + NSString *installParamsString = @"{\"+clicked_branch_link\":1,\"+is_first_session\":1,\"~campaign\":\"content 123 launch\"}"; + [[BNCPreferenceHelper sharedInstance] setInstallParams:installParamsString]; + + BranchLinkProperties *result = [self.branch getFirstReferringBranchLinkProperties]; + XCTAssertNotNil(result); + XCTAssertEqualObjects(result.campaign, @"content 123 launch"); +} + +- (void)testGetFirstReferringBranchLinkProperties_NotClickedBranchLink { + NSString *installParamsString = @"{\"+clicked_branch_link\":false,\"+is_first_session\":true}"; + [[BNCPreferenceHelper sharedInstance] setInstallParams:installParamsString]; + + BranchLinkProperties *result = [self.branch getFirstReferringBranchLinkProperties]; + XCTAssertNil(result); +} + +- (void)testGetFirstReferringParams { + NSString *installParamsString = @"{\"+clicked_branch_link\":true,\"+is_first_session\":true}"; + [[BNCPreferenceHelper sharedInstance] setInstallParams:installParamsString]; + + NSDictionary *result = [self.branch getFirstReferringParams]; + XCTAssertEqualObjects([result objectForKey:@"+clicked_branch_link"], @true); +} + +- (void)testGetLatestReferringParams { + NSString *sessionParamsString = @"{\"+clicked_branch_link\":true,\"+is_first_session\":false}"; + [[BNCPreferenceHelper sharedInstance] setSessionParams:sessionParamsString]; + + NSDictionary *result = [self.branch getLatestReferringParams]; + XCTAssertEqualObjects([result objectForKey:@"+clicked_branch_link"], @true); +} + +//- (void)testGetLatestReferringParamsSynchronous { +// NSString *sessionParamsString = @"{\"+clicked_branch_link\":true,\"+is_first_session\":false}"; +// [[BNCPreferenceHelper sharedInstance] setSessionParams:sessionParamsString]; +// +// NSDictionary *result = [self.branch getLatestReferringParamsSynchronous]; +// XCTAssertEqualObjects([result objectForKey:@"+clicked_branch_link"], @true); +//} + +- (void)testGetLatestReferringBranchUniversalObject_ClickedBranchLink { + NSString *sessionParamsString = @"{\"+clicked_branch_link\":1,\"+is_first_session\":false,\"$og_title\":\"My Latest Content\"}"; + [[BNCPreferenceHelper sharedInstance] setSessionParams:sessionParamsString]; + + BranchUniversalObject *result = [self.branch getLatestReferringBranchUniversalObject]; + XCTAssertNotNil(result); + XCTAssertEqualObjects(result.title, @"My Latest Content"); +} + +- (void)testGetLatestReferringBranchLinkProperties_ClickedBranchLink { + NSString *sessionParamsString = @"{\"+clicked_branch_link\":true,\"+is_first_session\":false,\"~campaign\":\"latest campaign\"}"; + [[BNCPreferenceHelper sharedInstance] setSessionParams:sessionParamsString]; + + BranchLinkProperties *result = [self.branch getLatestReferringBranchLinkProperties]; + XCTAssertNotNil(result); + XCTAssertEqualObjects(result.campaign, @"latest campaign"); +} + +- (void)testGetShortURL { + NSString *shortURL = [self.branch getShortURL]; + XCTAssertNotNil(shortURL, @"URL should not be nil"); + XCTAssertTrue([shortURL hasPrefix:@"https://"], @"URL should start with 'https://'"); +} + +- (void)testGetLongURLWithParamsAndChannelAndTagsAndFeatureAndStageAndAlias { + NSDictionary *params = @{@"key": @"value"}; + NSString *channel = @"channel1"; + NSArray *tags = @[@"tag1", @"tag2"]; + NSString *feature = @"feature1"; + NSString *stage = @"stage1"; + NSString *alias = @"alias1"; + + NSString *generatedURL = [self.branch getLongURLWithParams:params andChannel:channel andTags:tags andFeature:feature andStage:stage andAlias:alias]; + NSString *expectedURL = @"https://bnc.lt/a/key_live_hcnegAumkH7Kv18M8AOHhfgiohpXq5tB?tags=tag1&tags=tag2&alias=alias1&feature=feature1&stage=stage1&source=ios&data=eyJrZXkiOiJ2YWx1ZSJ9"; + + XCTAssertEqualObjects(generatedURL, expectedURL, @"URL should match the expected format"); +} + +- (void)testSetDMAParamsForEEA { + XCTAssertFalse([[BNCPreferenceHelper sharedInstance] eeaRegionInitialized]); + + [Branch setDMAParamsForEEA:FALSE AdPersonalizationConsent:TRUE AdUserDataUsageConsent:TRUE]; + XCTAssertTrue([[BNCPreferenceHelper sharedInstance] eeaRegionInitialized]); + XCTAssertFalse([BNCPreferenceHelper sharedInstance].eeaRegion); + XCTAssertTrue([BNCPreferenceHelper sharedInstance].adPersonalizationConsent); + XCTAssertTrue([BNCPreferenceHelper sharedInstance].adUserDataUsageConsent); + + // Manually clear values after testing + // By design, this API is meant to be set once and always set. However, in a test scenario it needs to be cleared. + [[BNCPreferenceHelper sharedInstance] writeObjectToDefaults:@"bnc_dma_eea" value:nil]; + [[BNCPreferenceHelper sharedInstance] writeObjectToDefaults:@"bnc_dma_ad_personalization" value:nil]; + [[BNCPreferenceHelper sharedInstance] writeObjectToDefaults:@"bnc_dma_ad_user_data" value:nil]; +} + +- (void)testSetConsumerProtectionAttributionLevel { + // Set to Reduced and check + Branch *branch = [Branch getInstance]; + [branch setConsumerProtectionAttributionLevel:BranchAttributionLevelReduced]; + XCTAssertEqual([BNCPreferenceHelper sharedInstance].attributionLevel, BranchAttributionLevelReduced); + + // Set to Minimal and check + [branch setConsumerProtectionAttributionLevel:BranchAttributionLevelMinimal]; + XCTAssertEqual([BNCPreferenceHelper sharedInstance].attributionLevel, BranchAttributionLevelMinimal); + + // Set to None and check + [branch setConsumerProtectionAttributionLevel:BranchAttributionLevelNone]; + XCTAssertEqual([BNCPreferenceHelper sharedInstance].attributionLevel, BranchAttributionLevelNone); + + // Set to Full and check + [branch setConsumerProtectionAttributionLevel:BranchAttributionLevelFull]; + XCTAssertEqual([BNCPreferenceHelper sharedInstance].attributionLevel, BranchAttributionLevelFull); + +} + + +@end diff --git a/BranchSDKTests/BranchConfigurationControllerTests.m b/BranchSDKTests/BranchConfigurationControllerTests.m new file mode 100644 index 000000000..74acc4106 --- /dev/null +++ b/BranchSDKTests/BranchConfigurationControllerTests.m @@ -0,0 +1,105 @@ +// +// BranchConfigurationControllerTests.m +// Branch-SDK-Tests +// +// Created by Nidhi Dixit on 6/12/25. +// + + +#import +#import "BranchConstants.h" +#import "BNCRequestFactory.h" +#import "BNCEncodingUtils.h" + +#if SWIFT_PACKAGE +@import BranchSwiftSDK; +#else +#import "BranchSDK/BranchSDK-Swift.h" +#endif + +@interface BranchConfigurationControllerTests : XCTestCase +@end + +@implementation BranchConfigurationControllerTests + +- (void)testSingletonInstance { + + ConfigurationController *instance1 = [ConfigurationController shared]; + XCTAssertNotNil(instance1); + + ConfigurationController *instance2 = [ConfigurationController shared]; + XCTAssertEqual(instance1, instance2); +} + +- (void)testPropertySettersAndGetters { + ConfigurationController *configController = [ConfigurationController shared]; + + 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 { + ConfigurationController *configController = [ConfigurationController shared]; + 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 { + ConfigurationController *configController = [ConfigurationController shared]; + 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/Sources/BranchSDK_ObjC/Public/BranchConstants.h b/BranchSDKTests/BranchConstants.h similarity index 100% rename from Sources/BranchSDK_ObjC/Public/BranchConstants.h rename to BranchSDKTests/BranchConstants.h diff --git a/BranchSDKTests/BranchEvent.Test.m b/BranchSDKTests/BranchEvent.Test.m new file mode 100644 index 000000000..ddb3d220f --- /dev/null +++ b/BranchSDKTests/BranchEvent.Test.m @@ -0,0 +1,575 @@ +// +// BranchEvent.Test.m +// Branch-SDK-Tests +// +// Created by Edward Smith on 8/15/17. +// Copyright © 2017 Branch Metrics. All rights reserved. +// +#import +#import "BNCPreferenceHelper.h" +#import "BranchConstants.h" +#import "BranchEvent.h" +#import "BNCDeviceInfo.h" +#import "NSError+Branch.h" + +@interface Branch (BranchEventTest) +- (void) processNextQueueItem; +@end + +@interface BranchEvent() + +- (NSString *)jsonStringForAdType:(BranchEventAdType)adType; + +// private BranchEvent methods used to check data before sending to network service. +- (NSDictionary *)buildEventDictionary; +- (BranchEventRequest *)buildRequestWithEventDictionary:(NSDictionary *)eventDictionary; + +@end + +@interface BranchEventTest : XCTestCase +@end + +@implementation BranchEventTest + +- (void)setUp { + [BNCPreferenceHelper sharedInstance].randomizedBundleToken = @"575759106028389737"; + [[BNCPreferenceHelper sharedInstance] clearInstrumentationDictionary]; +} + +- (void)tearDown { + +} + +// TODO: fix this test +- (void)testDescription { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventPurchase]; + event.transactionID = @"1234"; + event.currency = BNCCurrencyUSD; + event.revenue = [NSDecimalNumber decimalNumberWithString:@"10.50"]; + event.eventDescription= @"Event description."; + event.customData = (NSMutableDictionary*) @{ + @"Key1": @"Value1" + }; + + NSString *d = event.description; +// BNCTAssertEqualMaskedString(d, +// @""); +} + +- (void)testExampleSyntax { + BranchUniversalObject *contentItem = [BranchUniversalObject new]; + contentItem.canonicalIdentifier = @"item/123"; + contentItem.canonicalUrl = @"https://branch.io/item/123"; + contentItem.contentMetadata.ratingAverage = 5.0; + + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventCompleteRegistration]; + event.eventDescription = @"Product Search"; + event.searchQuery = @"product name"; + event.customData = @{ @"rating": @"5" }; + + [event logEvent]; +} + +- (void)testStandardInviteEvent { + + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventInvite]; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"INVITE"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testCustomInviteEvent { + + BranchEvent *event = [BranchEvent customEventWithName:@"INVITE"]; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"INVITE"]); + XCTAssertNotNil(eventDictionary[@"content_items"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testStandardLoginEvent { + + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventLogin]; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"LOGIN"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testCustomLoginEvent { + + BranchEvent *event = [BranchEvent customEventWithName:@"LOGIN"]; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"LOGIN"]); + XCTAssertNotNil(eventDictionary[@"content_items"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testStandardReserveEvent { + + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventReserve]; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"RESERVE"]); + XCTAssertNotNil(eventDictionary[@"content_items"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testCustomReserveEvent { + + BranchEvent *event = [BranchEvent customEventWithName:@"RESERVE"]; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"RESERVE"]); + XCTAssertNotNil(eventDictionary[@"content_items"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testStandardSubscribeEvent { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventSubscribe]; + event.currency = BNCCurrencyUSD; + event.revenue = [NSDecimalNumber decimalNumberWithString:@"1.0"]; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"SUBSCRIBE"]); + + NSDictionary *eventData = eventDictionary[@"event_data"]; + XCTAssert([eventData[@"currency"] isEqualToString:BNCCurrencyUSD]); + XCTAssert([eventData[@"revenue"] isEqual:[NSDecimalNumber decimalNumberWithString:@"1.0"]]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testCustomSubscribeEvent { + + BranchEvent *event = [BranchEvent customEventWithName:@"SUBSCRIBE"]; + event.currency = BNCCurrencyUSD; + event.revenue = [NSDecimalNumber decimalNumberWithString:@"1.0"]; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"SUBSCRIBE"]); + XCTAssertNotNil(eventDictionary[@"content_items"]); + + NSDictionary *eventData = eventDictionary[@"event_data"]; + XCTAssert([eventData[@"currency"] isEqualToString:BNCCurrencyUSD]); + XCTAssert([eventData[@"revenue"] isEqual:[NSDecimalNumber decimalNumberWithString:@"1.0"]]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testStandardStartTrialEvent { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventStartTrial]; + event.currency = BNCCurrencyUSD; + event.revenue = [NSDecimalNumber decimalNumberWithString:@"1.0"]; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"START_TRIAL"]); + + NSDictionary *eventData = eventDictionary[@"event_data"]; + XCTAssert([eventData[@"currency"] isEqualToString:BNCCurrencyUSD]); + XCTAssert([eventData[@"revenue"] isEqual:[NSDecimalNumber decimalNumberWithString:@"1.0"]]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testCustomStartTrialEvent { + + BranchEvent *event = [BranchEvent customEventWithName:@"START_TRIAL"]; + event.currency = BNCCurrencyUSD; + event.revenue = [NSDecimalNumber decimalNumberWithString:@"1.0"]; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"START_TRIAL"]); + XCTAssertNotNil(eventDictionary[@"content_items"]); + + NSDictionary *eventData = eventDictionary[@"event_data"]; + XCTAssert([eventData[@"currency"] isEqualToString:BNCCurrencyUSD]); + XCTAssert([eventData[@"revenue"] isEqual:[NSDecimalNumber decimalNumberWithString:@"1.0"]]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testStandardClickAdEvent { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventClickAd]; + event.adType = BranchEventAdTypeBanner; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"CLICK_AD"]); + + NSDictionary *eventData = eventDictionary[@"event_data"]; + XCTAssert([eventData[@"ad_type"] isEqual:[event jsonStringForAdType:event.adType]]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testCustomClickAdEvent { + + BranchEvent *event = [BranchEvent customEventWithName:@"CLICK_AD"]; + event.adType = BranchEventAdTypeBanner; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"CLICK_AD"]); + XCTAssertNotNil(eventDictionary[@"content_items"]); + + NSDictionary *eventData = eventDictionary[@"event_data"]; + XCTAssert([eventData[@"ad_type"] isEqual:[event jsonStringForAdType:event.adType]]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testStandardViewAdEvent { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewAd]; + event.adType = BranchEventAdTypeBanner; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"VIEW_AD"]); + + NSDictionary *eventData = eventDictionary[@"event_data"]; + XCTAssert([eventData[@"ad_type"] isEqual:[event jsonStringForAdType:event.adType]]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testCustomViewAdEvent { + + BranchEvent *event = [BranchEvent customEventWithName:@"VIEW_AD"]; + event.adType = BranchEventAdTypeBanner; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + buo.canonicalIdentifier = @"item/12345"; + buo.canonicalUrl = @"https://branch.io/deepviews"; + buo.title = @"My Content Title"; + buo.contentDescription = @"my_product_description1"; + + NSMutableArray *contentItems = [NSMutableArray new]; + [contentItems addObject:buo]; + event.contentItems = contentItems; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"VIEW_AD"]); + XCTAssertNotNil(eventDictionary[@"content_items"]); + + NSDictionary *eventData = eventDictionary[@"event_data"]; + XCTAssert([eventData[@"ad_type"] isEqual:[event jsonStringForAdType:event.adType]]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testStandardOptInEvent { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventOptIn]; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"OPT_IN"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testCustomOptInEvent { + BranchEvent *event = [BranchEvent customEventWithName:@"OPT_IN"]; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"OPT_IN"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testStandardOptOutEvent { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventOptOut]; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"OPT_OUT"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testCustomOptOutEvent { + BranchEvent *event = [BranchEvent customEventWithName:@"OPT_OUT"]; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"OPT_OUT"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + + +- (void)testStandardInitiateStreamEvent { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventInitiateStream]; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"INITIATE_STREAM"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testCustomInitiateStreamEvent { + BranchEvent *event = [BranchEvent customEventWithName:@"INITIATE_STREAM"]; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"INITIATE_STREAM"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testStandardCompleteStreamEvent { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventCompleteStream]; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"COMPLETE_STREAM"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testCustomCompleteStreamEvent { + BranchEvent *event = [BranchEvent customEventWithName:@"COMPLETE_STREAM"]; + + NSDictionary *eventDictionary = [event buildEventDictionary]; + XCTAssertNotNil(eventDictionary); + XCTAssert([eventDictionary[@"name"] isEqualToString:@"COMPLETE_STREAM"]); + + BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; + XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); +} + +- (void)testJsonStringForAdTypeNone { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewAd]; + XCTAssertNil([event jsonStringForAdType:BranchEventAdTypeNone]); +} + +- (void)testJsonStringForAdTypeBanner { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewAd]; + XCTAssertTrue([[event jsonStringForAdType:BranchEventAdTypeBanner] isEqualToString:@"BANNER"]); +} + +- (void)testJsonStringForAdTypeInterstitial { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewAd]; + XCTAssertTrue([[event jsonStringForAdType:BranchEventAdTypeInterstitial] isEqualToString:@"INTERSTITIAL"]); +} + +- (void)testJsonStringForAdTypeRewardedVideo { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewAd]; + XCTAssertTrue([[event jsonStringForAdType:BranchEventAdTypeRewardedVideo] isEqualToString:@"REWARDED_VIDEO"]); +} + +- (void)testJsonStringForAdTypeNative { + BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewAd]; + XCTAssertTrue([[event jsonStringForAdType:BranchEventAdTypeNative] isEqualToString:@"NATIVE"]); +} + +- (void) testCustomEventWithContentItem { + BranchUniversalObject *buo = [[BranchUniversalObject new] initWithTitle:@"buoTitle"]; + BranchEvent *event = [BranchEvent customEventWithName:@"testEvent" contentItem:buo]; + + XCTAssertTrue(event.contentItems.count == 1); + XCTAssertTrue([event.contentItems.firstObject.title isEqualToString:@"buoTitle"]); +} + +- (void)testLogEventWithCompletion_InvalidEventName { + XCTestExpectation *expectation = [self expectationWithDescription:@"Logging Event"]; + BranchEvent *event = [BranchEvent customEventWithName:@""]; + + [event logEventWithCompletion:^(BOOL success, NSError * _Nullable error) { + XCTAssertFalse(success, @"Success should be NO for invalid event name"); + XCTAssertNotNil(error, @"Error should not be nil for invalid event name"); + XCTAssertEqual(error.code, BNCGeneralError, @"Error code should match expected value for invalid event name"); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:5 handler:nil]; +} + + +@end diff --git a/BranchSDKTests/BranchEvent.Test.swift b/BranchSDKTests/BranchEvent.Test.swift new file mode 100644 index 000000000..49d819cc9 --- /dev/null +++ b/BranchSDKTests/BranchEvent.Test.swift @@ -0,0 +1,129 @@ +// +// BranchEvent.Test.swift +// Branch-SDK-Tests +// +// Created by edward on 10/9/17. +// Copyright © 2017 Branch, Inc. All rights reserved. +// + +import XCTest +/* +// TODO: fix this test class, requires modules which our testbed is not using +final class BranchEventTestSwift : XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + Branch.getInstance("key_live_foo") + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testBranchEvent() throws { + + // Set up the Branch Universal Object -- + + let branchUniversalObject = BranchUniversalObject.init() + branchUniversalObject.canonicalIdentifier = "item/12345" + branchUniversalObject.canonicalUrl = "https://branch.io/deepviews" + branchUniversalObject.title = "My Content Title" + branchUniversalObject.contentDescription = "my_product_description1" + branchUniversalObject.imageUrl = "https://test_img_url" + branchUniversalObject.keywords = [ "My_Keyword1", "My_Keyword2" ] + branchUniversalObject.creationDate = Date.init(timeIntervalSince1970:1501869445321.0/1000.0) + branchUniversalObject.expirationDate = Date.init(timeIntervalSince1970:212123232544.0/1000.0) + branchUniversalObject.locallyIndex = true + branchUniversalObject.publiclyIndex = false + + branchUniversalObject.contentMetadata.contentSchema = .commerceProduct + branchUniversalObject.contentMetadata.quantity = 2 + branchUniversalObject.contentMetadata.price = 23.20 + branchUniversalObject.contentMetadata.currency = .USD + branchUniversalObject.contentMetadata.sku = "1994320302" + branchUniversalObject.contentMetadata.productName = "my_product_name1" + branchUniversalObject.contentMetadata.productBrand = "my_prod_Brand1" + branchUniversalObject.contentMetadata.productCategory = .babyToddler + branchUniversalObject.contentMetadata.productVariant = "3T" + branchUniversalObject.contentMetadata.condition = .fair + + branchUniversalObject.contentMetadata.ratingAverage = 5; + branchUniversalObject.contentMetadata.ratingCount = 5; + branchUniversalObject.contentMetadata.ratingMax = 7; + branchUniversalObject.contentMetadata.rating = 6; + branchUniversalObject.contentMetadata.addressStreet = "Street_name1" + branchUniversalObject.contentMetadata.addressCity = "city1" + branchUniversalObject.contentMetadata.addressRegion = "Region1" + branchUniversalObject.contentMetadata.addressCountry = "Country1" + branchUniversalObject.contentMetadata.addressPostalCode = "postal_code" + branchUniversalObject.contentMetadata.latitude = 12.07 + branchUniversalObject.contentMetadata.longitude = -97.5 + branchUniversalObject.contentMetadata.imageCaptions = [ + "my_img_caption1", + "my_img_caption_2" + ] + branchUniversalObject.contentMetadata.customMetadata = [ + "Custom_Content_metadata_key1": "Custom_Content_metadata_val1", + "Custom_Content_metadata_key2": "Custom_Content_metadata_val2" + ] + + // Set up the event properties -- + + let event = BranchEvent.standardEvent(.purchase) + event.transactionID = "12344555" + event.currency = .USD; + event.revenue = 1.5 + event.shipping = 10.2 + event.tax = 12.3 + event.coupon = "test_coupon"; + event.affiliation = "test_affiliation"; + event.eventDescription = "Event _description"; + event.searchQuery = "Query" + event.customData = [ + "Custom_Event_Property_Key1": "Custom_Event_Property_val1", + "Custom_Event_Property_Key2": "Custom_Event_Property_val2" + ] + + var testDictionary = event.dictionary() + var dictionary = self.mutableDictionaryFromBundleJSON(withKey: "V2EventProperties") + XCTAssert((dictionary?.isEqual(to: testDictionary))!) + + testDictionary = branchUniversalObject.dictionary() as! [AnyHashable : Any] + dictionary = self.mutableDictionaryFromBundleJSON(withKey: "BranchUniversalObjectJSON") + dictionary!["$publicly_indexable"] = nil // Remove this value since we don't add false values. + XCTAssert((dictionary?.isEqual(to: testDictionary))!) + + event.contentItems = [ branchUniversalObject ] + event.logEvent() + } + + func testExampleSyntaxSwift() throws { + let contentItem = BranchUniversalObject.init() + contentItem.canonicalIdentifier = "item/123" + contentItem.canonicalUrl = "https://branch.io/item/123" + contentItem.contentMetadata.ratingAverage = 5.0; + + var event = BranchEvent.standardEvent(.spendCredits) + event.transactionID = "tx1234" + event.eventDescription = "Product Search" + event.searchQuery = "user search query terms for product xyz" + event.customData["Custom_Event_Property_Key1"] = "Custom_Event_Property_val1" + event.contentItems = [ contentItem ] + event.logEvent() + + event = BranchEvent.standardEvent(.viewItem) + event.logEvent(); + + // Quickly log an event: + BranchEvent.standardEvent(.viewItem).logEvent() + + // Quickly log an event with content: + let branchUniversalObject = BranchUniversalObject.init() + branchUniversalObject.canonicalIdentifier = "item/12345" + branchUniversalObject.canonicalUrl = "https://branch.io/deepviews" + branchUniversalObject.title = "My Content Title" + BranchEvent.standardEvent(.viewItem, withContentItem: branchUniversalObject).logEvent() + } +} +*/ diff --git a/BranchSDKTests/BranchLastAttributedTouchDataTests.m b/BranchSDKTests/BranchLastAttributedTouchDataTests.m new file mode 100644 index 000000000..908711125 --- /dev/null +++ b/BranchSDKTests/BranchLastAttributedTouchDataTests.m @@ -0,0 +1,63 @@ +// +// BranchLastAttributedTouchDataTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 9/18/19. +// Copyright © 2019 Branch, Inc. All rights reserved. +// + +#import +#import "BNCJsonLoader.h" +#import "BranchLastAttributedTouchData.h" + +@interface BranchLastAttributedTouchDataTests : XCTestCase + +@end + +@implementation BranchLastAttributedTouchDataTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)testBuildFromJSON { + NSDictionary *json = [BNCJsonLoader dictionaryFromJSONFileNamed:@"latd"]; + XCTAssertNotNil(json); + + BranchLastAttributedTouchData *latd = [BranchLastAttributedTouchData buildFromJSON:json]; + XCTAssertNotNil(latd); + XCTAssertNotNil(latd.lastAttributedTouchJSON); + XCTAssertNotNil(latd.attributionWindow); +} + +- (void)testBuildFromJSON_EmptyData { + NSDictionary *json = [BNCJsonLoader dictionaryFromJSONFileNamed:@"latd_empty_data"]; + XCTAssertNotNil(json); + + BranchLastAttributedTouchData *latd = [BranchLastAttributedTouchData buildFromJSON:json]; + XCTAssertNotNil(latd); + XCTAssertTrue(latd.lastAttributedTouchJSON.count == 0); +} + +- (void)testBuildFromJSON_MissingData { + NSDictionary *json = [BNCJsonLoader dictionaryFromJSONFileNamed:@"latd_missing_data"]; + XCTAssertNotNil(json); + + BranchLastAttributedTouchData *latd = [BranchLastAttributedTouchData buildFromJSON:json]; + XCTAssertNil(latd); +} + +- (void)testBuildFromJSON_MissingWindow { + NSDictionary *json = [BNCJsonLoader dictionaryFromJSONFileNamed:@"latd_missing_window"]; + XCTAssertNotNil(json); + + BranchLastAttributedTouchData *latd = [BranchLastAttributedTouchData buildFromJSON:json]; + XCTAssertNotNil(latd); + XCTAssertNil(latd.attributionWindow); +} + +@end diff --git a/BranchSDKTests/BranchLoggerTests.m b/BranchSDKTests/BranchLoggerTests.m new file mode 100644 index 000000000..1a4be3490 --- /dev/null +++ b/BranchSDKTests/BranchLoggerTests.m @@ -0,0 +1,261 @@ +// +// BranchLoggerTests.m +// Branch-SDK-Tests +// +// Created by Nipun Singh on 2/5/24. +// Copyright © 2024 Branch, Inc. All rights reserved. +// + +#import +#import "BranchLogger.h" +#import "Branch.h" + +@interface BranchLoggerTests : XCTestCase + +@end + +@implementation BranchLoggerTests + +// public API test +- (void)testEnableLoggingSetsCorrectDefaultLevel { + [[Branch getInstance] enableLogging]; + XCTAssertEqual([BranchLogger shared].logLevelThreshold, BranchLogLevelDebug, "Default log level should be Debug."); +} + +- (void)testLoggingEnabled_NOByDefault { + BranchLogger *logger = [BranchLogger new]; + + __block int count = 0; + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + count = count + 1; + }; + [logger logError:@"msg" error:nil]; + + XCTAssertTrue(count == 0); +} + +- (void)testLoggingEnabled_Yes { + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; + + __block int count = 0; + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + count = count + 1; + }; + + [logger logError:@"msg" error:nil]; + XCTAssertTrue(count == 1); + + [logger logError:@"msg" error:nil]; + XCTAssertTrue(count == 2); +} + +- (void)testLoggingIgnoresNil { + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; + + __block int count = 0; + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + count = count + 1; + }; + + [logger logError:nil error:nil]; + XCTAssertTrue(count == 0); +} + +- (void)testLoggingIgnoresEmptyString { + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; + + __block int count = 0; + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + count = count + 1; + }; + + [logger logError:@"" error:nil]; + XCTAssertTrue(count == 0); +} + +- (void)testLoggingEnabled_YesThenNo { + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; + + __block int count = 0; + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + count = count + 1; + }; + + // one call + [logger logError:@"msg" error:nil]; + XCTAssertTrue(count == 1); + + // disable, second call is ignored + logger.loggingEnabled = NO; + [logger logError:@"msg" error:nil]; + XCTAssertTrue(count == 1); +} + +- (void)testLogLevel_DebugByDefault { + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; + + __block int count = 0; + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + count = count + 1; + }; + + [logger logError:@"msg" error:nil]; + XCTAssertTrue(count == 1); + [logger logWarning:@"msg" error:nil]; + XCTAssertTrue(count == 2); + [logger logDebug:@"msg" error:nil]; + XCTAssertTrue(count == 3); + + // this should be ignored and the counter not incremented + [logger logVerbose:@"msg" error:nil]; + XCTAssertTrue(count == 3); +} + +- (void)testLogLevel_Error { + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; + logger.logLevelThreshold = BranchLogLevelError; + + + __block int count = 0; + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + count = count + 1; + }; + + [logger logError:@"msg" error:nil]; + XCTAssertTrue(count == 1); + + // these should be ignored and the counter not incremented + [logger logWarning:@"msg" error:nil]; + XCTAssertTrue(count == 1); + [logger logDebug:@"msg" error:nil]; + XCTAssertTrue(count == 1); + [logger logVerbose:@"msg" error:nil]; + XCTAssertTrue(count == 1); +} + +- (void)testLogLevel_Warning { + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; + logger.logLevelThreshold = BranchLogLevelWarning; + + + __block int count = 0; + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + count = count + 1; + }; + + [logger logError:@"msg" error:nil]; + XCTAssertTrue(count == 1); + [logger logWarning:@"msg" error:nil]; + XCTAssertTrue(count == 2); + + // this should be ignored and the counter not incremented + [logger logDebug:@"msg" error:nil]; + XCTAssertTrue(count == 2); + [logger logVerbose:@"msg" error:nil]; + XCTAssertTrue(count == 2); +} + +- (void)testLogLevel_Verbose { + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; + logger.logLevelThreshold = BranchLogLevelVerbose; + + + __block int count = 0; + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + count = count + 1; + }; + + [logger logError:@"msg" error:nil]; + XCTAssertTrue(count == 1); + [logger logWarning:@"msg" error:nil]; + XCTAssertTrue(count == 2); + [logger logDebug:@"msg" error:nil]; + XCTAssertTrue(count == 3); + [logger logVerbose:@"msg" error:nil]; + XCTAssertTrue(count == 4); +} + +- (void)testLogFormat_Default { + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; + + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + NSString *expectedMessage = @"[BranchLoggerTests testLogFormat_Default] msg"; + + XCTAssertTrue([expectedMessage isEqualToString:message]); + XCTAssertTrue(logLevel == BranchLogLevelError); + XCTAssertNil(error); + }; + + [logger logError:@"msg" error:nil]; +} + +- (void)testLogFormat_NSError { + __block NSError *originalError = [NSError errorWithDomain:@"com.domain.test" code:200 userInfo:@{@"Error Message": @"Test Error"}]; + + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; + + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + NSString *expectedMessage = @"[BranchLoggerTests testLogFormat_NSError] msg"; + + XCTAssertTrue([expectedMessage isEqualToString:message]); + XCTAssertTrue(logLevel == BranchLogLevelError); + XCTAssertTrue(originalError == error); + }; + + [logger logError:@"msg" error:originalError]; +} + +- (void)testLogFormat_includeCallerDetailsNO { + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; + logger.includeCallerDetails = NO; + + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + NSString *expectedMessage = @"msg"; + + XCTAssertTrue([expectedMessage isEqualToString:message]); + XCTAssertTrue(logLevel == BranchLogLevelError); + XCTAssertNil(error); + }; + + [logger logError:@"msg" error:nil]; +} + +- (void)testLogFormat_includeCallerDetailsNO_NSError { + __block NSError *originalError = [NSError errorWithDomain:@"com.domain.test" code:200 userInfo:@{@"Error Message": @"Test Error"}]; + + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; + logger.includeCallerDetails = NO; + + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + NSString *expectedMessage = @"msg"; + + XCTAssertTrue([expectedMessage isEqualToString:message]); + XCTAssertTrue(logLevel == BranchLogLevelError); + XCTAssertTrue(originalError == error); + }; + + [logger logError:@"msg" error:originalError]; +} + +- (void)testDefaultBranchLogFormat { + NSError *error = [NSError errorWithDomain:@"com.domain.test" code:200 userInfo:@{@"Error Message": @"Test Error"}]; + + NSString *expectedMessage = @"[BranchSDK][Error]msg NSError: Error Domain=com.domain.test Code=200 \"(null)\" UserInfo={Error Message=Test Error}"; + NSString *formattedMessage = [BranchLogger formatMessage:@"msg" logLevel:BranchLogLevelError error:error]; + + XCTAssertTrue([expectedMessage isEqualToString:formattedMessage]); +} + +@end diff --git a/BranchSDKTests/BranchPluginSupportTests.m b/BranchSDKTests/BranchPluginSupportTests.m new file mode 100644 index 000000000..d46b620fc --- /dev/null +++ b/BranchSDKTests/BranchPluginSupportTests.m @@ -0,0 +1,91 @@ +// +// BranchPluginSupportTests.m +// Branch-SDK-Tests +// +// Created by Nipun Singh on 1/25/22. +// Copyright © 2022 Branch, Inc. All rights reserved. +// + +#import +#import "BranchPluginSupport.h" + +@interface BranchPluginSupportTests : XCTestCase +@property (nonatomic, strong, readwrite) NSDictionary *deviceDescription; +@end + +@implementation BranchPluginSupportTests + +- (void)setUp { + self.deviceDescription = [[BranchPluginSupport new] deviceDescription]; +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)testAppVersion { + // checks test app version + XCTAssert([@"1.0" isEqualToString:_deviceDescription[@"app_version"]]); +} + +- (void)testBrandName { + XCTAssert([@"Apple" isEqualToString:_deviceDescription[@"brand"]]); +} + +- (void)testModelName_Simulator { + // intel processor + bool x86_64 = [@"x86_64" isEqualToString:_deviceDescription[@"model"]]; + + // apple processor + bool arm64 = [@"arm64" isEqualToString:_deviceDescription[@"model"]]; + + XCTAssert(x86_64 || arm64); +} + +- (void)testOSName { + XCTAssertNotNil(_deviceDescription[@"os"]); + XCTAssert([_deviceDescription[@"os"] isEqualToString:[UIDevice currentDevice].systemName]); +} + +- (void)testOSVersion { + XCTAssertNotNil(_deviceDescription[@"os_version"]); + XCTAssert([_deviceDescription[@"os_version"] isEqualToString:[UIDevice currentDevice].systemVersion]); +} + +- (void)testEnvironment { + XCTAssert([@"FULL_APP" isEqualToString:_deviceDescription[@"environment"]]); +} + +- (void)testScreenWidth { + XCTAssert(_deviceDescription[@"screen_width"].intValue > 320); +} + +- (void)testScreenHeight { + XCTAssert(_deviceDescription[@"screen_height"].intValue > 320); +} + +- (void)testScreenScale { + XCTAssert(_deviceDescription[@"screen_dpi"].intValue > 0); +} + +- (void)testCountry { + NSString *locale = [NSLocale currentLocale].localeIdentifier; + XCTAssertNotNil(locale); + XCTAssert([locale containsString:_deviceDescription[@"country"]]); +} + +- (void)testLanguage { + NSString *locale = [NSLocale currentLocale].localeIdentifier; + XCTAssertNotNil(locale); + XCTAssert([locale containsString:_deviceDescription[@"language"]]); +} + +- (void)testLocalIPAddress { + NSString *address = _deviceDescription[@"local_ip"]; + XCTAssertNotNil(address); + + // shortest ipv4 is 7 + XCTAssert(address.length >= 7); +} + +@end diff --git a/BranchSDKTests/BranchQRCodeTests.m b/BranchSDKTests/BranchQRCodeTests.m new file mode 100644 index 000000000..3d1e1ffc6 --- /dev/null +++ b/BranchSDKTests/BranchQRCodeTests.m @@ -0,0 +1,154 @@ +// +// BranchQRCodeTests.m +// Branch-SDK-Tests +// +// Created by Nipun Singh on 4/14/22. +// Copyright © 2022 Branch, Inc. All rights reserved. +// + +#import +#import "Branch.h" +#import "BranchQRCode.h" +#import "BNCQRCodeCache.h" + +@interface BranchQRCodeTests : XCTestCase + +@end + +@implementation BranchQRCodeTests + +- (void)testNormalQRCodeDataWithAllSettings { + XCTestExpectation *expectation = [self expectationWithDescription:@"Fetching QR Code"]; + + BranchQRCode *qrCode = [BranchQRCode new]; + qrCode.width = @(1000); + qrCode.margin = @(1); + qrCode.codeColor = [UIColor blueColor]; + qrCode.backgroundColor = [UIColor whiteColor]; + qrCode.centerLogo = @"https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg"; + qrCode.imageFormat = BranchQRCodeImageFormatPNG; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + BranchLinkProperties *lp = [BranchLinkProperties new]; + + [qrCode getQRCodeAsData:buo linkProperties:lp completion:^(NSData * _Nonnull qrCode, NSError * _Nonnull error) { + XCTAssertNil(error); + XCTAssertNotNil(qrCode); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:10 handler:^(NSError *error) { + if (error) { + NSLog(@"Error Testing QR Code Cache: %@", error); + XCTFail(); + } + }]; +} + +- (void)testNormalQRCodeAsDataWithNoSettings { + XCTestExpectation *expectation = [self expectationWithDescription:@"Fetching QR Code"]; + + BranchQRCode *qrCode = [BranchQRCode new]; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + BranchLinkProperties *lp = [BranchLinkProperties new]; + + [qrCode getQRCodeAsData:buo linkProperties:lp completion:^(NSData * _Nonnull qrCode, NSError * _Nonnull error) { + XCTAssertNil(error); + XCTAssertNotNil(qrCode); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:10 handler:^(NSError *error) { + if (error) { + NSLog(@"Error Testing QR Code Cache: %@", error); + XCTFail(); + } + }]; +} + +- (void)testNormalQRCodeWithInvalidLogoURL { + XCTestExpectation *expectation = [self expectationWithDescription:@"Fetching QR Code"]; + + BranchQRCode *qrCode = [BranchQRCode new]; + qrCode.centerLogo = @"https://branch.branch/notARealImageURL.jpg"; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + BranchLinkProperties *lp = [BranchLinkProperties new]; + + [qrCode getQRCodeAsData:buo linkProperties:lp completion:^(NSData * _Nonnull qrCode, NSError * _Nonnull error) { + XCTAssertNil(error); + XCTAssertNotNil(qrCode); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:10 handler:^(NSError *error) { + if (error) { + NSLog(@"Error Testing QR Code Cache: %@", error); + XCTFail(); + } + }]; +} + +- (void)testNormalQRCodeAsImage { + XCTestExpectation *expectation = [self expectationWithDescription:@"Fetching QR Code"]; + + BranchQRCode *qrCode = [BranchQRCode new]; + + BranchUniversalObject *buo = [BranchUniversalObject new]; + BranchLinkProperties *lp = [BranchLinkProperties new]; + + [qrCode getQRCodeAsImage:buo linkProperties:lp completion:^(UIImage * _Nonnull qrCode, NSError * _Nonnull error) { + XCTAssertNil(error); + XCTAssertNotNil(qrCode); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:10 handler:^(NSError *error) { + if (error) { + NSLog(@"Error Testing QR Code Cache: %@", error); + XCTFail(); + } + }]; +} + +- (void)testQRCodeCache { + XCTestExpectation *expectation = [self expectationWithDescription:@"Fetching QR Code"]; + + BranchQRCode *myQRCode = [BranchQRCode new]; + BranchUniversalObject *buo = [BranchUniversalObject new]; + BranchLinkProperties *lp = [BranchLinkProperties new]; + + [myQRCode getQRCodeAsData:buo linkProperties:lp completion:^(NSData * _Nonnull qrCode, NSError * _Nonnull error) { + + XCTAssertNil(error); + XCTAssertNotNil(qrCode); + + NSMutableDictionary *parameters = [NSMutableDictionary new]; + NSMutableDictionary *settings = [NSMutableDictionary new]; + + settings[@"image_format"] = @"PNG"; + settings[@"width"] = @(300); + settings[@"margin"] = @(1); + + parameters[@"qr_code_settings"] = settings; + parameters[@"data"] = [NSMutableDictionary new]; + parameters[@"branch_key"] = [Branch branchKey]; + + + NSData *cachedQRCode = [[BNCQRCodeCache sharedInstance] checkQRCodeCache:parameters]; + + XCTAssertEqual(cachedQRCode, qrCode); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:10 handler:^(NSError *error) { + if (error) { + NSLog(@"Error Testing QR Code Cache: %@", error); + XCTFail(); + } + }]; +} + + +@end diff --git a/BranchSDKTests/BranchSDKTests.m b/BranchSDKTests/BranchSDKTests.m new file mode 100644 index 000000000..7a37169d8 --- /dev/null +++ b/BranchSDKTests/BranchSDKTests.m @@ -0,0 +1,36 @@ +// +// BranchSDKTests.m +// BranchSDKTests +// +// Created by Nidhi Dixit on 7/6/25. +// + +#import + +@interface BranchSDKTests : XCTestCase + +@end + +@implementation BranchSDKTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)testExample { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/BranchSDKTests/BranchSDKTests.xctestplan b/BranchSDKTests/BranchSDKTests.xctestplan new file mode 100644 index 000000000..445c0d7d4 --- /dev/null +++ b/BranchSDKTests/BranchSDKTests.xctestplan @@ -0,0 +1,37 @@ +{ + "configurations" : [ + { + "id" : "9EAB663B-7807-43EE-AD4E-658E8734932A", + "name" : "Test Scheme Action", + "options" : { + + } + } + ], + "defaultOptions" : { + "targetForVariableExpansion" : { + "containerPath" : "container:BranchSDK.xcodeproj", + "identifier" : "5F22116E2894A9C000C5B190", + "name" : "TestHost" + } + }, + "testTargets" : [ + { + "parallelizable" : false, + "target" : { + "containerPath" : "container:BranchSDK.xcodeproj", + "identifier" : "E7CA74EA2E1B4F75002EFB40", + "name" : "BranchSDKTests" + } + }, + { + "enabled" : false, + "target" : { + "containerPath" : "container:BranchSDK.xcodeproj", + "identifier" : "5F2211832894A9C100C5B190", + "name" : "TestHostTests" + } + } + ], + "version" : 1 +} diff --git a/BranchSDKTests/BranchShareLinkTests.m b/BranchSDKTests/BranchShareLinkTests.m new file mode 100644 index 000000000..c41fdb618 --- /dev/null +++ b/BranchSDKTests/BranchShareLinkTests.m @@ -0,0 +1,38 @@ +// +// BranchShareLinkTests.m +// Branch-SDK-Tests +// +// Created by Nipun Singh on 5/5/22. +// Copyright © 2022 Branch, Inc. All rights reserved. +// + +#import +#import "BranchShareLink.h" +#import "BranchLinkProperties.h" +#import "Branch.h" + +@interface BranchShareLinkTests : XCTestCase + +@end + +@implementation BranchShareLinkTests + +- (void)testAddLPLinkMetadata { + BranchUniversalObject *buo = [[BranchUniversalObject alloc] initWithCanonicalIdentifier:@"test/001"]; + BranchLinkProperties *lp = [[BranchLinkProperties alloc] init]; + + BranchShareLink *bsl = [[BranchShareLink alloc] initWithUniversalObject:buo linkProperties:lp]; + + if (@available(iOS 13.0, macCatalyst 13.1, *)) { + NSURL *imageURL = [NSURL URLWithString:@"https://cdn.branch.io/branch-assets/1598575682753-og_image.png"]; + NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; + UIImage *iconImage = [UIImage imageWithData:imageData]; + + [bsl addLPLinkMetadata:@"Test Preview Title" icon:iconImage]; + XCTAssertNotNil([bsl lpMetaData]); + } else { + XCTAssertTrue(true); + } +} + +@end diff --git a/BranchSDKTests/BranchUniversalObjectTests.m b/BranchSDKTests/BranchUniversalObjectTests.m new file mode 100644 index 000000000..9a7112e31 --- /dev/null +++ b/BranchSDKTests/BranchUniversalObjectTests.m @@ -0,0 +1,446 @@ +// +// BranchUniversalObjectTests.m +// Branch-TestBed +// +// Created by Edward Smith on 8/15/17. +// Copyright © 2017 Branch Metrics. All rights reserved. +// + +#import +#import "BranchUniversalObject.h" + +@interface BranchUniversalObjectTests : XCTestCase +@end + +@implementation BranchUniversalObjectTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +#pragma mark BranchContentMetadata tests + +- (BranchContentMetadata *)branchContentMetadataWithAllPropertiesSet { + BranchContentMetadata *metadata = [BranchContentMetadata new]; + metadata.contentSchema = BranchContentSchemaOther; + metadata.quantity = 10; + metadata.price = [[NSDecimalNumber alloc] initWithDouble:5.5]; + metadata.currency = BNCCurrencyUSD; + metadata.sku = @"testSKU"; + metadata.productName = @"testProductName"; + metadata.productBrand = @"testProductBrand"; + metadata.productCategory = BNCProductCategoryApparel; + metadata.productVariant = @"testProductVariant"; + metadata.condition = BranchConditionNew; + metadata.ratingAverage = 3.5; + metadata.ratingCount = 2; + metadata.ratingMax = 4; + metadata.rating = 3; + metadata.addressStreet = @"195 Page Mill Road"; + metadata.addressCity = @"Palo Alto"; + metadata.addressRegion = @"CA"; + metadata.addressCountry = @"USA"; + metadata.addressPostalCode = @"94306"; + metadata.latitude = 37.426; + metadata.longitude = -122.138; + + metadata.imageCaptions = @[ + @"Hello World", + @"Goodbye World" + ].mutableCopy; + + metadata.customMetadata = @{ + @"custom0": @"custom data 0" + }.mutableCopy; + + return metadata; +} + +- (void)verifyBranchContentMetadataWithAllProperties:(BranchContentMetadata *)metadata { + XCTAssertNotNil(metadata); + + XCTAssertEqual(BranchContentSchemaOther, metadata.contentSchema); + XCTAssertTrue([@(10) isEqualToNumber:@(metadata.quantity)]); + XCTAssertTrue([[[NSDecimalNumber alloc] initWithDouble:5.5] isEqualToNumber:metadata.price]); + + XCTAssertEqual(BNCCurrencyUSD, metadata.currency); + XCTAssertTrue([@"testSKU" isEqualToString:metadata.sku]); + XCTAssertTrue([@"testProductName" isEqualToString:metadata.productName]); + XCTAssertTrue([@"testProductBrand" isEqualToString:metadata.productBrand]); + XCTAssertEqual(BNCProductCategoryApparel, metadata.productCategory); + XCTAssertTrue([@"testProductVariant" isEqualToString:metadata.productVariant]); + XCTAssertEqual(BranchConditionNew, metadata.condition); + XCTAssertTrue([@(3.5) isEqualToNumber:@(metadata.ratingAverage)]); + XCTAssertTrue([@(2) isEqualToNumber:@(metadata.ratingCount)]); + XCTAssertTrue([@(4) isEqualToNumber:@(metadata.ratingMax)]); + XCTAssertTrue([@(3) isEqualToNumber:@(metadata.rating)]); + + XCTAssertTrue([@"195 Page Mill Road" isEqualToString:metadata.addressStreet]); + XCTAssertTrue([@"Palo Alto" isEqualToString:metadata.addressCity]); + XCTAssertTrue([@"CA" isEqualToString:metadata.addressRegion]); + XCTAssertTrue([@"USA" isEqualToString:metadata.addressCountry]); + XCTAssertTrue([@"94306" isEqualToString:metadata.addressPostalCode]); + + XCTAssertTrue([@(37.426) isEqualToNumber:@(metadata.latitude)]); + XCTAssertTrue([@(-122.138) isEqualToNumber:@(metadata.longitude)]); + + XCTAssertNotNil(metadata.imageCaptions); + XCTAssertTrue(metadata.imageCaptions.count == 2); + XCTAssertTrue([metadata.imageCaptions[0] isEqualToString:@"Hello World"]); + XCTAssertTrue([metadata.imageCaptions[1] isEqualToString:@"Goodbye World"]); + + XCTAssertNotNil(metadata.customMetadata); + XCTAssertTrue(metadata.customMetadata.allKeys.count == 1); +} + +- (void)verifyBranchContentMetadataDictionaryWithAllPropertiesSet:(NSDictionary *)dict { + XCTAssertTrue([@"OTHER" isEqualToString:dict[@"$content_schema"]]); + XCTAssertTrue([@(10) isEqualToNumber:dict[@"$quantity"]]); + XCTAssertTrue([[[NSDecimalNumber alloc] initWithDouble:5.5] isEqualToNumber:dict[@"$price"]]); + XCTAssertTrue([@"USD" isEqualToString:dict[@"$currency"]]); + XCTAssertTrue([@"testSKU" isEqualToString:dict[@"$sku"]]); + XCTAssertTrue([@"testProductName" isEqualToString:dict[@"$product_name"]]); + XCTAssertTrue([@"testProductBrand" isEqualToString:dict[@"$product_brand"]]); + XCTAssertTrue([@"Apparel & Accessories" isEqualToString:dict[@"$product_category"]]); + XCTAssertTrue([@"testProductVariant" isEqualToString:dict[@"$product_variant"]]); + XCTAssertTrue([@"NEW" isEqualToString:dict[@"$condition"]]); + + XCTAssertTrue([@(3.5) isEqualToNumber:dict[@"$rating_average"]]); + XCTAssertTrue([@(2) isEqualToNumber:dict[@"$rating_count"]]); + XCTAssertTrue([@(4) isEqualToNumber:dict[@"$rating_max"]]); + XCTAssertTrue([@(3) isEqualToNumber:dict[@"$rating"]]); + + XCTAssertTrue([@"195 Page Mill Road" isEqualToString:dict[@"$address_street"]]); + XCTAssertTrue([@"Palo Alto" isEqualToString:dict[@"$address_city"]]); + XCTAssertTrue([@"CA" isEqualToString:dict[@"$address_region"]]); + XCTAssertTrue([@"USA" isEqualToString:dict[@"$address_country"]]); + XCTAssertTrue([@"94306" isEqualToString:dict[@"$address_postal_code"]]); + + XCTAssertTrue([@(37.426) isEqualToNumber:dict[@"$latitude"]]); + XCTAssertTrue([@(-122.138) isEqualToNumber:dict[@"$longitude"]]); + + XCTAssertTrue([dict[@"$image_captions"] isKindOfClass:NSArray.class]); + NSArray *tmp = dict[@"$image_captions"]; + XCTAssertTrue(tmp.count == 2); + XCTAssertTrue([tmp[0] isEqualToString:@"Hello World"]); + XCTAssertTrue([tmp[1] isEqualToString:@"Goodbye World"]); + + XCTAssertTrue([@"custom data 0" isEqualToString:dict[@"custom0"]]); +} + +- (void)testBranchContentMetadataCreation_NoPropertiesSet { + BranchContentMetadata *metadata = [BranchContentMetadata new]; + + // most properties default to nil. primitives default to 0 + XCTAssertNil(metadata.contentSchema); + XCTAssertEqual(0, metadata.quantity); + XCTAssertNil(metadata.price); + XCTAssertNil(metadata.currency); + XCTAssertNil(metadata.sku); + XCTAssertNil(metadata.productName); + XCTAssertNil(metadata.productBrand); + XCTAssertNil(metadata.productCategory); + XCTAssertNil(metadata.productVariant); + XCTAssertNil(metadata.condition); + XCTAssertEqual(0, metadata.ratingAverage); + XCTAssertEqual(0, metadata.ratingCount); + XCTAssertEqual(0, metadata.ratingMax); + XCTAssertEqual(0, metadata.rating); + XCTAssertNil(metadata.addressStreet); + XCTAssertNil(metadata.addressCity); + XCTAssertNil(metadata.addressRegion); + XCTAssertNil(metadata.addressCountry); + XCTAssertNil(metadata.addressPostalCode); + XCTAssertEqual(0, metadata.latitude); + XCTAssertEqual(0, metadata.longitude); + + // defaults to an empty array + XCTAssertNotNil(metadata.imageCaptions); + XCTAssertTrue(metadata.imageCaptions.count == 0); + + // defaults to an empty dictionary + XCTAssertNotNil(metadata.customMetadata); + XCTAssertTrue(metadata.customMetadata.allKeys.count == 0); +} + +- (void)testBranchContentMetadataCreation_AllPropertiesSet { + BranchContentMetadata *metadata = [self branchContentMetadataWithAllPropertiesSet]; + [self verifyBranchContentMetadataWithAllProperties:metadata]; +} + +- (void)testBranchContentMetadataDictionary_NoPropertiesSet { + BranchContentMetadata *metadata = [BranchContentMetadata new]; + NSDictionary *dict = metadata.dictionary; + + XCTAssertNotNil(dict); + XCTAssertTrue(dict.allKeys.count == 0); +} + +- (void)testBranchContentMetadataDictionary_AllPropertiesSet { + BranchContentMetadata *metadata = [self branchContentMetadataWithAllPropertiesSet]; + NSDictionary *dict = metadata.dictionary; + + XCTAssertNotNil(dict); + XCTAssertTrue(dict.allKeys.count == 23); + [self verifyBranchContentMetadataDictionaryWithAllPropertiesSet:dict]; +} + +- (void)testBranchContentMetadata_contentMetadataWithDictionary { + BranchContentMetadata *original = [self branchContentMetadataWithAllPropertiesSet]; + NSDictionary *dict = [original dictionary]; + + BranchContentMetadata *metadata = [BranchContentMetadata contentMetadataWithDictionary:dict]; + [self verifyBranchContentMetadataWithAllProperties:metadata]; +} + +- (void)testBranchContentMetadataDescription_NoPropertiesSet { + BranchContentMetadata *metadata = [BranchContentMetadata new]; + NSString *desc = [metadata description]; + XCTAssertTrue([desc containsString:@"BranchContentMetadata"]); + XCTAssertTrue([desc containsString:@"schema: (null) userData: 0 items"]); +} + +- (void)testBranchContentMetadataDescription_AllPropertiesSet { + BranchContentMetadata *metadata = [self branchContentMetadataWithAllPropertiesSet]; + NSString *desc = [metadata description]; + XCTAssertTrue([desc containsString:@"BranchContentMetadata"]); + XCTAssertTrue([desc containsString:@"schema: OTHER userData: 1 items"]); +} + +#pragma mark BranchUniversalObject tests + +- (BranchUniversalObject *)branchUniversalObjectWithAllPropertiesSet { + BranchUniversalObject *buo = [[BranchUniversalObject alloc] initWithCanonicalIdentifier:@"io.branch.testObject"]; + buo.canonicalUrl = @"https://branch.io"; + buo.title = @"Test Title"; + buo.contentDescription = @"the quick brown fox jumps over the lazy dog"; + buo.imageUrl = @"https://branch.io"; + buo.keywords = @[@"keyword1", @"keyword2"]; + buo.expirationDate = [NSDate dateWithTimeIntervalSinceNow:1]; + buo.locallyIndex = YES; + buo.publiclyIndex = YES; + + buo.contentMetadata = [self branchContentMetadataWithAllPropertiesSet]; + return buo; +} + +- (void)verifyBranchUniversalObjectWithAllPropertiesSet:(BranchUniversalObject *)buo { + XCTAssertNotNil(buo); + XCTAssertTrue([@"https://branch.io" isEqualToString:buo.canonicalUrl]); + XCTAssertTrue([@"Test Title" isEqualToString:buo.title]); + XCTAssertTrue([@"the quick brown fox jumps over the lazy dog" isEqualToString:buo.contentDescription]); + XCTAssertTrue([@"https://branch.io" isEqualToString:buo.imageUrl]); + + XCTAssertTrue(buo.keywords.count == 2); + XCTAssertTrue([buo.keywords[0] isEqualToString:@"keyword1"]); + XCTAssertTrue([buo.keywords[1] isEqualToString:@"keyword2"]); + + XCTAssertTrue([buo.creationDate compare:buo.expirationDate] == NSOrderedAscending); + + XCTAssertTrue(buo.locallyIndex); + XCTAssertTrue(buo.publiclyIndex); + + [self verifyBranchContentMetadataWithAllProperties:buo.contentMetadata]; +} + +- (void)verifyBranchUniversalObjectDictionaryWithAllPropertiesSet:(NSDictionary *)dict { + XCTAssertTrue([@"io.branch.testObject" isEqualToString:dict[@"$canonical_identifier"]]); + XCTAssertTrue([@"https://branch.io" isEqualToString:dict[@"$canonical_url"]]); + XCTAssertTrue([@"Test Title" isEqualToString:dict[@"$og_title"]]); + XCTAssertTrue([@"the quick brown fox jumps over the lazy dog" isEqualToString:dict[@"$og_description"]]); + XCTAssertTrue([@"https://branch.io" isEqualToString:dict[@"$og_image_url"]]); + + XCTAssertTrue(dict[@"$locally_indexable"]); + XCTAssertTrue(dict[@"$publicly_indexable"]); + + XCTAssertTrue([dict[@"$creation_timestamp"] isKindOfClass:NSNumber.class]); + XCTAssertTrue([dict[@"$exp_date"] isKindOfClass:NSNumber.class]); + NSNumber *creationDate = dict[@"$creation_timestamp"]; + NSNumber *expirationDate = dict[@"$exp_date"]; + XCTAssertTrue([creationDate compare:expirationDate] == NSOrderedAscending); + + XCTAssertTrue([dict[@"$keywords"] isKindOfClass:NSArray.class]); + NSArray *tmp = dict[@"$keywords"]; + XCTAssertTrue(tmp.count == 2); + XCTAssertTrue([tmp[0] isEqualToString:@"keyword1"]); + XCTAssertTrue([tmp[1] isEqualToString:@"keyword2"]); + + // the BranchContentMetadata dictionary is NOT in a sub dictionary, it is merged in at the top level + [self verifyBranchContentMetadataDictionaryWithAllPropertiesSet:dict]; +} + +- (void)testBranchUniversalObjectCreation { + BranchUniversalObject *buo = [BranchUniversalObject new]; + XCTAssertNotNil(buo); + + XCTAssertNil(buo.canonicalIdentifier); + XCTAssertNil(buo.canonicalUrl); + XCTAssertNil(buo.title); + XCTAssertNil(buo.contentDescription); + XCTAssertNil(buo.imageUrl); + XCTAssertNil(buo.keywords); + XCTAssertNil(buo.creationDate); + XCTAssertNil(buo.expirationDate); + XCTAssertFalse(buo.locallyIndex); + XCTAssertFalse(buo.publiclyIndex); + + XCTAssertNotNil(buo.contentMetadata); +} + +- (void)testBranchUniversalObjectCreation_initWithCanonicalIdentifier { + BranchUniversalObject *buo = [[BranchUniversalObject alloc] initWithCanonicalIdentifier:@"io.branch.testObject"]; + XCTAssertNotNil(buo); + + XCTAssertTrue([@"io.branch.testObject" isEqualToString:buo.canonicalIdentifier]); + XCTAssertNil(buo.canonicalUrl); + XCTAssertNil(buo.title); + XCTAssertNil(buo.contentDescription); + XCTAssertNil(buo.imageUrl); + XCTAssertNil(buo.keywords); + XCTAssertNotNil(buo.creationDate); + XCTAssertNil(buo.expirationDate); + XCTAssertFalse(buo.locallyIndex); + XCTAssertFalse(buo.publiclyIndex); + + XCTAssertNotNil(buo.contentMetadata); +} + +- (void)testBranchUniversalObjectCreation_initWithTitle { + BranchUniversalObject *buo = [[BranchUniversalObject alloc] initWithTitle:@"Test Title"]; + XCTAssertNotNil(buo); + + XCTAssertNil(buo.canonicalIdentifier); + XCTAssertNil(buo.canonicalUrl); + XCTAssertTrue([@"Test Title" isEqualToString:buo.title]); + XCTAssertNil(buo.contentDescription); + XCTAssertNil(buo.imageUrl); + XCTAssertNil(buo.keywords); + XCTAssertNotNil(buo.creationDate); + XCTAssertNil(buo.expirationDate); + XCTAssertFalse(buo.locallyIndex); + XCTAssertFalse(buo.publiclyIndex); + + XCTAssertNotNil(buo.contentMetadata); +} + +- (void)testBranchUniversalObject_AllPropertiesSet { + BranchUniversalObject *buo = [self branchUniversalObjectWithAllPropertiesSet]; + [self verifyBranchUniversalObjectWithAllPropertiesSet:buo]; +} + +- (void)testBranchUniversalObjectDescription_AllPropertiesSet { + BranchUniversalObject *buo = [self branchUniversalObjectWithAllPropertiesSet]; + NSString *desc = buo.description; + + // Verifies a few properties used to generate the description string + XCTAssertTrue([desc containsString:@"BranchUniversalObject"]); + XCTAssertTrue([desc containsString:@"canonicalIdentifier: io.branch.testObject"]); + XCTAssertTrue([desc containsString:@"title: Test Title"]); + XCTAssertTrue([desc containsString:@"contentDescription: the quick brown fox jumps over the lazy dog"]); +} + +- (void)testBranchUniversalObjectDictionary_AllPropertiesSet { + BranchUniversalObject *buo = [self branchUniversalObjectWithAllPropertiesSet]; + NSDictionary *dict = buo.dictionary; + + XCTAssertNotNil(dict); + XCTAssertTrue(dict.allKeys.count == 33); + [self verifyBranchUniversalObjectDictionaryWithAllPropertiesSet:dict]; +} + +- (void)testBranchUniversalObject_objectWithDictionary { + BranchUniversalObject *original = [self branchUniversalObjectWithAllPropertiesSet]; + NSDictionary *dict = [original dictionary]; + + BranchUniversalObject *buo = [BranchUniversalObject objectWithDictionary:dict]; + [self verifyBranchUniversalObjectWithAllPropertiesSet:buo]; +} + +- (void)testBranchUniversalObject_getDictionaryWithCompleteLinkProperties_NoLinkPropertiesSet { + BranchUniversalObject *original = [self branchUniversalObjectWithAllPropertiesSet]; + BranchLinkProperties *linkProperties = [BranchLinkProperties new]; + NSDictionary *dict = [original getDictionaryWithCompleteLinkProperties:linkProperties]; + + XCTAssertNotNil(dict); + XCTAssertTrue([@(0) isEqualToNumber:dict[@"~duration"]]); +} + +- (void)testBranchUniversalObject_getDictionaryWithCompleteLinkProperties_AllLinkPropertiesSet { + BranchUniversalObject *original = [self branchUniversalObjectWithAllPropertiesSet]; + BranchLinkProperties *linkProperties = [BranchLinkProperties new]; + + linkProperties.tags = @[@"tag1", @"tag2"]; + linkProperties.feature = @"test feature"; + linkProperties.alias = @"test alias"; + linkProperties.channel = @"test channel"; + linkProperties.matchDuration = 10; + + // BranchUniversalObject.controlParams overwrites BranchContentMetadata.customMetadata + linkProperties.controlParams = @{ + @"testControlParam": @"test control param", + //@"custom0": @"test control param" + }; + + NSDictionary *dict = [original getDictionaryWithCompleteLinkProperties:linkProperties]; + XCTAssertNotNil(dict); + XCTAssertTrue(dict.allKeys.count == 39); + + XCTAssertTrue([@(10) isEqualToNumber:dict[@"~duration"]]); + XCTAssertTrue([@"test alias" isEqualToString:dict[@"~alias"]]); + XCTAssertTrue([@"test channel" isEqualToString:dict[@"~channel"]]); + XCTAssertTrue([@"test feature" isEqualToString:dict[@"~feature"]]); + + XCTAssertTrue([@"test control param" isEqualToString:dict[@"testControlParam"]]); + + // BranchUniversalObject fields are at the top level of the dictionary + [self verifyBranchUniversalObjectDictionaryWithAllPropertiesSet:dict]; +} + +- (void)testBranchUniversalObject_getParamsForServerRequestWithAddedLinkProperties_NoLinkPropertiesSet { + BranchUniversalObject *original = [self branchUniversalObjectWithAllPropertiesSet]; + BranchLinkProperties *linkProperties = [BranchLinkProperties new]; + + // Nothing is added with this call + NSDictionary *dict = [original getParamsForServerRequestWithAddedLinkProperties:linkProperties]; + + XCTAssertNotNil(dict); + + // BranchUniversalObject fields are at the top level of the dictionary + [self verifyBranchUniversalObjectDictionaryWithAllPropertiesSet:dict]; +} + +- (void)testBranchUniversalObject_getParamsForServerRequestWithAddedLinkProperties_AllLinkPropertiesSet { + BranchUniversalObject *original = [self branchUniversalObjectWithAllPropertiesSet]; + BranchLinkProperties *linkProperties = [BranchLinkProperties new]; + linkProperties.tags = @[@"tag1", @"tag2"]; + linkProperties.feature = @"test feature"; + linkProperties.alias = @"test alias"; + linkProperties.channel = @"test channel"; + linkProperties.matchDuration = 10; + + // BranchUniversalObject.controlParams overwrites BranchContentMetadata.customMetadata + linkProperties.controlParams = @{ + @"testControlParam": @"test control param", + //@"custom0": @"test control param" + }; + + NSDictionary *dict = [original getParamsForServerRequestWithAddedLinkProperties:linkProperties]; + XCTAssertNotNil(dict); + XCTAssertTrue(dict.allKeys.count == 34); + + // only the control parameters are in the dictionary + XCTAssertTrue([@"test control param" isEqualToString:dict[@"testControlParam"]]); + XCTAssertNil(dict[@"~duration"]); + XCTAssertNil(dict[@"~alias"]); + XCTAssertNil(dict[@"~channel"]); + XCTAssertNil(dict[@"~feature"]); + + // BranchUniversalObject fields are at the top level of the dictionary + [self verifyBranchUniversalObjectDictionaryWithAllPropertiesSet:dict]; +} + +@end diff --git a/BranchSDKTests/DispatchToIsolationQueueTests.m b/BranchSDKTests/DispatchToIsolationQueueTests.m new file mode 100644 index 000000000..89043aa94 --- /dev/null +++ b/BranchSDKTests/DispatchToIsolationQueueTests.m @@ -0,0 +1,76 @@ +// +// BNCPreInitBlockTests.m +// Branch-SDK-Tests +// +// Created by Benas Klastaitis on 12/9/19. +// Copyright © 2019 Branch, Inc. All rights reserved. +// + +#import +// #import "Branch.h" + +@interface DispatchToIsolationQueueTests : XCTestCase +// @property (nonatomic, strong, readwrite) Branch *branch; +// @property (nonatomic, strong, readwrite) BNCPreferenceHelper *prefHelper; +@end + +// this is an integration test, needs to be moved to a new target +@implementation DispatchToIsolationQueueTests + +- (void)setUp { + // self.branch = [Branch getInstance]; + // self.prefHelper = [[BNCPreferenceHelper alloc] init]; +} + +- (void)tearDown { + // [self.prefHelper setRequestMetadataKey:@"$marketing_cloud_visitor_id" value:@"dummy"]; +} + +- (void)testPreInitBlock { + // __block XCTestExpectation *expectation = [self expectationWithDescription:@""]; + + // [self.branch dispatchToIsolationQueue:^{ + // dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + // [self.branch setRequestMetadataKey:@"$marketing_cloud_visitor_id" value:@"adobeID123"]; + // dispatch_semaphore_signal(semaphore); + // }); + // dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + // }]; + + // [self.branch initSessionWithLaunchOptions:nil andRegisterDeepLinkHandlerUsingBranchUniversalObject: + // ^ (BranchUniversalObject * _Nullable universalObject, + // BranchLinkProperties * _Nullable linkProperties, + // NSError * _Nullable error) { + // [expectation fulfill]; + // }]; + + // // test that session initialization blocking works + // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + // id initializationStatus = [self.branch valueForKey:@"initializationStatus"]; + // XCTAssertTrue([self enumIntValueFromId:initializationStatus] == 0);// uninitialized + // XCTAssertNil([[self.prefHelper requestMetadataDictionary] objectForKey:@"$marketing_cloud_visitor_id"]); + // }); + + // // test that initialization does happen afterwards and that pre init block was executed + // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + // id initializationStatus = [self.branch valueForKey:@"initializationStatus"]; + // XCTAssertTrue([self enumIntValueFromId:initializationStatus] == 2);// initialized + + // XCTAssertTrue([[[self.prefHelper requestMetadataDictionary] objectForKey:@"$marketing_cloud_visitor_id"] isEqualToString:@"adobeID123"]); + // }); + + + // [self waitForExpectationsWithTimeout:6 handler:^(NSError * _Nullable error) { + // NSLog(@"%@", error); + // }]; +} + +// -(int)enumIntValueFromId:(id)enumValueId { +// if (![enumValueId respondsToSelector:@selector(intValue)]) +// return -1; + +// return [enumValueId intValue]; +// } + +@end diff --git a/TestDeepLinking/TestDeepLinkingUITestsWithHostApp/Info.plist b/BranchSDKTests/Info.plist similarity index 86% rename from TestDeepLinking/TestDeepLinkingUITestsWithHostApp/Info.plist rename to BranchSDKTests/Info.plist index 64d65ca49..ba72822e8 100644 --- a/TestDeepLinking/TestDeepLinkingUITestsWithHostApp/Info.plist +++ b/BranchSDKTests/Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) + en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -13,9 +13,11 @@ CFBundleName $(PRODUCT_NAME) CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) + BNDL CFBundleShortVersionString 1.0 + CFBundleSignature + ???? CFBundleVersion 1 diff --git a/BranchSDKTests/NSErrorBranchTests.m b/BranchSDKTests/NSErrorBranchTests.m new file mode 100644 index 000000000..4399b7484 --- /dev/null +++ b/BranchSDKTests/NSErrorBranchTests.m @@ -0,0 +1,54 @@ +/** + @file NSErrorBranchCategoryTests.m + @package Branch-SDK + @brief Branch error tests. + + @author Edward Smith + @date August 2017 + @copyright Copyright © 2017 Branch. All rights reserved. +*/ + +#import +#import "NSError+Branch.h" + +@interface NSErrorBranchTests : XCTestCase +@end + +@implementation NSErrorBranchTests + +- (void)testErrorDomain { + XCTAssertTrue([@"io.branch.sdk.error" isEqualToString:[NSError bncErrorDomain]]); +} + +- (void)testError { + NSError *error = [NSError branchErrorWithCode:BNCInitError]; + XCTAssert(error.domain == [NSError bncErrorDomain]); + XCTAssert(error.code == BNCInitError); + XCTAssert([error.localizedDescription isEqualToString: + @"The Branch user session has not been initialized."] + ); +} + +- (void)testErrorWithUnderlyingError { + NSError *underlyingError = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileNoSuchFileError userInfo:nil]; + NSError *error = [NSError branchErrorWithCode:BNCServerProblemError error:underlyingError]; + + XCTAssert(error.domain == [NSError bncErrorDomain]); + XCTAssert(error.code == BNCServerProblemError); + XCTAssert([error.localizedDescription isEqualToString: @"Trouble reaching the Branch servers, please try again shortly."]); + + XCTAssert(error.userInfo[NSUnderlyingErrorKey] == underlyingError); + XCTAssert([error.localizedFailureReason isEqualToString:@"The file doesn’t exist."]); +} + +- (void)testErrorWithMessage { + NSString *message = [NSString stringWithFormat:@"Network operation of class '%@' does not conform to the BNCNetworkOperationProtocol.", NSStringFromClass([self class])]; + NSError *error = [NSError branchErrorWithCode:BNCNetworkServiceInterfaceError localizedMessage:message]; + + XCTAssert(error.domain == [NSError bncErrorDomain]); + XCTAssert(error.code == BNCNetworkServiceInterfaceError); + XCTAssert([error.localizedDescription isEqualToString: @"The underlying network service does not conform to the BNCNetworkOperationProtocol."]); + XCTAssert([error.localizedFailureReason isEqualToString: @"Network operation of class 'NSErrorBranchTests' does not conform to the BNCNetworkOperationProtocol."]); +} + +@end diff --git a/BranchSDKTests/NSMutableDictionaryBranchTests.m b/BranchSDKTests/NSMutableDictionaryBranchTests.m new file mode 100644 index 000000000..9fadbefb2 --- /dev/null +++ b/BranchSDKTests/NSMutableDictionaryBranchTests.m @@ -0,0 +1,389 @@ +// +// NSMutableDictionaryBranchTests.m +// Branch-SDK-Tests +// +// Created by Ernest Cho on 2/9/24. +// Copyright © 2024 Branch, Inc. All rights reserved. +// + +#import +#import "NSMutableDictionary+Branch.h" + +@interface NSMutableDictionaryBranchTests : XCTestCase + +@end + +@implementation NSMutableDictionaryBranchTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)testSafeSetObject_StringString { + NSMutableDictionary *dict = [NSMutableDictionary new]; + + [dict bnc_safeSetObject:@"foo" forKey:@"bar"]; + XCTAssertTrue(dict.count == 1); + XCTAssertTrue([@"foo" isEqualToString:dict[@"bar"]]); +} + +- (void)testSafeSetObject_NilString { + NSMutableDictionary *dict = [NSMutableDictionary new]; + + [dict bnc_safeSetObject:nil forKey:@"bar"]; + XCTAssertTrue(dict.count == 0); +} + +- (void)testSafeSetObject_StringNil { + NSMutableDictionary *dict = [NSMutableDictionary new]; + + [dict bnc_safeSetObject:@"foo" forKey:nil]; + XCTAssertTrue(dict.count == 0); +} + +- (void)testSafeAddEntriesFromDictionary { + + // NSStrings are never copied, so use NSMutableStrings + NSMutableDictionary *other = [NSMutableDictionary new]; + other[@"foo"] = [[NSMutableString alloc] initWithString:@"bar"]; + other[@"hello"] = [[NSMutableString alloc] initWithString:@"world"]; + + NSMutableDictionary *dict = [NSMutableDictionary new]; + [dict bnc_safeAddEntriesFromDictionary:other]; + + NSArray *keyset = [other allKeys]; + for (id key in keyset) { + id original = other[key]; + id copy = dict[key]; + + // same object value + XCTAssertTrue([original isEqual:copy]); + + // different object instance + XCTAssertTrue(original != copy); + } +} + +- (void)testSafeAddEntriesFromDictionary_NestedArray { + + // NSStrings are never copied, so use NSMutableStrings + NSMutableDictionary *other = [NSMutableDictionary new]; + other[@"foo"] = [[NSMutableString alloc] initWithString:@"bar"]; + other[@"hello"] = [[NSMutableString alloc] initWithString:@"world"]; + + NSMutableArray *array = [NSMutableArray new]; + [array addObject:[[NSMutableString alloc] initWithString:@"dog"]]; + [array addObject:[[NSMutableString alloc] initWithString:@"cat"]]; + [array addObject:[[NSMutableString alloc] initWithString:@"child"]]; + + other[@"good"] = array; + + NSMutableDictionary *dict = [NSMutableDictionary new]; + [dict bnc_safeAddEntriesFromDictionary:other]; + + NSArray *keyset = [other allKeys]; + for (id key in keyset) { + id original = other[key]; + id copy = dict[key]; + + // same object value + XCTAssertTrue([original isEqual:copy]); + + // different object instance + XCTAssertTrue(original != copy); + } + + // confirm that copyItems is a one layer deep copy + NSArray *arrayCopy = dict[@"good"]; + XCTAssertTrue(array.count == arrayCopy.count); + XCTAssertTrue(array != arrayCopy); + + for (int i=0; i +#import "NSString+Branch.h" + +#define _countof(array) (sizeof(array)/sizeof(array[0])) + +@interface NSStringBranchTests : XCTestCase +@end + +@implementation NSStringBranchTests + +- (void)testMaskEqual { + XCTAssertTrue([@"0123" bnc_isEqualToMaskedString:@"0123"]); + XCTAssertFalse([@"0123" bnc_isEqualToMaskedString:@"012"]); + XCTAssertFalse([@"0123" bnc_isEqualToMaskedString:@"01234"]); + XCTAssertTrue([@"0123" bnc_isEqualToMaskedString:@"01*3"]); + XCTAssertFalse([@"0123" bnc_isEqualToMaskedString:@"01*4"]); + XCTAssertTrue([@"0123" bnc_isEqualToMaskedString:@"*123"]); + XCTAssertTrue([@"0123" bnc_isEqualToMaskedString:@"012*"]); + XCTAssertTrue([@"日本語123日本語" bnc_isEqualToMaskedString:@"日本語123日本語"]); + XCTAssertFalse([@"日本語123日本語" bnc_isEqualToMaskedString:@"日本語1234本語"]); + XCTAssertTrue([@"日本語123日本語" bnc_isEqualToMaskedString:@"日本語***日本語"]); + XCTAssertTrue([@"日本語123日本語" bnc_isEqualToMaskedString:@"***123日本語"]); +} + +@end diff --git a/BranchSDKTestsHostApp/AppDelegate.h b/BranchSDKTestsHostApp/AppDelegate.h new file mode 100644 index 000000000..ba35f21cd --- /dev/null +++ b/BranchSDKTestsHostApp/AppDelegate.h @@ -0,0 +1,14 @@ +// +// AppDelegate.h +// BranchSDKTestsHostApp +// +// Created by Nidhi Dixit on 7/6/25. +// + +#import + +@interface AppDelegate : UIResponder + + +@end + diff --git a/BranchSDKTestsHostApp/AppDelegate.m b/BranchSDKTestsHostApp/AppDelegate.m new file mode 100644 index 000000000..3c267c2e5 --- /dev/null +++ b/BranchSDKTestsHostApp/AppDelegate.m @@ -0,0 +1,40 @@ +// +// AppDelegate.m +// BranchSDKTestsHostApp +// +// Created by Nidhi Dixit on 7/6/25. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + + +#pragma mark - UISceneSession lifecycle + + +- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role]; +} + + +- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. +} + + +@end diff --git a/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/AccentColor.colorset/Contents.json b/BranchSDKTestsHostApp/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from DeepLinkDemo/DeepLinkDemo/Assets.xcassets/AccentColor.colorset/Contents.json rename to BranchSDKTestsHostApp/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/BranchSDKTestsHostApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/BranchSDKTestsHostApp/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..230588010 --- /dev/null +++ b/BranchSDKTestsHostApp/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/Contents.json b/BranchSDKTestsHostApp/Assets.xcassets/Contents.json similarity index 100% rename from DeepLinkDemo/DeepLinkDemo/Assets.xcassets/Contents.json rename to BranchSDKTestsHostApp/Assets.xcassets/Contents.json diff --git a/DeepLinkDemo/DeepLinkDemo/Base.lproj/LaunchScreen.storyboard b/BranchSDKTestsHostApp/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from DeepLinkDemo/DeepLinkDemo/Base.lproj/LaunchScreen.storyboard rename to BranchSDKTestsHostApp/Base.lproj/LaunchScreen.storyboard diff --git a/TestHost/Base.lproj/Main.storyboard b/BranchSDKTestsHostApp/Base.lproj/Main.storyboard similarity index 95% rename from TestHost/Base.lproj/Main.storyboard rename to BranchSDKTestsHostApp/Base.lproj/Main.storyboard index 25a763858..808a21ce7 100644 --- a/TestHost/Base.lproj/Main.storyboard +++ b/BranchSDKTestsHostApp/Base.lproj/Main.storyboard @@ -9,7 +9,7 @@ - + diff --git a/DeepLinkDemo/DeepLinkDemo/DeepLinkDemo.entitlements b/BranchSDKTestsHostApp/BranchSDKTestsHostAppRelease.entitlements similarity index 50% rename from DeepLinkDemo/DeepLinkDemo/DeepLinkDemo.entitlements rename to BranchSDKTestsHostApp/BranchSDKTestsHostAppRelease.entitlements index 51c38f856..9ad5d115f 100644 --- a/DeepLinkDemo/DeepLinkDemo/DeepLinkDemo.entitlements +++ b/BranchSDKTestsHostApp/BranchSDKTestsHostAppRelease.entitlements @@ -4,9 +4,11 @@ com.apple.developer.associated-domains - applinks:timber.test-app.link - applinks:timber.test-app.link - applinks:timber.test-app.link + applinks:bnc.lt + applinks:bnctestbed.app.link + applinks:bnctestbed.test-app.link + applinks:bnctestbed-alternate.app.link + applinks:bnctestbed-alternate.test-app.link diff --git a/TestHost/Info.plist b/BranchSDKTestsHostApp/Info.plist similarity index 59% rename from TestHost/Info.plist rename to BranchSDKTestsHostApp/Info.plist index dd3c9afda..f0cb4d34f 100644 --- a/TestHost/Info.plist +++ b/BranchSDKTestsHostApp/Info.plist @@ -2,6 +2,17 @@ + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + branchtest + + + UIApplicationSceneManifest UIApplicationSupportsMultipleScenes @@ -14,12 +25,19 @@ UISceneConfigurationName Default Configuration UISceneDelegateClassName - $(PRODUCT_MODULE_NAME).SceneDelegate + SceneDelegate UISceneStoryboardFile Main + branch_key + + live + key_live_hcnegAumkH7Kv18M8AOHhfgiohpXq5tB + test + key_test_hdcBLUy1xZ1JD0tKg7qrLcgirFmPPVJc + diff --git a/BranchSDKTestsHostApp/SceneDelegate.h b/BranchSDKTestsHostApp/SceneDelegate.h new file mode 100644 index 000000000..ae4e37f24 --- /dev/null +++ b/BranchSDKTestsHostApp/SceneDelegate.h @@ -0,0 +1,15 @@ +// +// SceneDelegate.h +// BranchSDKTestsHostApp +// +// Created by Nidhi Dixit on 7/6/25. +// + +#import + +@interface SceneDelegate : UIResponder + +@property (strong, nonatomic) UIWindow * window; + +@end + diff --git a/BranchSDKTestsHostApp/SceneDelegate.m b/BranchSDKTestsHostApp/SceneDelegate.m new file mode 100644 index 000000000..be25ed27f --- /dev/null +++ b/BranchSDKTestsHostApp/SceneDelegate.m @@ -0,0 +1,57 @@ +// +// SceneDelegate.m +// BranchSDKTestsHostApp +// +// Created by Nidhi Dixit on 7/6/25. +// + +#import "SceneDelegate.h" + +@interface SceneDelegate () + +@end + +@implementation SceneDelegate + + +- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). +} + + +- (void)sceneDidDisconnect:(UIScene *)scene { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). +} + + +- (void)sceneDidBecomeActive:(UIScene *)scene { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. +} + + +- (void)sceneWillResignActive:(UIScene *)scene { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). +} + + +- (void)sceneWillEnterForeground:(UIScene *)scene { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. +} + + +- (void)sceneDidEnterBackground:(UIScene *)scene { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. +} + + +@end diff --git a/BranchSDKTestsHostApp/ViewController.h b/BranchSDKTestsHostApp/ViewController.h new file mode 100644 index 000000000..83b3d1118 --- /dev/null +++ b/BranchSDKTestsHostApp/ViewController.h @@ -0,0 +1,14 @@ +// +// ViewController.h +// BranchSDKTestsHostApp +// +// Created by Nidhi Dixit on 7/6/25. +// + +#import + +@interface ViewController : UIViewController + + +@end + diff --git a/BranchSDKTestsHostApp/ViewController.m b/BranchSDKTestsHostApp/ViewController.m new file mode 100644 index 000000000..0a3c38aa1 --- /dev/null +++ b/BranchSDKTestsHostApp/ViewController.m @@ -0,0 +1,22 @@ +// +// ViewController.m +// BranchSDKTestsHostApp +// +// Created by Nidhi Dixit on 7/6/25. +// + +#import "ViewController.h" + +@interface ViewController () + +@end + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + + +@end diff --git a/BranchSDKTestsHostApp/cannedData/example.json b/BranchSDKTestsHostApp/cannedData/example.json new file mode 100644 index 000000000..d3be9b233 --- /dev/null +++ b/BranchSDKTestsHostApp/cannedData/example.json @@ -0,0 +1,31 @@ +{ + "user_string": "test user", + "user_number": 3.14, + "user_dict": { + "id": "273e4c5da13b978ee2f78f8997abd972959c184aaffb8cad716721a00a08d32b", + "name": "hello@branch.io" + }, + "user_dict_mixed": { + "id": 123, + "name": "hello@branch.io" + }, + "user_dict_numbers": { + "id": 123, + "name": 42 + }, + "user_array": [ + "123", + "abc", + "xyz" + ], + "user_array_mixed": [ + "abc", + 123, + "xyz" + ], + "user_array_numbers": [ + 1, + 2, + 3 + ] +} diff --git a/BranchSDKTestsHostApp/cannedData/latd.json b/BranchSDKTestsHostApp/cannedData/latd.json new file mode 100644 index 000000000..cc8d42631 --- /dev/null +++ b/BranchSDKTestsHostApp/cannedData/latd.json @@ -0,0 +1,7 @@ +{ + "last_attributed_touch_data": { + "$3p": "hello", + "~campaign": "world" + }, + "attribution_window": 30 +} diff --git a/BranchSDKTestsHostApp/cannedData/latd_empty_data.json b/BranchSDKTestsHostApp/cannedData/latd_empty_data.json new file mode 100644 index 000000000..5561c6a3c --- /dev/null +++ b/BranchSDKTestsHostApp/cannedData/latd_empty_data.json @@ -0,0 +1,4 @@ +{ + "last_attributed_touch_data": { }, + "attribution_window": 30 +} diff --git a/BranchSDKTestsHostApp/cannedData/latd_missing_data.json b/BranchSDKTestsHostApp/cannedData/latd_missing_data.json new file mode 100644 index 000000000..5dfcf058b --- /dev/null +++ b/BranchSDKTestsHostApp/cannedData/latd_missing_data.json @@ -0,0 +1,3 @@ +{ + "attribution_window": 30 +} diff --git a/BranchSDKTestsHostApp/cannedData/latd_missing_window.json b/BranchSDKTestsHostApp/cannedData/latd_missing_window.json new file mode 100644 index 000000000..7e4649891 --- /dev/null +++ b/BranchSDKTestsHostApp/cannedData/latd_missing_window.json @@ -0,0 +1,6 @@ +{ + "last_attributed_touch_data": { + "$3p": "hello", + "~campaign": "world" + } +} diff --git a/BranchSDKTestsHostApp/main.m b/BranchSDKTestsHostApp/main.m new file mode 100644 index 000000000..abfb64588 --- /dev/null +++ b/BranchSDKTestsHostApp/main.m @@ -0,0 +1,18 @@ +// +// main.m +// BranchSDKTestsHostApp +// +// Created by Nidhi Dixit on 7/6/25. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + NSString * appDelegateClassName; + @autoreleasepool { + // Setup code that might create autoreleased objects goes here. + appDelegateClassName = NSStringFromClass([AppDelegate class]); + } + return UIApplicationMain(argc, argv, nil, appDelegateClassName); +} diff --git a/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.pbxproj b/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.pbxproj deleted file mode 100644 index 6117713fe..000000000 --- a/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.pbxproj +++ /dev/null @@ -1,586 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 55; - objects = { - -/* Begin PBXBuildFile section */ - 180748E82833A914006DB0FA /* ReadLogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 180748E72833A914006DB0FA /* ReadLogViewController.swift */; }; - 180748EA2833CC85006DB0FA /* ParentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 180748E92833CC85006DB0FA /* ParentViewController.swift */; }; - 182B1F43282E0ECE00EA8C70 /* AddMetaDataVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182B1F42282E0ECE00EA8C70 /* AddMetaDataVC.swift */; }; - 182B1F45282E210B00EA8C70 /* MetaDataTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182B1F44282E210B00EA8C70 /* MetaDataTableViewCell.swift */; }; - 183F6FA2282D109800E293F6 /* TrackContentVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 183F6FA1282D109800E293F6 /* TrackContentVC.swift */; }; - 1877918A283C8D2400229CD5 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18779189283C8D2400229CD5 /* Utils.swift */; }; - 1889ACED283BE1C9009E3601 /* NSURLSessionBranch.m in Sources */ = {isa = PBXBuildFile; fileRef = 1889ACEC283BE1C9009E3601 /* NSURLSessionBranch.m */; }; - 18AC5ADE283F61430098736E /* LogFileListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18AC5ADD283F61430098736E /* LogFileListViewController.swift */; }; - 2A2347C154C6746FA55C3649 /* Pods_DeepLinkDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDBB5A837B0C008CA5BEC1EF /* Pods_DeepLinkDemo.framework */; }; - 7E1A39D42818289B002B302D /* DispalyVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E1A39D32818289B002B302D /* DispalyVC.swift */; }; - 7E2AE639280ED92800142446 /* CreateObjectReferenceObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E2AE638280ED92800142446 /* CreateObjectReferenceObject.swift */; }; - 7E2AE63B280EE1F700142446 /* GenerateURLVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E2AE63A280EE1F700142446 /* GenerateURLVC.swift */; }; - 7E2AE63F280EE23500142446 /* NavigateContentVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E2AE63E280EE23500142446 /* NavigateContentVC.swift */; }; - 7E37E69B280CF9D1003E42DB /* CommonMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E37E69A280CF9D1003E42DB /* CommonMethod.swift */; }; - 7E37E69D280D061E003E42DB /* SIAlertView in Resources */ = {isa = PBXBuildFile; fileRef = 7E37E69C280D061E003E42DB /* SIAlertView */; }; - 7E37E6A1280D12E2003E42DB /* img.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E37E6A0280D12E2003E42DB /* img.png */; }; - 7E6505F6281B003C006179FF /* ReadVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E6505F5281B003C006179FF /* ReadVC.swift */; }; - 7E7477CA2809C46C0088A7D3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E7477C92809C46C0088A7D3 /* AppDelegate.swift */; }; - 7E7477CE2809C46C0088A7D3 /* HomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E7477CD2809C46C0088A7D3 /* HomeViewController.swift */; }; - 7E7477D12809C46C0088A7D3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7E7477CF2809C46C0088A7D3 /* Main.storyboard */; }; - 7E7477D32809C46D0088A7D3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7E7477D22809C46D0088A7D3 /* Assets.xcassets */; }; - 7E7477D62809C46D0088A7D3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7E7477D42809C46D0088A7D3 /* LaunchScreen.storyboard */; }; - 7ED8BFED2835EFA90080C0CB /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ED8BFEC2835EFA90080C0CB /* Reachability.swift */; }; - 7ED8BFEF2835EFB40080C0CB /* CommonAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ED8BFEE2835EFB40080C0CB /* CommonAlert.swift */; }; - 7EE84374281CDFAE00A1561C /* StartupOptionsData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EE84373281CDFAE00A1561C /* StartupOptionsData.swift */; }; - 7EF58D5B2812CF2300BA92D5 /* WebViewVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EF58D5A2812CF2300BA92D5 /* WebViewVC.swift */; }; - B7B7DC2A2859974E00D45FC5 /* TextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7B7DC292859974E00D45FC5 /* TextViewController.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 180748E72833A914006DB0FA /* ReadLogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadLogViewController.swift; sourceTree = ""; }; - 180748E92833CC85006DB0FA /* ParentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParentViewController.swift; sourceTree = ""; }; - 182B1F42282E0ECE00EA8C70 /* AddMetaDataVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddMetaDataVC.swift; sourceTree = ""; }; - 182B1F44282E210B00EA8C70 /* MetaDataTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetaDataTableViewCell.swift; sourceTree = ""; }; - 183F6FA1282D109800E293F6 /* TrackContentVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackContentVC.swift; sourceTree = ""; }; - 18779189283C8D2400229CD5 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; - 1889ACEB283BE1C9009E3601 /* NSURLSessionBranch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSURLSessionBranch.h; sourceTree = ""; }; - 1889ACEC283BE1C9009E3601 /* NSURLSessionBranch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSURLSessionBranch.m; sourceTree = ""; }; - 18AC5ADD283F61430098736E /* LogFileListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogFileListViewController.swift; sourceTree = ""; }; - 7E1A39D32818289B002B302D /* DispalyVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DispalyVC.swift; sourceTree = ""; }; - 7E2AE638280ED92800142446 /* CreateObjectReferenceObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateObjectReferenceObject.swift; sourceTree = ""; }; - 7E2AE63A280EE1F700142446 /* GenerateURLVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenerateURLVC.swift; sourceTree = ""; }; - 7E2AE63E280EE23500142446 /* NavigateContentVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigateContentVC.swift; sourceTree = ""; }; - 7E37E69A280CF9D1003E42DB /* CommonMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonMethod.swift; sourceTree = ""; }; - 7E37E69C280D061E003E42DB /* SIAlertView */ = {isa = PBXFileReference; lastKnownFileType = folder; path = SIAlertView; sourceTree = ""; }; - 7E37E69E280D0676003E42DB /* Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Header.h; sourceTree = ""; }; - 7E37E69F280D06FF003E42DB /* DeepLinkDemo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DeepLinkDemo-Bridging-Header.h"; sourceTree = ""; }; - 7E37E6A0280D12E2003E42DB /* img.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = img.png; sourceTree = ""; }; - 7E6505F5281B003C006179FF /* ReadVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadVC.swift; sourceTree = ""; }; - 7E7477C62809C46C0088A7D3 /* DeepLinkDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DeepLinkDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 7E7477C92809C46C0088A7D3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 7E7477CD2809C46C0088A7D3 /* HomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = ""; }; - 7E7477D02809C46C0088A7D3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 7E7477D22809C46D0088A7D3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 7E7477D52809C46D0088A7D3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 7E7477D72809C46D0088A7D3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 7ED8BFEB2835EFA90080C0CB /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = ""; }; - 7ED8BFEC2835EFA90080C0CB /* Reachability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reachability.swift; sourceTree = ""; }; - 7ED8BFEE2835EFB40080C0CB /* CommonAlert.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommonAlert.swift; sourceTree = ""; }; - 7EE84373281CDFAE00A1561C /* StartupOptionsData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartupOptionsData.swift; sourceTree = ""; }; - 7EF58D5A2812CF2300BA92D5 /* WebViewVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewVC.swift; sourceTree = ""; }; - 7EF58D5C2816D14700BA92D5 /* DeepLinkDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DeepLinkDemo.entitlements; sourceTree = ""; }; - 88EDCA13B444CE5565DC92FA /* Pods-DeepLinkDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DeepLinkDemo.release.xcconfig"; path = "Target Support Files/Pods-DeepLinkDemo/Pods-DeepLinkDemo.release.xcconfig"; sourceTree = ""; }; - B7B7DC292859974E00D45FC5 /* TextViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewController.swift; sourceTree = ""; }; - C06885D21868B25319262FC1 /* Pods-DeepLinkDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DeepLinkDemo.debug.xcconfig"; path = "Target Support Files/Pods-DeepLinkDemo/Pods-DeepLinkDemo.debug.xcconfig"; sourceTree = ""; }; - DDBB5A837B0C008CA5BEC1EF /* Pods_DeepLinkDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DeepLinkDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 7E7477C32809C46C0088A7D3 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 2A2347C154C6746FA55C3649 /* Pods_DeepLinkDemo.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 0D26D1E3284DFA33003FAB18 /* Constants */ = { - isa = PBXGroup; - children = ( - 18779189283C8D2400229CD5 /* Utils.swift */, - 7ED8BFEE2835EFB40080C0CB /* CommonAlert.swift */, - 7E37E69A280CF9D1003E42DB /* CommonMethod.swift */, - ); - path = Constants; - sourceTree = ""; - }; - 29D53CAAE9E9EF2F96296086 /* Frameworks */ = { - isa = PBXGroup; - children = ( - DDBB5A837B0C008CA5BEC1EF /* Pods_DeepLinkDemo.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 7E2AE642280EFF1200142446 /* Controllers */ = { - isa = PBXGroup; - children = ( - 7E7477CD2809C46C0088A7D3 /* HomeViewController.swift */, - B7B7DC292859974E00D45FC5 /* TextViewController.swift */, - 7E2AE638280ED92800142446 /* CreateObjectReferenceObject.swift */, - 7E2AE63A280EE1F700142446 /* GenerateURLVC.swift */, - 7E2AE63E280EE23500142446 /* NavigateContentVC.swift */, - 7E1A39D32818289B002B302D /* DispalyVC.swift */, - 7EF58D5A2812CF2300BA92D5 /* WebViewVC.swift */, - 7E6505F5281B003C006179FF /* ReadVC.swift */, - 183F6FA1282D109800E293F6 /* TrackContentVC.swift */, - 182B1F42282E0ECE00EA8C70 /* AddMetaDataVC.swift */, - 182B1F44282E210B00EA8C70 /* MetaDataTableViewCell.swift */, - 180748E72833A914006DB0FA /* ReadLogViewController.swift */, - 18AC5ADD283F61430098736E /* LogFileListViewController.swift */, - 180748E92833CC85006DB0FA /* ParentViewController.swift */, - ); - path = Controllers; - sourceTree = ""; - }; - 7E7477BD2809C46C0088A7D3 = { - isa = PBXGroup; - children = ( - 7E7477C82809C46C0088A7D3 /* DeepLinkDemo */, - 7E7477C72809C46C0088A7D3 /* Products */, - DB9F65A595474F5DA261D89A /* Pods */, - 29D53CAAE9E9EF2F96296086 /* Frameworks */, - ); - sourceTree = ""; - }; - 7E7477C72809C46C0088A7D3 /* Products */ = { - isa = PBXGroup; - children = ( - 7E7477C62809C46C0088A7D3 /* DeepLinkDemo.app */, - ); - name = Products; - sourceTree = ""; - }; - 7E7477C82809C46C0088A7D3 /* DeepLinkDemo */ = { - isa = PBXGroup; - children = ( - 7E2AE642280EFF1200142446 /* Controllers */, - 1889ACEB283BE1C9009E3601 /* NSURLSessionBranch.h */, - 1889ACEC283BE1C9009E3601 /* NSURLSessionBranch.m */, - 7ED8BFEA2835EF9E0080C0CB /* Reachability */, - 7EF58D5C2816D14700BA92D5 /* DeepLinkDemo.entitlements */, - 7E37E69C280D061E003E42DB /* SIAlertView */, - 7E7477C92809C46C0088A7D3 /* AppDelegate.swift */, - 7EE84373281CDFAE00A1561C /* StartupOptionsData.swift */, - 0D26D1E3284DFA33003FAB18 /* Constants */, - 7E7477CF2809C46C0088A7D3 /* Main.storyboard */, - 7E37E6A0280D12E2003E42DB /* img.png */, - 7E7477D22809C46D0088A7D3 /* Assets.xcassets */, - 7E7477D42809C46D0088A7D3 /* LaunchScreen.storyboard */, - 7E7477D72809C46D0088A7D3 /* Info.plist */, - 7E37E69E280D0676003E42DB /* Header.h */, - 7E37E69F280D06FF003E42DB /* DeepLinkDemo-Bridging-Header.h */, - ); - path = DeepLinkDemo; - sourceTree = ""; - }; - 7ED8BFEA2835EF9E0080C0CB /* Reachability */ = { - isa = PBXGroup; - children = ( - 7ED8BFEB2835EFA90080C0CB /* Reachability.h */, - 7ED8BFEC2835EFA90080C0CB /* Reachability.swift */, - ); - path = Reachability; - sourceTree = ""; - }; - DB9F65A595474F5DA261D89A /* Pods */ = { - isa = PBXGroup; - children = ( - C06885D21868B25319262FC1 /* Pods-DeepLinkDemo.debug.xcconfig */, - 88EDCA13B444CE5565DC92FA /* Pods-DeepLinkDemo.release.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 7E7477C52809C46C0088A7D3 /* DeepLinkDemo */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7E7477DA2809C46D0088A7D3 /* Build configuration list for PBXNativeTarget "DeepLinkDemo" */; - buildPhases = ( - 8C8C5B24F34C07814525F311 /* [CP] Check Pods Manifest.lock */, - 7E7477C22809C46C0088A7D3 /* Sources */, - 7E7477C32809C46C0088A7D3 /* Frameworks */, - 7E7477C42809C46C0088A7D3 /* Resources */, - 9086714B33BB3D176E3DED70 /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = DeepLinkDemo; - productName = DeepLinkDemo; - productReference = 7E7477C62809C46C0088A7D3 /* DeepLinkDemo.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 7E7477BE2809C46C0088A7D3 /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1330; - LastUpgradeCheck = 1330; - TargetAttributes = { - 7E7477C52809C46C0088A7D3 = { - CreatedOnToolsVersion = 13.3.1; - LastSwiftMigration = 1340; - }; - }; - }; - buildConfigurationList = 7E7477C12809C46C0088A7D3 /* Build configuration list for PBXProject "DeepLinkDemo" */; - compatibilityVersion = "Xcode 13.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 7E7477BD2809C46C0088A7D3; - productRefGroup = 7E7477C72809C46C0088A7D3 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 7E7477C52809C46C0088A7D3 /* DeepLinkDemo */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 7E7477C42809C46C0088A7D3 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7E37E6A1280D12E2003E42DB /* img.png in Resources */, - 7E7477D62809C46D0088A7D3 /* LaunchScreen.storyboard in Resources */, - 7E7477D32809C46D0088A7D3 /* Assets.xcassets in Resources */, - 7E37E69D280D061E003E42DB /* SIAlertView in Resources */, - 7E7477D12809C46C0088A7D3 /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 8C8C5B24F34C07814525F311 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-DeepLinkDemo-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 9086714B33BB3D176E3DED70 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-DeepLinkDemo/Pods-DeepLinkDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-DeepLinkDemo/Pods-DeepLinkDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-DeepLinkDemo/Pods-DeepLinkDemo-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 7E7477C22809C46C0088A7D3 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 182B1F43282E0ECE00EA8C70 /* AddMetaDataVC.swift in Sources */, - 7E6505F6281B003C006179FF /* ReadVC.swift in Sources */, - 7ED8BFED2835EFA90080C0CB /* Reachability.swift in Sources */, - 7E7477CE2809C46C0088A7D3 /* HomeViewController.swift in Sources */, - 180748E82833A914006DB0FA /* ReadLogViewController.swift in Sources */, - 7E7477CA2809C46C0088A7D3 /* AppDelegate.swift in Sources */, - 7EF58D5B2812CF2300BA92D5 /* WebViewVC.swift in Sources */, - 1877918A283C8D2400229CD5 /* Utils.swift in Sources */, - 1889ACED283BE1C9009E3601 /* NSURLSessionBranch.m in Sources */, - 7E37E69B280CF9D1003E42DB /* CommonMethod.swift in Sources */, - 183F6FA2282D109800E293F6 /* TrackContentVC.swift in Sources */, - 180748EA2833CC85006DB0FA /* ParentViewController.swift in Sources */, - 7E2AE63B280EE1F700142446 /* GenerateURLVC.swift in Sources */, - 7E1A39D42818289B002B302D /* DispalyVC.swift in Sources */, - 182B1F45282E210B00EA8C70 /* MetaDataTableViewCell.swift in Sources */, - 7ED8BFEF2835EFB40080C0CB /* CommonAlert.swift in Sources */, - 7EE84374281CDFAE00A1561C /* StartupOptionsData.swift in Sources */, - 7E2AE639280ED92800142446 /* CreateObjectReferenceObject.swift in Sources */, - 18AC5ADE283F61430098736E /* LogFileListViewController.swift in Sources */, - 7E2AE63F280EE23500142446 /* NavigateContentVC.swift in Sources */, - B7B7DC2A2859974E00D45FC5 /* TextViewController.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 7E7477CF2809C46C0088A7D3 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 7E7477D02809C46C0088A7D3 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 7E7477D42809C46D0088A7D3 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 7E7477D52809C46D0088A7D3 /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 7E7477D82809C46D0088A7D3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 7E7477D92809C46D0088A7D3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 7E7477DB2809C46D0088A7D3 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = C06885D21868B25319262FC1 /* Pods-DeepLinkDemo.debug.xcconfig */; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD)"; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 2; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = R63EM248DP; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = DeepLinkDemo/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = SaaS_SDK_TestBed_iOS; - INFOPLIST_KEY_LSApplicationCategoryType = ""; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; - INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortraitUpsideDown"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = UIInterfaceOrientationPortrait; - INFOPLIST_OUTPUT_FORMAT = "same-as-input"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Framework", - ); - MARKETING_VERSION = 1.1; - PLIST_FILE_OUTPUT_FORMAT = "same-as-input"; - PRODUCT_BUNDLE_IDENTIFIER = io.branch.saas.sdk.testbed; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "iOS Saas SDK - Dev"; - STRINGS_FILE_OUTPUT_ENCODING = "UTF-8"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 1; - }; - name = Debug; - }; - 7E7477DC2809C46D0088A7D3 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 88EDCA13B444CE5565DC92FA /* Pods-DeepLinkDemo.release.xcconfig */; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD)"; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 2; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = R63EM248DP; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = DeepLinkDemo/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = SaaS_SDK_TestBed_iOS; - INFOPLIST_KEY_LSApplicationCategoryType = ""; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; - INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortraitUpsideDown"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = UIInterfaceOrientationPortrait; - INFOPLIST_OUTPUT_FORMAT = "same-as-input"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Framework", - ); - MARKETING_VERSION = 1.1; - ONLY_ACTIVE_ARCH = YES; - PLIST_FILE_OUTPUT_FORMAT = "same-as-input"; - PRODUCT_BUNDLE_IDENTIFIER = io.branch.saas.sdk.testbed; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "iOS Saas SDK - Dev"; - STRINGS_FILE_OUTPUT_ENCODING = "UTF-8"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 1; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 7E7477C12809C46C0088A7D3 /* Build configuration list for PBXProject "DeepLinkDemo" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7E7477D82809C46D0088A7D3 /* Debug */, - 7E7477D92809C46D0088A7D3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 7E7477DA2809C46D0088A7D3 /* Build configuration list for PBXNativeTarget "DeepLinkDemo" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7E7477DB2809C46D0088A7D3 /* Debug */, - 7E7477DC2809C46D0088A7D3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 7E7477BE2809C46C0088A7D3 /* Project object */; -} diff --git a/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a62..000000000 --- a/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/DeepLinkDemo/DeepLinkDemo.xcworkspace/contents.xcworkspacedata b/DeepLinkDemo/DeepLinkDemo.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index dbfeee663..000000000 --- a/DeepLinkDemo/DeepLinkDemo.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/DeepLinkDemo/DeepLinkDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/DeepLinkDemo/DeepLinkDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/DeepLinkDemo/DeepLinkDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/DeepLinkDemo/DeepLinkDemo/AppDelegate.swift b/DeepLinkDemo/DeepLinkDemo/AppDelegate.swift deleted file mode 100644 index bebb005e5..000000000 --- a/DeepLinkDemo/DeepLinkDemo/AppDelegate.swift +++ /dev/null @@ -1,268 +0,0 @@ -// -// AppDelegate.swift -// DeepLinkDemo -// -// Created by Rakesh kumar on 4/15/22. -// - -import UIKit -import BranchSDK -import IQKeyboardManager -@main -class AppDelegate: UIResponder, UIApplicationDelegate { - var window: UIWindow? - static var shared: AppDelegate { - return (UIApplication.shared.delegate as? AppDelegate)! - - } - var launchOption = [UIApplication.LaunchOptionsKey : Any]() - var delegate: AppDelegate! - - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { - print("didFinishLaunchingWithOptions") - if #available(iOS 10.0, *) { - let center = UNUserNotificationCenter.current() - UNUserNotificationCenter.current().delegate = self - center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in - if granted { - print("Allowed to send Notification") - } else { - print("Not allowed to send Notification") - } - } - }else{ - let notificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) - UIApplication.shared.registerUserNotificationSettings(notificationSettings) - _ = application.beginBackgroundTask(withName: "showNotification", expirationHandler: nil) - } - - Utils.shared.clearAllLogFiles() - Utils.shared.setLogFile("AppLaunch") - IQKeyboardManager.shared().isEnabled = true - StartupOptionsData.setActiveSetDebugEnabled(true) - StartupOptionsData.setPendingSetDebugEnabled(true) - Utils.shared.setLogFile("AppDelegate") - return true - } - - - func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { - - //check for link_click_id - if url.absoluteString.contains("link_click_id") == true{ - return Branch.getInstance().application(app, open: url, options: options) - } - return true - } - - - func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { - // handler for Universal Links - return Branch.getInstance().continue(userActivity) - } - - func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { - // handler for Push Notifications - Branch.getInstance().handlePushNotification(userInfo) - } - - - - func application(_ application: UIApplication, didReceiveRemoteNotification launchOptions: [AnyHashable: Any]) -> Void { - Branch.getInstance().handlePushNotification(launchOptions) - } - - func application(_ application: UIApplication, didReceive notification: UILocalNotification){ - print(#function) - } - - func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, for notification: UILocalNotification, completionHandler: @escaping () -> Void){ - print(#function) - } - - - // Respond to URL scheme links - func application(_ application: UIApplication, - open url: URL, - sourceApplication: String?, - annotation: Any) -> Bool { - - let branchHandled = Branch.getInstance().application(application, - open: url, - sourceApplication: sourceApplication, - annotation: annotation - ) - if(!branchHandled) { - // If not handled by Branch, do other deep link routing for the Facebook SDK, Pinterest SDK, etc - - } - return true - } - - // Respond to Universal Links - func application(_ - application: UIApplication, - continue userActivity: NSUserActivity, - restorationHandler: @escaping ([Any]?) -> Void - ) -> Bool { - let branchHandled = Branch.getInstance().continue(userActivity) - if (userActivity.activityType == NSUserActivityTypeBrowsingWeb) { - if let url = userActivity.webpageURL, - !branchHandled { - - } - } - - // Apply your logic to determine the return value of this method - return true - } - - - func pushNewView() { - if let controller = NavigateContentVC() as? NavigateContentVC { - if let window = self.window, let rootViewController = window.rootViewController { - var currentController = rootViewController - while let presentedController = currentController.presentedViewController { - currentController = presentedController - } - currentController.present(controller, animated: true, completion: nil) - } - } - } - func handleDeepLinkObject(object: BranchUniversalObject, linkProperties:BranchLinkProperties, error:NSError) { - - NSLog("Deep linked with object: %@.", object); - let deeplinkText = object.contentMetadata.customMetadata.value(forKey: "deeplink_text") - let textDetail = "Successfully Deeplinked:\n\n%@\nSession Details:\n\n%@, \(String(describing: deeplinkText)) \(String(describing: Branch.getInstance().getLatestReferringParams()?.description))" - NSLog(textDetail) - self.pushNewView() - } - - - - - func getBranchData(_ launchOptions: [UIApplication.LaunchOptionsKey : Any]?) { - - Branch.getInstance().initSession( - launchOptions: launchOptions, - automaticallyDisplayDeepLinkController: false, - deepLinkHandler: { params, error in - - defer { - let notificationName = Notification.Name("BranchCallbackCompleted") - NotificationCenter.default.post(name: notificationName, object: nil) - } - - guard error == nil else { - NSLog("Branch TestBed: Initialization failed: " + error!.localizedDescription) - return - } - - guard let paramsDictionary = (params as? Dictionary) else { - NSLog("No Branch parameters returned") - return - } - - let clickedBranchLink = params?[BRANCH_INIT_KEY_CLICKED_BRANCH_LINK] as! Bool? - if let referringLink = paramsDictionary["~referring_link"] as! String?, - let trackerId = paramsDictionary["ios_tracker_id"] as! String?, - let clickedBranchLink = clickedBranchLink, - clickedBranchLink { - var adjustUrl = URLComponents(string: referringLink) - var adjust_tracker:URLQueryItem - if referringLink.starts(with: "https://") || referringLink.starts(with: "http://") { - adjust_tracker = URLQueryItem(name: "adjust_t", value: trackerId) - } else { - adjust_tracker = URLQueryItem(name: "adjust_tracker", value: trackerId) - } - let adjust_campaign = URLQueryItem(name: "adjust_campaign", value: paramsDictionary[BRANCH_INIT_KEY_CAMPAIGN] as? String) - let adjust_adgroup = URLQueryItem(name: "adjust_adgroup", value: paramsDictionary[BRANCH_INIT_KEY_CHANNEL] as? String) - let adjust_creative = URLQueryItem(name: "adjust_creative", value: paramsDictionary[BRANCH_INIT_KEY_FEATURE] as? String) - let queryItems = [adjust_tracker,adjust_campaign,adjust_adgroup,adjust_creative] - adjustUrl?.queryItems = queryItems -// if let url = adjustUrl?.url { -// //Adjust.appWillOpen(url) -// } - } - // Deeplinking logic for use when automaticallyDisplayDeepLinkController = false - if let clickedBranchLink = clickedBranchLink, - clickedBranchLink { - let nc = self.window!.rootViewController as! UINavigationController - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "DispalyVC") as? DispalyVC { - let linkurl = UserDefaults.standard.value(forKey: "link") as? String ?? "" - //let referringLink = paramsDictionary["~referring_link"] as! String - let content = String(format:"\nReferring link: %@ \n\nSession Details:\n %@", linkurl, paramsDictionary.jsonStringRepresentation!) - vc.textDescription = content - vc.appData = paramsDictionary - vc.linkURL = linkurl - nc.pushViewController(vc, animated: true) - } - } else { - NSLog("Branch TestBed: Finished init with params\n%@", paramsDictionary.description) - } - }) - } - - - func handleURL(_ url: URL) { - guard url.pathComponents.count >= 3 else { return } - - let section = url.pathComponents[1] - let detail = url.pathComponents[2] - - switch section { - case "post": - guard let id = Int(detail) else { break } - // navigateToItem(id) - case "settings": - //navigateToSettings(detail) - break - default: break - } - } - -} - - -@available(iOS 10.0, *) -extension AppDelegate: UNUserNotificationCenterDelegate{ - - func getApprovalForSendingNotification(){ - if #available(iOS 11.0, *) { - let center = UNUserNotificationCenter.current() - UNUserNotificationCenter.current().delegate = self - center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in - if granted { - print("Allowed to send Notification") - } else { - print("Not allowed to send Notification") - } - } - }else{ - let notificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) - UIApplication.shared.registerUserNotificationSettings(notificationSettings) - } - } - func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { - completionHandler([.alert, .badge, .sound]) - } - func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { - print(response) - let content = response.notification.request.content - print(content.userInfo) - Branch.getInstance().handlePushNotification(content.userInfo) - } - -} -extension Dictionary { - var jsonStringRepresentation: String? { - guard let theJSONData = try? JSONSerialization.data(withJSONObject: self, - options: [.prettyPrinted]) else { - return nil - } - - return String(data: theJSONData, encoding: .ascii) - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/AppIcon.appiconset/Contents.json b/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 9221b9bb1..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "20x20" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "20x20" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "29x29" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "29x29" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "40x40" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "40x40" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "60x60" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "60x60" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "20x20" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "20x20" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "29x29" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "29x29" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "40x40" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "40x40" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "76x76" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "76x76" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "83.5x83.5" - }, - { - "idiom" : "ios-marketing", - "scale" : "1x", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/Contents.json b/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/Contents.json deleted file mode 100644 index d18ba8435..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/Contents.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "icons8-left-100.png", - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - }, - "properties" : { - "template-rendering-intent" : "template" - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/icons8-left-100.png b/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/icons8-left-100.png deleted file mode 100644 index b1952be8aac5931b6a6676536e7615aba06a0106..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 627 zcmeAS@N?(olHy`uVBq!ia0vp^DImkG4uAb{HyJG}WchLAhmo6!devX|_Qw7xQ#Uf4IdbI8LxB(THW}?>TAq~j%z$~% z(mg$w4GoKDu-yxYJ2rF13`-y8^_tp`r3=i|()fNigio3JQPx6U*tmV~l<6B;Vmdl! z9+rEc`ZP7B2guTUzzSq_0a<(AWP&!&nKgGK#LN&D!d{kPan7nH1y4aJw5UV zwgOo>%yP++p*Q$!7Ov^pw^p%$dq(cwZrPbnPQ3UW#lpAk&gpC0nD{&I_e5QLTXy^A zIk5)^r4|~kPmMaaYi<7Lw9@syip&pWKCD=*Q(G`SO+a~y`qwmFCibXzsp&@bZ)F)i zANY4|_YK2(iLevi>Y|?>CAIGP6Q`IT5PBkdhiK7>g-(5pp(h-7a#?ysDYmcGe)5<@ z^i$(pF5h1s(WcETwPq)s=bJYhEeoz%Qq#dTBk-g=dky0?SJpEbcjB|p9CtmP-M7_S yGU#FMC7ra!*Cx+<$`A1BI3q{lB$buP`x(C7)?)Q@d(;n1MGT&M+U#57K(hy~sWdJ}(^F82E!gCK) zOULBg!Y)8KzN~KaRb(ThbaHT9)9Tv(&A|cT^70R6_YcHv1(?y zs}w8;DQ~w-EcT;gcfEW!^}rc0`=pv)(l~=B#g?nQ7CnSh~Hx zSR<@o+cH*tx}iEgX-v&`nUR;r$zUS#;QvQ?tX@;EAIoxlxQTP<_4j^oBnZzmb#waFwm zU)~#HUbbi^`zsW`DXC=GSbVslopNj6$;bB20|;pl0I|qP(MwKHuK$saOHwukcWOM& zy54sfVG_jiKX=1qFhQMwHd&I@$=&VbJ5;n#V#DC+QT?0~mPI#Kb{2ZER51+IUi7>~ z$QW!L)V&#b=6tJSDN$L|#->eGc9=bpoN%sYII4atHw4dOcyy#1^W7yRXr`Dr(NC~I zE*W>ItkJ&5d^i{DWu20Z zl?V^JPftY-I3K214uKEjEU2A10x&EuaEEd==7jmVH|XF-y^VXB%zA3$7ECq8-eGmr zphe0Lt_}5M1d*vcYALDFM)I5CSj!X;nVCS$GpDdEm|0u8G{zefk~rrqAw=F|^A)Nt z;xbN=(B8ea9IkepCwavQ6h#D{Pt4b{&-NsuOs9|EDzjYbH4}-mvww$VHLPoO+bHXF z(N$%o-TfePs(>kiT>5D;O@2`a)w?TFJr9k|~ zy*QxsU*1?^$!u3{Clbr3UbSXU$v*=sKSk0**-Ah1gGO^ryksz&9khuZsI^4#H$z8T z!YiVfh-dWEorg;OpM&<$tL8 z3JA!7mV8+6Yq;vq#Nj~j(9HB=JZ+}&~``yH~XnX8WKb*5Hr z5X~b6KIqk7&P^`jFXRn@(7mdR*axJ&JhDawe_55POlPO`s3co|wON=VyXp&3*k^?J zywBLw$jO%4dex2m>FVZjL1$o!fe^o0LAo&V6db0001i0SrI#eacZ@b2EH221f&9_z zV#=0Ric@&(T~HkUEN zV)RbTf|-zLc5>W~Dmc;l;nO@_Y?SR*)0Uzi*MB5LS9rBPpZXm4^)FVUEN+5~YE%i* zJlq3k_4%z?syw%DoB3=)ZS|PR6 z&g4u;X`f`Byh_z~lRv5p95Eglxa$bzwaBP2P6gX5y z3u#&T6Glic$5WJzt;ugV8Eo{!j`3h9ppFStneueO!2zf-3+ow5C1?$rN{oG&n0 zZq%I|v62km$sI>YKelr@xzlxWf5EoO)#Z&^e>O?c&q{Xcr_t2Xlw!NTMDD!xjnC6zi5bE>9L<^{-HGW zLb`8=*LM@{qn9{D45PbwF>{w_EG`a7=K_JRYy3UXaw~ zd%{pe%;~C`2u&E*ayBy8&M=E$Nh}B6G4cRn{kXADgykibYxd+lErtS30ow$~uaM8I z-;{+Lq|0v{-(^HM6WvNT#Q~bg%wl{z4Wk#k_=>89Sx96A!9%WN>08OJ;xf~TKBu*2 zq7Lj^OtKA+KzW(FV2Z~t0`F$sy+-8UQMAFj{)zKKWKzRq1-v3U0-k{+a4Prj|3$t0 znY!5>Sku(LP5rqUCk%7U^9wdZ2l`6UW4-;eem5R~e`Qg;E@68zI#x`#IZE zT-DC)LrLi5(^&pVA;RAF~PMX|rG}aY!P7WF*y*QD` z*SLRwoGcik4WAqu#Kk+k}o7o+S`gw_t?&vHq(JaT|;Lt z>gSEa4=jt^t^iWO0T-R?huh;tWQ`SK@ek1QG6!@X_olDIQ)^_4FPuKJR4K{txdEzX zRi(H4hWZCx3ahX3$7vf+!#<-Y)g6lFe~jTZ7cVJozjx81n=Tj(5%~igk-mSXm zspMJi#h9zJ@{)jS`kC7H)6*aB-qwcG=;u}K_~|8oZ<0thZ1XHO%04yv`BJd^0TK6% zac-DTu3@;en`+effxC5~h99wSgh%UQE_BH~3>OuCkfy^eKCBtOwtYzZHR=H0W_uJ; ziVvU&_`H2KGufwkFddL9a=naxz8~@yndXhvKOuNZ5kmq10Zsnba*_TMZ+3PK8=r@T z@Z-gRQYwb1n8N*(#O)WO!t%fzu z$(r1dX;E{+Iur%KrIjJjHYeH@5FQ_bp_uUCU+rK}{kcu+nZc)G{};!f2MR zS;oa~l-zC{dxKxCD`<- z;xM#1D^uPr`3(xJxR?Wd9<{S_u+USPHIq33rBe=qYUsA&Ymj8SMkBZ0m4kl_#V>EV zLcy1cR&v;K**(MAGe4F!-O5gXUA#j>KbBOOq0IjO=1S|9g!*B4KY#%c_wSGcK-yrf JIt@Gc{{RlH+F}3z diff --git a/DeepLinkDemo/DeepLinkDemo/Base.lproj/Main.storyboard b/DeepLinkDemo/DeepLinkDemo/Base.lproj/Main.storyboard deleted file mode 100644 index 7c5844536..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Base.lproj/Main.storyboard +++ /dev/null @@ -1,2685 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/DeepLinkDemo/DeepLinkDemo/Constants/CommonAlert.swift b/DeepLinkDemo/DeepLinkDemo/Constants/CommonAlert.swift deleted file mode 100644 index feb4c06e4..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Constants/CommonAlert.swift +++ /dev/null @@ -1,22 +0,0 @@ - -import UIKit - -class CommonAlert { - - static let shared = CommonAlert() - - func showActionAlertView(title:String,message:String,actions:[UIAlertAction],preferredStyle:UIAlertController.Style = .alert,viewController:UIViewController?) -> Void { - let alertController = UIAlertController(title: title, message:message, preferredStyle: preferredStyle) - if actions.isEmpty { - alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action: UIAlertAction!) in - viewController?.dismiss(animated: true, completion: nil) - })) - }else{ - for action in actions { - alertController.addAction(action) - } - } - - viewController?.present(alertController, animated: true, completion: nil) - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Constants/CommonMethod.swift b/DeepLinkDemo/DeepLinkDemo/Constants/CommonMethod.swift deleted file mode 100644 index de52c755b..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Constants/CommonMethod.swift +++ /dev/null @@ -1,59 +0,0 @@ -// CommonMethod.swift -// DeepLinkDemo -// Created by Rakesh kumar on 4/18/22. - - -import Foundation -import UIKit -import BranchSDK -import SystemConfiguration - - -class CommonMethod { - - static let sharedInstance = CommonMethod() - var branchUniversalObject = BranchUniversalObject() - var linkProperties = BranchLinkProperties() - var contentMetaData : BranchContentMetadata? = nil - - var branchData = [String: AnyObject]() - - func navigatetoContent(onCompletion:@escaping (NSDictionary?) -> Void) -> Void { - guard let data = branchData as? [String: AnyObject] else { return } - onCompletion(data as NSDictionary) - } - - func showActionAlertView(title:String,message:String,actions:[UIAlertAction],preferredStyle:UIAlertController.Style = .alert,viewController:UIViewController?) -> Void { - let alertController = UIAlertController(title: title, message:message, preferredStyle: preferredStyle) - if actions.isEmpty { - alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action: UIAlertAction!) in - viewController?.dismiss(animated: true, completion: nil) - - })) - } else { - for action in actions { - alertController.addAction(action) - } - } - } - - func isInternetAvailable() -> Bool { - var zeroAddress = sockaddr_in() - zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress)) - zeroAddress.sin_family = sa_family_t(AF_INET) - let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) { - $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in - SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress) - } - } - - var flags = SCNetworkReachabilityFlags() - - if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) { - return false - } - let isReachable = flags.contains(.reachable) - let needsConnection = flags.contains(.connectionRequired) - return (isReachable && !needsConnection) - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Constants/Utils.swift b/DeepLinkDemo/DeepLinkDemo/Constants/Utils.swift deleted file mode 100644 index b0182457b..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Constants/Utils.swift +++ /dev/null @@ -1,87 +0,0 @@ -// -// Utils.swift -// DeepLinkDemo -// -// Created by Apple on 24/05/22. -// - -import Foundation -import UIKit - -class Utils: NSObject { - - static let shared = Utils() - var logFileName: String? - var prevCommandLogFileName: String? - - func clearAllLogFiles(){ - - let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! - - do { - let fileURLs = try FileManager.default.contentsOfDirectory(at: documentsUrl, - includingPropertiesForKeys: nil, - options: .skipsHiddenFiles) - for fileURL in fileURLs { - try FileManager.default.removeItem(at: fileURL) - } - } catch { - NSLog("Failed to delete the file %@", error.localizedDescription) - } - - } - - - func removeItem(_ relativeFilePath: String) { - guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return } - let absoluteFilePath = documentsDirectory.appendingPathComponent(relativeFilePath) - try? FileManager.default.removeItem(at: absoluteFilePath) - } - - func setLogFile(_ fileName: String?) { - if fileName == nil { - logFileName = nil - return - } - let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).map(\.path)[0] - let pathForLog = "\(documentsDirectory)/\(fileName ?? "app").log" - self.removeItem(pathForLog) - if (logFileName == nil) { - logFileName = pathForLog - prevCommandLogFileName = logFileName - } else { - prevCommandLogFileName = logFileName - logFileName = pathForLog - } - let cstr = (pathForLog as NSString).utf8String - freopen(cstr, "a+", stderr) - - } - - func printLogMessage(_ message: String) { - objc_sync_enter(self) - do { - print(message) // print to console - - if !FileManager.default.fileExists(atPath: logFileName!) { // does it exits? - FileManager.default.createFile(atPath: logFileName!, contents: nil) - } - - if let data = message.data(using: .utf8) { - let fileHandle = try FileHandle(forWritingTo: URL(fileURLWithPath: logFileName!)) - if #available(iOS 13.4, *) { - print(" ============= ********** Writing in file " + logFileName!) - try fileHandle.seekToEnd() - try fileHandle.write(contentsOf: data) - try fileHandle.close() - } else { - print("Unable to write log: iOS Version not supported") - } - } - } catch let error as NSError { // something wrong - print("Unable to write log: \(error.debugDescription)") // debug printout - } - objc_sync_exit(self) - } -} - diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/AddMetaDataVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/AddMetaDataVC.swift deleted file mode 100644 index 76884a790..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/AddMetaDataVC.swift +++ /dev/null @@ -1,117 +0,0 @@ -// -// AddMetaDataVC.swift -// DeepLinkDemo -// -// Created by Apple on 13/05/22. -// - -import UIKit -import BranchSDK - -class AddMetaDataVC: ParentViewController { - - @IBOutlet weak var metaDataTblVw: UITableView! - private var reachability:Reachability? - override func viewDidLoad() { - super.viewDidLoad() - - self.metaDataTblVw.keyboardDismissMode = .onDrag - reachabilityCheck() - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - Utils.shared.setLogFile("AddMetadata") - } - - - @IBAction func backBtnAction(){ - self.navigationController?.popToRootViewController(animated: true) - } - - @objc func submitBtnAction(){ - if let cell = metaDataTblVw.cellForRow(at: IndexPath(row: 0, section: 0)) as? MetaDataTableViewCell{ - -// let branchUniversalObject = CommonMethod.sharedInstance.branchUniversalObject -// branchUniversalObject.canonicalIdentifier = branchUniversalObject.canonicalIdentifier -// branchUniversalObject.canonicalUrl = "https://branch.io/item/12345" -// branchUniversalObject.title = branchUniversalObject.title - let contentMetadata = BranchContentMetadata() - let contentSchemaSelected : BranchContentSchema = BranchContentSchema(rawValue: cell.contentSchema.text!) - contentMetadata.contentSchema = contentSchemaSelected - let quantityEntered = Double(cell.quantity.text ?? "0") - contentMetadata.quantity = quantityEntered ?? 0 - let formattedPrice = NSDecimalNumber(string: cell.price.text ?? "0.0") - if cell.price.text != "" { - contentMetadata.price = formattedPrice - let currencySelected: BNCCurrency = BNCCurrency(rawValue: cell.currencyName.text!) - contentMetadata.currency = currencySelected - } - contentMetadata.sku = cell.sku.text - contentMetadata.productName = cell.productName.text - contentMetadata.productBrand = cell.productBrand.text - let productCategorySelected: BNCProductCategory = BNCProductCategory(rawValue: cell.productCategory.text!) - contentMetadata.productCategory = productCategorySelected - contentMetadata.productVariant = cell.productVariant.text - let conditionSelected: BranchCondition = BranchCondition(rawValue: cell.productCondition.text!) - contentMetadata.condition = conditionSelected - contentMetadata.customMetadata = [ - "custom_key1": cell.customMetadata.text!, - ] - contentMetadata.addressStreet = cell.street.text - contentMetadata.addressCity = cell.city.text - contentMetadata.addressRegion = cell.region.text - contentMetadata.addressCountry = cell.country.text - contentMetadata.addressPostalCode = cell.postalCode.text - - contentMetadata.latitude = Double(cell.latitude.text ?? "0.0") ?? 0.0 - contentMetadata.longitude = Double(cell.longitude.text ?? "0.0") ?? 0.0 - - contentMetadata.ratingAverage = Double(cell.averageRating.text ?? "0.0") ?? 0.0 - contentMetadata.ratingMax = Double(cell.maximumRating.text ?? "0.0") ?? 0.0 - contentMetadata.ratingCount = Int(cell.ratingCount.text ?? "0") ?? 0 - contentMetadata.rating = Double(cell.rating.text ?? "0.0") ?? 0.0 - - contentMetadata.imageCaptions = [cell.imageCaption.text ?? ""] - CommonMethod.sharedInstance.contentMetaData = contentMetadata - print("ContentMetaData:", contentMetadata) - - let metadataDetail = String(format: "%@", contentMetadata) - NSLog("Metadata", metadataDetail); - Utils.shared.setLogFile("AddMetadata") - - self.navigationController?.popViewController(animated: true) - } - } - -} - -extension AddMetaDataVC: UITableViewDataSource, UITableViewDelegate{ - func numberOfSections(in tableView: UITableView) -> Int { - return 1 - } - - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return 1 - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - if let cell = tableView.dequeueReusableCell(withIdentifier: "MetaDataTableViewCell", for: indexPath) as? MetaDataTableViewCell{ - cell.submitBtn.addTarget(self, action: #selector(submitBtnAction), for: UIControl.Event.touchUpInside) - cell.pickerDelegate = self - return cell - } - return UITableViewCell() - } - - func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - return UITableView.automaticDimension - } -} - - -extension AddMetaDataVC: PickerViewDelegate{ - func removePickerView() { - self.view.endEditing(true) - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/CreateObjectReferenceObject.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/CreateObjectReferenceObject.swift deleted file mode 100644 index 061f256d1..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/CreateObjectReferenceObject.swift +++ /dev/null @@ -1,268 +0,0 @@ -// CreateObjectReferenceObject.swift -// DeepLinkDemo -// Created by Rakesh kumar on 4/19/22. - -import UIKit -import BranchSDK - - -class CreateObjectReferenceObject: ParentViewController { - @IBOutlet weak var txtFldContentTitle: UITextField! - @IBOutlet weak var txtFldCanonicalIdentifier: UITextField! - @IBOutlet weak var txtFldDescription: UITextField! - @IBOutlet weak var txtFldImageUrl: UITextField! - @IBOutlet weak var scrollViewMain: UIScrollView! - - var screenMode = 0 - var txtFldValue = "" - var responseStatus = "" - - enum ScreenMode { - static let createBUO = 0 - static let readdeeplink = 1 - static let sharedeeplink = 2 - static let navigatetoContent = 3 - static let handlLinkinWebview = 4 - static let createdeeplink = 5 - static let sendnotification = 6 - static let trackContent = 7 - static let displayContent = 8 - } - - override func viewDidLoad() { - super.viewDidLoad() - - uiSetUp() - - super.reachabilityCheck() - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - if self.screenMode == ScreenMode.trackContent { - Utils.shared.setLogFile("TrackContent") - } - else { - Utils.shared.setLogFile("CreateBUO") - } - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - scrollViewMain.contentSize.height = scrollViewMain.subviews.sorted(by: { $0.frame.maxY < $1.frame.maxY }).last?.frame.maxY ?? scrollViewMain.contentSize.height - } - - @IBAction func backAction(_ sender: Any) { - self.navigationController?.popToRootViewController(animated: true) - } - - @objc func addMetaDataAction(sender: UIButton) { - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "AddMetaDataVC") as? AddMetaDataVC { - self.navigationController?.pushViewController(vc, animated: true) - } - } - fileprivate func handleOkBtnAction(dict : [String:Any], alertMessage: String) { - Utils.shared.setLogFile("CreateBUO") - if self.screenMode == ScreenMode.displayContent { - launchGenerateURLVC(dict: dict, displayContent: true) - }else if self.screenMode == ScreenMode.trackContent { - NSLog("screenMode:", self.screenMode) - launchGenerateURLVC(dict: dict, message: alertMessage, TrackContent: true) - }else if self.screenMode == ScreenMode.sendnotification { - NSLog("screenMode:", self.screenMode) - launchGenerateURLVC(dict: dict, forNotification: true) - }else if self.screenMode == ScreenMode.createdeeplink { - NSLog("screenMode:", self.screenMode) - launchGenerateURLVC(dict: dict, CreateDeepLink: true) - }else if self.screenMode == ScreenMode.sharedeeplink { - NSLog("screenMode:", self.screenMode) - launchGenerateURLVC(dict: dict, ShareDeepLink: true) - }else if self.screenMode == ScreenMode.readdeeplink { - NSLog("screenMode:", self.screenMode) - launchGenerateURLVC(dict: dict) - }else if self.screenMode == ScreenMode.navigatetoContent { - NSLog("screenMode:", self.screenMode) - launchGenerateURLVC(dict: dict, NavigateToContent: true) - }else if self.screenMode == ScreenMode.handlLinkinWebview { - NSLog("screenMode:", self.screenMode) - launchGenerateURLVC(dict: dict, handleLinkInWebview: true) - }else { - self.navigationController?.popToRootViewController(animated: true) - } - } - - func launchGenerateURLVC(dict: [String:Any], message: String? = "", ShareDeepLink: Bool? = false, displayContent: Bool? = false, NavigateToContent: Bool? = false, TrackContent: Bool? = false, handleLinkInWebview: Bool? = false, CreateDeepLink: Bool? = false, forNotification: Bool? = false) { - if self.screenMode == ScreenMode.trackContent { - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "TextViewController") as? TextViewController { - vc.isTrackContent = TrackContent! - vc.forNotification = forNotification! - vc.isCreateDeepLink = CreateDeepLink! - vc.isShareDeepLink = ShareDeepLink! - vc.isNavigateToContent = NavigateToContent! - vc.handleLinkInWebview = handleLinkInWebview! - vc.isDisplayContent = displayContent! - vc.dictData = dict - vc.textViewText = message! - vc.responseStatus = self.responseStatus - self.navigationController?.pushViewController(vc, animated: true) - } - } else { - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "GenerateURLVC") as? GenerateURLVC { - vc.isTrackContent = TrackContent! - vc.forNotification = forNotification! - vc.isCreateDeepLink = CreateDeepLink! - vc.isShareDeepLink = ShareDeepLink! - vc.isNavigateToContent = NavigateToContent! - vc.handleLinkInWebview = handleLinkInWebview! - vc.isDisplayContent = displayContent! - vc.dictData = dict - self.navigationController?.pushViewController(vc, animated: true) - } - } - } - - @objc func submitAction(sender : UIButton) { - - self.view.endEditing(true) - CommonMethod.sharedInstance.branchUniversalObject = BranchUniversalObject(canonicalIdentifier: txtFldCanonicalIdentifier.text!) - CommonMethod.sharedInstance.branchUniversalObject.title = txtFldContentTitle.text! - CommonMethod.sharedInstance.branchUniversalObject.contentDescription = txtFldDescription.text! - CommonMethod.sharedInstance.branchUniversalObject.imageUrl = txtFldImageUrl.text! - let linkProperties = BranchLinkProperties() - - - var dict = [String:Any]() - dict["$canonicalIdentifier"] = txtFldCanonicalIdentifier.text! - dict["title"] = txtFldContentTitle.text! - dict["description"] = txtFldDescription.text! - dict["imgurl"] = txtFldImageUrl.text! - - CommonMethod.sharedInstance.branchUniversalObject.locallyIndex = true - CommonMethod.sharedInstance.branchUniversalObject.publiclyIndex = true - if CommonMethod.sharedInstance.contentMetaData != nil { - CommonMethod.sharedInstance.branchUniversalObject.contentMetadata = CommonMethod.sharedInstance.contentMetaData! - } - print("universalObject:", CommonMethod.sharedInstance.branchUniversalObject) - NSLog("CommonMethod.sharedInstance.branchUniversalObject:",CommonMethod.sharedInstance.branchUniversalObject) - - if self.screenMode == ScreenMode.trackContent { - let selectedEvent: BranchStandardEvent = BranchStandardEvent(rawValue: txtFldValue) - BranchEvent.standardEvent(selectedEvent, withContentItem: CommonMethod.sharedInstance.branchUniversalObject).logEvent {[weak self] isLogged, loggingErr in - if isLogged { - self?.responseStatus = "Success" - NSLog("BranchEvent Logged") - Utils.shared.setLogFile("TrackContent") - - DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) { - //AJAY - let alertMessage = self?.getAPIDetailFromLogFile(fileName: "TrackContent.log") - - self?.handleOkBtnAction(dict: dict, alertMessage: alertMessage ?? "") - } - }else{ - NSLog("BranchEvent failed to log \(loggingErr?.localizedDescription ?? "NA")") - } - } - - } - else { - CommonMethod.sharedInstance.branchUniversalObject.listOnSpotlight(with: linkProperties) { (url, error) in - if (error == nil) { - NSLog("Successfully indexed on spotlight \(url)") - } - } - let alert = UIAlertController(title: "Alert", message: "BranchUniversalObject reference created", preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in - UserDefaults.standard.set("buo", forKey: "isStatus") - UserDefaults.standard.set(true, forKey: "isCreatedBUO") - self.handleOkBtnAction(dict: dict, alertMessage: "") - })) - self.present(alert, animated: true, completion: nil) - } - } - - private func loadTextWithFileName(_ fileName: String) -> String? { - if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first { - let fileURL = dir.appendingPathComponent(fileName) - guard let text = try? String(contentsOf: fileURL, encoding: .utf8) else { - return nil - } - return text - } - return nil - } - - fileprivate func getAPIDetailFromLogFile(fileName: String) -> String{ - var alertMessage = "LogFilePath : \(self.getLogFilepath(fileName)!) \n\n" - alertMessage = alertMessage + "\n\n" - if let fileContent = self.loadTextWithFileName(fileName), !fileContent.isEmpty { - - if let startlocation = fileContent.range(of: "BranchSDK API LOG START OF FILE"),let endlocation = fileContent.range(of: "BranchSDK API LOG END OF FILE"){ - let apiResponse = fileContent[startlocation.lowerBound.. String? { - let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first - let fileURL = dir?.appendingPathComponent(fileName) - let fileURLStr = fileURL?.path - return fileURLStr - } -} - -extension CreateObjectReferenceObject { - func uiSetUp() { - - let addMetaDataBtn = UIButton(frame: CGRect(x: self.view.frame.width/2-90, y: txtFldImageUrl.frame.maxY+30, width: 180, height: 55)) - addMetaDataBtn.setTitle("Add Metadata", for: .normal) - addMetaDataBtn.backgroundColor = UIColor(red: 89.0/255.0, green: 12.0/255.0, blue: 228.0/255.0, alpha: 1.0) - addMetaDataBtn.layer.cornerRadius = 8 - addMetaDataBtn.setTitleColor(UIColor.white, for: .normal) - addMetaDataBtn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 22.0) - addMetaDataBtn.addTarget(self, action: #selector(addMetaDataAction), for: .touchUpInside) - scrollViewMain.addSubview(addMetaDataBtn) - - let submitBtn = UIButton(frame: CGRect(x: self.view.frame.width/2-60, y: addMetaDataBtn.frame.maxY+30, width: 120, height: 55)) - submitBtn.setTitle("Submit", for: .normal) - submitBtn.backgroundColor = UIColor(red: 89.0/255.0, green: 12.0/255.0, blue: 228.0/255.0, alpha: 1.0) - submitBtn.layer.cornerRadius = 8 - submitBtn.setTitleColor(UIColor.white, for: .normal) - submitBtn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 22.0) - submitBtn.addTarget(self, action: #selector(self.submitAction), for: .touchUpInside) - scrollViewMain.addSubview(submitBtn) - - - txtFldContentTitle.setLeftPaddingPoints(10) - txtFldDescription.setLeftPaddingPoints(10) - txtFldImageUrl.setLeftPaddingPoints(10) - txtFldCanonicalIdentifier.setLeftPaddingPoints(10) - txtFldCanonicalIdentifier.attributedPlaceholder = NSAttributedString( - string: "Canonical Identifier", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - - txtFldContentTitle.attributedPlaceholder = NSAttributedString( - string: "Content Title", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - - txtFldDescription.attributedPlaceholder = NSAttributedString( - string: "Content Description", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldImageUrl.attributedPlaceholder = NSAttributedString( - string: "Image URL", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/DispalyVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/DispalyVC.swift deleted file mode 100644 index b98f2ccab..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/DispalyVC.swift +++ /dev/null @@ -1,60 +0,0 @@ -// -// DispalyVC.swift -// DeepLinkDemo -// -// Created by Rakesh kumar on 4/26/22. -// - -import UIKit -import BranchSDK - -class DispalyVC: ParentViewController { - - @IBOutlet weak var pageTitle: UILabel! - - @IBOutlet weak var textViewDescription: UITextView! - - var textDescription = "" - var linkURL = "" - var appData : Dictionary = Dictionary() - private var reachability:Reachability? - override func viewDidLoad() { - super.viewDidLoad() - - debugPrint("textDescription", textDescription) - - if appData["nav_to"] is String { - self.pageTitle.text = "Navigate To Content" - let content = String(format:"\nReferring link: %@ \n\nSession Details:\n %@", linkURL, appData.jsonStringRepresentation!) - self.textViewDescription.text = content - } else if appData["display_Cont"] is String { - self.pageTitle.text = "Display Content" - let content = String(format:"\nReferring link: %@ \n\nSession Details:\n %@", linkURL, appData.jsonStringRepresentation!) - self.textViewDescription.text = content - } - else{ - self.pageTitle.text = "Read Deep Linking" - self.textViewDescription.text = String(format:"%@", textDescription) - } - - reachabilityCheck() - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - if appData["nav_to"] is String { - Utils.shared.setLogFile("NavigateContentDetail") - } else if appData["display_Cont"] is String { - Utils.shared.setLogFile("DisplayContentDetail") - } else { - Utils.shared.setLogFile("ReadDeepLinkingDetail") - } - } - - - - @IBAction func backAction(_ sender: Any) { - self.navigationController?.popToRootViewController(animated: true) - } - -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/GenerateURLVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/GenerateURLVC.swift deleted file mode 100644 index a1db4f8f6..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/GenerateURLVC.swift +++ /dev/null @@ -1,257 +0,0 @@ -// -// GenerateURLVC.swift -// DeepLinkDemo -// Created by Rakesh kumar on 4/19/22. - -import UIKit -import BranchSDK -class GenerateURLVC: ParentViewController { - @IBOutlet weak var txtFldCChannel: UITextField! - @IBOutlet weak var txtFldFeature: UITextField! - @IBOutlet weak var txtFldChampaignName: UITextField! - @IBOutlet weak var txtFldStage: UITextField! - @IBOutlet weak var txtFldDeskTopUrl: UITextField! - @IBOutlet weak var txtFldAndroidUrl: UITextField! - @IBOutlet weak var txtFldiOSTopUrl: UITextField! - @IBOutlet weak var txtFldAdditionalData: UITextField! - @IBOutlet weak var scrollViewMain: UIScrollView! - - var responseStatus = "" - var screenMode = 0 - - var dictData = [String:Any]() - - var isShareDeepLink = false - - var isDisplayContent = false - - var isNavigateToContent = false - - var isTrackContent = false - - var handleLinkInWebview = false - - var isCreateDeepLink = false - - var forNotification = false - - override func viewDidLoad() { - super.viewDidLoad() - uiSetUp() - - NSLog("dictData", dictData) - super.reachabilityCheck() - } - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - scrollViewMain.contentSize.height = scrollViewMain.subviews.sorted(by: { $0.frame.maxY < $1.frame.maxY }).last?.frame.maxY ?? scrollViewMain.contentSize.height - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - Utils.shared.setLogFile("CreateDeeplink") - } - - - @IBAction func backAction(_ sender: Any) { - self.navigationController?.popToRootViewController(animated: true) - } - - func fireLocalNotification(linkurl: String){ - let dict = [ - "aps": [ - "alert":[ - "title":"Hi", - "body":"Hi, How Are You Dear" - ] - ], - "mutable-content" : false, - "branch": "\(linkurl)" - ] as [String : Any] - let notification = UILocalNotification() - notification.fireDate = Date(timeIntervalSinceNow: 1) - notification.alertBody = "Notification for handling deeplink" - notification.alertAction = "TestBed App" - notification.soundName = UILocalNotificationDefaultSoundName - notification.userInfo = dict - UIApplication.shared.scheduleLocalNotification(notification) - // sleep(2) - // self.navigationController?.popToRootViewController(animated: true) - } - - fileprivate func processShortURLGenerated(_ url: String?) { - NSLog("Check out my ShortUrl!! \(url ?? "")") - Utils.shared.setLogFile("CreateDeeplink") - let alertMessage = self.getAPIDetailFromLogFile("CreateDeeplink.log") - DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) { - UserDefaults.standard.set("createdeeplinking", forKey: "isStatus") - UserDefaults.standard.set(true, forKey: "isCreatedDeepLink") - UserDefaults.standard.set("\(url ?? "")", forKey: "link") - if self.forNotification == true { - self.fireLocalNotification(linkurl: "\(url ?? "")") - self.launchTextViewController(url: "\(url ?? "")", message: alertMessage, forNotification: true) - }else if self.isShareDeepLink == true { - let bsl = BranchShareLink(universalObject: CommonMethod.sharedInstance.branchUniversalObject, linkProperties: CommonMethod.sharedInstance.linkProperties) - if #available(iOS 13.0, *) { - let metaData: LPLinkMetadata = LPLinkMetadata() - let iconImage = UIImage(named: "qentelli_logo") - metaData.iconProvider = NSItemProvider(object: iconImage!) - metaData.title = "Share Deeplink from the app" - metaData.url = URL(string: "\(url ?? "")") - bsl.lpMetaData = metaData - } - bsl.presentActivityViewController(from: self, anchor: nil) - } else if self.isTrackContent == true { - self.launchTextViewController(url: "\(url ?? "")", message: alertMessage, TrackContentWeb: true) - } else if self.isNavigateToContent == true { - self.launchTextViewController(url: "\(url ?? "")", message: alertMessage, NavigateToContent: true) - } else if self.isDisplayContent == true { - self.launchTextViewController(url: "\(url ?? "")", message: alertMessage, displayContent: true) - } else if self.handleLinkInWebview == true { - self.launchTextViewController(url: "\(url ?? "")", message: alertMessage, handleLinkInWebview: true) - } else if self.isCreateDeepLink == true{ - self.launchTextViewController(url: "\(url ?? "")", message: alertMessage, CreateDeepLink: true) - } else { - self.launchTextViewController(url: "\(url ?? "")", message: alertMessage) - } - } - } - - func launchTextViewController(url: String? = "",message: String? = "", ShareDeepLink: Bool? = false, displayContent: Bool? = false, NavigateToContent: Bool? = false, TrackContent: Bool? = false, TrackContentWeb: Bool? = false, handleLinkInWebview: Bool? = false, CreateDeepLink: Bool? = false, forNotification: Bool? = false) { - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "TextViewController") as? TextViewController { - vc.isTrackContent = TrackContent! - vc.forNotification = forNotification! - vc.isCreateDeepLink = CreateDeepLink! - vc.isShareDeepLink = ShareDeepLink! - vc.isNavigateToContent = NavigateToContent! - vc.handleLinkInWebview = handleLinkInWebview! - vc.isDisplayContent = displayContent! - vc.isTrackContenttoWeb = TrackContentWeb! - vc.textViewText = message ?? "" - vc.responseStatus = self.responseStatus - vc.url = url ?? "" - self.navigationController?.pushViewController(vc, animated: true) - } - } - - private func loadTextWithFileName(_ fileName: String) -> String? { - if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first { - let fileURL = dir.appendingPathComponent(fileName) - guard let text = try? String(contentsOf: fileURL, encoding: .utf8) else { - return nil - } - return text - } - return nil - } - - fileprivate func getAPIDetailFromLogFile(_ fileName: String) -> String{ - var alertMessage = "LogFilePath : \(self.getLogFilepath(fileName)!) \n\n" - alertMessage = alertMessage + "\n\n" - if let fileContent = self.loadTextWithFileName(fileName), !fileContent.isEmpty { - let startlocation = fileContent.range(of: "BranchSDK API LOG START OF FILE") - let endlocation = fileContent.range(of: "BranchSDK API LOG END OF FILE") - if ((startlocation?.lowerBound != startlocation?.upperBound) && (endlocation?.lowerBound != endlocation?.upperBound)){ - let apiResponse = fileContent[startlocation!.lowerBound.. String? { - let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first - let fileURL = dir?.appendingPathComponent(fileName) - let fileURLStr = fileURL?.path - return fileURLStr - } - - @IBAction func submitAction(sender : UIButton) { - self.view.endEditing(true) - let linkProperties = BranchLinkProperties() - linkProperties.feature = txtFldFeature.text - linkProperties.channel = txtFldCChannel.text - linkProperties.campaign = txtFldChampaignName.text - linkProperties.stage = txtFldStage.text - linkProperties.addControlParam("$desktop_url", withValue: txtFldDeskTopUrl.text) - linkProperties.addControlParam("$ios_url", withValue: txtFldiOSTopUrl.text) - linkProperties.addControlParam("$android_url", withValue: txtFldAndroidUrl.text) - linkProperties.addControlParam("custom", withValue: txtFldAdditionalData.text) - if isNavigateToContent == true { - linkProperties.addControlParam("nav_to", withValue: "landing_page") - } else if isDisplayContent == true { - linkProperties.addControlParam("display_Cont", withValue: "landing_page") - } - - - CommonMethod.sharedInstance.branchUniversalObject.getShortUrl(with: linkProperties, andCallback: {[weak self] url, error in - - if error == nil { - self?.responseStatus = "Success" - self?.processShortURLGenerated(url) - } else { - self?.responseStatus = "Failure" - } - }) - - - } - -} - -extension GenerateURLVC { - func uiSetUp() { - let submitBtn = UIButton(frame: CGRect(x: self.view.frame.width/2-60, y: txtFldAdditionalData.frame.maxY+15, width: 120, height: 55)) - submitBtn.setTitle("Submit", for: .normal) - submitBtn.backgroundColor = UIColor(red: 89.0/255.0, green: 12.0/255.0, blue: 228.0/255.0, alpha: 1.0) - submitBtn.layer.cornerRadius = 8 - submitBtn.setTitleColor(UIColor.white, for: .normal) - submitBtn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 22.0) - submitBtn.addTarget(self, action: #selector(self.submitAction), for: .touchUpInside) - scrollViewMain.addSubview(submitBtn) - - txtFldCChannel.setLeftPaddingPoints(10) - txtFldFeature.setLeftPaddingPoints(10) - txtFldChampaignName.setLeftPaddingPoints(10) - txtFldStage.setLeftPaddingPoints(10) - txtFldDeskTopUrl.setLeftPaddingPoints(10) - txtFldAdditionalData.setLeftPaddingPoints(10) - txtFldAndroidUrl.setLeftPaddingPoints(10) - txtFldiOSTopUrl.setLeftPaddingPoints(10) - - txtFldCChannel.attributedPlaceholder = NSAttributedString( - string: "Channel name like Facebook", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldFeature.attributedPlaceholder = NSAttributedString( - string: "Feature eg: Sharing", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldChampaignName.attributedPlaceholder = NSAttributedString( - string: "Campaign name", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldStage.attributedPlaceholder = NSAttributedString( - string: "Stage", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldDeskTopUrl.attributedPlaceholder = NSAttributedString( - string: "Desktop URL", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldAndroidUrl.attributedPlaceholder = NSAttributedString( - string: "Android URL", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldiOSTopUrl.attributedPlaceholder = NSAttributedString( - string: "iOS URL", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldAdditionalData.attributedPlaceholder = NSAttributedString( - string: "Additional Data", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/HomeViewController.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/HomeViewController.swift deleted file mode 100644 index b4880dce9..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/HomeViewController.swift +++ /dev/null @@ -1,452 +0,0 @@ -// ViewController.swift -// DeepLinkDemo -// Created by Rakesh kumar on 4/15/22 - -import UIKit -import BranchSDK -class HomeViewController: UITableViewController { - private var reachability:Reachability? - - @IBOutlet weak var btnCreatBUO: UIButton! - @IBOutlet weak var btnTrackingEnabled: UIButton! - @IBOutlet weak var btnCreateDeepLinking: UIButton! - @IBOutlet weak var btnShareLink: UIButton! - @IBOutlet weak var btnSendNotification: UIButton! - @IBOutlet weak var btnTrackUser: UIButton! - @IBOutlet weak var btnLoadWebView: UIButton! - @IBOutlet weak var btReadDeeplink: UIButton! - @IBOutlet weak var btnTrackContent: UIButton! - @IBOutlet weak var btnNavigateToContent: UIButton! - @IBOutlet weak var btnDisplayContent: UIButton! - @IBOutlet weak var btnReadLog: UIButton! - @IBOutlet weak var btnSetDMAParams: UIButton! - @IBOutlet weak var btnSendV2Event: UIButton! - @IBOutlet weak var btnSetAttributionLevel: UIButton! - - @IBOutlet weak var switchControl: UISwitch! - - @IBOutlet weak var labelStatus: UILabel! - - let branchObj:Branch! = nil - var logData: String! = "" - var branchSDKInitialized = false; - - override func viewDidLoad() { - super.viewDidLoad() - - btnTrackingEnabled.layer.cornerRadius = 8.0 - btnCreatBUO.layer.cornerRadius = 8.0 - btnCreateDeepLinking.layer.cornerRadius = 8.0 - btnShareLink.layer.cornerRadius = 8.0 - btnShareLink.layer.cornerRadius = 8.0 - btnTrackUser.layer.cornerRadius = 8.0 - btnSendNotification.layer.cornerRadius = 8.0 - btReadDeeplink.layer.cornerRadius = 8.0 - btnTrackContent.layer.cornerRadius = 8.0 - btnNavigateToContent.layer.cornerRadius = 8.0 - btnReadLog.layer.cornerRadius = 8.0 - btnLoadWebView.layer.cornerRadius = 8.0 - btnSetDMAParams.layer.cornerRadius = 8.0 - btnSendV2Event.layer.cornerRadius = 8.0 - btnSetAttributionLevel.layer.cornerRadius = 8.0 - - NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil) - - reachabilityCheck(textValue:"") - - if Branch.trackingDisabled(){ - switchControl.isOn = false - }else{ - switchControl.isOn = true - } - - btnReadLog.isHidden = true - - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - Utils.shared.setLogFile("Homepage") - } - - func reachabilityCheck(textValue:String?) { - CommonMethod.sharedInstance.contentMetaData = nil - reachability = Reachability()! - reachability!.whenReachable = { reachability in - Branch.setBranchKey("key_test_om2EWe1WBeBYmpz9Z1mdpopouDmoN72T") - DispatchQueue.main.async { - if textValue == "displayContent" { - self.initBranch() - self.launchBUOVC(mode: 8) - } else if textValue == "navigatetoContent" { - self.initBranch() - self.launchBUOVC(mode: 3) - } else if textValue == "sendNotification" { - self.initBranch() - self.launchBUOVC(mode: 6) - } else if textValue == "loadUrlInWeb" { - self.initBranch() - self.launchBUOVC(mode: 4) - } else if textValue == "createDeep" { - self.initBranch() - self.launchBUOVC(mode: 5) - } else if textValue == "shareDeeplinking" { - self.initBranch() - self.launchBUOVC(mode: 2) - } else if textValue == "readDeeplinking" { - self.initBranch() - self.launchBUOVC(mode: 1) - } else if textValue == "trackContent" { - self.initBranch() - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "TrackContentVC") as? TrackContentVC { - self.navigationController?.pushViewController(vc, animated: true) - } - } else if textValue == "trackUser" { - self.initBranch() - Branch.getInstance().setIdentity("qentelli_test_user") { params, error in - - if let referringParams = params as? [String :AnyObject] { - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "TextViewController") as? TextViewController { - vc.isTrackUser = true - vc.textViewText = "Result \(referringParams)" - vc.responseStatus = "Success" - self.navigationController?.pushViewController(vc, animated: true) - } - }else{ - NSLog("track user error--> \(error!.localizedDescription)") - } - } - } else if textValue == "swichAction" { - - } else if textValue == "createObject" { - self.initBranch() - self.launchBUOVC(mode: 0) - } else if textValue == "readSystemLog" { - self.initBranch() - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "LogFileListViewController") as? LogFileListViewController { - self.navigationController?.pushViewController(vc, animated: true) - } - } else if textValue == "setDMAParams" { - self.setDMAParamsWrapper() - } else if textValue == "sendV2Event" { - self.sendV2EventWrapper() - } else if textValue == "setAttributionLevel" { - self.setAttributionLevelWrapper() - } - } - } - - reachability?.whenUnreachable = { reachability in - DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) { - self.networkError() - } - } - do { - try reachability?.startNotifier() - } catch { - NSLog("Unable to start notifier") - } - } - func launchBUOVC(mode: Int) { - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "CreateObjectReferenceObject") as? CreateObjectReferenceObject { - vc.screenMode = mode - self.navigationController?.pushViewController(vc, animated: true) - } - } - - func networkError() { - CommonAlert.shared.showActionAlertView(title: "Failure", message: "Your internet/network connection appears to be offline. Please check your internet/network connection.", actions: [], preferredStyle: .alert, viewController: self) - } - - func enableBranchLogging(callback: @escaping BranchLogCallback){ - Branch.enableLogging(at: .verbose, withCallback: callback) - } - - func initBranch(){ - if branchSDKInitialized { - return - } - self.enableBranchLogging(){(message:String, loglevel:BranchLogLevel, error:Error?)->() in - if (message.contains("BranchSDK")){ - self.logData = self.logData + message + "\n" - Utils.shared.printLogMessage(message + "\n") - } - } - AppDelegate.shared.getBranchData(AppDelegate.shared.launchOption) - branchSDKInitialized = true - } - - func logEvent(){ - let event = BranchEvent.standardEvent(.purchase) - // Add a populated `BranchUniversalObject` to the event - let buo = BranchUniversalObject(canonicalIdentifier: "item/12345") - event.contentItems = [ buo ] - // Add additional event data - event.alias = "my custom alias" - event.transactionID = "12344555" - event.eventDescription = "event_description" - event.searchQuery = "item 123" - event.customData = [ - "Custom_Event_Property_Key1": "Custom_Event_Property_val1", - "Custom_Event_Property_Key2": "Custom_Event_Property_val2" - ] - // Log the event - event.logEvent() - } - - func setAttributionLevelWrapper() { - self.logData = "Error: Missing testData.\n" - - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - let vc = storyBoard.instantiateViewController(withIdentifier: "TextViewController") as? TextViewController - vc?.isSetAttributionLevel = true - - do { - let argCount = ProcessInfo.processInfo.arguments.count - if argCount >= 2 { - - for i in (1 ..< argCount) { - let data = ProcessInfo.processInfo.arguments[i].data(using: .utf8)! - - if let jsonObject = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [String:AnyObject] - { - if jsonObject["consumer_protection_attribution_level"] != nil { - let attribution_level = jsonObject["consumer_protection_attribution_level"] as! String - self.logData = "" - self.enableBranchLogging(){(msg:String,msg2:BranchLogLevel,msg3:Error?)->() in - if (msg.contains("BranchSDK")){ - self.logData = self.logData + msg + "\n" - } - vc?.updateText(msg: self.logData) - } - if(self.branchSDKInitialized){ - Branch.getInstance().resetUserSession() - } - - switch attribution_level { - case "0": - Branch.getInstance().setConsumerProtectionAttributionLevel(.full) - case "1": - Branch.getInstance().setConsumerProtectionAttributionLevel(.reduced) - case "2": - Branch.getInstance().setConsumerProtectionAttributionLevel(.minimal) - case "3": - Branch.getInstance().setConsumerProtectionAttributionLevel(.none) - default: - Branch.getInstance().setConsumerProtectionAttributionLevel(.full) - } - - AppDelegate.shared.getBranchData(AppDelegate.shared.launchOption) - self.branchSDKInitialized = true - } else { - self.logData = "Missing params from JSON Object: \n" + jsonObject.description - } - } else { - self.logData = "Bad JSON : \n" + ProcessInfo.processInfo.arguments[i] - } - } - - - } - } catch let error as NSError { - print(error) - self.logData += error.localizedDescription - } - vc?.updateText(msg: self.logData) - self.navigationController?.pushViewController(vc!, animated: true) - } - - func setDMAParamsWrapper() { - self.logData = "Error: Missing testData.\n" - - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - let vc = storyBoard.instantiateViewController(withIdentifier: "TextViewController") as? TextViewController - vc?.isSetDMAParams = true - - do { - let argCount = ProcessInfo.processInfo.arguments.count - if argCount >= 2 { - - for i in (1 ..< argCount) { - let data = ProcessInfo.processInfo.arguments[i].data(using: .utf8)! - - if let jsonObject = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [String:AnyObject] - { - if ((jsonObject["dma_eea"] != nil) && (jsonObject["dma_eea"] != nil) && (jsonObject["dma_eea"] != nil)) { - let dma_eea = jsonObject["dma_eea"] as! Bool - let dma_ad_personalization = jsonObject["dma_ad_personalization"] as! Bool - let dma_ad_user_data = jsonObject["dma_ad_user_data"] as! Bool - self.logData = "" - self.enableBranchLogging(){(msg:String,msg2:BranchLogLevel,msg3:Error?)->() in - if (msg.contains("BranchSDK")){ - self.logData = self.logData + msg + "\n" - } - vc?.updateText(msg: self.logData) - } - if(self.branchSDKInitialized){ - Branch.getInstance().resetUserSession() - } - - Branch.setDMAParamsForEEA(dma_eea, adPersonalizationConsent: dma_ad_personalization, adUserDataUsageConsent: dma_ad_user_data) - AppDelegate.shared.getBranchData(AppDelegate.shared.launchOption) - self.branchSDKInitialized = true - } else { - self.logData = "Missing params from JSON Object: \n" + jsonObject.description - } - } else { - self.logData = "Bad JSON : \n" + ProcessInfo.processInfo.arguments[i] - } - } - - - } - } catch let error as NSError { - print(error) - self.logData += error.localizedDescription - } - vc?.updateText(msg: self.logData) - self.navigationController?.pushViewController(vc!, animated: true) - } - - func sendV2EventWrapper(){ - self.logData = "" - - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - let vc = storyBoard.instantiateViewController(withIdentifier: "TextViewController") as? TextViewController - - self.enableBranchLogging(){(msg:String,msg2:BranchLogLevel,msg3:Error?)->() in - if (msg.contains("BranchSDK")){ - self.logData = self.logData + msg + "\n" - vc?.updateText(msg: self.logData) - } - } - self.logEvent() - self.navigationController?.pushViewController(vc!, animated: true) - vc?.isSendV2Event = true - vc?.updateText(msg: self.logData) - self.branchSDKInitialized = true - } - - @IBAction func sendNotificationAction(_ sender: Any) { - reachabilityCheck(textValue: "sendNotification") - } - - @objc func methodOfReceivedNotification(notification: Notification) { - - Branch.getInstance().initSession( launchOptions: AppDelegate.shared.launchOption, - andRegisterDeepLinkHandlerUsingBranchUniversalObject: { [self] universalObject, linkProperties, error in - if universalObject != nil { - NSLog("UniversalObject", universalObject ?? "NA") - NSLog("LinkProperties", linkProperties ?? "NA") - NSLog("UniversalObject Metadata:", universalObject?.contentMetadata.customMetadata ?? "NA") - if let isRead = UserDefaults.standard.value(forKey: "isRead") as? Bool, isRead == true { - if let dictData = universalObject?.contentMetadata.customMetadata as? NSDictionary { - let referedlink = dictData.value(forKey: "~referring_link") as? String ?? "" - // let linkurl = UserDefaults.standard.value(forKey: "link") as? String ?? "" - NSLog("referedlink:", referedlink) - UserDefaults.standard.set(referedlink, forKey: "link") - NSLog("Deep linked with object: %@.", universalObject ?? BranchUniversalObject()); - let deeplinkText = universalObject?.contentMetadata.customMetadata.value(forKey: "deeplink_text") - let textDetail = "Successfully Deeplinked:\n\n%@\nSession Details:\n\n%@, \(String(describing: deeplinkText)) \(String(describing: Branch.getInstance().getLatestReferringParams()?.description))" - UserDefaults.standard.setValue(textDetail, forKey: "textDetail") - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "DispalyVC") as? DispalyVC { - vc.textDescription = textDetail - self.navigationController?.pushViewController(vc, animated: true) - } - } - } else { - NSLog("No Deep linked object"); - } - } - }) - } - - @IBAction func displayContentBtnAction(_ sender: Any) { - reachabilityCheck(textValue: "displayContent") - } - - @IBAction func navigatetoContentBtnAction(_ sender: Any) { - reachabilityCheck(textValue: "navigatetoContent") - } - - @IBAction func loadUrlInWebViewAction(_ sender: Any) { - reachabilityCheck(textValue: "loadUrlInWeb") - } - - @IBAction func createDeeplinking(_ sender: Any) { - reachabilityCheck(textValue: "createDeep") - } - - @IBAction func shareDeeplinking(_ sender: Any) { - reachabilityCheck(textValue: "shareDeeplinking") - } - - @IBAction func readDeeplinking(_ sender: Any) { - reachabilityCheck(textValue: "readDeeplinking") - } - - @IBAction func trackContentAction(_ sender: Any) { - reachabilityCheck(textValue: "trackContent") - } - - @IBAction func trackUserAction(_ sender: Any) { - reachabilityCheck(textValue: "trackUser") - } - - @IBAction func swichAction(_ sender: UISwitch) { - reachabilityCheck(textValue: "swichAction") - if sender.isOn == true { - NSLog("is OFF", "ison") - btnTrackingEnabled.setTitle("Tracking Enabled", for: .normal) - btnTrackingEnabled.titleLabel?.font = UIFont.boldSystemFont(ofSize: 36) - Branch.setTrackingDisabled(true) - - } else { - NSLog("is ON", "isOFF") - Branch.setTrackingDisabled(false) - btnTrackingEnabled.setTitle("Tracking Disabled", for: .normal) - btnTrackingEnabled.titleLabel?.font = UIFont(name: "Helvetica", size:36) - } - } - - @IBAction func createObject(_ sender: Any) { - reachabilityCheck(textValue: "createObject") - - } - - @IBAction func readSystemLog(){ - reachabilityCheck(textValue: "readSystemLog") - - - } - - @IBAction func setDMAParams(){ - reachabilityCheck(textValue: "setDMAParams") - } - - @IBAction func sendV2Event(){ - reachabilityCheck(textValue: "sendV2Event") - } - - @IBAction func setAttributionLevel(){ - reachabilityCheck(textValue: "setAttributionLevel") - } -} - -extension UITextField { - func setLeftPaddingPoints(_ amount:CGFloat){ - let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.frame.size.height)) - self.leftView = paddingView - self.leftViewMode = .always - } - func setRightPaddingPoints(_ amount:CGFloat) { - let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.frame.size.height)) - self.rightView = paddingView - self.rightViewMode = .always - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/LogFileListViewController.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/LogFileListViewController.swift deleted file mode 100644 index 844af618d..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/LogFileListViewController.swift +++ /dev/null @@ -1,84 +0,0 @@ -// -// LogFileListViewController.swift -// DeepLinkDemo -// -// Created by Apple on 26/05/22. -// - -import UIKit - -class LogFileListViewController: UIViewController { - - var fileNames = [String]() - - @IBOutlet weak var logFileListTblView: UITableView! - - override func viewDidLoad() { - super.viewDidLoad() - - fileNames = getAllLogFileNames() - } - - func getAllLogFileNames() -> [String]{ - let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! - - do { - var fileName = [String]() - let fileURLs = try FileManager.default.contentsOfDirectory(at: documentsUrl, - includingPropertiesForKeys: nil, - options: .skipsHiddenFiles) - for fileURL in fileURLs { - fileName.append(fileURL.lastPathComponent) - } - - return fileName - } catch { - NSLog("Failed to delete/read the file in document directory %@", error.localizedDescription) - } - return [""] - } - @IBAction func backAction(_ sender: Any) { - self.navigationController?.popToRootViewController(animated: true) - } - - -} - - -extension LogFileListViewController: UITableViewDataSource, UITableViewDelegate{ - func numberOfSections(in tableView: UITableView) -> Int { - return 1 - } - - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return fileNames.count - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - if let cell = tableView.dequeueReusableCell(withIdentifier: "LogTableViewCell", for: indexPath) as? LogTableViewCell{ - cell.nameLbl.text = fileNames[indexPath.row] - return cell - } - return UITableViewCell() - } - - func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - return 60 - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - let selectedFile = fileNames[indexPath.row] - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "ReadLogViewController") as? ReadLogViewController { - vc.selectedFileName = selectedFile - self.navigationController?.pushViewController(vc, animated: true) - } - - } -} - - -class LogTableViewCell: UITableViewCell{ - - @IBOutlet weak var nameLbl: UILabel! -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/MetaDataTableViewCell.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/MetaDataTableViewCell.swift deleted file mode 100644 index bc5170c63..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/MetaDataTableViewCell.swift +++ /dev/null @@ -1,224 +0,0 @@ -// -// MetaDataTableViewCell.swift -// DeepLinkDemo -// -// Created by Apple on 13/05/22. -// - -import UIKit -import BranchSDK - -protocol PickerViewDelegate{ - func removePickerView() -} -class MetaDataTableViewCell: UITableViewCell { - - var pickerDelegate: PickerViewDelegate! - - private let contentSchemaNames = ["COMMERCE_AUCTION", "COMMERCE_BUSINESS", "COMMERCE_OTHER", - "COMMERCE_PRODUCT", "COMMERCE_RESTAURANT", "COMMERCE_SERVICE", - "COMMERCE_TRAVEL_FLIGHT", "COMMERCE_TRAVEL_HOTEL", "COMMERCE_TRAVEL_OTHER", - "GAME_STATE", "MEDIA_IMAGE", "MEDIA_MIXED", "MEDIA_MUSIC", "MEDIA_OTHER", - "MEDIA_VIDEO", "OTHER", "TEXT_ARTICLE", "TEXT_BLOG", "TEXT_OTHER", - "TEXT_RECIPE", "TEXT_REVIEW", "TEXT_SEARCH_RESULTS", "TEXT_STORY", - "TEXT_TECHNICAL_DOC"] - - private let productCategories = ["Animals & Pet Supplies", "Apparel & Accessories", "Arts & Entertainment", - "Baby & Toddler", "Business & Industrial", "Cameras & Optics", - "Electronics", "Food, Beverages & Tobacco", "Furniture", "Hardware", - "Health & Beauty", "Home & Garden", "Luggage & Bags", "Mature", - "Media", "Media", "Office Supplies", "Religious & Ceremonial", - "Software", "Sporting Goods", "Toys & Games", "Vehicles & Parts"] - - - private let productConditions = ["EXCELLENT", "NEW", "GOOD", "FAIR", "POOR", "USED", "REFURBISHED", "OTHER"] - - - private let currencyNames = ["USD", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BOV", "BRL", "BSD", "BTN", "BWP", "BYN", "BYR", "CAD", "CDF", "CHE", "CHF", "CHW", "CLF", "CLP", "CNY", "COP", "COU", "CRC", "CUC", "CUP", "CVE", "CZK", "DJF", "DKK", "DOP", "DZD", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP", "GEL", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD", "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "INR", "IQD", "IRR", "ISK", "JMD", "JOD", "JPY", "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LYD", "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP", "MRO", "MUR", "MVR", "MWK", "MXN", "MXV", "MYR", "MZN", "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON", "RSD", "RUB", "RWF", "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "SSP", "STD", "SYP", "SZL", "THB", "TJS", "TMT", "TND", "TOP", "TRY", "TTD", "TWD", "TZS", "UAH", "UGX", "USN", "UYI", "UYU", "UZS", "VEF", "VND", "VUV", "WST", "XAF", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XDR", "XFU", "XOF", "XPD", "XPF", "XPT", "XSU", "XTS", "XUA", "XXX", "YER", "ZAR", "ZMW"] - - private var pickerView = UIPickerView() - - @IBOutlet weak var contentSchema: UITextField! - @IBOutlet weak var productName: UITextField! - @IBOutlet weak var productBrand: UITextField! - @IBOutlet weak var productVariant: UITextField! - @IBOutlet weak var productCategory: UITextField! - @IBOutlet weak var productCondition: UITextField! - @IBOutlet weak var street: UITextField! - @IBOutlet weak var city: UITextField! - @IBOutlet weak var region: UITextField! - @IBOutlet weak var country: UITextField! - @IBOutlet weak var postalCode: UITextField! - @IBOutlet weak var latitude: UITextField! - @IBOutlet weak var longitude: UITextField! - @IBOutlet weak var sku: UITextField! - @IBOutlet weak var rating: UITextField! - @IBOutlet weak var averageRating: UITextField! - @IBOutlet weak var maximumRating: UITextField! - @IBOutlet weak var ratingCount: UITextField! - @IBOutlet weak var imageCaption: UITextField! - @IBOutlet weak var quantity: UITextField! - @IBOutlet weak var price: UITextField! - @IBOutlet weak var currencyName: UITextField! - @IBOutlet weak var customMetadata: UITextField! - - @IBOutlet weak var submitBtn: UIButton! - - fileprivate func setAtrributePlaceHolder(targetField: UITextField, placeholderTxt: String){ - targetField.setLeftPaddingPoints(10) - targetField.attributedPlaceholder = NSAttributedString( - string: placeholderTxt, - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - - } - - fileprivate func prepareUI(){ - self.setAtrributePlaceHolder(targetField: self.productName, placeholderTxt: "Product Name") - self.setAtrributePlaceHolder(targetField: self.productBrand, placeholderTxt: "Product Brand") - self.setAtrributePlaceHolder(targetField: self.productVariant, placeholderTxt: "Product Variant") - self.setAtrributePlaceHolder(targetField: self.street, placeholderTxt: "Street") - self.setAtrributePlaceHolder(targetField: self.city, placeholderTxt: "City") - self.setAtrributePlaceHolder(targetField: self.region, placeholderTxt: "Region") - self.setAtrributePlaceHolder(targetField: self.country, placeholderTxt: "Country") - self.setAtrributePlaceHolder(targetField: self.postalCode, placeholderTxt: "Postal Code") - self.setAtrributePlaceHolder(targetField: self.latitude, placeholderTxt: "Latitude") - self.setAtrributePlaceHolder(targetField: self.longitude, placeholderTxt: "Longitude") - self.setAtrributePlaceHolder(targetField: self.sku, placeholderTxt: "SKU") - self.setAtrributePlaceHolder(targetField: self.rating, placeholderTxt: "Rating") - self.setAtrributePlaceHolder(targetField: self.averageRating, placeholderTxt: "Average Rating") - self.setAtrributePlaceHolder(targetField: self.maximumRating, placeholderTxt: "Maximum Rating") - self.setAtrributePlaceHolder(targetField: self.ratingCount, placeholderTxt: "Rating Count") - self.setAtrributePlaceHolder(targetField: self.imageCaption, placeholderTxt: "Image Caption") - self.setAtrributePlaceHolder(targetField: self.quantity, placeholderTxt: "Quantity") - self.setAtrributePlaceHolder(targetField: self.price, placeholderTxt: "Price") - self.setAtrributePlaceHolder(targetField: self.customMetadata, placeholderTxt: "Custom Metadata") - - } - - fileprivate func setupPickerViewDataSource() { - pickerView.dataSource = self - pickerView.delegate = self - - let toolBar = UIToolbar(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width,height: 44.0)) - let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) - let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(tapDone)) - let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(tapCancel)) - toolBar.setItems([cancelButton, flexibleSpace, doneButton], animated: false) - - contentSchema.inputView = pickerView - contentSchema.inputAccessoryView = toolBar - contentSchema.text = contentSchemaNames.first - - currencyName.inputView = pickerView - currencyName.inputAccessoryView = toolBar - currencyName.text = currencyNames.first - - productCondition.inputView = pickerView - productCondition.inputAccessoryView = toolBar - productCondition.text = productConditions.first - - productCategory.inputView = pickerView - productCategory.inputAccessoryView = toolBar - productCategory.text = productCategories.first - - productCategory.setLeftPaddingPoints(10) - productCondition.setLeftPaddingPoints(10) - currencyName.setLeftPaddingPoints(10) - contentSchema.setLeftPaddingPoints(10) - - - - } - - override func awakeFromNib() { - super.awakeFromNib() - - prepareUI() - - setupPickerViewDataSource() - - self.selectionStyle = .none - } - - @objc func tapDone() { - if contentSchema.isFirstResponder{ - let selectedRow = pickerView.selectedRow(inComponent: 0) - if contentSchemaNames.indices.contains(selectedRow){ - contentSchema.text = contentSchemaNames[selectedRow] - } - contentSchema.resignFirstResponder() - } else if currencyName.isFirstResponder{ - let selectedRow = pickerView.selectedRow(inComponent: 0) - if currencyNames.indices.contains(selectedRow){ - currencyName.text = currencyNames[selectedRow] - } - currencyName.resignFirstResponder() - } else if productCondition.isFirstResponder{ - let selectedRow = pickerView.selectedRow(inComponent: 0) - if productConditions.indices.contains(selectedRow){ - productCondition.text = productConditions[selectedRow] - } - productCondition.resignFirstResponder() - } else if productCategory.isFirstResponder{ - let selectedRow = pickerView.selectedRow(inComponent: 0) - if productCategories.indices.contains(selectedRow){ - productCategory.text = productCategories[selectedRow] - } - productCategory.resignFirstResponder() - } - self.endEditing(true) - } - - @objc func tapCancel() { - self.endEditing(true) - } - - -} - - -extension MetaDataTableViewCell: UIPickerViewDataSource, UIPickerViewDelegate{ - - func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { - if contentSchema.isFirstResponder{ - return contentSchemaNames.count - } else if currencyName.isFirstResponder{ - return currencyNames.count - } else if productCondition.isFirstResponder{ - return productConditions.count - } else if productCategory.isFirstResponder{ - return productCategories.count - } - return 0 - } - - func numberOfComponents(in pickerView: UIPickerView) -> Int { - return 1 - } - - func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { - if contentSchema.isFirstResponder{ - return contentSchemaNames[row] - } else if currencyName.isFirstResponder{ - return currencyNames[row] - } else if productCondition.isFirstResponder{ - return productConditions[row] - } else if productCategory.isFirstResponder{ - return productCategories[row] - } - return nil - } - - func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { - if contentSchema.isFirstResponder{ - contentSchema.text = contentSchemaNames[row] - } else if currencyName.isFirstResponder{ - currencyName.text = currencyNames[row] - } else if productCondition.isFirstResponder{ - productCondition.text = productConditions[row] - } else if productCategory.isFirstResponder{ - productCategory.text = productCategories[row] - } - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/NavigateContentVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/NavigateContentVC.swift deleted file mode 100644 index 225b64e8c..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/NavigateContentVC.swift +++ /dev/null @@ -1,108 +0,0 @@ -// -// NavigateContentVC.swift -// DeepLinkDemo -// -// Created by Rakesh kumar on 4/19/22. -// - -import UIKit - -class NavigateContentVC: ParentViewController { - @IBOutlet weak var txtFldCChannel: UITextField! - @IBOutlet weak var txtFldFeature: UITextField! - @IBOutlet weak var txtFldChampaignName: UITextField! - @IBOutlet weak var txtFldStage: UITextField! - @IBOutlet weak var txtFldDeskTopUrl: UITextField! - @IBOutlet weak var txtFldAdditionalData: UITextField! - @IBOutlet weak var scrollViewMain: UIScrollView! - private var reachability:Reachability? - - override func viewDidLoad() { - super.viewDidLoad() - uiSetUp() - reachabilityCheck() - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - Utils.shared.setLogFile("NavigateContent") - } - - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - scrollViewMain.contentSize.height = scrollViewMain.subviews.sorted(by: { $0.frame.maxY < $1.frame.maxY }).last?.frame.maxY ?? scrollViewMain.contentSize.height - } - - @IBAction func backAction(_ sender: Any) { - self.navigationController?.popToRootViewController(animated: true) - } - - @objc func submitAction(sender : UIButton) { - self.view.endEditing(true) - CommonMethod.sharedInstance.branchUniversalObject.publiclyIndex = true - CommonMethod.sharedInstance.branchUniversalObject.locallyIndex = true - CommonMethod.sharedInstance.branchUniversalObject.contentMetadata.customMetadata["key1"] = txtFldDeskTopUrl.text! - CommonMethod.sharedInstance.linkProperties.channel = txtFldCChannel.text! - CommonMethod.sharedInstance.linkProperties.feature = txtFldFeature.text! - CommonMethod.sharedInstance.linkProperties.campaign = txtFldChampaignName.text! - CommonMethod.sharedInstance.linkProperties.stage = txtFldStage.text! - CommonMethod.sharedInstance.linkProperties.addControlParam("$desktop_url", withValue: txtFldDeskTopUrl.text!) - CommonMethod.sharedInstance.linkProperties.addControlParam("custom_data", withValue: "yes") - CommonMethod.sharedInstance.branchUniversalObject.getShortUrl(with:CommonMethod.sharedInstance.linkProperties, andCallback: { (optUrl: String?, error: Error?) in - if error == nil, let url = optUrl { - NSLog("got my Branch link to share: %@", url) - Utils.shared.setLogFile("NavigateContent") - DispatchQueue.main.async { - UserDefaults.standard.set(true, forKey: "isCreatedDeepLink") - UserDefaults.standard.set(url, forKey: "link") - self.navigationController?.popToRootViewController(animated: true) - } - } - }) - } -} - -extension NavigateContentVC { - - func uiSetUp() { - let submitBtn = UIButton(frame: CGRect(x: self.view.frame.width/2-60, y: txtFldAdditionalData.frame.maxY+30, width: 120, height: 55)) - submitBtn.setTitle("Submit", for: .normal) - submitBtn.backgroundColor = UIColor(red: 89.0/255.0, green: 12.0/255.0, blue: 228.0/255.0, alpha: 1.0) - submitBtn.layer.cornerRadius = 8 - submitBtn.setTitleColor(UIColor.white, for: .normal) - submitBtn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 22.0) - submitBtn.addTarget(self, action: #selector(self.submitAction), for: .touchUpInside) - scrollViewMain.addSubview(submitBtn) - txtFldCChannel.setLeftPaddingPoints(10) - txtFldFeature.setLeftPaddingPoints(10) - txtFldChampaignName.setLeftPaddingPoints(10) - txtFldStage.setLeftPaddingPoints(10) - txtFldDeskTopUrl.setLeftPaddingPoints(10) - txtFldAdditionalData.setLeftPaddingPoints(10) - txtFldCChannel.attributedPlaceholder = NSAttributedString( - string: "Channel name like Facebook", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldFeature.attributedPlaceholder = NSAttributedString( - string: "Feature eg: Sharing", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldChampaignName.attributedPlaceholder = NSAttributedString( - string: "Champaign name", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldStage.attributedPlaceholder = NSAttributedString( - string: "Stage", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldDeskTopUrl.attributedPlaceholder = NSAttributedString( - string: "Desktop URL", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldAdditionalData.attributedPlaceholder = NSAttributedString( - string: "Additional Data", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/ParentViewController.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/ParentViewController.swift deleted file mode 100644 index 241dd72e9..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/ParentViewController.swift +++ /dev/null @@ -1,39 +0,0 @@ -// ParentViewController.swift -// DeepLinkDemo -// Created by Apple on 17/05/22. - -import UIKit -class ParentViewController: UIViewController { - private var reachability:Reachability? - - override func viewDidLoad() { - super.viewDidLoad() - reachabilityCheck() - } - - override var preferredStatusBarStyle: UIStatusBarStyle { - return .lightContent - } - - - func reachabilityCheck() { - reachability = Reachability()! - reachability!.whenReachable = { reachability in - } - reachability?.whenUnreachable = { reachability in - DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { - self.networkError() - } - } - do { - try reachability?.startNotifier() - } catch { - NSLog("Unable to start notifier") - } - } - - func networkError() { - CommonAlert.shared.showActionAlertView(title: "Failure", message: "Your internet/network connection appears to be offline. Please check your internet/network connection.", actions: [], preferredStyle: .alert, viewController: self) - } - -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/ReadDeeplinkingVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/ReadDeeplinkingVC.swift deleted file mode 100644 index 6d72dfa49..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/ReadDeeplinkingVC.swift +++ /dev/null @@ -1,108 +0,0 @@ -// -// ReadDeeplinkingVC.swift -// DeepLinkDemo -// -// Created by Rakesh kumar on 4/19/22. - -import UIKit -import Branch - -class ReadDeeplinkingVC: ParentViewController { - @IBOutlet weak var txtFldCChannel: UITextField! - @IBOutlet weak var txtFldFeature: UITextField! - @IBOutlet weak var txtFldChampaignName: UITextField! - @IBOutlet weak var txtFldStage: UITextField! - @IBOutlet weak var txtFldDeskTopUrl: UITextField! - @IBOutlet weak var txtFldAdditionalData: UITextField! - @IBOutlet weak var scrollViewMain: UIScrollView! - private var reachability:Reachability? - override func viewDidLoad() { - super.viewDidLoad() - uiSetUp() - reachabilityCheck() - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - Utils.shared.setLogFile("ReadDeeplinking") - } - - - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - scrollViewMain.contentSize.height = scrollViewMain.subviews.sorted(by: { $0.frame.maxY < $1.frame.maxY }).last?.frame.maxY ?? scrollViewMain.contentSize.height - } - - @IBAction func backAction(_ sender: Any) { - self.navigationController?.popToRootViewController(animated: true) - } - - @objc func submitAction(sender : UIButton) { - self.view.endEditing(true) - - CommonMethod.sharedInstance.branchUniversalObject.publiclyIndex = true - CommonMethod.sharedInstance.branchUniversalObject.locallyIndex = true - CommonMethod.sharedInstance.branchUniversalObject.contentMetadata.customMetadata["key1"] = txtFldDeskTopUrl.text! - - CommonMethod.sharedInstance.linkProperties.channel = txtFldCChannel.text! - CommonMethod.sharedInstance.linkProperties.feature = txtFldFeature.text! - CommonMethod.sharedInstance.linkProperties.campaign = txtFldChampaignName.text! - CommonMethod.sharedInstance.linkProperties.stage = txtFldStage.text! - CommonMethod.sharedInstance.linkProperties.addControlParam("$desktop_url", withValue: txtFldDeskTopUrl.text!) - CommonMethod.sharedInstance.linkProperties.addControlParam("custom_data", withValue: "yes") - CommonMethod.sharedInstance.branchUniversalObject.getShortUrl(with:CommonMethod.sharedInstance.linkProperties, andCallback: { (optUrl: String?, error: Error?) in - if error == nil, let url = optUrl { - NSLog("got my Branch link to share: %@", url) - DispatchQueue.main.async { - UserDefaults.standard.set(true, forKey: "isCreatedDeepLink") - UserDefaults.standard.set(url, forKey: "link") - self.navigationController?.popToRootViewController(animated: true) - } - } - }) - } -} - -extension ReadDeeplinkingVC { - - func uiSetUp() { - let submitBtn = UIButton(frame: CGRect(x: self.view.frame.width/2-60, y: txtFldAdditionalData.frame.maxY+30, width: 120, height: 55)) - submitBtn.setTitle("Submit", for: .normal) - submitBtn.backgroundColor = UIColor(red: 89.0/255.0, green: 12.0/255.0, blue: 228.0/255.0, alpha: 1.0) - submitBtn.layer.cornerRadius = 8 - submitBtn.setTitleColor(UIColor.white, for: .normal) - submitBtn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 22.0) - submitBtn.addTarget(self, action: #selector(self.submitAction), for: .touchUpInside) - scrollViewMain.addSubview(submitBtn) - txtFldCChannel.setLeftPaddingPoints(10) - txtFldFeature.setLeftPaddingPoints(10) - txtFldChampaignName.setLeftPaddingPoints(10) - txtFldStage.setLeftPaddingPoints(10) - txtFldDeskTopUrl.setLeftPaddingPoints(10) - txtFldAdditionalData.setLeftPaddingPoints(10) - txtFldCChannel.attributedPlaceholder = NSAttributedString( - string: "Channel name like Facebook", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldFeature.attributedPlaceholder = NSAttributedString( - string: "Feature eg: Sharing", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldChampaignName.attributedPlaceholder = NSAttributedString( - string: "Campaign name", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldStage.attributedPlaceholder = NSAttributedString( - string: "Stage", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldDeskTopUrl.attributedPlaceholder = NSAttributedString( - string: "Desktop URL", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - txtFldAdditionalData.attributedPlaceholder = NSAttributedString( - string: "Additional Data", - attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] - ) - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/ReadLogViewController.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/ReadLogViewController.swift deleted file mode 100644 index d88749390..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/ReadLogViewController.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// ReadLogViewController.swift -// DeepLinkDemo -// -// Created by Apple on 17/05/22. -// - -import UIKit - -class ReadLogViewController: ParentViewController { - - @IBOutlet weak var textViewDescription: UITextView! - - var selectedFileName = "" - - override func viewDidLoad() { - super.viewDidLoad() - - self.textViewDescription.text = loadTextWithFileName(selectedFileName) - reachabilityCheck() - } - - - @IBAction func backAction(_ sender: Any) { - self.navigationController?.popToRootViewController(animated: true) - } - - private func loadTextWithFileName(_ fileName: String) -> String? { - if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first { - let fileURL = dir.appendingPathComponent(fileName) - guard let text = try? String(contentsOf: fileURL, encoding: .utf8) else { - return nil - } - return text - } - return nil - } - -} - - diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/ReadVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/ReadVC.swift deleted file mode 100644 index 08fe32021..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/ReadVC.swift +++ /dev/null @@ -1,50 +0,0 @@ -// -// ReadVC.swift -// DeepLinkDemo -// -// Created by Rakesh kumar on 4/28/22. -// - -import UIKit -import BranchSDK -class ReadVC: ParentViewController { - - @IBOutlet weak var btnback: UIButton! - @IBOutlet weak var labelTxt: UILabel! - @IBOutlet weak var btnShare: UIButton! - var strTxt = "" - private var reachability:Reachability? - override func viewDidLoad() { - super.viewDidLoad() - labelTxt.text = "Success\nUrl is generated.\nHere is the Short URL\(strTxt)" - btnShare.layer.cornerRadius = 8.0 - let tap = UITapGestureRecognizer(target: self, action: #selector(self.onClicLabel(sender:))) - labelTxt.isUserInteractionEnabled = true - labelTxt.addGestureRecognizer(tap) - reachabilityCheck() - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - } - - - // And that's the function :) - @objc func onClicLabel(sender:UITapGestureRecognizer) { - - UserDefaults.standard.set(true, forKey: "isRead") - let anURL = URL(string: strTxt) - Branch.getInstance().handleDeepLink(anURL) - } - - @IBAction func backAction(_ sender: Any) { - self.navigationController?.popToRootViewController(animated: true) - } - - @IBAction func btnrReadDeeplink(_ sender: Any) { - UserDefaults.standard.set(true, forKey: "isRead") - let anURL = URL(string: strTxt) - Branch.getInstance().handleDeepLink(anURL) - } - -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/ShareDynamicallyVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/ShareDynamicallyVC.swift deleted file mode 100644 index cb71f1bed..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/ShareDynamicallyVC.swift +++ /dev/null @@ -1,10 +0,0 @@ -// -// ShareDynamicallyVC.swift -// DeepLinkDemo -// -// Created by Rakesh kumar on 4/19/22. -// - -import UIKit -class ShareDynamicallyVC: ParentViewController { -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/TextViewController.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/TextViewController.swift deleted file mode 100644 index b55b15c90..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/TextViewController.swift +++ /dev/null @@ -1,101 +0,0 @@ -// -// TextViewController.swift -// DeepLinkDemo -// -// Created by ajaykumar on 15/06/22. -// - -import Foundation -import UIKit -import CoreSpotlight; -import MobileCoreServices; - -class TextViewController: UIViewController { - - var isShareDeepLink = false - var isNavigateToContent = false - var isDisplayContent = false - var isTrackContent = false - var isTrackContenttoWeb = false - var handleLinkInWebview = false - var isCreateDeepLink = false - var forNotification = false - var isTrackUser = false - var isSetDMAParams = false - var isSendV2Event = false - var isSetAttributionLevel = false - - var url = "" - var responseStatus = "" - var dictData = [String:Any]() - var textViewText = "" - - @IBOutlet weak var statusLabel: UILabel! - - @IBOutlet weak var logDataTextView: UITextView! - - - override func viewDidLoad() { - super.viewDidLoad() - logDataTextView.text = textViewText - statusLabel.text = responseStatus - logDataTextView.isEditable = false - } - - @IBAction func BackButtonAction(_ sender: Any) { - self.navigationController?.popToRootViewController(animated: true) - } - @IBAction func nextButtonAction(_ sender: Any) { - if self.isTrackContent == true { - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "GenerateURLVC") as? GenerateURLVC { - vc.isTrackContent = true - vc.forNotification = false - vc.isCreateDeepLink = false - vc.isShareDeepLink = false - vc.isNavigateToContent = false - vc.dictData = dictData - self.navigationController?.pushViewController(vc, animated: true) - } - } else if self.isTrackUser == true { - self.navigationController?.popToRootViewController(animated: true) - } else if self.forNotification == true { - self.navigationController?.popToRootViewController(animated: true) - } else if self.isTrackContenttoWeb || self.isCreateDeepLink { - launchWebView() - } else if self.isNavigateToContent || self.isDisplayContent || self.handleLinkInWebview { - launchReadVC() - } else if self.isSetDMAParams == true { - self.navigationController?.popToRootViewController(animated: true) - } else if self.isSendV2Event == true { - self.navigationController?.popToRootViewController(animated: true) - } else if self.isSetAttributionLevel == true { - self.navigationController?.popToRootViewController(animated: true) - } - else { - launchReadVC() - } - } - - func launchReadVC(){ - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "ReadVC") as? ReadVC { - vc.strTxt = url - self.navigationController?.pushViewController(vc, animated: true) - } - } - - func launchWebView(){ - //Fixed - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "WebViewVC") as? WebViewVC { - self.navigationController?.pushViewController(vc, animated: true) - } - } - - func updateText(msg: String) -> () { - DispatchQueue.main.async() { - self.logDataTextView?.text = msg - } - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/TrackContentVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/TrackContentVC.swift deleted file mode 100644 index 9efe7653d..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/TrackContentVC.swift +++ /dev/null @@ -1,88 +0,0 @@ -// -// TrackContentVC.swift -// DeepLinkDemo -// -// Created by Apple on 12/05/22. -// - -import UIKit -import BranchSDK - -class TrackContentVC: ParentViewController { - - @IBOutlet weak var txtFldOptions: UITextField! - - var pickerView = UIPickerView() - - var trackContenOptions = [String]() - private var reachability:Reachability? - override func viewDidLoad() { - super.viewDidLoad() - - trackContenOptions = ["ADD_TO_CART", "ADD_TO_WISHLIST", "VIEW_CART", "INITIATE_PURCHASE", "ADD_PAYMENT_INFO", "PURCHASE", "SPEND_CREDITS", "SUBSCRIBE", "START_TRIAL", "CLICK_AD", "VIEW_AD", "SEARCH", "VIEW_ITEM", "VIEW_ITEMS", "RATE", "SHARE", "START_TRIAL", "CLICK_AD", "COMPLETE_REGISTRATION", "COMPLETE_TUTORIAL", "ACHIEVE_LEVEL", "UNLOCK_ACHIEVEMENT", "INVITE", "LOGIN", "RESERVE", "OPT_IN", "OPT_OUT"] - - pickerView.dataSource = self - pickerView.delegate = self - - txtFldOptions.inputView = pickerView - let toolBar = UIToolbar(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width,height: 44.0)) - let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) - let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: target, action: #selector(tapDone)) - let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: target, action: #selector(tapCancel)) - toolBar.setItems([cancelButton, flexibleSpace, doneButton], animated: false) - txtFldOptions.inputAccessoryView = toolBar - - txtFldOptions.text = trackContenOptions.first - reachabilityCheck() - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - } - - - @objc func tapDone() { - let selectedRow = pickerView.selectedRow(inComponent: 0) - if trackContenOptions.indices.contains(selectedRow){ - txtFldOptions.text = trackContenOptions[selectedRow] - } - txtFldOptions.resignFirstResponder() - self.view.endEditing(true) - } - @objc func tapCancel() { - self.view.endEditing(true) - } - - @IBAction func backBtnAction(){ - self.navigationController?.popToRootViewController(animated: true) - } - - @IBAction func nextBtnAction(){ - let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) - if let vc = storyBoard.instantiateViewController(withIdentifier: "CreateObjectReferenceObject") as? CreateObjectReferenceObject { - vc.screenMode = 7 - vc.txtFldValue = String(txtFldOptions.text ?? "") - self.navigationController?.pushViewController(vc, animated: true) - } - } - -} - -extension TrackContentVC: UIPickerViewDataSource, UIPickerViewDelegate{ - - func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { - return trackContenOptions.count - } - - func numberOfComponents(in pickerView: UIPickerView) -> Int { - return 1 - } - - func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { - return trackContenOptions[row] - } - - func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { - txtFldOptions.text = trackContenOptions[row] - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/ViewController.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/ViewController.swift deleted file mode 100644 index 359d647da..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/ViewController.swift +++ /dev/null @@ -1,20 +0,0 @@ -// ViewController.swift -// DeepLinkDemo -// Created by Apple on 17/05/22 -import UIKit - -class ViewController: ParentViewController { - - override func viewDidLoad() { - super.viewDidLoad() - super.reachabilityCheck() - } - - - - override var preferredStatusBarStyle: UIStatusBarStyle { - return .lightContent - } - - -} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/WebViewVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/WebViewVC.swift deleted file mode 100644 index b244ac66a..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Controllers/WebViewVC.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// WebViewVC.swift -// DeepLinkDemo -// -// Created by Rakesh kumar on 4/22/22. -// - -import UIKit -import WebKit -import SafariServices - -class WebViewVC: ParentViewController, WKNavigationDelegate { - - @IBOutlet weak var webViewContainer: UIView! - - var webViewDetail: WKWebView = WKWebView() - private var reachability:Reachability? - - override func viewDidLoad() { - super.viewDidLoad() - - loadWKWebview() - reachabilityCheck() - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - Utils.shared.setLogFile("HandleLinksInapp") - } - - fileprivate func loadWKWebview(){ - let webConfiguration = WKWebViewConfiguration() - let customFrame = CGRect.init(origin: CGPoint.zero, size: CGSize.init(width: self.webViewContainer.frame.size.width, height: self.webViewContainer.frame.size.height)) - self.webViewDetail = WKWebView (frame: customFrame , configuration: webConfiguration) - webViewDetail.translatesAutoresizingMaskIntoConstraints = false - self.webViewContainer.addSubview(webViewDetail) - self.view.addConstraint(NSLayoutConstraint(item: webViewDetail, attribute: .trailing, relatedBy: .equal, toItem: self.webViewContainer, attribute: .trailing, multiplier: 1, constant: 0)) - self.view.addConstraint(NSLayoutConstraint(item: webViewDetail, attribute: .leading, relatedBy: .equal, toItem: self.webViewContainer, attribute: .leading, multiplier: 1, constant: 0)) - self.view.addConstraint(NSLayoutConstraint(item: webViewDetail, attribute: .top, relatedBy: .equal, toItem: self.webViewContainer, attribute: .top, multiplier: 1, constant: 0)) - self.view.addConstraint(NSLayoutConstraint(item: webViewDetail, attribute: .bottom, relatedBy: .equal, toItem: self.webViewContainer, attribute: .bottom, multiplier: 1, constant: 0)) - - webViewDetail.navigationDelegate = self - if let deeplinkurl: String = UserDefaults.standard.string(forKey: "link"){ - webViewDetail.load(URLRequest(url: URL(string: deeplinkurl)!)) - } - } - - @IBAction func backBtnTapped(){ - self.navigationController?.popToRootViewController(animated: true) - } - -} - -extension WebViewVC: SFSafariViewControllerDelegate{ - func safariViewControllerDidFinish(_ controller: SFSafariViewController) { - self.dismiss(animated: true) - self.navigationController?.popViewController(animated: true) - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/DeepLinkDemo-Bridging-Header.h b/DeepLinkDemo/DeepLinkDemo/DeepLinkDemo-Bridging-Header.h deleted file mode 100644 index 28c03fdc2..000000000 --- a/DeepLinkDemo/DeepLinkDemo/DeepLinkDemo-Bridging-Header.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// DeepLinkDemo-Bridging-Header.h -// DeepLinkDemo -// -// Created by Rakesh kumar on 4/18/22. -// - -#ifndef DeepLinkDemo_Bridging_Header_h -#define DeepLinkDemo_Bridging_Header_h -#import "SIAlertView.h" - -#endif /* DeepLinkDemo_Bridging_Header_h */ diff --git a/DeepLinkDemo/DeepLinkDemo/Header.h b/DeepLinkDemo/DeepLinkDemo/Header.h deleted file mode 100644 index d3e5fefff..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Header.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// Header.h -// DeepLinkDemo -// -// Created by Rakesh kumar on 4/18/22. -// - -#ifndef Header_h -#define Header_h -#import "SIAlertView.h" - -#endif /* Header_h */ diff --git a/DeepLinkDemo/DeepLinkDemo/Info.plist b/DeepLinkDemo/DeepLinkDemo/Info.plist deleted file mode 100644 index 6ce93adf7..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Info.plist +++ /dev/null @@ -1,54 +0,0 @@ - - - - - CFBundleSignature - ???? - CFBundleURLTypes - - - CFBundleURLSchemes - - Timber - - - - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - - UIBackgroundModes - - fetch - processing - remote-notification - - UIStatusBarStyle - UIStatusBarStyleLightContent - adjust_app_token - x66ziay2jtvk - amplitude_api_key - 3dc11880800fe99b829ca66886abf9e5 - appboy_api_key - d781dccf-9f96-46a8-878a-a1bef7bb6968 - appmetrica_api_key - 4805cb1a-2e2c-4a03-af63-4c712939817b - appsflyer_api_key - 84qHoE3ZXh7SetmHU6boi5 - branch_key - - live - key_live_nf8w3l1WBpzWdlC00KsLNdmbuEccK6Yr - test - key_test_om2EWe1WBeBYmpz9Z1mdpopouDmoN72T - - branch_universal_link_domains - - timber.app.link - timber-alternate.app.link - timber.test.app.link - timber-alternate.test.app.link - - - diff --git a/DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.h b/DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.h deleted file mode 100644 index 125b19377..000000000 --- a/DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// NSURLSession+Branch.h -// -// Created by Ernest Cho on 10/11/18. -// Copyright © 2018 Branch Metrics, Inc. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface NSURLSession (Branch) - -@end - -NS_ASSUME_NONNULL_END diff --git a/DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.m b/DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.m deleted file mode 100644 index 379c8e752..000000000 --- a/DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.m +++ /dev/null @@ -1,94 +0,0 @@ -// -// NSURLSession+Branch.m -// -// Created by Ernest Cho on 10/11/18. -// Copyright © 2018 Branch Metrics, Inc. All rights reserved. -// - -#import "NSURLSessionBranch.h" -#import -#import "BranchLogger.h" - -@implementation NSURLSession (Branch) - -+ (void)load { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - [self swizzleSelector:@selector(dataTaskWithRequest:completionHandler:) - withSelector:@selector(xxx_dataTaskWithRequest:completionHandler:)]; - }); -} - -// swaps originalSelector with swizzledSelector -+ (void)swizzleSelector:(SEL)originalSelector withSelector:(SEL)swizzledSelector { - Class class = [self class]; - - Method originalMethod = class_getInstanceMethod(class, originalSelector); - Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); - - method_exchangeImplementations(originalMethod, swizzledMethod); -} - -- (void)logNetworkTrafficRequest:(NSURLRequest *)request data:(NSData *)data response:(NSURLResponse *)response { - [[BranchLogger shared] logDebug: @"BranchSDK API LOG START OF FILE" error:nil]; - - [[BranchLogger shared] logDebug:(@"[LogEntryStart]\n\n") error:nil]; - [[BranchLogger shared] logDebug:(@"---------------------------------------------------------------------BranchSDK LOG START ---------------------------------------------------------------------" ) error:nil]; - [[BranchLogger shared] logDebug:(@"[LogEntryStart]\n\n") error:nil]; - [[BranchLogger shared] logDebug:([NSString stringWithFormat: @"BranchSDK Request log: %@", request]) error:nil]; - - NSData *body = [request HTTPBody]; - if (body) { - [[BranchLogger shared] logDebug:(@"[LogEntryStart]\n\n") error:nil]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"BranchSDK Request Body: %@", [NSString stringWithUTF8String:body.bytes]] error:nil]; - } - - [[BranchLogger shared] logDebug:(@"[LogEntryStart]\n\n") error:nil]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"BranchSDK Response: %@", response] error:nil]; - - if (data.bytes) { - [[BranchLogger shared] logDebug:(@"\n\n") error:nil]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"BranchSDK Response Data: %@", [NSString stringWithUTF8String:data.bytes]] error:nil]; - } - [[BranchLogger shared] logDebug:(@"[LogEntryStart]\n\n") error:nil]; - [[BranchLogger shared] logDebug:(@"---------------------------------------------------------------------BranchSDK LOG END ---------------------------------------------------------------------" ) error:nil]; - [[BranchLogger shared] logDebug:(@"[LogEntryStart]\n\n") error:nil]; - [[BranchLogger shared] logDebug:(@"BranchSDK API LOG END OF FILE") error:nil]; - -} - -// replacement method for dataTaskWithRequest -- (NSURLSessionDataTask *)xxx_dataTaskWithRequest:(NSURLRequest *)request - completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler { - - // create a new block that just calls the original block after logging the request - void (^completionHandlerWithLogging)(NSData *, NSURLResponse *, NSError *) = ^(NSData *data, NSURLResponse *response, NSError *error) { - if (completionHandler) { - - [self logNetworkTrafficRequest:request data:data response:response]; - completionHandler(data, response, error); - } - }; - - return [self xxx_dataTaskWithRequest:request completionHandler:completionHandlerWithLogging]; -} - -- (NSData *)dataFromJSONFileNamed:(NSString *)fileName { - // If this class is part of the Test target, [self class] returns the Test Bundle - // NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"json"]; - - NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:@"json"]; - NSString *jsonString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL]; - return [jsonString dataUsingEncoding:NSUTF8StringEncoding]; -} - -- (NSDictionary *)dictionaryFromJSONFileNamed:(NSString *)fileName { - NSData *jsonData = [self dataFromJSONFileNamed:fileName]; - id dict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil]; - if ([dict isKindOfClass:NSDictionary.class]) { - return dict; - } - return nil; -} - -@end diff --git a/DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.h b/DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.h deleted file mode 100644 index ad32df88d..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// Reachability.h -// Reachability -// -// Created by Yuki Nagai on 11/2/15. -// Copyright © 2015 Ashley Mills. All rights reserved. -// - -#import - -//! Project version number for Reachability. -FOUNDATION_EXPORT double ReachabilityVersionNumber; - -//! Project version string for Reachability. -FOUNDATION_EXPORT const unsigned char ReachabilityVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.swift b/DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.swift deleted file mode 100644 index 9f5f4d7ae..000000000 --- a/DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.swift +++ /dev/null @@ -1,270 +0,0 @@ -/* - Copyright (c) 2014, Ashley Mills - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - */ - -import SystemConfiguration -import Foundation - -public enum ReachabilityError: Error { - case FailedToCreateWithAddress(sockaddr_in) - case FailedToCreateWithHostname(String) - case UnableToSetCallback - case UnableToSetDispatchQueue -} - -public let ReachabilityChangedNotification = NSNotification.Name("ReachabilityChangedNotification") - -func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) { - - guard let info = info else { return } - - let reachability = Unmanaged.fromOpaque(info).takeUnretainedValue() - - DispatchQueue.main.async { - reachability.reachabilityChanged() - } -} - -public class Reachability { - - public typealias NetworkReachable = (Reachability) -> () - public typealias NetworkUnreachable = (Reachability) -> () - - public enum NetworkStatus: CustomStringConvertible { - - case notReachable, reachableViaWiFi, reachableViaWWAN - - public var description: String { - switch self { - case .reachableViaWWAN: return "Cellular" - case .reachableViaWiFi: return "WiFi" - case .notReachable: return "No Connection" - } - } - } - - public var whenReachable: NetworkReachable? - public var whenUnreachable: NetworkUnreachable? - public var reachableOnWWAN: Bool - - // The notification center on which "reachability changed" events are being posted - public var notificationCenter: NotificationCenter = NotificationCenter.default - public var currentReachabilityString: String { - return "\(currentReachabilityStatus)" - } - - public var currentReachabilityStatus: NetworkStatus { - guard isReachable else { return .notReachable } - if isReachableViaWiFi { - return .reachableViaWiFi - } - if isRunningOnDevice { - return .reachableViaWWAN - } - return .notReachable - } - - fileprivate var previousFlags: SCNetworkReachabilityFlags? - fileprivate var isRunningOnDevice: Bool = { - #if (arch(i386) || arch(x86_64)) && os(iOS) - return false - #else - return true - #endif - }() - fileprivate var notifierRunning = false - fileprivate var reachabilityRef: SCNetworkReachability? - fileprivate let reachabilitySerialQueue = DispatchQueue(label: "uk.co.ashleymills.reachability") - required public init(reachabilityRef: SCNetworkReachability) { - reachableOnWWAN = true - self.reachabilityRef = reachabilityRef - } - - public convenience init?(hostname: String) { - guard let ref = SCNetworkReachabilityCreateWithName(nil, hostname) else { return nil } - self.init(reachabilityRef: ref) - } - - public convenience init?() { - var zeroAddress = sockaddr() - zeroAddress.sa_len = UInt8(MemoryLayout.size) - zeroAddress.sa_family = sa_family_t(AF_INET) - guard let ref: SCNetworkReachability = withUnsafePointer(to: &zeroAddress, { - SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)) - }) else { return nil } - self.init(reachabilityRef: ref) - } - - deinit { - stopNotifier() - reachabilityRef = nil - whenReachable = nil - whenUnreachable = nil - } -} - -public extension Reachability { - - // MARK: - *** Notifier methods *** - func startNotifier() throws { - guard let reachabilityRef = reachabilityRef, !notifierRunning else { return } - var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil) - context.info = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) - if !SCNetworkReachabilitySetCallback(reachabilityRef, callback, &context) { - stopNotifier() - throw ReachabilityError.UnableToSetCallback - } - if !SCNetworkReachabilitySetDispatchQueue(reachabilityRef, reachabilitySerialQueue) { - stopNotifier() - throw ReachabilityError.UnableToSetDispatchQueue - } - // Perform an intial check - reachabilitySerialQueue.async { - self.reachabilityChanged() - } - notifierRunning = true - } - - func stopNotifier() { - defer { notifierRunning = false } - guard let reachabilityRef = reachabilityRef else { return } - SCNetworkReachabilitySetCallback(reachabilityRef, nil, nil) - SCNetworkReachabilitySetDispatchQueue(reachabilityRef, nil) - } - - // MARK: - *** Connection test methods *** - var isReachable: Bool { - - guard isReachableFlagSet else { return false } - - if isConnectionRequiredAndTransientFlagSet { - return false - } - if isRunningOnDevice { - if isOnWWANFlagSet && !reachableOnWWAN { - // We don't want to connect when on 3G. - return false - } - } - return true - } - - var isReachableViaWWAN: Bool { - // Check we're not on the simulator, we're REACHABLE and check we're on WWAN - return isRunningOnDevice && isReachableFlagSet && isOnWWANFlagSet - } - - var isReachableViaWiFi: Bool { - // Check we're reachable - guard isReachableFlagSet else { return false } - // If reachable we're reachable, but not on an iOS device (i.e. simulator), we must be on WiFi - guard isRunningOnDevice else { return true } - // Check we're NOT on WWAN - return !isOnWWANFlagSet - } - - var description: String { - - let W = isRunningOnDevice ? (isOnWWANFlagSet ? "W" : "-") : "X" - let R = isReachableFlagSet ? "R" : "-" - let c = isConnectionRequiredFlagSet ? "c" : "-" - let t = isTransientConnectionFlagSet ? "t" : "-" - let i = isInterventionRequiredFlagSet ? "i" : "-" - let C = isConnectionOnTrafficFlagSet ? "C" : "-" - let D = isConnectionOnDemandFlagSet ? "D" : "-" - let l = isLocalAddressFlagSet ? "l" : "-" - let d = isDirectFlagSet ? "d" : "-" - return "\(W)\(R) \(c)\(t)\(i)\(C)\(D)\(l)\(d)" - } -} - -fileprivate extension Reachability { - - func reachabilityChanged() { - let flags = reachabilityFlags - guard previousFlags != flags else { return } - let block = isReachable ? whenReachable : whenUnreachable - block?(self) - if ReachabilityChangedNotification.rawValue != "" { - self.notificationCenter.post(name: ReachabilityChangedNotification, object:self) - } - previousFlags = flags - } - - var isOnWWANFlagSet: Bool { - #if os(iOS) - return reachabilityFlags.contains(.isWWAN) - #else - return false - #endif - } - var isReachableFlagSet: Bool { - return reachabilityFlags.contains(.reachable) - } - var isConnectionRequiredFlagSet: Bool { - return reachabilityFlags.contains(.connectionRequired) - } - var isInterventionRequiredFlagSet: Bool { - return reachabilityFlags.contains(.interventionRequired) - } - var isConnectionOnTrafficFlagSet: Bool { - return reachabilityFlags.contains(.connectionOnTraffic) - } - var isConnectionOnDemandFlagSet: Bool { - return reachabilityFlags.contains(.connectionOnDemand) - } - var isConnectionOnTrafficOrDemandFlagSet: Bool { - return !reachabilityFlags.intersection([.connectionOnTraffic, .connectionOnDemand]).isEmpty - } - var isTransientConnectionFlagSet: Bool { - return reachabilityFlags.contains(.transientConnection) - } - var isLocalAddressFlagSet: Bool { - return reachabilityFlags.contains(.isLocalAddress) - } - var isDirectFlagSet: Bool { - return reachabilityFlags.contains(.isDirect) - } - var isConnectionRequiredAndTransientFlagSet: Bool { - return reachabilityFlags.intersection([.connectionRequired, .transientConnection]) == [.connectionRequired, .transientConnection] - } - - var reachabilityFlags: SCNetworkReachabilityFlags { - - guard let reachabilityRef = reachabilityRef else { return SCNetworkReachabilityFlags() } - - var flags = SCNetworkReachabilityFlags() - let gotFlags = withUnsafeMutablePointer(to: &flags) { - SCNetworkReachabilityGetFlags(reachabilityRef, UnsafeMutablePointer($0)) - } - - if gotFlags { - return flags - } else { - return SCNetworkReachabilityFlags() - } - } -} diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel-d.png b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel-d.png deleted file mode 100644 index fa432a55d32f8e321808401315985797224b4ab7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1041 zcmaJ=PiWIn7|&324kidYY-5MFOmL!2nzYT@usXY@vxQ}puDCi-%#znNcFBv$tIeti z^AAH1**pll^rQ!c?IiwXcu)r(ytsoP4nY{=X&`zM#h0#~9yUXg_uj|%`+dLf&%2Qx zInmnE*+NlNYbq&a$hz12n)i_ZtIXIcSvqhcheuH!mlYdQF%3;XkTR4>n1PBmef|yX zr>I>A^=uC3u>xFU%5+3GO4oQrviHm^4Qej97^OEw<>WMoBO8Jc z6Y!~ijst?gaKVrua7O{}=XlmnUctu&#gHKKeW3o(B$}<|#f&smk3~*Vx`44IvTV6r zX37Bu*^?|6i9|dOp7#+CpEGS@#r2s^PlG{%j%w=`){zN3Mr8t(aFixWH&ZaIEn3s5 zmx&aNbrp-{7{8ZN!%>$1?`jxZ-VV;dzk0VNcCynJWHZn~C0iwp%lCMpEHQ3F1tU9) z&{U&}=>o#YDIg2PM+ML;E2?gKhQl?4EQ=}A!HTKEloX{22czqnD8*u2I3^{6VLrxj z34V|dB&5C=9}Xl!k`#zHuo6;B1~hR4s}XD>7?2{tAWyJ^+hV<8Ff0;Tg0_AEYC|?M zKrLxe-&sq1XDyppZ5u81Jft15ED^(ct^KFf4HKCkZ@V?PUN1*f|2CRbQ2bzfV!^suV~tTY#W=N5bK`B(13jpbRV^1A%s{l~Ph w_N2Os#+T@CW7Xe_Xl?z=(7V%@e};FrQ|{O9`@?5Wc6ygIl^Bth2G3sk11qCa#{d8T diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel-d@2x.png b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel-d@2x.png deleted file mode 100644 index 8f359b8a5ed12145a0cd57d6d154813afae655fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1245 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%qp275hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)y-fM)1rW~NxVni#uSnwVIcSQt4O8oC-e85z5}m^&I-7`vLf zxEMRb^t$9Hm*%GCmB93-AoM!o)C)=sxdlL*T~doO%TiO^it=+6z@E0s#O)SyoaRCG zrr>sq1x~&CK*#8Vq82HtVM4(417gAxE|3FH`l)%q^j-u^*b^$x{9|BX^!Ide45_%) z66EQ1BtT&8naL@#N;lILEp)!{y<&aCyhYEpZ{7m^2dXTBQ`?>}7{1oAQYlk=UHkc= z^4(t#R9!>&O8r>sd)dWd-gC46?`D{vQGUkwH{o!Marl{b6W{FxSpu70On9sQjPq}= z`7_gQ`>i^sFT9jov@COlj(67WX-`yUEt~jym&kF$%6aV9tv?@na$eWPL$9kz=D6bh z@1EC76=jZ3+_g@4ql#z1lNootImA6ytm-;sAQI|(S!6Cl$-Ce440wwcX*5+cK9tlc z;b>~exh=L$Yl}`d&*25T);(RfTp-DPBfE>o1f`wI9XAYkF1>wm=}<+My66YRHW^Ni z?O9K2e~8|9_`$`k{EuBVeeHR1#bXolw{v%BE?%clb7XN6`_Ho73y#&Dh}u4v}$3MR z%5;i&QT*D$i+bA-4|0y57alwb3SJZxeCgWFgEb_1@BR7xe*e#RerRxS zWBty0ilQ1515%Q#b>6pi3;91uj=UgCGmfY6Fv{S9VneD|Lt_vm3?&PbP|=DfmS7h} zZEDw3X`Gh#iz+f0#ltYJVG%Y(b@jNGqUIq6V=$|mQTpq`V;bmMlpYDme%Xq_oIX&p z;c#g%rIzw)M5BAUL6<8M0Rv(MxW>5Yh;EcF>xyLWnOPc?AvhnUSA$B+Lm-B12trK2 zr}{Y#2m-?eLxRBV0lc5%SwDFN9~Trug2;zK<)Mi;Tg!+^slVcjoT79NV@qV&LZQGE z0t~XVEEkDHJPn@r5roevnpkmtrqfnckf5X5x`lOQ0#8vHLlZbklSo%nFswCM)2Wn+ z6pVEhi{%)RD)VdUhH1!BVj*d;5fZhD4}GDDWdgy~?#RAEAj(nN#Nbxn*115zXy3kWfp5zi8|^^;KRw~+zLNsD^zSOPWm zDqO90EWw&wmIT9kt^KRjRTG&XZ@V_Ql3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)y-fM)1rW~NxVnwq(pyBRu~SQt4O8oC-e85z5}m^&I-7`vLf zxEMRb^t$9Hm*%GCmB93-AoM!n)C)=sxdlL*T~doO%TiO^it=+6z@E0s#O4+gV;4&k z6Wr!O^`>BR3q-FoPPga-9itD5TBN9k2?5g&hzU=)Kn^_Vr{)3Edl4{UJFYEW%)r3N z>*?YcQgLfa(80{Z4gz19D)#UPJabNnrhnjgcQAL>vT2U4%09s_ z_&<2I6*5dWm>)9l`J6AFlY_i^3>R$`%WCSqy-hTG?T*WT8`ewpo9BB?a#^JD%lNB% zQ(BLu8H?OO)6ir3eq6lU6ZHC$|IfT=vApOmo8T3jV9EQ1JdS4%|CsTAS@X5~_hc=m7e!BnMZ~(g>qzIG~ThoM-|pEbAixkE!AqNCHvLU;GGy7`FF> zl1jt0(8o!-N{SAKv{eJKF)Y|=8={m25FY_!iWVX^UcMo4MGg^zUV#>j2*@bClO`CL zjHjf@tQ3%m&JH|ib4Wl1P{eI@T(dYkL=<#6w0F!Dffpb!8zOdsN(%`*qMHEsl5Uqo zGYszYk&MUd^D%8WOEWA*qu1wRJe=3Zv3|Vx5XhS;k8(-AyXXs@LPQ2agQKWiE=T6v zq;8H;Odt?&G+5S!5H2gPLD6<;R!d2N2bN?i22^wncNE1DeFBCE6zNV1s!^8JtYVo^ z!6;iaD2Ak+luAHB_&-!t%V-NG!EU_&6t+@%15im|=@X`e8aLYFxH7ni2}G!yDP12g zRWXs#p>Ab#1CI>&@RNclDVk$wEieRui)j`VH3`J{5P>vEMUlBK+TTtGqCQVM>t~oK z+r_%0yg$sgyQ5y7cSlNGUY90RpurMX-sSo$a-CsN4dj^zrg90$-KMVMg`_#9ax9*T zdPS~WITmk4E`@@joYwx;>XHe~kFzZgE;^J)A82UaO*Gh>SNA2*rI?QK;gtQoFU}l! zkJq~QbCKNC+U)sf&xbm{Og$J{n69fmbMW-a;9|0EOWuC8`mkZW@$KBJyY=jy!+HO) zrF&oJts84i%ejsDx#i6Z=i*ZJ_1fXtaJFW#?!$}Lh2uxl*&jWRe+~xwmxx>6exLdj s{oMR?`*x~%W|;23ymkNV>nqxxYV2Kyr{UL3{kn5eW6?POq-*%vAA8DDApigX diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default-d@2x.png b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default-d@2x.png deleted file mode 100644 index 6d21603e14f6b0ac15c21633067c32221c82ce8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1247 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%qp275hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)y-fM)1rW~Nv<8yLE}nH!s$SQwcb8oC-e85z5}m^&I-7`vLf zxEMRb^t$9Hm*%GCmB93-AoQBy)C)=sxdlL*T~doO%TiO^it=+6z@E0s#O)SioaRCG zrr>sq2~NHGK*#8Vq82HtVM4(417gAxE|3FH`l)%q^j-u^*d6aP#2FYE13g_FLn?07 z1bO?lI0)$OJDh*8NtRRHK(f^Ep5xvIIfvLPnS2BB4?=3kR?L(Z2otzr(BRB*EqnLm zGN)&%{9UW6uFB6dJa5bx8oKjORnk4f^D_khE=+wlBl?;5Bo%fQUXI8qMSo7&EWi9C z<=&**KZ-Fh8yIoA*3WqAewI znt<^$&GFrt!MS3gdlEPEnk9_aH1u*MD?^iOjLp?tza4D$B@pScbS?83{ F1OUq6tL6Xz diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default.png b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default.png deleted file mode 100644 index 17eab59209babad2fe43fd721463dd754f35cd59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1035 zcmaJ=O-K|`93POZBr6CKI}Kw{W;q^U4(OZ8 zDhHvJ63^32HN_ywXdG&;ewa4hA%q z2G0jDBH&J1Nc94i+fq@GfU7x%jSOg!zM@)y6DUF9NHP;b_)RsRC4#|3gi)igr;JY{$E!u$!B-0h0wToNzSUxZxJxl`V)4P!V);5RO%< z*jt1MxhdqoXn^A zpe#j`d@Lx3B`GLYxDwPROkkl3SKsFHHM#yUm^St-0mnEG^iBtwWI1WU*ddk_8;!AX zIaX6|i>ud;g{{eDa4?MD+J9PIG2!{~x7ESLhwA793(vcQ2m49W_y)cd7t>NQ=e_C4 zaQmmpePfNBI&|&lr>3{)d)=>H(K}shGc$A31DE$Mo>|=(T>i53dHy5O^l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)y-fM)1rW~Nv<8yLE}nHyW0SQwcb8oC-e85z5}m^&I-7`vLf zxEMRb^t$9Hm*%GCmB93-AoM!o)C)=sxdlL*T~doO%TiO^it=+6z@E0s#O)SyoaRCG zrr>sq1x~&CK*#8Vq82HtVM4(417gAxE|3FH`l)%q^j-u^*vFi^_!$@&c|2VlLn>~~ z2{O!Ub`ZE@%^03wwQJ9TAeG%-at~`1!d@Mz3;e|3{m;Q};xR8J?@C9l7Y0WoIgFa$ zE4eUkbDx!LnO5e1e8sZNmJ^?C4kfeNHEn<3;%CuNUBJC>X=c@vWs3xtNnd&YAg1jj zr`>@+t2gO9Ucx_X%eADQi3%Jpnpd@M?pUR@@tRlc^*g_q-ZSgy-xE3hasR>Q_lXkQ z&Ys$|q_XX8dT**Hqxx6hzid}5bSgu-mAodUTzJtRE5ho1x^v=ti?+UF89Rkcbuc<45>c0kqBrZVc4!-B=Dqjl_xt@n-5x=m=R5Yg=M`P;4xK9g9H%e?7(x- zh+*sYDajN}39YQ8s~*w8cx=@`Yz%7**@h_f0f={lw4!mumq$+sT#-4VBOrJMBMN$z z!^0+MAC4!b;XWxS6QP56qs<}#6+jWU)qc%lZH~z4vS{y^NdnJ7U>`>;2bB`q@ThJA zJmB%UB`-zc4CA5v0fwOt;Ix;bNiTXCH|1vo3`^JH`G-K>Ou2_m@XdK&=)@7d5E?8= zW-=L1#^=$^G)V=6K}Un8-3Z~fvKka^w`Nrr6nJ1sreZ)v*KkKs?A8Y%N1#ZTQ&5c+ zSP$*cj$1hDi$Q$mgFsdii$Y}5oI z)Xk)>_ZOeUTA+RorLf+#7PV{qjdg22W!3yPWqVmwD64UeM8EFY|^_cv2v zAJ5Pf)kH_Uyf4Bx2PnoDjnMVs0+-jNK^17Qz?E0Ik)m8@7*qp!=7FgU0lC@KRXmq8 zs}zr=zNlWFD;JL?Sd>emU`VI6f3><`Li6KnR|XdyRz@FaXx>dU*e_i#explqF2;wG z_I&HvhON`yaz3rjmbk9WS$pG$nvTrFxq&qg)^^5cN=6g-*uu8EHQR6c-;ZZ6yfr_l z+{pg>*WSE7U3Gn8Vc^pAyO1Rl3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)y-fM)1rW~NxVTDV!b8JW5nyO^068oC-e8Mqibxwx4cni)Gg z8Cf{O^t$9Hm*%GCmB93-!1bCL;M5CB47mkBn_W_iGRsm^+=}vZ6~Lah%Eav!7o6rn z^`_u-i>WJ4z4}1M=!2pbDXL*Y!1M!R!V@l#15f&?dBF5u1Wed1Z1aj37#Q6>T^vIy zZcUjK?{(Ng;8=S4=1eBmkG_I7jSuFt?`>LizRR}Z*Neh0EJw=^8gnRV?QLj!uv_

3+>w5_|A|Bj1|*U=&S zL;gbDpZDi2P(JYf+1HBslizWk-8;Si=X8;Mzk=sRO`U2p`A*conznC3HFJc2xfv>| zO`jud%DAdv(ju;%S8b-Bd8KwJoyA?}hmLooUo5j#sG;B!(J2hZ>y2D})7W|XIo@3; zmM}cBL}UVMiqc8zgvBn*61lS#&Ug52YZNjunEQF7Js#5(a`SQBj1ZTPG#dF>w#0|qz4{FT}X8xMgB8c$b0mvv4FO#nR!s&fDU diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive.png b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive.png deleted file mode 100644 index 28f3264e5c4081f75035c44e8565703ae6949ca9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1033 zcmaJ=O=#0l9M7E0eK;sy{6O@Pm7%aEP1>eyXt%XZ;|gYsuDIS@n!K)|%ZJIE&8E0+ zsIY?vcM-vph(}=}f+$R32%emX2!ib7ZZh;Bc#!$ht(}L>kmSAh=l}ctfB%oSG&Xvn zxBFB#K@h#U5h0J)Bi`59f&XjyiH~?WiLymBZkAC^wjq&H%@PDTU7mt@D66wq-oXSx zwEML}5f!D2ykhEvid0Bn$9=^%c&02AgT9M49Gw(M&uZ_c&NKfIR}vtbt@VU^snE1_3&XtyxGj4d5}#C36NPNvw1y1>I`V8qRK+ zaKUI-wrGY5dMPy>CF%dJy5913P#*5--Iv%Y%vzAnL&u!472LRTpBKvFGd7fwX%|d$ zx>?1siiu38Vp5}z|1BpV9M2}u%jP@1Ol*_ap;*+@DhaAAhY zvgx1@N(*9y;X;`-8%s5@f~m~t&_GSBx`)jii1mg+w{Tw zjfF+V<74;NvV&C*){;6<3ysClUTgnpb<>3B$J@3B7av-q4-Gu;HXiK0=;dGdQe4Xk zse=2Zbp6EUo42oDulKGo!vlxcwiaB*ckd~&L~;F(6K5`!JNiZO_WbsC&yC-IqFbL= z=Qr-xmsf&aKH>uy^gUYi-9n diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive@2x.png b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive@2x.png deleted file mode 100644 index 1a82328a00c35f68fad523dcd1e6c703a73632bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1187 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%qp275hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)y-fM)1rW~NxVTDV!b8JQUyyO^068oC-e8Mqibxwx4cni)Gg z8Cf{O^t$9Hm*%GCmB93-AoQBx)C)=sxdlL*T~doO%TiO^it=+6z@E0s#O)SCoaRCG zrr>sq5l+4OK*#8Vq82HtVM4(417gAxE|3FH`l)%q^j-u^*!=SQTp1V`MLk^{Ln>~~ z39`;RJoFJfdLYyP0iYtRBt&)HJ z(pIK!o0n^kZ+`!_ugq=jR;M-9`GR)u6XbImLQigBO)lW6yQY4*#dE3PGO0)TA3XDt zIm;6MUB3TLJAc+ikriG`MLZ-V0+*-Q{{Et|+gU3!>@NQetwhPE%i1+WuAbKZA^mW{ z1&Ny~)wAR$N=fN3b5&g4`tlLOSra~Hsd$Nvdz30>rMm^j1qs^t-aKLNm^^8JoS@Cw zX~$Z3sOvW^@9dr3Q9S=mZ}v|2-orDF>6=YGn>t@;PS*NU$>+XKSSf1zy-#NOva=Jd v_iHit3I1R_7r9gY-cFhCv;4Hx8QB;<-OYUedI`sEP_g0Z>gTe~DWM4f3PX@d diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.h b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.h deleted file mode 100644 index 49eaae22f..000000000 --- a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.h +++ /dev/null @@ -1,69 +0,0 @@ -// SIAlertView.h -// SIAlertView -// Created by Kevin Cao on 13-4-29. -// Copyright (c) 2013年 Sumi Interactive. All rights reserved. - -#import -extern NSString *const SIAlertViewWillShowNotification; -extern NSString *const SIAlertViewDidShowNotification; -extern NSString *const SIAlertViewWillDismissNotification; -extern NSString *const SIAlertViewDidDismissNotification; -typedef NS_ENUM(NSInteger, SIAlertViewButtonType) { - SIAlertViewButtonTypeDefault = 0, - SIAlertViewButtonTypeDestructive, - SIAlertViewButtonTypeCancel -}; -typedef NS_ENUM(NSInteger, SIAlertViewBackgroundStyle) { - SIAlertViewBackgroundStyleGradient = 0, - SIAlertViewBackgroundStyleSolid, -}; -typedef NS_ENUM(NSInteger, SIAlertViewButtonsListStyle) { - SIAlertViewButtonsListStyleNormal = 0, - SIAlertViewButtonsListStyleRows -}; -typedef NS_ENUM(NSInteger, SIAlertViewTransitionStyle) { - SIAlertViewTransitionStyleSlideFromBottom = 0, - SIAlertViewTransitionStyleSlideFromTop, - SIAlertViewTransitionStyleFade, - SIAlertViewTransitionStyleBounce, - SIAlertViewTransitionStyleDropDown -}; -@class SIAlertView; -typedef void(^SIAlertViewHandler)(SIAlertView *alertView); -@interface SIAlertView : UIView -@property (nonatomic, copy) NSString *title; -@property (nonatomic, copy) NSString *message; -@property (nonatomic, assign) SIAlertViewTransitionStyle transitionStyle; // default is SIAlertViewTransitionStyleSlideFromBottom -@property (nonatomic, assign) SIAlertViewBackgroundStyle backgroundStyle; // default is SIAlertViewBackgroundStyleGradient -@property (nonatomic, assign) SIAlertViewButtonsListStyle buttonsListStyle; // default is SIAlertViewButtonsListStyleNormal -@property (nonatomic, copy) SIAlertViewHandler willShowHandler; -@property (nonatomic, copy) SIAlertViewHandler didShowHandler; -@property (nonatomic, copy) SIAlertViewHandler willDismissHandler; -@property (nonatomic, copy) SIAlertViewHandler didDismissHandler; -@property (nonatomic, readonly, getter = isVisible) BOOL visible; -@property (nonatomic, readonly, getter = isParallaxEffectEnabled) BOOL enabledParallaxEffect; -@property (nonatomic, strong) UIColor *viewBackgroundColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; -@property (nonatomic, strong) UIColor *titleColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; -@property (nonatomic, strong) UIColor *messageColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; -@property (nonatomic, strong) UIFont *titleFont NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; -@property (nonatomic, strong) UIFont *messageFont NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; -@property (nonatomic, strong) UIFont *buttonFont NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; -@property (nonatomic, strong) UIColor *buttonColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; -@property (nonatomic, strong) UIColor *cancelButtonColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; -@property (nonatomic, strong) UIColor *destructiveButtonColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; -@property (nonatomic, assign) CGFloat cornerRadius NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; // default is 2.0 -@property (nonatomic, assign) CGFloat shadowRadius NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; // default is 8.0 - -@property (nonatomic) BOOL shouldRemoveAfterTouch; - -- (void)setDefaultButtonImage:(UIImage *)defaultButtonImage forState:(UIControlState)state NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; -- (void)setCancelButtonImage:(UIImage *)cancelButtonImage forState:(UIControlState)state NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; -- (void)setDestructiveButtonImage:(UIImage *)destructiveButtonImage forState:(UIControlState)state NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; - -- (instancetype)initWithTitle:(NSString *)title andMessage:(NSString *)message NS_DESIGNATED_INITIALIZER; -- (void)addButtonWithTitle:(NSString *)title type:(SIAlertViewButtonType)type handler:(SIAlertViewHandler)handler; - -- (void)show; -- (void)dismissAnimated:(BOOL)animated; - -@end diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.m b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.m deleted file mode 100644 index e2f988e2d..000000000 --- a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.m +++ /dev/null @@ -1,1253 +0,0 @@ -// SIAlertView.m -// SIAlertView -// Created by Kevin Cao on 13-4-29. -// Copyright (c) 2013年 Sumi Interactive. All rights reserved. - -#import "SIAlertView.h" -#import "UIWindow+SIUtils.h" -#import -NSString *const SIAlertViewWillShowNotification = @"SIAlertViewWillShowNotification"; -NSString *const SIAlertViewDidShowNotification = @"SIAlertViewDidShowNotification"; -NSString *const SIAlertViewWillDismissNotification = @"SIAlertViewWillDismissNotification"; -NSString *const SIAlertViewDidDismissNotification = @"SIAlertViewDidDismissNotification"; -#define DEBUG_LAYOUT 0 -#define MESSAGE_MIN_LINE_COUNT 3 -#define MESSAGE_MAX_LINE_COUNT 15 -#define GAP 10 -#define CANCEL_BUTTON_PADDING_TOP 5 -#define CONTENT_PADDING_LEFT 10 -#define CONTENT_PADDING_TOP 12 -#define CONTENT_PADDING_BOTTOM 10 -#define BUTTON_HEIGHT 45.0//([[UIScreen mainScreen] bounds].size.height/(2208.0/147.0))//47 -#define CONTAINER_WIDTH 300 - -const UIWindowLevel UIWindowLevelSIAlert = 1996.0; // don't overlap system's alert -const UIWindowLevel UIWindowLevelSIAlertBackground = 1985.0; // below the alert window - -@class SIAlertBackgroundWindow; -static NSMutableArray *__si_alert_queue; -static BOOL __si_alert_animating; -static SIAlertBackgroundWindow *__si_alert_background_window; -static SIAlertView *__si_alert_current_view; - -@interface SIAlertView () - -@property (nonatomic, strong) NSMutableArray *items; -@property (nonatomic, weak) UIWindow *oldKeyWindow; -@property (nonatomic, strong) UIWindow *alertWindow; -#ifdef __IPHONE_7_0 -@property (nonatomic, assign) UIViewTintAdjustmentMode oldTintAdjustmentMode; -#endif -@property (nonatomic, assign, getter = isVisible) BOOL visible; - -@property (nonatomic, strong) UILabel *titleLabel; -@property (nonatomic, strong) UILabel *messageLabel; -@property (nonatomic, strong) UIView *containerView; -@property (nonatomic, strong) NSMutableArray *buttons; - -@property (nonatomic, assign, getter = isLayoutDirty) BOOL layoutDirty; - -+ (NSMutableArray *)sharedQueue; -+ (SIAlertView *)currentAlertView; - -+ (BOOL)isAnimating; -+ (void)setAnimating:(BOOL)animating; - -+ (void)showBackground; -+ (void)hideBackgroundAnimated:(BOOL)animated; - -- (void)setup; -- (void)invalidateLayout; -- (void)resetTransition; - -@end - -#pragma mark - SIBackgroundWindow - -@interface SIAlertBackgroundWindow : UIWindow - -@end - -@interface SIAlertBackgroundWindow () - -@property (nonatomic, assign) SIAlertViewBackgroundStyle style; - -@end - -@implementation SIAlertBackgroundWindow - -- (instancetype)initWithFrame:(CGRect)frame andStyle:(SIAlertViewBackgroundStyle)style -{ - self = [super initWithFrame:frame]; - if (self) { - self.style = style; - self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - self.opaque = NO; - self.windowLevel = UIWindowLevelSIAlertBackground; - } - return self; -} - -- (void)drawRect:(CGRect)rect -{ - CGContextRef context = UIGraphicsGetCurrentContext(); - switch (self.style) { - case SIAlertViewBackgroundStyleGradient: - { - size_t locationsCount = 2; - CGFloat locations[2] = {0.0f, 1.0f}; - CGFloat colors[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.75f}; - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount); - CGColorSpaceRelease(colorSpace); - - CGPoint center = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2); - CGFloat radius = MIN(self.bounds.size.width, self.bounds.size.height) ; - CGContextDrawRadialGradient (context, gradient, center, 0, center, radius, kCGGradientDrawsAfterEndLocation); - CGGradientRelease(gradient); - break; - } - case SIAlertViewBackgroundStyleSolid: - { - [[UIColor colorWithWhite:0 alpha:0.5] set]; - CGContextFillRect(context, self.bounds); - break; - } - } -} - -@end - -#pragma mark - SIAlertItem -@interface SIAlertItem : NSObject -@property (nonatomic, copy) NSString *title; -@property (nonatomic, assign) SIAlertViewButtonType type; -@property (nonatomic, copy) SIAlertViewHandler action; -@end -@implementation SIAlertItem -@end - -#pragma mark - SIAlertViewController -@interface SIAlertViewController : UIViewController -@property (nonatomic, strong) SIAlertView *alertView; -@end - -@implementation SIAlertViewController - -#pragma mark - View life cycle - -- (void)loadView -{ - self.view = self.alertView; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - [self.alertView setup]; -} - -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration -{ - [self.alertView resetTransition]; - [self.alertView invalidateLayout]; -} - -#ifdef __IPHONE_7_0 -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration -{ - if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) { - [self setNeedsStatusBarAppearanceUpdate]; - } -} -#endif - -- (UIInterfaceOrientationMask)supportedInterfaceOrientations -{ - UIViewController *viewController = [self.alertView.oldKeyWindow currentViewController]; - if (viewController) { - return [viewController supportedInterfaceOrientations]; - } - return UIInterfaceOrientationMaskAll; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation -{ - UIViewController *viewController = [self.alertView.oldKeyWindow currentViewController]; - if (viewController) { - return [viewController shouldAutorotateToInterfaceOrientation:toInterfaceOrientation]; - } - return YES; -} - -- (BOOL)shouldAutorotate -{ - UIViewController *viewController = [self.alertView.oldKeyWindow currentViewController]; - if (viewController) { - return [viewController shouldAutorotate]; - } - return YES; -} - -#ifdef __IPHONE_7_0 -- (UIStatusBarStyle)preferredStatusBarStyle -{ - UIWindow *window = self.alertView.oldKeyWindow; - if (!window) { - window = [UIApplication sharedApplication].windows[0]; - } - return [[window viewControllerForStatusBarStyle] preferredStatusBarStyle]; -} - -- (BOOL)prefersStatusBarHidden -{ - UIWindow *window = self.alertView.oldKeyWindow; - if (!window) { - window = [UIApplication sharedApplication].windows[0]; - } - return [[window viewControllerForStatusBarHidden] prefersStatusBarHidden]; -} -#endif - -@end - -#pragma mark - SIAlert - -@implementation SIAlertView - -+ (void)initialize { - if (self != [SIAlertView class]) - return; - SIAlertView *appearance = [self appearance]; - appearance.viewBackgroundColor = [UIColor whiteColor]; - appearance.titleColor = [UIColor blackColor]; - appearance.messageColor = [UIColor darkGrayColor]; - appearance.titleFont = [UIFont fontWithName:@"SegoeUI" size:20.0]; // FONT_MAVEN_REGULAR - appearance.messageFont = [UIFont fontWithName:@"SegoeUI-Light" size:18.0];// FONT_MAVEN_LIGHT_300 - appearance.buttonFont = [UIFont fontWithName:@"SegoeUI" size:20.0];// FONT_MAVEN_REGULAR - appearance.buttonColor = [UIColor whiteColor];//[UIColor colorWithRed:39.0/255.0 green:75.0/255.0 blue:160.0/255.0 alpha:1.0]; - appearance.cancelButtonColor = [UIColor whiteColor]; - appearance.destructiveButtonColor = [UIColor whiteColor];//[UIColor colorWithRed:77.0/255.0 green:184.0/255.0 blue:49.0/255.0 alpha:1.0]; - appearance.destructiveButtonColor = [UIColor whiteColor]; - appearance.cornerRadius = 5.0; - appearance.shadowRadius = 5.0; -} -/* -- (instancetype)init -{ - return [self initWithTitle:nil andMessage:nil]; -}*/ - -- (instancetype)initWithTitle:(NSString *)title andMessage:(NSString *)message { - self = [super initWithFrame:CGRectZero]; - if (self) { - - if (title.length > 0) { // Check Added because nill could not be passed (from swift) - _title = title; - } else { - _title = nil; - } - _message = message; - _enabledParallaxEffect = YES; - self.items = [[NSMutableArray alloc] init]; - } - return self; -} - -#pragma mark - Class methods - -+ (NSMutableArray *)sharedQueue -{ - if (!__si_alert_queue) { - __si_alert_queue = [NSMutableArray array]; - } - return __si_alert_queue; -} - -+ (SIAlertView *)currentAlertView -{ - return __si_alert_current_view; -} - -+ (void)setCurrentAlertView:(SIAlertView *)alertView -{ - __si_alert_current_view = alertView; -} - -+ (BOOL)isAnimating -{ - return __si_alert_animating; -} - -+ (void)setAnimating:(BOOL)animating { - __si_alert_animating = animating; -} - -+ (void)showBackground { - if (!__si_alert_background_window) { - CGRect frame = [UIScreen mainScreen].bounds; - if([[UIScreen mainScreen] respondsToSelector:@selector(fixedCoordinateSpace)]) - { - frame = [[UIScreen mainScreen].fixedCoordinateSpace convertRect:frame fromCoordinateSpace:[UIScreen mainScreen].coordinateSpace]; - } - - __si_alert_background_window = [[SIAlertBackgroundWindow alloc] initWithFrame:frame - andStyle:[SIAlertView currentAlertView].backgroundStyle]; - [__si_alert_background_window makeKeyAndVisible]; - __si_alert_background_window.alpha = 0; - [UIView animateWithDuration:0.3 - animations:^{ - __si_alert_background_window.alpha = 1; - }]; - } -} - -- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - UITouch *touch = [touches anyObject]; - CGPoint location = [touch locationInView:self]; -// NSLog(@"%@",self.containerView); - if (self.shouldRemoveAfterTouch && self.containerView) { - if (!(((location.y > CGRectGetMinY(self.containerView.frame)) && (location.y < CGRectGetMaxY(self.containerView.frame))) && ((location.x > CGRectGetMinX(self.containerView.frame)) && (location.x < CGRectGetMaxX(self.containerView.frame))))) { - self.shouldRemoveAfterTouch = NO; - [self dismissAnimated:YES]; - } - } -} - -+ (void)hideBackgroundAnimated:(BOOL)animated -{ - if (!animated) { - [__si_alert_background_window removeFromSuperview]; - __si_alert_background_window = nil; - return; - } - [UIView animateWithDuration:0.3 - animations:^{ - __si_alert_background_window.alpha = 0; - } - completion:^(BOOL finished) { - [__si_alert_background_window removeFromSuperview]; - __si_alert_background_window = nil; - }]; -} - -#pragma mark - Setters - -- (void)setTitle:(NSString *)title -{ - _title = title; - [self invalidateLayout]; -} - -- (void)setMessage:(NSString *)message -{ - _message = message; - [self invalidateLayout]; -} - -#pragma mark - Public - -- (void)addButtonWithTitle:(NSString *)title type:(SIAlertViewButtonType)type handler:(SIAlertViewHandler)handler -{ - SIAlertItem *item = [[SIAlertItem alloc] init]; - item.title = title; - item.type = type; - item.action = handler; - [self.items addObject:item]; -} - -- (void)show -{ - if (self.isVisible) { - return; - } - - self.oldKeyWindow = [UIApplication sharedApplication].keyWindow; -#ifdef __IPHONE_7_0 - if ([self.oldKeyWindow respondsToSelector:@selector(setTintAdjustmentMode:)]) { // for iOS 7 - self.oldTintAdjustmentMode = self.oldKeyWindow.tintAdjustmentMode; - self.oldKeyWindow.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed; - } -#endif - - if (![[SIAlertView sharedQueue] containsObject:self]) { - [[SIAlertView sharedQueue] addObject:self]; - } - - if ([SIAlertView isAnimating]) { - return; // wait for next turn - } - - if ([SIAlertView currentAlertView].isVisible) { - SIAlertView *alert = [SIAlertView currentAlertView]; - [alert dismissAnimated:YES cleanup:NO]; - return; - } - - if (self.willShowHandler) { - self.willShowHandler(self); - } - - [[NSNotificationCenter defaultCenter] postNotificationName:SIAlertViewWillShowNotification object:self userInfo:nil]; - - self.visible = YES; - - [SIAlertView setAnimating:YES]; - [SIAlertView setCurrentAlertView:self]; - - // transition background - [SIAlertView showBackground]; - - SIAlertViewController *viewController = [[SIAlertViewController alloc] initWithNibName:nil bundle:nil]; - viewController.alertView = self; - - if (!self.alertWindow) { - UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - window.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - window.opaque = NO; - window.windowLevel = UIWindowLevelSIAlert; - window.rootViewController = viewController; - self.alertWindow = window; - } - [self.alertWindow makeKeyAndVisible]; - - [self validateLayout]; - [self.containerView setClipsToBounds:YES]; - - CGFloat yAxisOfBackgroundLayer = self.containerView.frame.size.height - BUTTON_HEIGHT - 0.5; - UIView *backgroundLayerOfButtons = [[UIView alloc] init]; - backgroundLayerOfButtons.frame = CGRectMake(0, yAxisOfBackgroundLayer, self.containerView.frame.size.width, self.containerView.frame.size.height - yAxisOfBackgroundLayer); - backgroundLayerOfButtons.backgroundColor = [UIColor colorWithRed:04.0/255.0 green:202.0/255.0 blue:169.0/255.0 alpha:1.0]; - [self.containerView insertSubview:backgroundLayerOfButtons atIndex:0]; - - [self transitionInCompletion:^{ - if (self.didShowHandler) { - self.didShowHandler(self); - } - [[NSNotificationCenter defaultCenter] postNotificationName:SIAlertViewDidShowNotification object:self userInfo:nil]; - #ifdef __IPHONE_7_0 - [self addParallaxEffect]; - #endif - - [SIAlertView setAnimating:NO]; - - NSInteger index = [[SIAlertView sharedQueue] indexOfObject:self]; - if (index < [SIAlertView sharedQueue].count - 1) { - [self dismissAnimated:YES cleanup:NO]; // dismiss to show next alert view - } - }]; -} - -- (void)dismissAnimated:(BOOL)animated -{ - [self dismissAnimated:animated cleanup:YES]; -} - -- (void)dismissAnimated:(BOOL)animated cleanup:(BOOL)cleanup -{ - BOOL isVisible = self.isVisible; - - if (isVisible) { - if (self.willDismissHandler) { - self.willDismissHandler(self); - } - [[NSNotificationCenter defaultCenter] postNotificationName:SIAlertViewWillDismissNotification object:self userInfo:nil]; - #ifdef __IPHONE_7_0 - [self removeParallaxEffect]; - #endif - } - - void (^dismissComplete)(void) = ^{ - self.visible = NO; - - [self teardown]; - - [SIAlertView setCurrentAlertView:nil]; - - SIAlertView *nextAlertView; - NSInteger index = [[SIAlertView sharedQueue] indexOfObject:self]; - if (index != NSNotFound && index < [SIAlertView sharedQueue].count - 1) { - nextAlertView = [SIAlertView sharedQueue][index + 1]; - } - - if (cleanup) { - [[SIAlertView sharedQueue] removeObject:self]; - } - - [SIAlertView setAnimating:NO]; - - if (isVisible) { - if (self.didDismissHandler) { - self.didDismissHandler(self); - } - [[NSNotificationCenter defaultCenter] postNotificationName:SIAlertViewDidDismissNotification object:self userInfo:nil]; - } - - // check if we should show next alert - if (!isVisible) { - return; - } - - if (nextAlertView) { - [nextAlertView show]; - } else { - // show last alert view - if ([SIAlertView sharedQueue].count > 0) { - SIAlertView *alert = [SIAlertView sharedQueue].lastObject; - [alert show]; - } - } - }; - - if (animated && isVisible) { - [SIAlertView setAnimating:YES]; - [self transitionOutCompletion:dismissComplete]; - - if ([SIAlertView sharedQueue].count == 1) { - [SIAlertView hideBackgroundAnimated:YES]; - } - - } else { - dismissComplete(); - - if ([SIAlertView sharedQueue].count == 0) { - [SIAlertView hideBackgroundAnimated:YES]; - } - } - - UIWindow *window = self.oldKeyWindow; -#ifdef __IPHONE_7_0 - if ([window respondsToSelector:@selector(setTintAdjustmentMode:)]) { - window.tintAdjustmentMode = self.oldTintAdjustmentMode; - } -#endif - if (!window) { - window = [UIApplication sharedApplication].windows[0]; - } - [window makeKeyWindow]; - window.hidden = NO; -} - -#pragma mark - Transitions - -- (void)transitionInCompletion:(void(^)(void))completion -{ - switch (self.transitionStyle) { - case SIAlertViewTransitionStyleSlideFromBottom: - { - CGRect rect = self.containerView.frame; - CGRect originalRect = rect; - rect.origin.y = self.bounds.size.height; - self.containerView.frame = rect; - [UIView animateWithDuration:0.3 - animations:^{ - self.containerView.frame = originalRect; - } - completion:^(BOOL finished) { - if (completion) { - completion(); - } - }]; - } - break; - case SIAlertViewTransitionStyleSlideFromTop: - { - CGRect rect = self.containerView.frame; - CGRect originalRect = rect; - rect.origin.y = -rect.size.height; - self.containerView.frame = rect; - [UIView animateWithDuration:0.3 - animations:^{ - self.containerView.frame = originalRect; - } - completion:^(BOOL finished) { - if (completion) { - completion(); - } - }]; - } - break; - case SIAlertViewTransitionStyleFade: - { - self.containerView.alpha = 0; - [UIView animateWithDuration:0.3 - animations:^{ - self.containerView.alpha = 1; - } - completion:^(BOOL finished) { - if (completion) { - completion(); - } - }]; - } - break; - case SIAlertViewTransitionStyleBounce: - { - CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"]; - animation.values = @[@(0.01), @(1.2), @(0.9), @(1)]; - animation.keyTimes = @[@(0), @(0.4), @(0.6), @(1)]; - animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; - animation.duration = 0.5; - animation.delegate = self; - [animation setValue:completion forKey:@"handler"]; - [self.containerView.layer addAnimation:animation forKey:@"bouce"]; - } - break; - case SIAlertViewTransitionStyleDropDown: - { - CGFloat y = self.containerView.center.y; - CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.y"]; - animation.values = @[@(y - self.bounds.size.height), @(y + 20), @(y - 10), @(y)]; - animation.keyTimes = @[@(0), @(0.5), @(0.75), @(1)]; - animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; - animation.duration = 0.4; - animation.delegate = self; - [animation setValue:completion forKey:@"handler"]; - [self.containerView.layer addAnimation:animation forKey:@"dropdown"]; - } - break; - default: - break; - } -} - -- (void)transitionOutCompletion:(void(^)(void))completion -{ - switch (self.transitionStyle) { - case SIAlertViewTransitionStyleSlideFromBottom: - { - CGRect rect = self.containerView.frame; - rect.origin.y = self.bounds.size.height; - [UIView animateWithDuration:0.3 - delay:0 - options:UIViewAnimationOptionCurveEaseIn - animations:^{ - self.containerView.frame = rect; - } - completion:^(BOOL finished) { - if (completion) { - completion(); - } - }]; - } - break; - case SIAlertViewTransitionStyleSlideFromTop: - { - CGRect rect = self.containerView.frame; - rect.origin.y = -rect.size.height; - [UIView animateWithDuration:0.3 - delay:0 - options:UIViewAnimationOptionCurveEaseIn - animations:^{ - self.containerView.frame = rect; - } - completion:^(BOOL finished) { - if (completion) { - completion(); - } - }]; - } - break; - case SIAlertViewTransitionStyleFade: - { - [UIView animateWithDuration:0.25 - animations:^{ - self.containerView.alpha = 0; - } - completion:^(BOOL finished) { - if (completion) { - completion(); - } - }]; - } - break; - case SIAlertViewTransitionStyleBounce: - { - CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"]; - animation.values = @[@(1), @(1.2), @(0.01)]; - animation.keyTimes = @[@(0), @(0.4), @(1)]; - animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; - animation.duration = 0.35; - animation.delegate = self; - [animation setValue:completion forKey:@"handler"]; - [self.containerView.layer addAnimation:animation forKey:@"bounce"]; - self.containerView.transform = CGAffineTransformMakeScale(0.01, 0.01); - } - break; - case SIAlertViewTransitionStyleDropDown: - { - CGPoint point = self.containerView.center; - point.y += self.bounds.size.height; - [UIView animateWithDuration:0.3 - delay:0 - options:UIViewAnimationOptionCurveEaseIn - animations:^{ - self.containerView.center = point; - CGFloat angle = ((CGFloat)arc4random_uniform(100) - 50.f) / 100.f; - self.containerView.transform = CGAffineTransformMakeRotation(angle); - } - completion:^(BOOL finished) { - if (completion) { - completion(); - } - }]; - } - break; - default: - break; - } -} - -- (void)resetTransition -{ - [self.containerView.layer removeAllAnimations]; -} - -#pragma mark - Layout - -- (void)layoutSubviews -{ - [super layoutSubviews]; - [self validateLayout]; -} - -- (void)invalidateLayout -{ - self.layoutDirty = YES; - [self setNeedsLayout]; -} - -- (void)validateLayout -{ - if (!self.isLayoutDirty) { - return; - } - self.layoutDirty = NO; -#if DEBUG_LAYOUT -// NSLog(@"%@, %@", self, NSStringFromSelector(_cmd)); -#endif - - CGFloat height = [self preferredHeight]; - CGFloat left = (self.bounds.size.width - CONTAINER_WIDTH) * 0.5; - CGFloat top = (self.bounds.size.height - height) * 0.5; - self.containerView.transform = CGAffineTransformIdentity; - self.containerView.frame = CGRectMake(left, top, CONTAINER_WIDTH, height); - self.containerView.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.containerView.bounds cornerRadius:self.containerView.layer.cornerRadius].CGPath; - - CGFloat y = CONTENT_PADDING_TOP; - if (self.titleLabel) { - self.titleLabel.text = self.title; - CGFloat height = [self heightForTitleLabel]; - self.titleLabel.frame = CGRectMake(CONTENT_PADDING_LEFT, y, self.containerView.bounds.size.width - CONTENT_PADDING_LEFT * 2, height); - y += height; - } - if (self.messageLabel) { - if (y > CONTENT_PADDING_TOP) { - y += GAP; - } - self.messageLabel.text = self.message; - CGFloat height = [self heightForMessageLabel]; - self.messageLabel.frame = CGRectMake(CONTENT_PADDING_LEFT, y, self.containerView.bounds.size.width - CONTENT_PADDING_LEFT * 2, height); - y += height; - } - if (self.items.count > 0) { - if (y > CONTENT_PADDING_TOP) { - y += GAP; - } - // y = self.containerView.bounds.size.height - BUTTON_HEIGHT; - if (self.items.count == 2 && self.buttonsListStyle == SIAlertViewButtonsListStyleNormal) { - //CGFloat width = (self.containerView.bounds.size.width - CONTENT_PADDING_LEFT * 2 - GAP) * 0.5; - CGFloat width = (self.containerView.bounds.size.width - 0.5) * 0.5; - UIButton *button = self.buttons[0]; -// button.frame = CGRectMake(CONTENT_PADDING_LEFT, y, width, BUTTON_HEIGHT); - button.frame = CGRectMake(0, y, width, BUTTON_HEIGHT); - button = self.buttons[1]; -// button.frame = CGRectMake(CONTENT_PADDING_LEFT + width + GAP, y, width, BUTTON_HEIGHT); - button.frame = CGRectMake(width + 0.5, y, width, BUTTON_HEIGHT); - } else { - for (NSUInteger i = 0; i < self.buttons.count; i++) { - UIButton *button = self.buttons[i]; -// button.frame = CGRectMake(CONTENT_PADDING_LEFT, y, self.containerView.bounds.size.width - CONTENT_PADDING_LEFT * 2, BUTTON_HEIGHT); - button.frame = CGRectMake(0, y, self.containerView.bounds.size.width, BUTTON_HEIGHT); - if (self.buttons.count > 1) { - if (i == self.buttons.count - 1 && ((SIAlertItem *)self.items[i]).type == SIAlertViewButtonTypeCancel) { - CGRect rect = button.frame; - rect.origin.y += CANCEL_BUTTON_PADDING_TOP; - button.frame = rect; - } - //y += BUTTON_HEIGHT + GAP; - y += BUTTON_HEIGHT + 0.5; - } - } - } - } -} - -- (CGFloat)preferredHeight -{ - CGFloat height = CONTENT_PADDING_TOP; - if (self.title) { - height += [self heightForTitleLabel]; - } - if (self.message) { - if (height > CONTENT_PADDING_TOP) { - height += GAP; - } - height += [self heightForMessageLabel]; - } - if (self.items.count > 0) { - if (height > CONTENT_PADDING_TOP) { - height += GAP; - } - if (self.items.count <= 2 && self.buttonsListStyle == SIAlertViewButtonsListStyleNormal) { - height += BUTTON_HEIGHT; - } else { -// height += (BUTTON_HEIGHT + GAP) * self.items.count - GAP; - height += (BUTTON_HEIGHT + 1.5) * self.items.count - 1.5; - if (self.buttons.count > 2 && ((SIAlertItem *)(self.items).lastObject).type == SIAlertViewButtonTypeCancel) { - height += CANCEL_BUTTON_PADDING_TOP; - } - } - } - //height += CONTENT_PADDING_BOTTOM; - return height; -} - -- (CGFloat)heightForTitleLabel { - if (self.titleLabel) { - float maxHeightOfTitleLabel = 2 * self.titleLabel.font.lineHeight; - (self.titleLabel).numberOfLines = 2; - (self.titleLabel).lineBreakMode = NSLineBreakByWordWrapping; - - #ifdef __IPHONE_7_0 - NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; - paragraphStyle.lineBreakMode = self.titleLabel.lineBreakMode; - - NSDictionary *attributes = @{NSFontAttributeName:self.titleLabel.font, - NSParagraphStyleAttributeName: paragraphStyle.copy}; - - // NSString class method: boundingRectWithSize:options:attributes:context is - // available only on ios7.0 sdk. - CGRect rect = [self.titleLabel.text boundingRectWithSize:CGSizeMake(CONTAINER_WIDTH - CONTENT_PADDING_LEFT * 2, maxHeightOfTitleLabel) - options:NSStringDrawingUsesLineFragmentOrigin - attributes:attributes - context:nil]; - return ceil(rect.size.height); - #else - CGSize size = [self.title sizeWithFont:self.titleLabel.font - minFontSize: - #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 - self.titleLabel.font.pointSize * self.titleLabel.minimumScaleFactor - #else - self.titleLabel.minimumFontSize - #endif - actualFontSize:nil - forWidth:CONTAINER_WIDTH - CONTENT_PADDING_LEFT * 2 - lineBreakMode:self.titleLabel.lineBreakMode]; - return size.height; - #endif - } - - return 0; -} - -- (CGFloat)heightForMessageLabel -{ - CGFloat minHeight = MESSAGE_MIN_LINE_COUNT * self.messageLabel.font.lineHeight; - if (self.messageLabel) { - CGFloat maxHeight = MESSAGE_MAX_LINE_COUNT * self.messageLabel.font.lineHeight; - - #ifdef __IPHONE_7_0 - NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; - paragraphStyle.lineBreakMode = self.messageLabel.lineBreakMode; - - NSDictionary *attributes = @{NSFontAttributeName:self.messageLabel.font, - NSParagraphStyleAttributeName: paragraphStyle.copy}; - - // NSString class method: boundingRectWithSize:options:attributes:context is - // available only on ios7.0 sdk. - //NSLog(@"Text of Message=>%@",self.messageLabel.text); - // NSLog(@"Widthof Expected label =>%d \n and height expected =>%f",(CONTAINER_WIDTH - CONTENT_PADDING_LEFT * 2), maxHeight); - CGRect rect = [self.messageLabel.text boundingRectWithSize:CGSizeMake(CONTAINER_WIDTH - CONTENT_PADDING_LEFT * 2, maxHeight) - options:NSStringDrawingUsesLineFragmentOrigin - attributes:attributes - context:nil]; - // NSLog(@"estimated height of Message label =>%f \n exact height of Message label=>%f",rect.size.height,MAX(minHeight, ceil(rect.size.height))); - return MAX(minHeight, ceil(rect.size.height)); - #else - CGSize size = [self.message sizeWithFont:self.messageLabel.font - constrainedToSize:CGSizeMake(CONTAINER_WIDTH - CONTENT_PADDING_LEFT * 2, maxHeight) - lineBreakMode:self.messageLabel.lineBreakMode]; - - return MAX(minHeight, size.height); - #endif - } - - return minHeight; -} - -#pragma mark - Setup - -- (void)setup -{ - [self setupContainerView]; - [self updateTitleLabel]; - [self updateMessageLabel]; - [self setupButtons]; - [self invalidateLayout]; -} - -- (void)teardown -{ - [self.containerView removeFromSuperview]; - self.containerView = nil; - self.titleLabel = nil; - self.messageLabel = nil; - [self.buttons removeAllObjects]; - [self.alertWindow removeFromSuperview]; - self.alertWindow = nil; - self.layoutDirty = NO; -} - -- (void)setupContainerView -{ - self.containerView = [[UIView alloc] initWithFrame:self.bounds]; - self.containerView.backgroundColor = _viewBackgroundColor ? _viewBackgroundColor : [UIColor whiteColor]; - self.containerView.layer.cornerRadius = self.cornerRadius; - self.containerView.layer.shadowOffset = CGSizeZero; - self.containerView.layer.shadowRadius = self.shadowRadius; - self.containerView.layer.shadowOpacity = 0.5; - [self addSubview:self.containerView]; -} - -- (void)updateTitleLabel -{ - if (self.title) { - if (!self.titleLabel) { - self.titleLabel = [[UILabel alloc] initWithFrame:self.bounds]; - self.titleLabel.textAlignment = NSTextAlignmentCenter; - self.titleLabel.backgroundColor = [UIColor clearColor]; - self.titleLabel.font = self.titleFont; - self.titleLabel.textColor = self.titleColor; - self.titleLabel.adjustsFontSizeToFitWidth = YES; -#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 - self.titleLabel.minimumScaleFactor = 0.75; -#else - self.titleLabel.minimumFontSize = self.titleLabel.font.pointSize * 0.75; -#endif - [self.containerView addSubview:self.titleLabel]; -#if DEBUG_LAYOUT - self.titleLabel.backgroundColor = [UIColor redColor]; -#endif - } - self.titleLabel.text = self.title; - } else { - [self.titleLabel removeFromSuperview]; - self.titleLabel = nil; - } - [self invalidateLayout]; -} - -- (void)updateMessageLabel -{ - if (self.message) { - if (!self.messageLabel) { - self.messageLabel = [[UILabel alloc] initWithFrame:self.bounds]; - self.messageLabel.textAlignment = NSTextAlignmentCenter; - self.messageLabel.backgroundColor = [UIColor clearColor]; - self.messageLabel.font = self.messageFont; - self.messageLabel.textColor = self.messageColor; - self.messageLabel.numberOfLines = MESSAGE_MAX_LINE_COUNT; - (self.messageLabel).lineBreakMode = NSLineBreakByWordWrapping; - [self.containerView addSubview:self.messageLabel]; -#if DEBUG_LAYOUT - self.messageLabel.backgroundColor = [UIColor redColor]; -#endif - } - self.messageLabel.text = self.message; - } else { - [self.messageLabel removeFromSuperview]; - self.messageLabel = nil; - } - [self invalidateLayout]; -} - -- (void)setupButtons -{ - self.buttons = [[NSMutableArray alloc] initWithCapacity:self.items.count]; - for (NSUInteger i = 0; i < self.items.count; i++) { - UIButton *button = [self buttonForItemIndex:i]; - [self.buttons addObject:button]; - [self.containerView addSubview:button]; - } -} - -- (UIButton *)buttonForItemIndex:(NSUInteger)index -{ - //CGFloat heightOfButton = [[CommonFunctions shareCommonMethods] targetYOrHeightSize:150.0]; - - SIAlertItem *item = self.items[index]; - UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; - button.tag = index; - button.autoresizingMask = UIViewAutoresizingFlexibleWidth; - button.titleLabel.font = self.buttonFont; - [button setTitle:item.title forState:UIControlStateNormal]; - UIImage *normalImage = nil; - UIImage *highlightedImage = [self imageWithColor:[UIColor clearColor] andFrame:CGRectMake(0, 0, 400, BUTTON_HEIGHT)]; - switch (item.type) { - case SIAlertViewButtonTypeCancel: - //normalImage = [UIImage imageNamed:@"SIAlertView.bundle/button-cancel"]; - //highlightedImage = [UIImage imageNamed:@"SIAlertView.bundle/button-cancel-d"]; - normalImage = [self imageWithColor:[UIColor colorWithRed:04.0/255.0 green:202.0/255.0 blue:169.0/255.0 alpha:1.0] andFrame:CGRectMake(0, 0, 400, BUTTON_HEIGHT)]; - - [button setTitleColor:self.cancelButtonColor forState:UIControlStateNormal]; - //[button setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; - //[button.layer setBorderColor:[COLOR_JUGNOO_MEALS_THEME CGColor]]; - //[button.layer setBorderWidth:2.0]; - break; - case SIAlertViewButtonTypeDestructive: - normalImage = [self imageWithColor:[UIColor colorWithRed:04.0/255.0 green:202.0/255.0 blue:169.0/255.0 alpha:1.0] andFrame:CGRectMake(0, 0, 400, BUTTON_HEIGHT)]; - //highlightedImage = [UIImage imageNamed:@"SIAlertView.bundle/button-destructive-d"]; - [button setTitleColor:self.destructiveButtonColor forState:UIControlStateNormal]; - //[button setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; - //[button.layer setBorderColor:[[UIColor whiteColor] CGColor]]; - //[button.layer setBorderWidth:2.0]; - break; - case SIAlertViewButtonTypeDefault: - default: - //normalImage = [UIImage imageNamed:@"SIAlertView.bundle/button-default"]; - //highlightedImage = [UIImage imageNamed:@"SIAlertView.bundle/button-default-d"]; - normalImage = [self imageWithColor:[UIColor colorWithRed:04.0/255.0 green:202.0/255.0 blue:169.0/255.0 alpha:1.0] andFrame:CGRectMake(0, 0, 400, BUTTON_HEIGHT)]; - [button setTitleColor:self.buttonColor forState:UIControlStateNormal]; - //[button setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; - //[button.layer setBorderColor:[[UIColor whiteColor] CGColor]]; - //[button.layer setBorderWidth:2.0]; - break; - } - /*CGFloat hInset = floorf(normalImage.size.width / 2); - CGFloat vInset = floorf(normalImage.size.height / 2); - UIEdgeInsets insets = UIEdgeInsetsMake(vInset, hInset, vInset, hInset); - normalImage = [normalImage resizableImageWithCapInsets:insets]; - highlightedImage = [highlightedImage resizableImageWithCapInsets:insets];*/ - [button setClipsToBounds:YES]; - //[button.layer setCornerRadius:4.0]; - [button setBackgroundImage:normalImage forState:UIControlStateNormal]; - [button setBackgroundImage:highlightedImage forState:UIControlStateHighlighted]; - // [button setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; - [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside]; - - return button; -} - -- (UIImage *)imageWithColor:(UIColor *)color andFrame:(CGRect)customFrame { - UIGraphicsBeginImageContext(customFrame.size); - CGContextRef context = UIGraphicsGetCurrentContext(); - CGContextSetFillColorWithColor(context, [color CGColor]); - CGContextFillRect(context, customFrame); - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return image; -} - -#pragma mark - Actions - -- (void)buttonAction:(UIButton *)button -{ - [SIAlertView setAnimating:YES]; // set this flag to YES in order to prevent showing another alert in action block - SIAlertItem *item = self.items[button.tag]; - if (item.action) { - item.action(self); - } - [self dismissAnimated:YES]; -} - -#pragma mark - CAAnimation delegate - -- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag -{ - void(^completion)(void) = [anim valueForKey:@"handler"]; - if (completion) { - completion(); - } -} - -#pragma mark - UIAppearance setters - -- (void)setViewBackgroundColor:(UIColor *)viewBackgroundColor -{ - if (_viewBackgroundColor == viewBackgroundColor) { - return; - } - _viewBackgroundColor = viewBackgroundColor; - self.containerView.backgroundColor = viewBackgroundColor; -} - -- (void)setTitleFont:(UIFont *)titleFont -{ - if (_titleFont == titleFont) { - return; - } - _titleFont = titleFont; - self.titleLabel.font = titleFont; - [self invalidateLayout]; -} - -- (void)setMessageFont:(UIFont *)messageFont -{ - if (_messageFont == messageFont) { - return; - } - _messageFont = messageFont; - self.messageLabel.font = messageFont; - [self invalidateLayout]; -} - -- (void)setTitleColor:(UIColor *)titleColor -{ - if (_titleColor == titleColor) { - return; - } - _titleColor = titleColor; - self.titleLabel.textColor = titleColor; -} - -- (void)setMessageColor:(UIColor *)messageColor -{ - if (_messageColor == messageColor) { - return; - } - _messageColor = messageColor; - self.messageLabel.textColor = messageColor; -} - -- (void)setButtonFont:(UIFont *)buttonFont -{ - if (_buttonFont == buttonFont) { - return; - } - _buttonFont = buttonFont; - for (UIButton *button in self.buttons) { - button.titleLabel.font = buttonFont; - } -} - -- (void)setCornerRadius:(CGFloat)cornerRadius -{ - if (_cornerRadius == cornerRadius) { - return; - } - _cornerRadius = cornerRadius; - self.containerView.layer.cornerRadius = cornerRadius; -} - -- (void)setShadowRadius:(CGFloat)shadowRadius -{ - if (_shadowRadius == shadowRadius) { - return; - } - _shadowRadius = shadowRadius; - self.containerView.layer.shadowRadius = shadowRadius; -} - -- (void)setButtonColor:(UIColor *)buttonColor -{ - if (_buttonColor == buttonColor) { - return; - } - _buttonColor = buttonColor; - [self setColor:buttonColor toButtonsOfType:SIAlertViewButtonTypeDefault]; -} - -- (void)setCancelButtonColor:(UIColor *)buttonColor -{ - if (_cancelButtonColor == buttonColor) { - return; - } - _cancelButtonColor = buttonColor; - [self setColor:buttonColor toButtonsOfType:SIAlertViewButtonTypeCancel]; -} - -- (void)setDestructiveButtonColor:(UIColor *)buttonColor -{ - if (_destructiveButtonColor == buttonColor) { - return; - } - _destructiveButtonColor = buttonColor; - [self setColor:buttonColor toButtonsOfType:SIAlertViewButtonTypeDestructive]; -} - - -- (void)setDefaultButtonImage:(UIImage *)defaultButtonImage forState:(UIControlState)state -{ - [self setButtonImage:defaultButtonImage forState:state andButtonType:SIAlertViewButtonTypeDefault]; -} - - -- (void)setCancelButtonImage:(UIImage *)cancelButtonImage forState:(UIControlState)state -{ - [self setButtonImage:cancelButtonImage forState:state andButtonType:SIAlertViewButtonTypeCancel]; -} - - -- (void)setDestructiveButtonImage:(UIImage *)destructiveButtonImage forState:(UIControlState)state -{ - [self setButtonImage:destructiveButtonImage forState:state andButtonType:SIAlertViewButtonTypeDestructive]; -} - - -- (void)setButtonImage:(UIImage *)image forState:(UIControlState)state andButtonType:(SIAlertViewButtonType)type -{ - for (NSUInteger i = 0; i < self.items.count; i++) - { - SIAlertItem *item = self.items[i]; - if(item.type == type) - { - UIButton *button = self.buttons[i]; - [button setBackgroundImage:image forState:state]; - } - } -} - - --(void)setColor:(UIColor *)color toButtonsOfType:(SIAlertViewButtonType)type { - for (NSUInteger i = 0; i < self.items.count; i++) { - SIAlertItem *item = self.items[i]; - if(item.type == type) { - UIButton *button = self.buttons[i]; - [button setTitleColor:color forState:UIControlStateNormal]; - //[button setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; - } - } -} - -# pragma mark - -# pragma mark Enable parallax effect (iOS7 only) - -#ifdef __IPHONE_7_0 -- (void)addParallaxEffect -{ - if (_enabledParallaxEffect && NSClassFromString(@"UIInterpolatingMotionEffect")) - { - UIInterpolatingMotionEffect *effectHorizontal = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"position.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; - UIInterpolatingMotionEffect *effectVertical = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"position.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; - effectHorizontal.maximumRelativeValue = @(20.0f); - effectHorizontal.minimumRelativeValue = @(-20.0f); - effectVertical.maximumRelativeValue = @(50.0f); - effectVertical.minimumRelativeValue = @(-50.0f); - [self.containerView addMotionEffect:effectHorizontal]; - [self.containerView addMotionEffect:effectVertical]; - } -} - -- (void)removeParallaxEffect -{ - if (_enabledParallaxEffect && NSClassFromString(@"UIInterpolatingMotionEffect")) - { - [self.containerView.motionEffects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - [self.containerView removeMotionEffect:obj]; - }]; - } -} -#endif - -@end diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.h b/DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.h deleted file mode 100644 index 3d5abf36f..000000000 --- a/DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// UIWindow+SIUtils.h -// SIAlertView -// -// Created by Kevin Cao on 13-11-1. -// Copyright (c) 2013年 Sumi Interactive. All rights reserved. -// - -#import - -@interface UIWindow (SIUtils) - -- (UIViewController *)currentViewController; - -#ifdef __IPHONE_7_0 -- (UIViewController *)viewControllerForStatusBarStyle; -- (UIViewController *)viewControllerForStatusBarHidden; -#endif - -@end diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.m b/DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.m deleted file mode 100644 index 2967def19..000000000 --- a/DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.m +++ /dev/null @@ -1,42 +0,0 @@ -// UIWindow+SIUtils.m -// SIAlertView -// Created by Kevin Cao on 13-11-1. -// Copyright (c) 2013年 Sumi Interactive. All rights reserved. - -#import "UIWindow+SIUtils.h" - -@implementation UIWindow (SIUtils) - -- (UIViewController *)currentViewController -{ - UIViewController *viewController = self.rootViewController; - while (viewController.presentedViewController) { - viewController = viewController.presentedViewController; - } - return viewController; -} - -#ifdef __IPHONE_7_0 - -- (UIViewController *)viewControllerForStatusBarStyle { - UIViewController *currentViewController = [self currentViewController]; - - while ([currentViewController childViewControllerForStatusBarStyle]) { - currentViewController = [currentViewController childViewControllerForStatusBarStyle]; - } - return currentViewController; -} - -- (UIViewController *)viewControllerForStatusBarHidden -{ - UIViewController *currentViewController = [self currentViewController]; - - while ([currentViewController childViewControllerForStatusBarHidden]) { - currentViewController = [currentViewController childViewControllerForStatusBarHidden]; - } - return currentViewController; -} - -#endif - -@end diff --git a/DeepLinkDemo/DeepLinkDemo/StartupOptionsData.swift b/DeepLinkDemo/DeepLinkDemo/StartupOptionsData.swift deleted file mode 100644 index f0a6697b4..000000000 --- a/DeepLinkDemo/DeepLinkDemo/StartupOptionsData.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// StartupOptionsData.swift -// TestBed-Swift -// -// Created by David Westgate on 9/17/17. -// Copyright © 2017 Branch Metrics. All rights reserved. -// - -import Foundation - -struct StartupOptionsData { - - static let userDefaults = UserDefaults.standard - - static func getActiveBranchKey() -> String? { - if let value = userDefaults.string(forKey: "activeBranchKey") { - return value - } else { - let value = "" - userDefaults.setValue(value, forKey: "activeBranchKey") - return value - } - } - - static func setActiveBranchKey(_ value: String) { - userDefaults.setValue(value, forKey: "activeBranchKey") - } - - static func getPendingBranchKey() -> String? { - if let value = userDefaults.string(forKey: "pendingBranchKey") { - return value - } else { - let value = "" - userDefaults.setValue(value, forKey: "pendingBranchKey") - return value - } - } - - static func setPendingBranchKey(_ value: String) { - userDefaults.setValue(value, forKey: "pendingBranchKey") - } - - static func getActiveSetDebugEnabled() -> Bool? { - return userDefaults.bool(forKey: "activeSetDebug") - } - - static func setActiveSetDebugEnabled(_ value: Bool) { - userDefaults.setValue(value, forKey: "activeSetDebug") - } - - static func getPendingSetDebugEnabled() -> Bool? { - return userDefaults.bool(forKey: "pendingSetDebug") - } - - static func setPendingSetDebugEnabled(_ value: Bool) { - userDefaults.setValue(value, forKey: "pendingSetDebug") - } - -} diff --git a/DeepLinkDemo/DeepLinkDemo/img.png b/DeepLinkDemo/DeepLinkDemo/img.png deleted file mode 100644 index 95f2e956295e4d10dbfad931ff5be4d8243c3e36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4030 zcma)<_ahXJM+U#57K(hy~sWdJ}(^F82E!gCK) zOULBg!Y)8KzN~KaRb(ThbaHT9)9Tv(&A|cT^70R6_YcHv1(?y zs}w8;DQ~w-EcT;gcfEW!^}rc0`=pv)(l~=B#g?nQ7CnSh~Hx zSR<@o+cH*tx}iEgX-v&`nUR;r$zUS#;QvQ?tX@;EAIoxlxQTP<_4j^oBnZzmb#waFwm zU)~#HUbbi^`zsW`DXC=GSbVslopNj6$;bB20|;pl0I|qP(MwKHuK$saOHwukcWOM& zy54sfVG_jiKX=1qFhQMwHd&I@$=&VbJ5;n#V#DC+QT?0~mPI#Kb{2ZER51+IUi7>~ z$QW!L)V&#b=6tJSDN$L|#->eGc9=bpoN%sYII4atHw4dOcyy#1^W7yRXr`Dr(NC~I zE*W>ItkJ&5d^i{DWu20Z zl?V^JPftY-I3K214uKEjEU2A10x&EuaEEd==7jmVH|XF-y^VXB%zA3$7ECq8-eGmr zphe0Lt_}5M1d*vcYALDFM)I5CSj!X;nVCS$GpDdEm|0u8G{zefk~rrqAw=F|^A)Nt z;xbN=(B8ea9IkepCwavQ6h#D{Pt4b{&-NsuOs9|EDzjYbH4}-mvww$VHLPoO+bHXF z(N$%o-TfePs(>kiT>5D;O@2`a)w?TFJr9k|~ zy*QxsU*1?^$!u3{Clbr3UbSXU$v*=sKSk0**-Ah1gGO^ryksz&9khuZsI^4#H$z8T z!YiVfh-dWEorg;OpM&<$tL8 z3JA!7mV8+6Yq;vq#Nj~j(9HB=JZ+}&~``yH~XnX8WKb*5Hr z5X~b6KIqk7&P^`jFXRn@(7mdR*axJ&JhDawe_55POlPO`s3co|wON=VyXp&3*k^?J zywBLw$jO%4dex2m>FVZjL1$o!fe^o0LAo&V6db0001i0SrI#eacZ@b2EH221f&9_z zV#=0Ric@&(T~HkUEN zV)RbTf|-zLc5>W~Dmc;l;nO@_Y?SR*)0Uzi*MB5LS9rBPpZXm4^)FVUEN+5~YE%i* zJlq3k_4%z?syw%DoB3=)ZS|PR6 z&g4u;X`f`Byh_z~lRv5p95Eglxa$bzwaBP2P6gX5y z3u#&T6Glic$5WJzt;ugV8Eo{!j`3h9ppFStneueO!2zf-3+ow5C1?$rN{oG&n0 zZq%I|v62km$sI>YKelr@xzlxWf5EoO)#Z&^e>O?c&q{Xcr_t2Xlw!NTMDD!xjnC6zi5bE>9L<^{-HGW zLb`8=*LM@{qn9{D45PbwF>{w_EG`a7=K_JRYy3UXaw~ zd%{pe%;~C`2u&E*ayBy8&M=E$Nh}B6G4cRn{kXADgykibYxd+lErtS30ow$~uaM8I z-;{+Lq|0v{-(^HM6WvNT#Q~bg%wl{z4Wk#k_=>89Sx96A!9%WN>08OJ;xf~TKBu*2 zq7Lj^OtKA+KzW(FV2Z~t0`F$sy+-8UQMAFj{)zKKWKzRq1-v3U0-k{+a4Prj|3$t0 znY!5>Sku(LP5rqUCk%7U^9wdZ2l`6UW4-;eem5R~e`Qg;E@68zI#x`#IZE zT-DC)LrLi5(^&pVA;RAF~PMX|rG}aY!P7WF*y*QD` z*SLRwoGcik4WAqu#Kk+k}o7o+S`gw_t?&vHq(JaT|;Lt z>gSEa4=jt^t^iWO0T-R?huh;tWQ`SK@ek1QG6!@X_olDIQ)^_4FPuKJR4K{txdEzX zRi(H4hWZCx3ahX3$7vf+!#<-Y)g6lFe~jTZ7cVJozjx81n=Tj(5%~igk-mSXm zspMJi#h9zJ@{)jS`kC7H)6*aB-qwcG=;u}K_~|8oZ<0thZ1XHO%04yv`BJd^0TK6% zac-DTu3@;en`+effxC5~h99wSgh%UQE_BH~3>OuCkfy^eKCBtOwtYzZHR=H0W_uJ; ziVvU&_`H2KGufwkFddL9a=naxz8~@yndXhvKOuNZ5kmq10Zsnba*_TMZ+3PK8=r@T z@Z-gRQYwb1n8N*(#O)WO!t%fzu z$(r1dX;E{+Iur%KrIjJjHYeH@5FQ_bp_uUCU+rK}{kcu+nZc)G{};!f2MR zS;oa~l-zC{dxKxCD`<- z;xM#1D^uPr`3(xJxR?Wd9<{S_u+USPHIq33rBe=qYUsA&Ymj8SMkBZ0m4kl_#V>EV zLcy1cR&v;K**(MAGe4F!-O5gXUA#j>KbBOOq0IjO=1S|9g!*B4KY#%c_wSGcK-yrf JIt@Gc{{RlH+F}3z diff --git a/DeepLinkDemo/IPA/Info.plist b/DeepLinkDemo/IPA/Info.plist deleted file mode 100644 index 42890b144..000000000 --- a/DeepLinkDemo/IPA/Info.plist +++ /dev/null @@ -1,27 +0,0 @@ - - - - - compileBitcode - - destination - export - method - development - provisioningProfiles - - io.branch.saas.sdk.testbed - iOS Saas SDK - Dev - - signingCertificate - Apple Development - signingStyle - manual - stripSwiftSymbols - - teamID - R63EM248DP - thinning - <none> - - diff --git a/DeepLinkDemo/Podfile b/DeepLinkDemo/Podfile deleted file mode 100644 index b7266ceb5..000000000 --- a/DeepLinkDemo/Podfile +++ /dev/null @@ -1,12 +0,0 @@ -# Uncomment the next line to define a global platform for your project - platform :ios, '12.0' - -target 'DeepLinkDemo' do - # Comment the next line if you don't want to use dynamic frameworks - use_frameworks! - pod 'IQKeyboardManager' - pod 'BranchSDK', :path => './../' - - # Pods for DeepLinkDemo - -end diff --git a/DeepLinkDemo/Podfile.lock b/DeepLinkDemo/Podfile.lock deleted file mode 100644 index e5b283e13..000000000 --- a/DeepLinkDemo/Podfile.lock +++ /dev/null @@ -1,23 +0,0 @@ -PODS: - - BranchSDK (3.4.4) - - IQKeyboardManager (6.5.19) - -DEPENDENCIES: - - BranchSDK (from `./../`) - - IQKeyboardManager - -SPEC REPOS: - trunk: - - IQKeyboardManager - -EXTERNAL SOURCES: - BranchSDK: - :path: "./../" - -SPEC CHECKSUMS: - BranchSDK: 28bec34fb99c53ab8e86b7bf69cc55a4505fe0b3 - IQKeyboardManager: c8665b3396bd0b79402b4c573eac345a31c7d485 - -PODFILE CHECKSUM: 8c4b32f5c4a14defd62bc8a2d1e49cee9e7c2173 - -COCOAPODS: 1.15.2 diff --git a/DeepLinkDemo/README.md b/DeepLinkDemo/README.md deleted file mode 100644 index e95c403f6..000000000 --- a/DeepLinkDemo/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# Branch SaaS SDK IOS TestApp - diff --git a/TestDeepLinking/Podfile b/TestDeepLinking/Podfile deleted file mode 100644 index 1a6061452..000000000 --- a/TestDeepLinking/Podfile +++ /dev/null @@ -1,8 +0,0 @@ -platform :ios, '9.0' - -target 'TestDeepLinking' do - # if swift - use_frameworks! - - pod 'Branch' -end diff --git a/TestDeepLinking/TestDeepLinking.xcodeproj/project.pbxproj b/TestDeepLinking/TestDeepLinking.xcodeproj/project.pbxproj deleted file mode 100644 index 31dd25628..000000000 --- a/TestDeepLinking/TestDeepLinking.xcodeproj/project.pbxproj +++ /dev/null @@ -1,733 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 51; - objects = { - -/* Begin PBXBuildFile section */ - 032DAEE82607431D00891641 /* TestDeepLinkWithoutApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 032DAED2260742D100891641 /* TestDeepLinkWithoutApp.m */; }; - 032DAEFE2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 032DAEFD2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.m */; }; - 033608162605E2110032A5DC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033608152605E2110032A5DC /* AppDelegate.swift */; }; - 033608182605E2110032A5DC /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033608172605E2110032A5DC /* SceneDelegate.swift */; }; - 0336081A2605E2110032A5DC /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033608192605E2110032A5DC /* ViewController.swift */; }; - 0336081D2605E2110032A5DC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0336081B2605E2110032A5DC /* Main.storyboard */; }; - 0336081F2605E2150032A5DC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0336081E2605E2150032A5DC /* Assets.xcassets */; }; - 033608222605E2150032A5DC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 033608202605E2150032A5DC /* LaunchScreen.storyboard */; }; - 033608302605F1E30032A5DC /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0336082F2605F1E30032A5DC /* CoreServices.framework */; }; - 033608322605F1F10032A5DC /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608312605F1F10032A5DC /* SystemConfiguration.framework */; }; - 033608342605F20C0032A5DC /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608332605F20C0032A5DC /* CoreTelephony.framework */; }; - 033608362605F2130032A5DC /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608352605F2130032A5DC /* WebKit.framework */; }; - 033608382605F21B0032A5DC /* CoreSpotlight.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608372605F21B0032A5DC /* CoreSpotlight.framework */; }; - 0336083B2605F2370032A5DC /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608392605F2370032A5DC /* AdSupport.framework */; }; - 0336083C2605F2370032A5DC /* iAd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0336083A2605F2370032A5DC /* iAd.framework */; }; - 0336083E2605F2880032A5DC /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608392605F2370032A5DC /* AdSupport.framework */; }; - 033608402605F4470032A5DC /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608392605F2370032A5DC /* AdSupport.framework */; }; - 03DE13B32606A1B4006D18F5 /* TestDeepLinking.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = 03DE13B22606A0C4006D18F5 /* TestDeepLinking.entitlements */; }; - 03DE13BA2606BFC4006D18F5 /* AdServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03DE13B92606BFC4006D18F5 /* AdServices.framework */; }; - 69BEC330F5B8AF8CE3C32174 /* Pods_TestDeepLinking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 815FC6A40AFE1F218C25C738 /* Pods_TestDeepLinking.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 032DAEDF2607430600891641 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0336080A2605E2100032A5DC /* Project object */; - proxyType = 1; - remoteGlobalIDString = 033608112605E2110032A5DC; - remoteInfo = TestDeepLinking; - }; - 032DAF002607491B00891641 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0336080A2605E2100032A5DC /* Project object */; - proxyType = 1; - remoteGlobalIDString = 033608112605E2110032A5DC; - remoteInfo = TestDeepLinking; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 032DAED2260742D100891641 /* TestDeepLinkWithoutApp.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestDeepLinkWithoutApp.m; sourceTree = ""; }; - 032DAEDA2607430600891641 /* TestDeepLinkingUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestDeepLinkingUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 032DAEDE2607430600891641 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 032DAEFB2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestDeepLinkingUITestsWithHostApp.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 032DAEFD2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestDeepLinkingUITestsWithHostApp.m; sourceTree = ""; }; - 032DAEFF2607491B00891641 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 032DAF122607504000891641 /* TestDeepLinking.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = TestDeepLinking.xctestplan; sourceTree = ""; }; - 033608122605E2110032A5DC /* TestDeepLinking.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestDeepLinking.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 033608152605E2110032A5DC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 033608172605E2110032A5DC /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - 033608192605E2110032A5DC /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 0336081C2605E2110032A5DC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 0336081E2605E2150032A5DC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 033608212605E2150032A5DC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 033608232605E2150032A5DC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 0336082F2605F1E30032A5DC /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; - 033608312605F1F10032A5DC /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; - 033608332605F20C0032A5DC /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; }; - 033608352605F2130032A5DC /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; - 033608372605F21B0032A5DC /* CoreSpotlight.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreSpotlight.framework; path = System/Library/Frameworks/CoreSpotlight.framework; sourceTree = SDKROOT; }; - 033608392605F2370032A5DC /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; - 0336083A2605F2370032A5DC /* iAd.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = iAd.framework; path = System/Library/Frameworks/iAd.framework; sourceTree = SDKROOT; }; - 03DE13B22606A0C4006D18F5 /* TestDeepLinking.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TestDeepLinking.entitlements; sourceTree = ""; }; - 03DE13B92606BFC4006D18F5 /* AdServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdServices.framework; path = ../../AdServices.framework; sourceTree = ""; }; - 0EE470FCEAEA1ECC99DC0A89 /* Pods-TestDeepLinking.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TestDeepLinking.release.xcconfig"; path = "Target Support Files/Pods-TestDeepLinking/Pods-TestDeepLinking.release.xcconfig"; sourceTree = ""; }; - 815FC6A40AFE1F218C25C738 /* Pods_TestDeepLinking.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TestDeepLinking.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 86113F63A46AE44E1E8B1648 /* Pods-TestDeepLinking.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TestDeepLinking.debug.xcconfig"; path = "Target Support Files/Pods-TestDeepLinking/Pods-TestDeepLinking.debug.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 032DAED72607430600891641 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 032DAEF82607491B00891641 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 0336080F2605E2110032A5DC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 033608362605F2130032A5DC /* WebKit.framework in Frameworks */, - 033608402605F4470032A5DC /* AdSupport.framework in Frameworks */, - 033608342605F20C0032A5DC /* CoreTelephony.framework in Frameworks */, - 03DE13BA2606BFC4006D18F5 /* AdServices.framework in Frameworks */, - 0336083E2605F2880032A5DC /* AdSupport.framework in Frameworks */, - 033608382605F21B0032A5DC /* CoreSpotlight.framework in Frameworks */, - 033608322605F1F10032A5DC /* SystemConfiguration.framework in Frameworks */, - 033608302605F1E30032A5DC /* CoreServices.framework in Frameworks */, - 0336083B2605F2370032A5DC /* AdSupport.framework in Frameworks */, - 0336083C2605F2370032A5DC /* iAd.framework in Frameworks */, - 69BEC330F5B8AF8CE3C32174 /* Pods_TestDeepLinking.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 032DAEDB2607430600891641 /* TestDeepLinkingUITests */ = { - isa = PBXGroup; - children = ( - 032DAED2260742D100891641 /* TestDeepLinkWithoutApp.m */, - 032DAEDE2607430600891641 /* Info.plist */, - ); - path = TestDeepLinkingUITests; - sourceTree = ""; - }; - 032DAEFC2607491B00891641 /* TestDeepLinkingUITestsWithHostApp */ = { - isa = PBXGroup; - children = ( - 032DAEFD2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.m */, - 032DAEFF2607491B00891641 /* Info.plist */, - ); - path = TestDeepLinkingUITestsWithHostApp; - sourceTree = ""; - }; - 033608092605E2100032A5DC = { - isa = PBXGroup; - children = ( - 033608142605E2110032A5DC /* TestDeepLinking */, - 032DAEDB2607430600891641 /* TestDeepLinkingUITests */, - 032DAEFC2607491B00891641 /* TestDeepLinkingUITestsWithHostApp */, - 033608132605E2110032A5DC /* Products */, - 0336082E2605F1E30032A5DC /* Frameworks */, - FBA3F883B3850B5894EAA121 /* Pods */, - ); - sourceTree = ""; - }; - 033608132605E2110032A5DC /* Products */ = { - isa = PBXGroup; - children = ( - 033608122605E2110032A5DC /* TestDeepLinking.app */, - 032DAEDA2607430600891641 /* TestDeepLinkingUITests.xctest */, - 032DAEFB2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 033608142605E2110032A5DC /* TestDeepLinking */ = { - isa = PBXGroup; - children = ( - 03DE13B22606A0C4006D18F5 /* TestDeepLinking.entitlements */, - 033608152605E2110032A5DC /* AppDelegate.swift */, - 032DAF122607504000891641 /* TestDeepLinking.xctestplan */, - 033608172605E2110032A5DC /* SceneDelegate.swift */, - 033608192605E2110032A5DC /* ViewController.swift */, - 0336081B2605E2110032A5DC /* Main.storyboard */, - 0336081E2605E2150032A5DC /* Assets.xcassets */, - 033608202605E2150032A5DC /* LaunchScreen.storyboard */, - 033608232605E2150032A5DC /* Info.plist */, - ); - path = TestDeepLinking; - sourceTree = ""; - }; - 0336082E2605F1E30032A5DC /* Frameworks */ = { - isa = PBXGroup; - children = ( - 03DE13B92606BFC4006D18F5 /* AdServices.framework */, - 033608392605F2370032A5DC /* AdSupport.framework */, - 0336083A2605F2370032A5DC /* iAd.framework */, - 033608372605F21B0032A5DC /* CoreSpotlight.framework */, - 033608352605F2130032A5DC /* WebKit.framework */, - 033608332605F20C0032A5DC /* CoreTelephony.framework */, - 033608312605F1F10032A5DC /* SystemConfiguration.framework */, - 0336082F2605F1E30032A5DC /* CoreServices.framework */, - 815FC6A40AFE1F218C25C738 /* Pods_TestDeepLinking.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - FBA3F883B3850B5894EAA121 /* Pods */ = { - isa = PBXGroup; - children = ( - 86113F63A46AE44E1E8B1648 /* Pods-TestDeepLinking.debug.xcconfig */, - 0EE470FCEAEA1ECC99DC0A89 /* Pods-TestDeepLinking.release.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 032DAED92607430600891641 /* TestDeepLinkingUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 032DAEE12607430600891641 /* Build configuration list for PBXNativeTarget "TestDeepLinkingUITests" */; - buildPhases = ( - 032DAED62607430600891641 /* Sources */, - 032DAED72607430600891641 /* Frameworks */, - 032DAED82607430600891641 /* Resources */, - 032DAF0826074B6A00891641 /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - 032DAEE02607430600891641 /* PBXTargetDependency */, - ); - name = TestDeepLinkingUITests; - productName = TestDeepLinkingUITests; - productReference = 032DAEDA2607430600891641 /* TestDeepLinkingUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; - 032DAEFA2607491B00891641 /* TestDeepLinkingUITestsWithHostApp */ = { - isa = PBXNativeTarget; - buildConfigurationList = 032DAF022607491B00891641 /* Build configuration list for PBXNativeTarget "TestDeepLinkingUITestsWithHostApp" */; - buildPhases = ( - 032DAEF72607491B00891641 /* Sources */, - 032DAEF82607491B00891641 /* Frameworks */, - 032DAEF92607491B00891641 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 032DAF012607491B00891641 /* PBXTargetDependency */, - ); - name = TestDeepLinkingUITestsWithHostApp; - productName = TestDeepLinkingUITestsWithHostApp; - productReference = 032DAEFB2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; - 033608112605E2110032A5DC /* TestDeepLinking */ = { - isa = PBXNativeTarget; - buildConfigurationList = 033608262605E2150032A5DC /* Build configuration list for PBXNativeTarget "TestDeepLinking" */; - buildPhases = ( - A6E708B8F29A1D55D1D76DE9 /* [CP] Check Pods Manifest.lock */, - 0336080E2605E2110032A5DC /* Sources */, - 0336080F2605E2110032A5DC /* Frameworks */, - 033608102605E2110032A5DC /* Resources */, - 249508BA477D5282ACF2EE9E /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = TestDeepLinking; - productName = TestDeepLinking; - productReference = 033608122605E2110032A5DC /* TestDeepLinking.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 0336080A2605E2100032A5DC /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 1200; - LastUpgradeCheck = 1200; - TargetAttributes = { - 032DAED92607430600891641 = { - CreatedOnToolsVersion = 12.3; - }; - 032DAEFA2607491B00891641 = { - CreatedOnToolsVersion = 12.3; - TestTargetID = 033608112605E2110032A5DC; - }; - 033608112605E2110032A5DC = { - CreatedOnToolsVersion = 12.0.1; - LastSwiftMigration = 1230; - }; - }; - }; - buildConfigurationList = 0336080D2605E2100032A5DC /* Build configuration list for PBXProject "TestDeepLinking" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 033608092605E2100032A5DC; - productRefGroup = 033608132605E2110032A5DC /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 033608112605E2110032A5DC /* TestDeepLinking */, - 032DAED92607430600891641 /* TestDeepLinkingUITests */, - 032DAEFA2607491B00891641 /* TestDeepLinkingUITestsWithHostApp */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 032DAED82607430600891641 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 032DAEF92607491B00891641 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 033608102605E2110032A5DC /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 03DE13B32606A1B4006D18F5 /* TestDeepLinking.entitlements in Resources */, - 033608222605E2150032A5DC /* LaunchScreen.storyboard in Resources */, - 0336081F2605E2150032A5DC /* Assets.xcassets in Resources */, - 0336081D2605E2110032A5DC /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 032DAF0826074B6A00891641 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "xcrun simctl terminate booted io.branch.TestiOSDeepLink\nxcrun simctl uninstall booted io.branch.TestiOSDeepLink\n\n"; - }; - 249508BA477D5282ACF2EE9E /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-TestDeepLinking/Pods-TestDeepLinking-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-TestDeepLinking/Pods-TestDeepLinking-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TestDeepLinking/Pods-TestDeepLinking-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - A6E708B8F29A1D55D1D76DE9 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-TestDeepLinking-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 032DAED62607430600891641 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 032DAEE82607431D00891641 /* TestDeepLinkWithoutApp.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 032DAEF72607491B00891641 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 032DAEFE2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 0336080E2605E2110032A5DC /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 0336081A2605E2110032A5DC /* ViewController.swift in Sources */, - 033608162605E2110032A5DC /* AppDelegate.swift in Sources */, - 033608182605E2110032A5DC /* SceneDelegate.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 032DAEE02607430600891641 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 033608112605E2110032A5DC /* TestDeepLinking */; - targetProxy = 032DAEDF2607430600891641 /* PBXContainerItemProxy */; - }; - 032DAF012607491B00891641 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 033608112605E2110032A5DC /* TestDeepLinking */; - targetProxy = 032DAF002607491B00891641 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 0336081B2605E2110032A5DC /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 0336081C2605E2110032A5DC /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 033608202605E2150032A5DC /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 033608212605E2150032A5DC /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 032DAEE22607430600891641 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = XHGU2TWQZE; - INFOPLIST_FILE = TestDeepLinkingUITests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.3; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.trusona.TestDeepLinkingUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 032DAEE32607430600891641 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = XHGU2TWQZE; - INFOPLIST_FILE = TestDeepLinkingUITests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.3; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.trusona.TestDeepLinkingUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = ""; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 032DAF032607491B00891641 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = XHGU2TWQZE; - INFOPLIST_FILE = TestDeepLinkingUITestsWithHostApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.3; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.trusona.TestDeepLinkingUITestsWithHostApp; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = TestDeepLinking; - }; - name = Debug; - }; - 032DAF042607491B00891641 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = XHGU2TWQZE; - INFOPLIST_FILE = TestDeepLinkingUITestsWithHostApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.3; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.trusona.TestDeepLinkingUITestsWithHostApp; - PRODUCT_NAME = "$(TARGET_NAME)"; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = TestDeepLinking; - }; - name = Release; - }; - 033608242605E2150032A5DC /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 033608252605E2150032A5DC /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 033608272605E2150032A5DC /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 86113F63A46AE44E1E8B1648 /* Pods-TestDeepLinking.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = TestDeepLinking/TestDeepLinking.entitlements; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = R63EM248DP; - EXCLUDED_ARCHS = arm64; - INFOPLIST_FILE = TestDeepLinking/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestiOSDeepLink; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 1; - }; - name = Debug; - }; - 033608282605E2150032A5DC /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 0EE470FCEAEA1ECC99DC0A89 /* Pods-TestDeepLinking.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = TestDeepLinking/TestDeepLinking.entitlements; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = R63EM248DP; - EXCLUDED_ARCHS = arm64; - INFOPLIST_FILE = TestDeepLinking/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestiOSDeepLink; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 1; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 032DAEE12607430600891641 /* Build configuration list for PBXNativeTarget "TestDeepLinkingUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 032DAEE22607430600891641 /* Debug */, - 032DAEE32607430600891641 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 032DAF022607491B00891641 /* Build configuration list for PBXNativeTarget "TestDeepLinkingUITestsWithHostApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 032DAF032607491B00891641 /* Debug */, - 032DAF042607491B00891641 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 0336080D2605E2100032A5DC /* Build configuration list for PBXProject "TestDeepLinking" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 033608242605E2150032A5DC /* Debug */, - 033608252605E2150032A5DC /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 033608262605E2150032A5DC /* Build configuration list for PBXNativeTarget "TestDeepLinking" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 033608272605E2150032A5DC /* Debug */, - 033608282605E2150032A5DC /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 0336080A2605E2100032A5DC /* Project object */; -} diff --git a/TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a62..000000000 --- a/TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/TestDeepLinking/TestDeepLinking.xcodeproj/xcshareddata/xcschemes/TestDeepLinking.xcscheme b/TestDeepLinking/TestDeepLinking.xcodeproj/xcshareddata/xcschemes/TestDeepLinking.xcscheme deleted file mode 100644 index fe40949b8..000000000 --- a/TestDeepLinking/TestDeepLinking.xcodeproj/xcshareddata/xcschemes/TestDeepLinking.xcscheme +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/TestDeepLinking/TestDeepLinking.xcworkspace/contents.xcworkspacedata b/TestDeepLinking/TestDeepLinking.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index ba8e3820e..000000000 --- a/TestDeepLinking/TestDeepLinking.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/TestDeepLinking/TestDeepLinking.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/TestDeepLinking/TestDeepLinking.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/TestDeepLinking/TestDeepLinking.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/TestDeepLinking/TestDeepLinking/AppDelegate.swift b/TestDeepLinking/TestDeepLinking/AppDelegate.swift deleted file mode 100644 index 8f1e6984d..000000000 --- a/TestDeepLinking/TestDeepLinking/AppDelegate.swift +++ /dev/null @@ -1,45 +0,0 @@ -// -// AppDelegate.swift -// TestDeepLinking -// -// Created by Nidhi on 3/20/21. -// - -import UIKit -import Branch - -@main -class AppDelegate: UIResponder, UIApplicationDelegate { - - - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - - BranchScene.shared().initSession(launchOptions: launchOptions, registerDeepLinkHandler: { (params, error, scene) in - let presentedVC : ViewController = UIApplication.shared.keyWindow?.rootViewController as! ViewController - let jsonData = try! JSONSerialization.data(withJSONObject:params, options: JSONSerialization.WritingOptions.prettyPrinted) - - let jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue)! as String - - presentedVC.addText(jsonString) - }) - return true - } - - // MARK: UISceneSession Lifecycle - - func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { - // Called when a new scene session is being created. - // Use this method to select a configuration to create the new scene with. - return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) - } - - func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { - // Called when the user discards a scene session. - // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. - // Use this method to release any resources that were specific to the discarded scenes, as they will not return. - } - - -} - diff --git a/TestDeepLinking/TestDeepLinking/Assets.xcassets/AccentColor.colorset/Contents.json b/TestDeepLinking/TestDeepLinking/Assets.xcassets/AccentColor.colorset/Contents.json deleted file mode 100644 index eb8789700..000000000 --- a/TestDeepLinking/TestDeepLinking/Assets.xcassets/AccentColor.colorset/Contents.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "colors" : [ - { - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/TestDeepLinking/TestDeepLinking/Assets.xcassets/AppIcon.appiconset/Contents.json b/TestDeepLinking/TestDeepLinking/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 9221b9bb1..000000000 --- a/TestDeepLinking/TestDeepLinking/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "20x20" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "20x20" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "29x29" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "29x29" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "40x40" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "40x40" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "60x60" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "60x60" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "20x20" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "20x20" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "29x29" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "29x29" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "40x40" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "40x40" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "76x76" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "76x76" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "83.5x83.5" - }, - { - "idiom" : "ios-marketing", - "scale" : "1x", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/TestDeepLinking/TestDeepLinking/Assets.xcassets/Contents.json b/TestDeepLinking/TestDeepLinking/Assets.xcassets/Contents.json deleted file mode 100644 index 73c00596a..000000000 --- a/TestDeepLinking/TestDeepLinking/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/TestDeepLinking/TestDeepLinking/Base.lproj/LaunchScreen.storyboard b/TestDeepLinking/TestDeepLinking/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index 865e9329f..000000000 --- a/TestDeepLinking/TestDeepLinking/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/TestDeepLinking/TestDeepLinking/Base.lproj/Main.storyboard b/TestDeepLinking/TestDeepLinking/Base.lproj/Main.storyboard deleted file mode 100644 index 99cb43c0a..000000000 --- a/TestDeepLinking/TestDeepLinking/Base.lproj/Main.storyboard +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/TestDeepLinking/TestDeepLinking/Info.plist b/TestDeepLinking/TestDeepLinking/Info.plist deleted file mode 100644 index 74d99de4a..000000000 --- a/TestDeepLinking/TestDeepLinking/Info.plist +++ /dev/null @@ -1,79 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.0 - CFBundleURLTypes - - - CFBundleTypeRole - Editor - CFBundleURLSchemes - - testiOSDeepLink - - - - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - UISceneConfigurations - - UIWindowSceneSessionRoleApplication - - - UISceneConfigurationName - Default Configuration - UISceneDelegateClassName - $(PRODUCT_MODULE_NAME).SceneDelegate - UISceneStoryboardFile - Main - - - - - UIApplicationSupportsIndirectInputEvents - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - branch_key - key_live_fk7pNcsmBjFPVS2VGlvrZaiazxkxxZ7r - - diff --git a/TestDeepLinking/TestDeepLinking/SceneDelegate.swift b/TestDeepLinking/TestDeepLinking/SceneDelegate.swift deleted file mode 100644 index dfeac44f1..000000000 --- a/TestDeepLinking/TestDeepLinking/SceneDelegate.swift +++ /dev/null @@ -1,64 +0,0 @@ -// -// SceneDelegate.swift -// TestDeepLinking -// -// Created by Nidhi on 3/20/21. -// - -import UIKit -import Branch - -class SceneDelegate: UIResponder, UIWindowSceneDelegate { - - var window: UIWindow? - - - func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. - // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. - // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). - guard let _ = (scene as? UIWindowScene) else { return } - if let userActivity = connectionOptions.userActivities.first { - - BranchScene.shared().scene(scene, continue: userActivity) - } - } - - func sceneDidDisconnect(_ scene: UIScene) { - // Called as the scene is being released by the system. - // This occurs shortly after the scene enters the background, or when its session is discarded. - // Release any resources associated with this scene that can be re-created the next time the scene connects. - // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). - } - - func sceneDidBecomeActive(_ scene: UIScene) { - // Called when the scene has moved from an inactive state to an active state. - // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. - } - - func sceneWillResignActive(_ scene: UIScene) { - // Called when the scene will move from an active state to an inactive state. - // This may occur due to temporary interruptions (ex. an incoming phone call). - } - - func sceneWillEnterForeground(_ scene: UIScene) { - // Called as the scene transitions from the background to the foreground. - // Use this method to undo the changes made on entering the background. - } - - func sceneDidEnterBackground(_ scene: UIScene) { - // Called as the scene transitions from the foreground to the background. - // Use this method to save data, release shared resources, and store enough scene-specific state information - // to restore the scene back to its current state. - } - - func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { - BranchScene.shared().scene(scene, continue: userActivity) - } - func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { - BranchScene.shared().scene(scene, openURLContexts: URLContexts) - } - - -} - diff --git a/TestDeepLinking/TestDeepLinking/TestDeepLinking.entitlements b/TestDeepLinking/TestDeepLinking/TestDeepLinking.entitlements deleted file mode 100644 index 343898fc9..000000000 --- a/TestDeepLinking/TestDeepLinking/TestDeepLinking.entitlements +++ /dev/null @@ -1,13 +0,0 @@ - - - - - com.apple.developer.associated-domains - - mnl7s.app.link - mnl7s-alternate.app.link - mnl7s.test-app.link - mnl7s-alternate.test-app.link - - - diff --git a/TestDeepLinking/TestDeepLinking/TestDeepLinking.xctestplan b/TestDeepLinking/TestDeepLinking/TestDeepLinking.xctestplan deleted file mode 100644 index 90b72d85e..000000000 --- a/TestDeepLinking/TestDeepLinking/TestDeepLinking.xctestplan +++ /dev/null @@ -1,36 +0,0 @@ -{ - "configurations" : [ - { - "id" : "21B9F7C4-BF2C-40DB-B313-9320AC57EB78", - "name" : "Configuration 1", - "options" : { - - } - } - ], - "defaultOptions" : { - "codeCoverage" : false, - "targetForVariableExpansion" : { - "containerPath" : "container:TestDeepLinking.xcodeproj", - "identifier" : "033608112605E2110032A5DC", - "name" : "TestDeepLinking" - } - }, - "testTargets" : [ - { - "target" : { - "containerPath" : "container:TestDeepLinking.xcodeproj", - "identifier" : "032DAED92607430600891641", - "name" : "TestDeepLinkingUITests" - } - }, - { - "target" : { - "containerPath" : "container:TestDeepLinking.xcodeproj", - "identifier" : "032DAEFA2607491B00891641", - "name" : "TestDeepLinkingUITestsWithHostApp" - } - } - ], - "version" : 1 -} diff --git a/TestDeepLinking/TestDeepLinking/ViewController.swift b/TestDeepLinking/TestDeepLinking/ViewController.swift deleted file mode 100644 index 0f5a341aa..000000000 --- a/TestDeepLinking/TestDeepLinking/ViewController.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// ViewController.swift -// TestDeepLinking -// -// Created by Nidhi on 3/20/21. -// - -import UIKit - -class ViewController: UIViewController { - - @IBOutlet var textView: UITextView! - override func viewDidLoad() { - super.viewDidLoad() - } - - func addText(_ text: String) { - textView.text = "" - textView.insertText(text) - } -} - diff --git a/TestDeepLinking/TestDeepLinkingUITests/Info.plist b/TestDeepLinking/TestDeepLinkingUITests/Info.plist deleted file mode 100644 index 64d65ca49..000000000 --- a/TestDeepLinking/TestDeepLinkingUITests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/TestDeepLinking/TestDeepLinkingUITests/TestDeepLinkWithoutApp.m b/TestDeepLinking/TestDeepLinkingUITests/TestDeepLinkWithoutApp.m deleted file mode 100644 index 22a741930..000000000 --- a/TestDeepLinking/TestDeepLinkingUITests/TestDeepLinkWithoutApp.m +++ /dev/null @@ -1,64 +0,0 @@ -// -// TestDeepLinkWithoutApp.m -// TestDeepLinking -// -// Created by Nidhi on 3/21/21. -// - -#import - -@interface TestDeepLinkWithoutApp : XCTestCase - -@end - -@implementation TestDeepLinkWithoutApp - -- (void)setUp { - self.continueAfterFailure = YES; - [self addUIInterruptionMonitorWithDescription:@"Open App" handler:^BOOL(XCUIElement * _Nonnull interruptingElement) { - [interruptingElement description]; - XCUIElement *button = interruptingElement.buttons[@"Open"]; - if ([button exists]) { - [button tap]; - return YES; - } - return NO; - }]; - -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -- (void)test0OpenLinkWithoutApp { - - XCUIApplication *safariApp = [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.mobilesafari"]; - //[safariApp setLaunchArguments: @[@"-u",@"https://ndixit-branch.github.io/TestWebPage.html"]]; - [safariApp launch]; - - sleep(1.0); - [safariApp.buttons[@"URL"] tap]; - //[safariApp.otherElements[@"URL"] tap]; - [safariApp.textFields[@"Search or enter website name"] tap]; - [safariApp typeText:@"https://mnl7s.app.link/CwOJ5aTaNeb"]; - [safariApp.buttons[@"Go"] tap]; - XCUIElement *testBedLink = [[safariApp.webViews descendantsMatchingType:XCUIElementTypeLink] elementBoundByIndex:0]; - - [testBedLink tap]; - - sleep(10); - [safariApp terminate]; - -// XCUIApplication *app = [[XCUIApplication alloc] initWithBundleIdentifier:@"io.branch.TestiOSDeepLink"]; -// -// if ([ app waitForExistenceWithTimeout:5] != NO) { -// NSString *deepLinkData = app.textViews[@"DeepLinkData"].value; -// XCTAssertTrue([deepLinkData containsString:self.deeplinkDataToCheck]); -// } else { -// XCTFail("Application not launched"); -// } -// -} - -@end diff --git a/TestDeepLinking/TestDeepLinkingUITestsWithHostApp/TestDeepLinkingUITestsWithHostApp.m b/TestDeepLinking/TestDeepLinkingUITestsWithHostApp/TestDeepLinkingUITestsWithHostApp.m deleted file mode 100644 index 7e40b4ba8..000000000 --- a/TestDeepLinking/TestDeepLinkingUITestsWithHostApp/TestDeepLinkingUITestsWithHostApp.m +++ /dev/null @@ -1,38 +0,0 @@ -// -// TestDeepLinkingUITestsWithHostApp.m -// TestDeepLinkingUITestsWithHostApp -// -// Created by Nidhi on 3/21/21. -// - -#import - -@interface TestDeepLinkingUITestsWithHostApp : XCTestCase - -@end - -@implementation TestDeepLinkingUITestsWithHostApp - -- (void)setUp { - self.continueAfterFailure = YES; -} - -- (void)tearDown { -} - -- (void)test1OpenApp { - XCUIApplication *app = [[XCUIApplication alloc] init]; - [app launch]; - - sleep(3); - if ([ app waitForExistenceWithTimeout:15] != NO) { - NSString *deepLinkData = app.textViews[@"tvID"].value; - NSLog(@"==== %@" , deepLinkData); - XCTAssertTrue([deepLinkData containsString:@"https:\\/\\/mnl7s.app.link\\/CwOJ5aTaNeb"]); - } else { - XCTFail("Application not launched"); - } -} - - -@end diff --git a/TestHost/AppDelegate.swift b/TestHost/AppDelegate.swift deleted file mode 100644 index c77614d85..000000000 --- a/TestHost/AppDelegate.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// AppDelegate.swift -// TestHost -// -// Created by Ernest Cho on 7/29/22. -// - -import UIKit -import BranchSDK - -@main -class AppDelegate: UIResponder, UIApplicationDelegate { - - - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. - return true - } - - // MARK: UISceneSession Lifecycle - - func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { - // Called when a new scene session is being created. - // Use this method to select a configuration to create the new scene with. - return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) - } - - func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { - // Called when the user discards a scene session. - // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. - // Use this method to release any resources that were specific to the discarded scenes, as they will not return. - } - - -} - diff --git a/TestHost/Assets.xcassets/AccentColor.colorset/Contents.json b/TestHost/Assets.xcassets/AccentColor.colorset/Contents.json deleted file mode 100644 index eb8789700..000000000 --- a/TestHost/Assets.xcassets/AccentColor.colorset/Contents.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "colors" : [ - { - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/TestHost/Assets.xcassets/AppIcon.appiconset/Contents.json b/TestHost/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 9221b9bb1..000000000 --- a/TestHost/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "20x20" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "20x20" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "29x29" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "29x29" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "40x40" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "40x40" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "60x60" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "60x60" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "20x20" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "20x20" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "29x29" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "29x29" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "40x40" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "40x40" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "76x76" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "76x76" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "83.5x83.5" - }, - { - "idiom" : "ios-marketing", - "scale" : "1x", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/TestHost/Assets.xcassets/Contents.json b/TestHost/Assets.xcassets/Contents.json deleted file mode 100644 index 73c00596a..000000000 --- a/TestHost/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/TestHost/Base.lproj/LaunchScreen.storyboard b/TestHost/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index 865e9329f..000000000 --- a/TestHost/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/TestHost/NSURLSession+Branch.h b/TestHost/NSURLSession+Branch.h deleted file mode 100644 index 28073f0a1..000000000 --- a/TestHost/NSURLSession+Branch.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// NSURLSession+Branch.h -// BranchSearchDemo -// -// Created by Ernest Cho on 10/11/18. -// Copyright © 2018 Branch Metrics, Inc. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface NSURLSession (Branch) - -@end - -NS_ASSUME_NONNULL_END diff --git a/TestHost/NSURLSession+Branch.m b/TestHost/NSURLSession+Branch.m deleted file mode 100644 index 594fc6b11..000000000 --- a/TestHost/NSURLSession+Branch.m +++ /dev/null @@ -1,64 +0,0 @@ -// -// NSURLSession+Branch.m -// BranchSearchDemo -// -// Created by Ernest Cho on 8/19/20. -// Copyright © 2020 Branch Metrics, Inc. All rights reserved. -// - -#import "NSURLSession+Branch.h" -#import - -@implementation NSURLSession (Branch) - -+ (void)load { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - [self swizzleSelector:@selector(dataTaskWithRequest:completionHandler:) - withSelector:@selector(xxx_dataTaskWithRequest:completionHandler:)]; - }); -} - -// swaps originalSelector with swizzledSelector -+ (void)swizzleSelector:(SEL)originalSelector withSelector:(SEL)swizzledSelector { - Class class = [self class]; - - Method originalMethod = class_getInstanceMethod(class, originalSelector); - Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); - - method_exchangeImplementations(originalMethod, swizzledMethod); -} - -- (void)logNetworkTrafficRequest:(NSURLRequest *)request data:(NSData *)data response:(NSURLResponse *)response { - NSLog(@"NSURLSessionDataTask Request: %@", request); - - NSData *body = [request HTTPBody]; - if (body) { - NSLog(@"NSURLSessionDataTask Request Body: %@", [NSString stringWithUTF8String:body.bytes]); - } - - NSLog(@"NSURLSessionDataTask Response: %@", response); - - if (data.bytes) { - NSLog(@"NSURLSessionDataTask Response Data: %@", [NSString stringWithUTF8String:data.bytes]); - } -} - -// replacement method for dataTaskWithRequest -- (NSURLSessionDataTask *)xxx_dataTaskWithRequest:(NSURLRequest *)request - completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler { - - // create a new block that just calls the original block after logging the request - void (^completionHandlerWithLogging)(NSData *, NSURLResponse *, NSError *) = ^(NSData *data, NSURLResponse *response, NSError *error) { - if (completionHandler) { - - [self logNetworkTrafficRequest:request data:data response:response]; - - completionHandler(data, response, error); - } - }; - - return [self xxx_dataTaskWithRequest:request completionHandler:completionHandlerWithLogging]; -} - -@end diff --git a/TestHost/SceneDelegate.swift b/TestHost/SceneDelegate.swift deleted file mode 100644 index ee2ca8f1b..000000000 --- a/TestHost/SceneDelegate.swift +++ /dev/null @@ -1,57 +0,0 @@ -// -// SceneDelegate.swift -// TestHost -// -// Created by Ernest Cho on 7/29/22. -// - -import UIKit -import BranchSDK - -class SceneDelegate: UIResponder, UIWindowSceneDelegate { - - var window: UIWindow? - - - func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. - // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. - // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). - guard let _ = (scene as? UIWindowScene) else { return } - - if let userActivity = connectionOptions.userActivities.first { - BranchScene.shared().scene(scene, continue: userActivity) - } - } - - func sceneDidDisconnect(_ scene: UIScene) { - // Called as the scene is being released by the system. - // This occurs shortly after the scene enters the background, or when its session is discarded. - // Release any resources associated with this scene that can be re-created the next time the scene connects. - // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). - } - - func sceneDidBecomeActive(_ scene: UIScene) { - // Called when the scene has moved from an inactive state to an active state. - // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. - } - - func sceneWillResignActive(_ scene: UIScene) { - // Called when the scene will move from an active state to an inactive state. - // This may occur due to temporary interruptions (ex. an incoming phone call). - } - - func sceneWillEnterForeground(_ scene: UIScene) { - // Called as the scene transitions from the background to the foreground. - // Use this method to undo the changes made on entering the background. - } - - func sceneDidEnterBackground(_ scene: UIScene) { - // Called as the scene transitions from the foreground to the background. - // Use this method to save data, release shared resources, and store enough scene-specific state information - // to restore the scene back to its current state. - } - - -} - diff --git a/TestHost/TestHost-Bridging-Header.h b/TestHost/TestHost-Bridging-Header.h deleted file mode 100644 index 1b2cb5d6d..000000000 --- a/TestHost/TestHost-Bridging-Header.h +++ /dev/null @@ -1,4 +0,0 @@ -// -// Use this file to import your target's public headers that you would like to expose to Swift. -// - diff --git a/TestHost/ViewController.swift b/TestHost/ViewController.swift deleted file mode 100644 index ab76ab909..000000000 --- a/TestHost/ViewController.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// ViewController.swift -// TestHost -// -// Created by Ernest Cho on 7/29/22. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - -} - diff --git a/TestHostTests/TestHostTests.swift b/TestHostTests/TestHostTests.swift deleted file mode 100644 index 231b61ed4..000000000 --- a/TestHostTests/TestHostTests.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// TestHostTests.swift -// TestHostTests -// -// Created by Ernest Cho on 7/29/22. -// - -import XCTest -@testable import TestHost - -class TestHostTests: XCTestCase { - - override func setUpWithError() throws { - // Put setup code here. This method is called before the invocation of each test method in the class. - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - - func testExample() throws { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. - // Any test you write for XCTest can be annotated as throws and async. - // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. - // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. - } - - func testPerformanceExample() throws { - // This is an example of a performance test case. - self.measure { - // Put the code you want to measure the time of here. - } - } - -} diff --git a/TestHostUITests/TestHostUITests.swift b/TestHostUITests/TestHostUITests.swift deleted file mode 100644 index 2f5a1af58..000000000 --- a/TestHostUITests/TestHostUITests.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// TestHostUITests.swift -// TestHostUITests -// -// Created by Ernest Cho on 7/29/22. -// - -import XCTest - -class TestHostUITests: XCTestCase { - - override func setUpWithError() throws { - // Put setup code here. This method is called before the invocation of each test method in the class. - - // In UI tests it is usually best to stop immediately when a failure occurs. - continueAfterFailure = false - - // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - - func testExample() throws { - // UI tests must launch the application that they test. - let app = XCUIApplication() - app.launch() - - // Use XCTAssert and related functions to verify your tests produce the correct results. - } - - func testLaunchPerformance() throws { - if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { - // This measures how long it takes to launch your application. - measure(metrics: [XCTApplicationLaunchMetric()]) { - XCUIApplication().launch() - } - } - } -} diff --git a/TestHostUITests/TestHostUITestsLaunchTests.swift b/TestHostUITests/TestHostUITestsLaunchTests.swift deleted file mode 100644 index a49cc5663..000000000 --- a/TestHostUITests/TestHostUITestsLaunchTests.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// TestHostUITestsLaunchTests.swift -// TestHostUITests -// -// Created by Ernest Cho on 7/29/22. -// - -import XCTest - -class TestHostUITestsLaunchTests: XCTestCase { - - override class var runsForEachTargetApplicationUIConfiguration: Bool { - true - } - - override func setUpWithError() throws { - continueAfterFailure = false - } - - func testLaunch() throws { - let app = XCUIApplication() - app.launch() - - // Insert steps here to perform after app launch but before taking a screenshot, - // such as logging into a test account or navigating somewhere in the app - - let attachment = XCTAttachment(screenshot: app.screenshot()) - attachment.name = "Launch Screen" - attachment.lifetime = .keepAlways - add(attachment) - } -} From af22cad2e611a24d75f0aa6577354ce212c3d11c Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Tue, 15 Jul 2025 21:33:55 +0530 Subject: [PATCH 26/27] Revert "Source Code folder and project workspace restructuring." This reverts commit 83cd1788d9dd57f588fb2fcb581763c9fd506fdf. --- BranchSDK.xcodeproj/project.pbxproj | 761 ++--- BranchSDKTests/BNCAPIServerTest.m | 515 ---- BranchSDKTests/BNCAppleReceiptTests.m | 33 - BranchSDKTests/BNCApplicationTests.m | 75 - BranchSDKTests/BNCCallbackMapTests.m | 134 - BranchSDKTests/BNCClassSerializationTests.m | 120 - BranchSDKTests/BNCCrashlyticsWrapperTests.m | 68 - BranchSDKTests/BNCCurrencyTests.m | 194 -- BranchSDKTests/BNCDeviceInfoTests.m | 190 -- BranchSDKTests/BNCDeviceSystemTests.m | 62 - .../BNCDisableAdNetworkCalloutsTests.m | 59 - BranchSDKTests/BNCEncodingUtilsTests.m | 609 ---- BranchSDKTests/BNCJSONUtilityTests.m | 188 -- BranchSDKTests/BNCJsonLoader.h | 20 - BranchSDKTests/BNCJsonLoader.m | 27 - BranchSDKTests/BNCKeyChainTests.m | 121 - BranchSDKTests/BNCLinkDataTests.m | 103 - BranchSDKTests/BNCNetworkInterfaceTests.m | 82 - BranchSDKTests/BNCODMTests.m | 102 - BranchSDKTests/BNCPartnerParametersTests.m | 219 -- BranchSDKTests/BNCPasteboardTests.m | 170 -- BranchSDKTests/BNCPreferenceHelperTests.m | 417 --- BranchSDKTests/BNCReachabilityTests.m | 45 - BranchSDKTests/BNCReferringURLUtilityTests.m | 538 ---- BranchSDKTests/BNCRequestFactoryTests.m | 234 -- BranchSDKTests/BNCSKAdNetworkTests.m | 264 -- BranchSDKTests/BNCSystemObserverTests.m | 139 - .../BNCURLFilterSkiplistUpgradeTests.m | 273 -- BranchSDKTests/BNCURLFilterTests.m | 168 -- BranchSDKTests/BNCUserAgentCollectorTests.m | 111 - .../Branch-SDK-Tests-Bridging-Header.h | 5 - BranchSDKTests/BranchActivityItemTests.m | 39 - BranchSDKTests/BranchClassTests.m | 265 -- .../BranchConfigurationControllerTests.m | 105 - BranchSDKTests/BranchEvent.Test.m | 575 ---- BranchSDKTests/BranchEvent.Test.swift | 129 - .../BranchLastAttributedTouchDataTests.m | 63 - BranchSDKTests/BranchLoggerTests.m | 261 -- BranchSDKTests/BranchPluginSupportTests.m | 91 - BranchSDKTests/BranchQRCodeTests.m | 154 - BranchSDKTests/BranchSDKTests.m | 36 - BranchSDKTests/BranchSDKTests.xctestplan | 37 - BranchSDKTests/BranchShareLinkTests.m | 38 - BranchSDKTests/BranchUniversalObjectTests.m | 446 --- .../DispatchToIsolationQueueTests.m | 76 - BranchSDKTests/NSErrorBranchTests.m | 54 - .../NSMutableDictionaryBranchTests.m | 389 --- BranchSDKTests/NSStringBranchTests.m | 35 - BranchSDKTestsHostApp/AppDelegate.h | 14 - BranchSDKTestsHostApp/AppDelegate.m | 40 - .../AppIcon.appiconset/Contents.json | 35 - BranchSDKTestsHostApp/SceneDelegate.h | 15 - BranchSDKTestsHostApp/SceneDelegate.m | 57 - BranchSDKTestsHostApp/ViewController.h | 14 - BranchSDKTestsHostApp/ViewController.m | 22 - BranchSDKTestsHostApp/cannedData/example.json | 31 - BranchSDKTestsHostApp/cannedData/latd.json | 7 - .../cannedData/latd_empty_data.json | 4 - .../cannedData/latd_missing_data.json | 3 - .../cannedData/latd_missing_window.json | 6 - BranchSDKTestsHostApp/main.m | 18 - .../DeepLinkDemo.xcodeproj/project.pbxproj | 586 ++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcschemes/DeepLinkDemo.xcscheme | 61 +- .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + DeepLinkDemo/DeepLinkDemo/AppDelegate.swift | 268 ++ .../AccentColor.colorset/Contents.json | 0 .../AppIcon.appiconset/Contents.json | 98 + .../Assets.xcassets/Contents.json | 0 .../back_img.imageset/Contents.json | 24 + .../back_img.imageset/icons8-left-100.png | Bin 0 -> 627 bytes .../qentelli_logo.imageset/Contents.json | 21 + .../qentelli_logo.imageset/img.png | Bin 0 -> 4030 bytes .../Base.lproj/LaunchScreen.storyboard | 0 .../DeepLinkDemo/Base.lproj/Main.storyboard | 2685 +++++++++++++++++ .../DeepLinkDemo/Constants/CommonAlert.swift | 22 + .../DeepLinkDemo/Constants/CommonMethod.swift | 59 + .../DeepLinkDemo/Constants/Utils.swift | 87 + .../Controllers/AddMetaDataVC.swift | 117 + .../CreateObjectReferenceObject.swift | 268 ++ .../DeepLinkDemo/Controllers/DispalyVC.swift | 60 + .../Controllers/GenerateURLVC.swift | 257 ++ .../Controllers/HomeViewController.swift | 452 +++ .../LogFileListViewController.swift | 84 + .../Controllers/MetaDataTableViewCell.swift | 224 ++ .../Controllers/NavigateContentVC.swift | 108 + .../Controllers/ParentViewController.swift | 39 + .../Controllers/ReadDeeplinkingVC.swift | 108 + .../Controllers/ReadLogViewController.swift | 41 + .../DeepLinkDemo/Controllers/ReadVC.swift | 50 + .../Controllers/ShareDynamicallyVC.swift | 10 + .../Controllers/TextViewController.swift | 101 + .../Controllers/TrackContentVC.swift | 88 + .../Controllers/ViewController.swift | 20 + .../DeepLinkDemo/Controllers/WebViewVC.swift | 59 + .../DeepLinkDemo-Bridging-Header.h | 12 + .../DeepLinkDemo/DeepLinkDemo.entitlements | 8 +- DeepLinkDemo/DeepLinkDemo/Header.h | 12 + DeepLinkDemo/DeepLinkDemo/Info.plist | 54 + .../DeepLinkDemo/NSURLSessionBranch.h | 16 + .../DeepLinkDemo/NSURLSessionBranch.m | 94 + .../DeepLinkDemo/Reachability/Reachability.h | 19 + .../Reachability/Reachability.swift | 270 ++ .../SIAlertView.bundle/button-cancel-d.png | Bin 0 -> 1041 bytes .../SIAlertView.bundle/button-cancel-d@2x.png | Bin 0 -> 1245 bytes .../SIAlertView.bundle/button-cancel.png | Bin 0 -> 1030 bytes .../SIAlertView.bundle/button-cancel@2x.png | Bin 0 -> 1179 bytes .../SIAlertView.bundle/button-default-d.png | Bin 0 -> 1045 bytes .../button-default-d@2x.png | Bin 0 -> 1247 bytes .../SIAlertView.bundle/button-default.png | Bin 0 -> 1035 bytes .../SIAlertView.bundle/button-default@2x.png | Bin 0 -> 1178 bytes .../button-destructive-d.png | Bin 0 -> 1057 bytes .../button-destructive-d@2x.png | Bin 0 -> 1237 bytes .../SIAlertView.bundle/button-destructive.png | Bin 0 -> 1033 bytes .../button-destructive@2x.png | Bin 0 -> 1187 bytes .../DeepLinkDemo/SIAlertView/SIAlertView.h | 69 + .../DeepLinkDemo/SIAlertView/SIAlertView.m | 1253 ++++++++ .../SIAlertView/UIWindow+SIUtils.h | 20 + .../SIAlertView/UIWindow+SIUtils.m | 42 + .../DeepLinkDemo/StartupOptionsData.swift | 59 + DeepLinkDemo/DeepLinkDemo/img.png | Bin 0 -> 4030 bytes DeepLinkDemo/IPA/Info.plist | 27 + DeepLinkDemo/Podfile | 12 + DeepLinkDemo/Podfile.lock | 23 + DeepLinkDemo/README.md | 2 + .../BranchSDK_ObjC/Public}/BranchConstants.h | 0 TestDeepLinking/Podfile | 8 + .../TestDeepLinking.xcodeproj/project.pbxproj | 733 +++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcschemes/TestDeepLinking.xcscheme | 104 + .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../TestDeepLinking/AppDelegate.swift | 45 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 98 + .../Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 + .../Base.lproj/Main.storyboard | 49 + TestDeepLinking/TestDeepLinking/Info.plist | 79 + .../TestDeepLinking/SceneDelegate.swift | 64 + .../TestDeepLinking.entitlements | 13 + .../TestDeepLinking.xctestplan | 36 + .../TestDeepLinking/ViewController.swift | 22 + .../TestDeepLinkingUITests}/Info.plist | 6 +- .../TestDeepLinkWithoutApp.m | 64 + .../Info.plist | 22 + .../TestDeepLinkingUITestsWithHostApp.m | 38 + TestHost/AppDelegate.swift | 37 + .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 98 + TestHost/Assets.xcassets/Contents.json | 6 + TestHost/Base.lproj/LaunchScreen.storyboard | 25 + .../Base.lproj/Main.storyboard | 2 +- .../Info.plist | 20 +- TestHost/NSURLSession+Branch.h | 17 + TestHost/NSURLSession+Branch.m | 64 + TestHost/SceneDelegate.swift | 57 + TestHost/TestHost-Bridging-Header.h | 4 + TestHost/ViewController.swift | 19 + TestHostTests/TestHostTests.swift | 36 + TestHostUITests/TestHostUITests.swift | 41 + .../TestHostUITestsLaunchTests.swift | 32 + 165 files changed, 10309 insertions(+), 8743 deletions(-) delete mode 100644 BranchSDKTests/BNCAPIServerTest.m delete mode 100644 BranchSDKTests/BNCAppleReceiptTests.m delete mode 100644 BranchSDKTests/BNCApplicationTests.m delete mode 100644 BranchSDKTests/BNCCallbackMapTests.m delete mode 100644 BranchSDKTests/BNCClassSerializationTests.m delete mode 100644 BranchSDKTests/BNCCrashlyticsWrapperTests.m delete mode 100644 BranchSDKTests/BNCCurrencyTests.m delete mode 100644 BranchSDKTests/BNCDeviceInfoTests.m delete mode 100644 BranchSDKTests/BNCDeviceSystemTests.m delete mode 100644 BranchSDKTests/BNCDisableAdNetworkCalloutsTests.m delete mode 100644 BranchSDKTests/BNCEncodingUtilsTests.m delete mode 100644 BranchSDKTests/BNCJSONUtilityTests.m delete mode 100644 BranchSDKTests/BNCJsonLoader.h delete mode 100644 BranchSDKTests/BNCJsonLoader.m delete mode 100644 BranchSDKTests/BNCKeyChainTests.m delete mode 100644 BranchSDKTests/BNCLinkDataTests.m delete mode 100644 BranchSDKTests/BNCNetworkInterfaceTests.m delete mode 100644 BranchSDKTests/BNCODMTests.m delete mode 100644 BranchSDKTests/BNCPartnerParametersTests.m delete mode 100644 BranchSDKTests/BNCPasteboardTests.m delete mode 100644 BranchSDKTests/BNCPreferenceHelperTests.m delete mode 100644 BranchSDKTests/BNCReachabilityTests.m delete mode 100644 BranchSDKTests/BNCReferringURLUtilityTests.m delete mode 100644 BranchSDKTests/BNCRequestFactoryTests.m delete mode 100644 BranchSDKTests/BNCSKAdNetworkTests.m delete mode 100644 BranchSDKTests/BNCSystemObserverTests.m delete mode 100644 BranchSDKTests/BNCURLFilterSkiplistUpgradeTests.m delete mode 100644 BranchSDKTests/BNCURLFilterTests.m delete mode 100644 BranchSDKTests/BNCUserAgentCollectorTests.m delete mode 100644 BranchSDKTests/Branch-SDK-Tests-Bridging-Header.h delete mode 100644 BranchSDKTests/BranchActivityItemTests.m delete mode 100644 BranchSDKTests/BranchClassTests.m delete mode 100644 BranchSDKTests/BranchConfigurationControllerTests.m delete mode 100644 BranchSDKTests/BranchEvent.Test.m delete mode 100644 BranchSDKTests/BranchEvent.Test.swift delete mode 100644 BranchSDKTests/BranchLastAttributedTouchDataTests.m delete mode 100644 BranchSDKTests/BranchLoggerTests.m delete mode 100644 BranchSDKTests/BranchPluginSupportTests.m delete mode 100644 BranchSDKTests/BranchQRCodeTests.m delete mode 100644 BranchSDKTests/BranchSDKTests.m delete mode 100644 BranchSDKTests/BranchSDKTests.xctestplan delete mode 100644 BranchSDKTests/BranchShareLinkTests.m delete mode 100644 BranchSDKTests/BranchUniversalObjectTests.m delete mode 100644 BranchSDKTests/DispatchToIsolationQueueTests.m delete mode 100644 BranchSDKTests/NSErrorBranchTests.m delete mode 100644 BranchSDKTests/NSMutableDictionaryBranchTests.m delete mode 100644 BranchSDKTests/NSStringBranchTests.m delete mode 100644 BranchSDKTestsHostApp/AppDelegate.h delete mode 100644 BranchSDKTestsHostApp/AppDelegate.m delete mode 100644 BranchSDKTestsHostApp/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 BranchSDKTestsHostApp/SceneDelegate.h delete mode 100644 BranchSDKTestsHostApp/SceneDelegate.m delete mode 100644 BranchSDKTestsHostApp/ViewController.h delete mode 100644 BranchSDKTestsHostApp/ViewController.m delete mode 100644 BranchSDKTestsHostApp/cannedData/example.json delete mode 100644 BranchSDKTestsHostApp/cannedData/latd.json delete mode 100644 BranchSDKTestsHostApp/cannedData/latd_empty_data.json delete mode 100644 BranchSDKTestsHostApp/cannedData/latd_missing_data.json delete mode 100644 BranchSDKTestsHostApp/cannedData/latd_missing_window.json delete mode 100644 BranchSDKTestsHostApp/main.m create mode 100644 DeepLinkDemo/DeepLinkDemo.xcodeproj/project.pbxproj create mode 100644 DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename BranchSDK.xcodeproj/xcshareddata/xcschemes/BranchSDKTests.xcscheme => DeepLinkDemo/DeepLinkDemo.xcodeproj/xcshareddata/xcschemes/DeepLinkDemo.xcscheme (58%) create mode 100644 DeepLinkDemo/DeepLinkDemo.xcworkspace/contents.xcworkspacedata create mode 100644 DeepLinkDemo/DeepLinkDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 DeepLinkDemo/DeepLinkDemo/AppDelegate.swift rename {BranchSDKTestsHostApp => DeepLinkDemo/DeepLinkDemo}/Assets.xcassets/AccentColor.colorset/Contents.json (100%) create mode 100644 DeepLinkDemo/DeepLinkDemo/Assets.xcassets/AppIcon.appiconset/Contents.json rename {BranchSDKTestsHostApp => DeepLinkDemo/DeepLinkDemo}/Assets.xcassets/Contents.json (100%) create mode 100644 DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/Contents.json create mode 100644 DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/icons8-left-100.png create mode 100644 DeepLinkDemo/DeepLinkDemo/Assets.xcassets/qentelli_logo.imageset/Contents.json create mode 100644 DeepLinkDemo/DeepLinkDemo/Assets.xcassets/qentelli_logo.imageset/img.png rename {BranchSDKTestsHostApp => DeepLinkDemo/DeepLinkDemo}/Base.lproj/LaunchScreen.storyboard (100%) create mode 100644 DeepLinkDemo/DeepLinkDemo/Base.lproj/Main.storyboard create mode 100644 DeepLinkDemo/DeepLinkDemo/Constants/CommonAlert.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Constants/CommonMethod.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Constants/Utils.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/AddMetaDataVC.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/CreateObjectReferenceObject.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/DispalyVC.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/GenerateURLVC.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/HomeViewController.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/LogFileListViewController.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/MetaDataTableViewCell.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/NavigateContentVC.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/ParentViewController.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/ReadDeeplinkingVC.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/ReadLogViewController.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/ReadVC.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/ShareDynamicallyVC.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/TextViewController.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/TrackContentVC.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/ViewController.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/Controllers/WebViewVC.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/DeepLinkDemo-Bridging-Header.h rename BranchSDKTestsHostApp/BranchSDKTestsHostAppRelease.entitlements => DeepLinkDemo/DeepLinkDemo/DeepLinkDemo.entitlements (50%) create mode 100644 DeepLinkDemo/DeepLinkDemo/Header.h create mode 100644 DeepLinkDemo/DeepLinkDemo/Info.plist create mode 100644 DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.h create mode 100644 DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.m create mode 100644 DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.h create mode 100644 DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel-d.png create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel-d@2x.png create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel.png create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel@2x.png create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default-d.png create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default-d@2x.png create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default.png create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default@2x.png create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive-d.png create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive-d@2x.png create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive.png create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive@2x.png create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.h create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.m create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.h create mode 100644 DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.m create mode 100644 DeepLinkDemo/DeepLinkDemo/StartupOptionsData.swift create mode 100644 DeepLinkDemo/DeepLinkDemo/img.png create mode 100644 DeepLinkDemo/IPA/Info.plist create mode 100644 DeepLinkDemo/Podfile create mode 100644 DeepLinkDemo/Podfile.lock create mode 100644 DeepLinkDemo/README.md rename {BranchSDKTests => Sources/BranchSDK_ObjC/Public}/BranchConstants.h (100%) create mode 100644 TestDeepLinking/Podfile create mode 100644 TestDeepLinking/TestDeepLinking.xcodeproj/project.pbxproj create mode 100644 TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 TestDeepLinking/TestDeepLinking.xcodeproj/xcshareddata/xcschemes/TestDeepLinking.xcscheme create mode 100644 TestDeepLinking/TestDeepLinking.xcworkspace/contents.xcworkspacedata create mode 100644 TestDeepLinking/TestDeepLinking.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 TestDeepLinking/TestDeepLinking/AppDelegate.swift create mode 100644 TestDeepLinking/TestDeepLinking/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 TestDeepLinking/TestDeepLinking/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 TestDeepLinking/TestDeepLinking/Assets.xcassets/Contents.json create mode 100644 TestDeepLinking/TestDeepLinking/Base.lproj/LaunchScreen.storyboard create mode 100644 TestDeepLinking/TestDeepLinking/Base.lproj/Main.storyboard create mode 100644 TestDeepLinking/TestDeepLinking/Info.plist create mode 100644 TestDeepLinking/TestDeepLinking/SceneDelegate.swift create mode 100644 TestDeepLinking/TestDeepLinking/TestDeepLinking.entitlements create mode 100644 TestDeepLinking/TestDeepLinking/TestDeepLinking.xctestplan create mode 100644 TestDeepLinking/TestDeepLinking/ViewController.swift rename {BranchSDKTests => TestDeepLinking/TestDeepLinkingUITests}/Info.plist (86%) create mode 100644 TestDeepLinking/TestDeepLinkingUITests/TestDeepLinkWithoutApp.m create mode 100644 TestDeepLinking/TestDeepLinkingUITestsWithHostApp/Info.plist create mode 100644 TestDeepLinking/TestDeepLinkingUITestsWithHostApp/TestDeepLinkingUITestsWithHostApp.m create mode 100644 TestHost/AppDelegate.swift create mode 100644 TestHost/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 TestHost/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 TestHost/Assets.xcassets/Contents.json create mode 100644 TestHost/Base.lproj/LaunchScreen.storyboard rename {BranchSDKTestsHostApp => TestHost}/Base.lproj/Main.storyboard (95%) rename {BranchSDKTestsHostApp => TestHost}/Info.plist (59%) create mode 100644 TestHost/NSURLSession+Branch.h create mode 100644 TestHost/NSURLSession+Branch.m create mode 100644 TestHost/SceneDelegate.swift create mode 100644 TestHost/TestHost-Bridging-Header.h create mode 100644 TestHost/ViewController.swift create mode 100644 TestHostTests/TestHostTests.swift create mode 100644 TestHostUITests/TestHostUITests.swift create mode 100644 TestHostUITests/TestHostUITestsLaunchTests.swift diff --git a/BranchSDK.xcodeproj/project.pbxproj b/BranchSDK.xcodeproj/project.pbxproj index d91b0675d..e65db2426 100644 --- a/BranchSDK.xcodeproj/project.pbxproj +++ b/BranchSDK.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 73; + objectVersion = 55; objects = { /* Begin PBXAggregateTarget section */ @@ -54,12 +54,25 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 5F2211722894A9C000C5B190 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F2211712894A9C000C5B190 /* AppDelegate.swift */; }; + 5F2211742894A9C000C5B190 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F2211732894A9C000C5B190 /* SceneDelegate.swift */; }; + 5F2211762894A9C000C5B190 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F2211752894A9C000C5B190 /* ViewController.swift */; }; + 5F2211792894A9C000C5B190 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F2211772894A9C000C5B190 /* Main.storyboard */; }; + 5F22117B2894A9C100C5B190 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5F22117A2894A9C100C5B190 /* Assets.xcassets */; }; + 5F22117E2894A9C100C5B190 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5F22117C2894A9C100C5B190 /* LaunchScreen.storyboard */; }; + 5F2211892894A9C100C5B190 /* TestHostTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F2211882894A9C100C5B190 /* TestHostTests.swift */; }; + 5F2211932894A9C100C5B190 /* TestHostUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F2211922894A9C100C5B190 /* TestHostUITests.swift */; }; + 5F2211952894A9C100C5B190 /* TestHostUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F2211942894A9C100C5B190 /* TestHostUITestsLaunchTests.swift */; }; 5F5FDA162B7DE2FE00F14A43 /* BranchLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5FDA152B7DE2FE00F14A43 /* BranchLogger.m */; }; 5F5FDA172B7DE2FE00F14A43 /* BranchLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5FDA152B7DE2FE00F14A43 /* BranchLogger.m */; }; 5F5FDA182B7DE2FE00F14A43 /* BranchLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5FDA152B7DE2FE00F14A43 /* BranchLogger.m */; }; 5F5FDA1A2B7DE31E00F14A43 /* BranchLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F5FDA192B7DE31E00F14A43 /* BranchLogger.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5F5FDA1B2B7DE31E00F14A43 /* BranchLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F5FDA192B7DE31E00F14A43 /* BranchLogger.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5F5FDA1C2B7DE31E00F14A43 /* BranchLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F5FDA192B7DE31E00F14A43 /* BranchLogger.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5F6DD2482894AEBD00AE9FB0 /* BranchSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */; }; + 5F6DD24C2894AF5E00AE9FB0 /* NSURLSession+Branch.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F6DD24A2894AF5E00AE9FB0 /* NSURLSession+Branch.m */; }; + 5F73EBFA28ECE65400608601 /* BranchSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F73EBF428ECE65400608601 /* BranchSDK.framework */; }; + 5F73EBFB28ECE65400608601 /* BranchSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5F73EBF428ECE65400608601 /* BranchSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 5FA71BA82B7AE6B2008009CA /* Branch.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FCDD3A22B7AC6A100EAF29F /* Branch.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5FC446652ACCB97000FF1C87 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 5FC446642ACCB96000FF1C87 /* PrivacyInfo.xcprivacy */; }; 5FC446662ACCB97100FF1C87 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 5FC446642ACCB96000FF1C87 /* PrivacyInfo.xcprivacy */; }; @@ -486,50 +499,48 @@ E7931D842E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; E7931D852E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; E7931D862E01C8AE0007A374 /* ConfigurationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7931D832E01C8AE0007A374 /* ConfigurationController.swift */; }; - E7CA74EF2E1B4F75002EFB40 /* BranchSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */; settings = {ATTRIBUTES = (Required, ); }; }; - E7CA75B92E1B994B002EFB40 /* AdServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7CA75B82E1B994B002EFB40 /* AdServices.framework */; }; - E7CA75BB2E1B9951002EFB40 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7CA75BA2E1B9951002EFB40 /* AdSupport.framework */; }; - E7CA75BC2E1B9957002EFB40 /* BranchSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */; }; - E7CA75BD2E1B9957002EFB40 /* BranchSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 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 */; }; E7F311B22DACB54100F824A7 /* BNCODMInfoCollector.h in Headers */ = {isa = PBXBuildFile; fileRef = E7F311B02DACB54100F824A7 /* BNCODMInfoCollector.h */; }; E7F311B32DACB54100F824A7 /* BNCODMInfoCollector.h in Headers */ = {isa = PBXBuildFile; fileRef = E7F311B02DACB54100F824A7 /* BNCODMInfoCollector.h */; }; + E7FBA85F2E14492700E7AAD9 /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E7FBA8602E1449D100E7AAD9 /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E7FBA8612E1449D100E7AAD9 /* BranchConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - E7CA75592E1B52F4002EFB40 /* PBXContainerItemProxy */ = { + 5F2211852894A9C100C5B190 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 5F2210142894A0DB00C5B190 /* Project object */; proxyType = 1; - remoteGlobalIDString = 5F22101C2894A0DB00C5B190; - remoteInfo = BranchSDK; + remoteGlobalIDString = 5F22116E2894A9C000C5B190; + remoteInfo = TestHost; }; - E7CA75A62E1B79CD002EFB40 /* PBXContainerItemProxy */ = { + 5F22118F2894A9C100C5B190 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 5F2210142894A0DB00C5B190 /* Project object */; proxyType = 1; - remoteGlobalIDString = E7CA755E2E1B59F5002EFB40; - remoteInfo = BranchSDKTestsHostApp; + remoteGlobalIDString = 5F22116E2894A9C000C5B190; + remoteInfo = TestHost; }; - E7CA75BE2E1B9957002EFB40 /* PBXContainerItemProxy */ = { + 5F73EBF828ECE65400608601 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 5F2210142894A0DB00C5B190 /* Project object */; proxyType = 1; - remoteGlobalIDString = 5F22101C2894A0DB00C5B190; - remoteInfo = BranchSDK; + remoteGlobalIDString = 5F73EBF328ECE65400608601; + remoteInfo = "BranchSDK-static"; }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - E7CA75C02E1B9957002EFB40 /* Embed Frameworks */ = { + 5F73EBFF28ECE65400608601 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - E7CA75BD2E1B9957002EFB40 /* BranchSDK.framework in Embed Frameworks */, + 5F73EBFB28ECE65400608601 /* BranchSDK.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -538,8 +549,24 @@ /* Begin PBXFileReference section */ 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BranchSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F22116F2894A9C000C5B190 /* TestHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestHost.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F2211712894A9C000C5B190 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 5F2211732894A9C000C5B190 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 5F2211752894A9C000C5B190 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 5F2211782894A9C000C5B190 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 5F22117A2894A9C100C5B190 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 5F22117D2894A9C100C5B190 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 5F22117F2894A9C100C5B190 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 5F2211842894A9C100C5B190 /* TestHostTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestHostTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F2211882894A9C100C5B190 /* TestHostTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestHostTests.swift; sourceTree = ""; }; + 5F22118E2894A9C100C5B190 /* TestHostUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestHostUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F2211922894A9C100C5B190 /* TestHostUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestHostUITests.swift; sourceTree = ""; }; + 5F2211942894A9C100C5B190 /* TestHostUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestHostUITestsLaunchTests.swift; sourceTree = ""; }; 5F5FDA152B7DE2FE00F14A43 /* BranchLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchLogger.m; sourceTree = ""; }; 5F5FDA192B7DE31E00F14A43 /* BranchLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BranchLogger.h; sourceTree = ""; }; + 5F6DD2492894AF5E00AE9FB0 /* TestHost-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TestHost-Bridging-Header.h"; sourceTree = ""; }; + 5F6DD24A2894AF5E00AE9FB0 /* NSURLSession+Branch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLSession+Branch.m"; sourceTree = ""; }; + 5F6DD24B2894AF5E00AE9FB0 /* NSURLSession+Branch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLSession+Branch.h"; sourceTree = ""; }; 5F73EBF428ECE65400608601 /* BranchSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BranchSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5F73EC0028EDEAC200608601 /* build_static_xcframework_noidfa.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build_static_xcframework_noidfa.sh; sourceTree = ""; }; 5F73EC0128EDEAC200608601 /* build_static_xcframework.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build_static_xcframework.sh; sourceTree = ""; }; @@ -693,88 +720,11 @@ 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 = ""; }; E7931D832E01C8AE0007A374 /* ConfigurationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ConfigurationController.swift; path = ../BranchSDK_Swift/ConfigurationController.swift; sourceTree = ""; }; - E7CA74EB2E1B4F75002EFB40 /* BranchSDKTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BranchSDKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - E7CA755F2E1B59F5002EFB40 /* BranchSDKTestsHostApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BranchSDKTestsHostApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; - E7CA75B82E1B994B002EFB40 /* AdServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdServices.framework; path = System/Library/Frameworks/AdServices.framework; sourceTree = SDKROOT; }; - E7CA75BA2E1B9951002EFB40 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; 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 = ""; }; + E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BranchConstants.h; path = Sources/BranchSDK_ObjC/Public/BranchConstants.h; sourceTree = ""; }; /* End PBXFileReference section */ -/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ - E7CA75522E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - BranchConstants.h, - ); - publicHeaders = ( - BranchConstants.h, - ); - target = 5F22101C2894A0DB00C5B190 /* BranchSDK */; - }; - E7CA75532E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - BranchConstants.h, - ); - publicHeaders = ( - BranchConstants.h, - ); - target = 5F73EBF328ECE65400608601 /* BranchSDK-static */; - }; - E7CA75542E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - BranchConstants.h, - ); - publicHeaders = ( - BranchConstants.h, - ); - target = 5F79038B28B5765D003144CD /* BranchSDK-tvOS */; - }; - E7CA75552E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - Info.plist, - ); - target = E7CA74EA2E1B4F75002EFB40 /* BranchSDKTests */; - }; - E7CA758B2E1B59F7002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - Info.plist, - ); - target = E7CA755E2E1B59F5002EFB40 /* BranchSDKTestsHostApp */; - }; - E7CA75B12E1B7B02002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - cannedData/example.json, - cannedData/latd_empty_data.json, - cannedData/latd_missing_data.json, - cannedData/latd_missing_window.json, - cannedData/latd.json, - ); - target = E7CA74EA2E1B4F75002EFB40 /* BranchSDKTests */; - }; -/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ - -/* Begin PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet section */ - E7CA75562E1B504C002EFB40 /* PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet */ = { - isa = PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet; - buildPhase = E7CA74E72E1B4F75002EFB40 /* Sources */; - membershipExceptions = ( - BNCJsonLoader.h, - "Branch-SDK-Tests-Bridging-Header.h", - ); - }; -/* End PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet section */ - -/* Begin PBXFileSystemSynchronizedRootGroup section */ - E7CA74EC2E1B4F75002EFB40 /* BranchSDKTests */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (E7CA75522E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E7CA75532E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E7CA75542E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E7CA75552E1B504C002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E7CA75562E1B504C002EFB40 /* PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = BranchSDKTests; sourceTree = ""; }; - E7CA75602E1B59F5002EFB40 /* BranchSDKTestsHostApp */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (E7CA75B12E1B7B02002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E7CA758B2E1B59F7002EFB40 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = BranchSDKTestsHostApp; sourceTree = ""; }; -/* End PBXFileSystemSynchronizedRootGroup section */ - /* Begin PBXFrameworksBuildPhase section */ 5F22101A2894A0DB00C5B190 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; @@ -783,35 +733,40 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5F73EBF128ECE65400608601 /* Frameworks */ = { + 5F22116C2894A9C000C5B190 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 5F6DD2482894AEBD00AE9FB0 /* BranchSDK.framework in Frameworks */, + 5F73EBFA28ECE65400608601 /* BranchSDK.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5F79038928B5765D003144CD /* Frameworks */ = { + 5F2211812894A9C100C5B190 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - E7CA74E82E1B4F75002EFB40 /* Frameworks */ = { + 5F22118B2894A9C100C5B190 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E7CA74EF2E1B4F75002EFB40 /* BranchSDK.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - E7CA755C2E1B59F5002EFB40 /* Frameworks */ = { + 5F73EBF128ECE65400608601 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F79038928B5765D003144CD /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E7CA75BC2E1B9957002EFB40 /* BranchSDK.framework in Frameworks */, - E7CA75B92E1B994B002EFB40 /* AdServices.framework in Frameworks */, - E7CA75BB2E1B9951002EFB40 /* AdSupport.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -821,12 +776,13 @@ 5F2210132894A0DB00C5B190 = { isa = PBXGroup; children = ( + E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */, 5FCDD36B2B7AC6A100EAF29F /* BranchSDK */, + 5F2211702894A9C000C5B190 /* TestHost */, + 5F2211872894A9C100C5B190 /* TestHostTests */, + 5F2211912894A9C100C5B190 /* TestHostUITests */, 5FF2AFDD28E7C1F200393216 /* Framework */, 5FF2AFDB28E7BF5500393216 /* Scripts */, - E7CA74EC2E1B4F75002EFB40 /* BranchSDKTests */, - E7CA75602E1B59F5002EFB40 /* BranchSDKTestsHostApp */, - E7CA75B72E1B994B002EFB40 /* Frameworks */, 5F22101E2894A0DB00C5B190 /* Products */, ); sourceTree = ""; @@ -835,14 +791,49 @@ isa = PBXGroup; children = ( 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */, + 5F22116F2894A9C000C5B190 /* TestHost.app */, + 5F2211842894A9C100C5B190 /* TestHostTests.xctest */, + 5F22118E2894A9C100C5B190 /* TestHostUITests.xctest */, 5F79038C28B5765D003144CD /* BranchSDK.framework */, 5F73EBF428ECE65400608601 /* BranchSDK.framework */, - E7CA74EB2E1B4F75002EFB40 /* BranchSDKTests.xctest */, - E7CA755F2E1B59F5002EFB40 /* BranchSDKTestsHostApp.app */, ); name = Products; sourceTree = ""; }; + 5F2211702894A9C000C5B190 /* TestHost */ = { + isa = PBXGroup; + children = ( + 5F2211712894A9C000C5B190 /* AppDelegate.swift */, + 5F2211732894A9C000C5B190 /* SceneDelegate.swift */, + 5F2211752894A9C000C5B190 /* ViewController.swift */, + 5F6DD24B2894AF5E00AE9FB0 /* NSURLSession+Branch.h */, + 5F6DD24A2894AF5E00AE9FB0 /* NSURLSession+Branch.m */, + 5F2211772894A9C000C5B190 /* Main.storyboard */, + 5F22117A2894A9C100C5B190 /* Assets.xcassets */, + 5F22117C2894A9C100C5B190 /* LaunchScreen.storyboard */, + 5F22117F2894A9C100C5B190 /* Info.plist */, + 5F6DD2492894AF5E00AE9FB0 /* TestHost-Bridging-Header.h */, + ); + path = TestHost; + sourceTree = ""; + }; + 5F2211872894A9C100C5B190 /* TestHostTests */ = { + isa = PBXGroup; + children = ( + 5F2211882894A9C100C5B190 /* TestHostTests.swift */, + ); + path = TestHostTests; + sourceTree = ""; + }; + 5F2211912894A9C100C5B190 /* TestHostUITests */ = { + isa = PBXGroup; + children = ( + 5F2211922894A9C100C5B190 /* TestHostUITests.swift */, + 5F2211942894A9C100C5B190 /* TestHostUITestsLaunchTests.swift */, + ); + path = TestHostUITests; + sourceTree = ""; + }; 5FCDD36B2B7AC6A100EAF29F /* BranchSDK */ = { isa = PBXGroup; children = ( @@ -1036,15 +1027,6 @@ path = Framework; sourceTree = ""; }; - E7CA75B72E1B994B002EFB40 /* Frameworks */ = { - isa = PBXGroup; - children = ( - E7CA75BA2E1B9951002EFB40 /* AdSupport.framework */, - E7CA75B82E1B994B002EFB40 /* AdServices.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -1052,6 +1034,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + E7FBA85F2E14492700E7AAD9 /* BranchConstants.h in Headers */, 5FCDD52E2B7AC6A300EAF29F /* Branch+Validator.h in Headers */, 5FCDD4A42B7AC6A200EAF29F /* BNCCallbacks.h in Headers */, 5FCDD4922B7AC6A100EAF29F /* BranchLinkProperties.h in Headers */, @@ -1134,6 +1117,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + E7FBA8602E1449D100E7AAD9 /* BranchConstants.h in Headers */, 5FCDD52F2B7AC6A300EAF29F /* Branch+Validator.h in Headers */, 5FCDD4A52B7AC6A200EAF29F /* BNCCallbacks.h in Headers */, 5FCDD4932B7AC6A100EAF29F /* BranchLinkProperties.h in Headers */, @@ -1216,6 +1200,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + E7FBA8612E1449D100E7AAD9 /* BranchConstants.h in Headers */, 5FCDD4BB2B7AC6A200EAF29F /* BranchPasteControl.h in Headers */, 5FCDD5302B7AC6A300EAF29F /* Branch+Validator.h in Headers */, 5FCDD4A62B7AC6A200EAF29F /* BNCCallbacks.h in Headers */, @@ -1315,6 +1300,61 @@ productReference = 5F22101D2894A0DB00C5B190 /* BranchSDK.framework */; productType = "com.apple.product-type.framework"; }; + 5F22116E2894A9C000C5B190 /* TestHost */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F2211962894A9C100C5B190 /* Build configuration list for PBXNativeTarget "TestHost" */; + buildPhases = ( + 5F22116B2894A9C000C5B190 /* Sources */, + 5F22116C2894A9C000C5B190 /* Frameworks */, + 5F22116D2894A9C000C5B190 /* Resources */, + 5F73EBFF28ECE65400608601 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 5F73EBF928ECE65400608601 /* PBXTargetDependency */, + ); + name = TestHost; + productName = TestHost; + productReference = 5F22116F2894A9C000C5B190 /* TestHost.app */; + productType = "com.apple.product-type.application"; + }; + 5F2211832894A9C100C5B190 /* TestHostTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F2211992894A9C100C5B190 /* Build configuration list for PBXNativeTarget "TestHostTests" */; + buildPhases = ( + 5F2211802894A9C100C5B190 /* Sources */, + 5F2211812894A9C100C5B190 /* Frameworks */, + 5F2211822894A9C100C5B190 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5F2211862894A9C100C5B190 /* PBXTargetDependency */, + ); + name = TestHostTests; + productName = TestHostTests; + productReference = 5F2211842894A9C100C5B190 /* TestHostTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 5F22118D2894A9C100C5B190 /* TestHostUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5F22119C2894A9C100C5B190 /* Build configuration list for PBXNativeTarget "TestHostUITests" */; + buildPhases = ( + 5F22118A2894A9C100C5B190 /* Sources */, + 5F22118B2894A9C100C5B190 /* Frameworks */, + 5F22118C2894A9C100C5B190 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5F2211902894A9C100C5B190 /* PBXTargetDependency */, + ); + name = TestHostUITests; + productName = TestHostUITests; + productReference = 5F22118E2894A9C100C5B190 /* TestHostUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; 5F73EBF328ECE65400608601 /* BranchSDK-static */ = { isa = PBXNativeTarget; buildConfigurationList = 5F73EBFC28ECE65400608601 /* Build configuration list for PBXNativeTarget "BranchSDK-static" */; @@ -1351,54 +1391,6 @@ productReference = 5F79038C28B5765D003144CD /* BranchSDK.framework */; productType = "com.apple.product-type.framework"; }; - E7CA74EA2E1B4F75002EFB40 /* BranchSDKTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = E7CA74F42E1B4F75002EFB40 /* Build configuration list for PBXNativeTarget "BranchSDKTests" */; - buildPhases = ( - E7CA74E72E1B4F75002EFB40 /* Sources */, - E7CA74E82E1B4F75002EFB40 /* Frameworks */, - E7CA74E92E1B4F75002EFB40 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - E7CA755A2E1B52F4002EFB40 /* PBXTargetDependency */, - E7CA75A72E1B79CD002EFB40 /* PBXTargetDependency */, - ); - fileSystemSynchronizedGroups = ( - E7CA74EC2E1B4F75002EFB40 /* BranchSDKTests */, - ); - name = BranchSDKTests; - packageProductDependencies = ( - ); - productName = BranchSDKTests; - productReference = E7CA74EB2E1B4F75002EFB40 /* BranchSDKTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - E7CA755E2E1B59F5002EFB40 /* BranchSDKTestsHostApp */ = { - isa = PBXNativeTarget; - buildConfigurationList = E7CA758C2E1B59F7002EFB40 /* Build configuration list for PBXNativeTarget "BranchSDKTestsHostApp" */; - buildPhases = ( - E7CA755B2E1B59F5002EFB40 /* Sources */, - E7CA755C2E1B59F5002EFB40 /* Frameworks */, - E7CA755D2E1B59F5002EFB40 /* Resources */, - E7CA75C02E1B9957002EFB40 /* Embed Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - E7CA75BF2E1B9957002EFB40 /* PBXTargetDependency */, - ); - fileSystemSynchronizedGroups = ( - E7CA75602E1B59F5002EFB40 /* BranchSDKTestsHostApp */, - ); - name = BranchSDKTestsHostApp; - packageProductDependencies = ( - ); - productName = BranchSDKTestsHostApp; - productReference = E7CA755F2E1B59F5002EFB40 /* BranchSDKTestsHostApp.app */; - productType = "com.apple.product-type.application"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -1416,6 +1408,18 @@ 5F2211672894A90500C5B190 = { CreatedOnToolsVersion = 13.4.1; }; + 5F22116E2894A9C000C5B190 = { + CreatedOnToolsVersion = 13.4.1; + LastSwiftMigration = 1340; + }; + 5F2211832894A9C100C5B190 = { + CreatedOnToolsVersion = 13.4.1; + TestTargetID = 5F22116E2894A9C000C5B190; + }; + 5F22118D2894A9C100C5B190 = { + CreatedOnToolsVersion = 13.4.1; + TestTargetID = 5F22116E2894A9C000C5B190; + }; 5F73EBF328ECE65400608601 = { CreatedOnToolsVersion = 14.0; LastSwiftMigration = 1640; @@ -1433,16 +1437,10 @@ 5FF9DEF428EE7C3600D62DE1 = { CreatedOnToolsVersion = 14.0; }; - E7CA74EA2E1B4F75002EFB40 = { - CreatedOnToolsVersion = 16.4; - TestTargetID = E7CA755E2E1B59F5002EFB40; - }; - E7CA755E2E1B59F5002EFB40 = { - CreatedOnToolsVersion = 16.4; - }; }; }; buildConfigurationList = 5F2210172894A0DB00C5B190 /* Build configuration list for PBXProject "BranchSDK" */; + compatibilityVersion = "Xcode 13.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -1450,7 +1448,6 @@ Base, ); mainGroup = 5F2210132894A0DB00C5B190; - preferredProjectObjectVersion = 55; productRefGroup = 5F22101E2894A0DB00C5B190 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -1458,12 +1455,13 @@ 5F22101C2894A0DB00C5B190 /* BranchSDK */, 5F73EBF328ECE65400608601 /* BranchSDK-static */, 5F79038B28B5765D003144CD /* BranchSDK-tvOS */, + 5F22116E2894A9C000C5B190 /* TestHost */, + 5F2211832894A9C100C5B190 /* TestHostTests */, + 5F22118D2894A9C100C5B190 /* TestHostUITests */, 5F2211672894A90500C5B190 /* xcframework */, 5FF9DEEC28EE7C0D00D62DE1 /* xcframework-noidfa */, 5FF9DEF428EE7C3600D62DE1 /* static-xcframework */, 5FF9DEF028EE7C2200D62DE1 /* static-xcframework-noidfa */, - E7CA74EA2E1B4F75002EFB40 /* BranchSDKTests */, - E7CA755E2E1B59F5002EFB40 /* BranchSDKTestsHostApp */, ); }; /* End PBXProject section */ @@ -1477,33 +1475,43 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5F73EBF228ECE65400608601 /* Resources */ = { + 5F22116D2894A9C000C5B190 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5FC446662ACCB97100FF1C87 /* PrivacyInfo.xcprivacy in Resources */, + 5F22117E2894A9C100C5B190 /* LaunchScreen.storyboard in Resources */, + 5F22117B2894A9C100C5B190 /* Assets.xcassets in Resources */, + 5F2211792894A9C000C5B190 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5F79038A28B5765D003144CD /* Resources */ = { + 5F2211822894A9C100C5B190 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5FC446672ACCB97200FF1C87 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - E7CA74E92E1B4F75002EFB40 /* Resources */ = { + 5F22118C2894A9C100C5B190 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - E7CA755D2E1B59F5002EFB40 /* Resources */ = { + 5F73EBF228ECE65400608601 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5FC446662ACCB97100FF1C87 /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F79038A28B5765D003144CD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5FC446672ACCB97200FF1C87 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1665,6 +1673,34 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 5F22116B2894A9C000C5B190 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F2211762894A9C000C5B190 /* ViewController.swift in Sources */, + 5F6DD24C2894AF5E00AE9FB0 /* NSURLSession+Branch.m in Sources */, + 5F2211722894A9C000C5B190 /* AppDelegate.swift in Sources */, + 5F2211742894A9C000C5B190 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F2211802894A9C100C5B190 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F2211892894A9C100C5B190 /* TestHostTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5F22118A2894A9C100C5B190 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5F2211952894A9C100C5B190 /* TestHostUITestsLaunchTests.swift in Sources */, + 5F2211932894A9C100C5B190 /* TestHostUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5F73EBF028ECE65400608601 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1815,40 +1851,45 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - E7CA74E72E1B4F75002EFB40 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - E7CA755B2E1B59F5002EFB40 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - E7CA755A2E1B52F4002EFB40 /* PBXTargetDependency */ = { + 5F2211862894A9C100C5B190 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 5F22101C2894A0DB00C5B190 /* BranchSDK */; - targetProxy = E7CA75592E1B52F4002EFB40 /* PBXContainerItemProxy */; + target = 5F22116E2894A9C000C5B190 /* TestHost */; + targetProxy = 5F2211852894A9C100C5B190 /* PBXContainerItemProxy */; }; - E7CA75A72E1B79CD002EFB40 /* PBXTargetDependency */ = { + 5F2211902894A9C100C5B190 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = E7CA755E2E1B59F5002EFB40 /* BranchSDKTestsHostApp */; - targetProxy = E7CA75A62E1B79CD002EFB40 /* PBXContainerItemProxy */; + target = 5F22116E2894A9C000C5B190 /* TestHost */; + targetProxy = 5F22118F2894A9C100C5B190 /* PBXContainerItemProxy */; }; - E7CA75BF2E1B9957002EFB40 /* PBXTargetDependency */ = { + 5F73EBF928ECE65400608601 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 5F22101C2894A0DB00C5B190 /* BranchSDK */; - targetProxy = E7CA75BE2E1B9957002EFB40 /* PBXContainerItemProxy */; + target = 5F73EBF328ECE65400608601 /* BranchSDK-static */; + targetProxy = 5F73EBF828ECE65400608601 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ +/* Begin PBXVariantGroup section */ + 5F2211772894A9C000C5B190 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5F2211782894A9C000C5B190 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 5F22117C2894A9C100C5B190 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 5F22117D2894A9C100C5B190 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + /* Begin XCBuildConfiguration section */ 5F2210222894A0DB00C5B190 /* Debug */ = { isa = XCBuildConfiguration; @@ -2065,6 +2106,156 @@ }; name = Release; }; + 5F2211972894A9C100C5B190 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = R63EM248DP; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = TestHost/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestHost; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "TestHost/TestHost-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 5F2211982894A9C100C5B190 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = R63EM248DP; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = TestHost/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestHost; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "TestHost/TestHost-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 5F22119A2894A9C100C5B190 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = R63EM248DP; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestHostTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestHost.app/TestHost"; + }; + name = Debug; + }; + 5F22119B2894A9C100C5B190 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = R63EM248DP; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestHostTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestHost.app/TestHost"; + }; + name = Release; + }; + 5F22119D2894A9C100C5B190 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = R63EM248DP; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestHostUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = TestHost; + }; + name = Debug; + }; + 5F22119E2894A9C100C5B190 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = R63EM248DP; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestHostUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = TestHost; + }; + name = Release; + }; 5F73EBFD28ECE65400608601 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2288,123 +2479,6 @@ }; name = Release; }; - E7CA74F22E1B4F75002EFB40 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = R63EM248DP; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 18.5; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = branch.BranchSDKTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_VERSION = 6.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BranchSDKTestsHostApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/BranchSDKTestsHostApp"; - }; - name = Debug; - }; - E7CA74F32E1B4F75002EFB40 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = R63EM248DP; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 18.5; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = branch.BranchSDKTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_VERSION = 6.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BranchSDKTestsHostApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/BranchSDKTestsHostApp"; - }; - name = Release; - }; - E7CA758D2E1B59F7002EFB40 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = R63EM248DP; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = BranchSDKTestsHostApp/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = BranchSDKTestsHostApp; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 18.5; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = branch.BranchSDKTestsHostApp; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - E7CA758E2E1B59F7002EFB40 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CODE_SIGN_ENTITLEMENTS = BranchSDKTestsHostApp/BranchSDKTestsHostAppRelease.entitlements; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = R63EM248DP; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = BranchSDKTestsHostApp/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = BranchSDKTestsHostApp; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 18.5; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = branch.BranchSDKTestsHostApp; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -2435,6 +2509,33 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 5F2211962894A9C100C5B190 /* Build configuration list for PBXNativeTarget "TestHost" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F2211972894A9C100C5B190 /* Debug */, + 5F2211982894A9C100C5B190 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F2211992894A9C100C5B190 /* Build configuration list for PBXNativeTarget "TestHostTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F22119A2894A9C100C5B190 /* Debug */, + 5F22119B2894A9C100C5B190 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5F22119C2894A9C100C5B190 /* Build configuration list for PBXNativeTarget "TestHostUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5F22119D2894A9C100C5B190 /* Debug */, + 5F22119E2894A9C100C5B190 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5F73EBFC28ECE65400608601 /* Build configuration list for PBXNativeTarget "BranchSDK-static" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -2480,24 +2581,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - E7CA74F42E1B4F75002EFB40 /* Build configuration list for PBXNativeTarget "BranchSDKTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - E7CA74F22E1B4F75002EFB40 /* Debug */, - E7CA74F32E1B4F75002EFB40 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - E7CA758C2E1B59F7002EFB40 /* Build configuration list for PBXNativeTarget "BranchSDKTestsHostApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - E7CA758D2E1B59F7002EFB40 /* Debug */, - E7CA758E2E1B59F7002EFB40 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = 5F2210142894A0DB00C5B190 /* Project object */; diff --git a/BranchSDKTests/BNCAPIServerTest.m b/BranchSDKTests/BNCAPIServerTest.m deleted file mode 100644 index 28bb3b3b3..000000000 --- a/BranchSDKTests/BNCAPIServerTest.m +++ /dev/null @@ -1,515 +0,0 @@ -// -// BNCAPIServerTest.m -// Branch-SDK-Tests -// -// Created by Nidhi Dixit on 9/6/23. -// Copyright © 2023 Branch, Inc. All rights reserved. -// - -#import -#import "BNCServerAPI.h" -#import "BNCSystemObserver.h" -#import "BNCConfig.h" -#import "BranchConstants.h" -#import "Branch.h" - -@interface BNCAPIServerTest : XCTestCase - -@end - -@implementation BNCAPIServerTest - -- (void)testInstallServiceURL { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - - NSString *url = [serverAPI installServiceURL]; - NSString *expectedUrlStr = @"https://api3.branch.io/v1/install"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testOpenServiceURL { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - - NSString *url = [serverAPI openServiceURL]; - NSString *expectedUrlStr = @"https://api3.branch.io/v1/open"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testStandardEventServiceURL { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - - NSString *url = [serverAPI standardEventServiceURL]; - NSString *expectedUrlStr = @"https://api3.branch.io/v2/event/standard"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testCustomEventServiceURL { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - - NSString *url = [serverAPI customEventServiceURL]; - NSString *expectedUrlStr = @"https://api3.branch.io/v2/event/custom"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testLinkServiceURL { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - - NSString *url = [serverAPI linkServiceURL]; - NSString *expectedUrlStr = @"https://api3.branch.io/v1/url"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testQRCodeServiceURL { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - - NSString *url = [serverAPI qrcodeServiceURL]; - NSString *expectedUrlStr = @"https://api3.branch.io/v1/qr-code"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testLATDServiceURL { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - - NSString *url = [serverAPI latdServiceURL]; - NSString *expectedUrlStr = @"https://api3.branch.io/v1/cpid/latd"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testValidationServiceURL { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - - NSString *url = [serverAPI validationServiceURL]; - NSString *expectedUrlPrefix= @"https://api3.branch.io/v1/app-link-settings"; - - XCTAssertTrue([url hasPrefix:expectedUrlPrefix]); -} - -- (void)testInstallServiceURL_Tracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI installServiceURL]; - NSString *expectedUrlStr = @"https://api-safetrack.branch.io/v1/install"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testOpenServiceURL_Tracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI openServiceURL]; - NSString *expectedUrlStr = @"https://api-safetrack.branch.io/v1/open"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testStandardEventServiceURL_Tracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI standardEventServiceURL]; - NSString *expectedUrlStr = @"https://api-safetrack.branch.io/v2/event/standard"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testCustomEventServiceURL_Tracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI customEventServiceURL]; - NSString *expectedUrlStr = @"https://api-safetrack.branch.io/v2/event/custom"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testLinkServiceURL_Tracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI linkServiceURL]; - NSString *expectedUrlStr = @"https://api3.branch.io/v1/url"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testQRCodeServiceURL_Tracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI qrcodeServiceURL]; - NSString *expectedUrlStr = @"https://api3.branch.io/v1/qr-code"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testLATDServiceURL_Tracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI latdServiceURL]; - NSString *expectedUrlStr = @"https://api3.branch.io/v1/cpid/latd"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testValidationServiceURL_Tracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI validationServiceURL]; - NSString *expectedUrlPrefix= @"https://api3.branch.io/v1/app-link-settings"; - - XCTAssertTrue([url hasPrefix:expectedUrlPrefix]); -} - -- (void)testInstallServiceURL_EU { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - - NSString *url = [serverAPI installServiceURL]; - NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/install"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testOpenServiceURL_EU { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - - NSString *url = [serverAPI openServiceURL]; - NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/open"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testStandardEventServiceURL_EU { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - - NSString *url = [serverAPI standardEventServiceURL]; - NSString *expectedUrlStr = @"https://api3-eu.branch.io/v2/event/standard"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testCustomEventServiceURL_EU { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - - NSString *url = [serverAPI customEventServiceURL]; - NSString *expectedUrlStr = @"https://api3-eu.branch.io/v2/event/custom"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testLinkServiceURL_EU { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - - NSString *url = [serverAPI linkServiceURL]; - NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/url"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testQRCodeServiceURL_EU { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - - NSString *url = [serverAPI qrcodeServiceURL]; - NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/qr-code"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testLATDServiceURL_EU { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - - NSString *url = [serverAPI latdServiceURL]; - NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/cpid/latd"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testValidationServiceURL_EU { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - - NSString *url = [serverAPI validationServiceURL]; - NSString *expectedUrlPrefix= @"https://api3-eu.branch.io/v1/app-link-settings"; - - XCTAssertTrue([url hasPrefix:expectedUrlPrefix]); -} - -- (void)testInstallServiceURL_EUTracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI installServiceURL]; - NSString *expectedUrlStr = @"https://api-safetrack-eu.branch.io/v1/install"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testOpenServiceURL_EUTracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI openServiceURL]; - NSString *expectedUrlStr = @"https://api-safetrack-eu.branch.io/v1/open"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testStandardEventServiceURL_EUTracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI standardEventServiceURL]; - NSString *expectedUrlStr = @"https://api-safetrack-eu.branch.io/v2/event/standard"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testCustomEventServiceURL_EUTracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI customEventServiceURL]; - NSString *expectedUrlStr = @"https://api-safetrack-eu.branch.io/v2/event/custom"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testLinkServiceURL_EUTracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI linkServiceURL]; - NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/url"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testQRCodeServiceURL_EUTracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI qrcodeServiceURL]; - NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/qr-code"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testLATDServiceURL_EUTracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI latdServiceURL]; - NSString *expectedUrlStr = @"https://api3-eu.branch.io/v1/cpid/latd"; - - XCTAssertTrue([url isEqualToString:expectedUrlStr]); -} - -- (void)testValidationServiceURL_EUTracking { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useEUServers = YES; - serverAPI.useTrackingDomain = YES; - - NSString *url = [serverAPI validationServiceURL]; - NSString *expectedUrlPrefix= @"https://api3-eu.branch.io/v1/app-link-settings"; - - XCTAssertTrue([url hasPrefix:expectedUrlPrefix]); -} - -- (void)testDefaultAPIURL { - BNCServerAPI *serverAPI = [BNCServerAPI new]; - XCTAssertNil(serverAPI.customAPIURL); - - NSString *storedUrl = [[BNCServerAPI sharedInstance] installServiceURL]; - NSString *expectedUrl = [BNC_API_URL stringByAppendingString: @"/v1/install"]; - XCTAssertEqualObjects(storedUrl, expectedUrl); -} - -- (void)testSetAPIURL_Example { - NSString *url = @"https://www.example.com"; - [Branch setAPIUrl:url]; - - NSString *storedUrl = [[BNCServerAPI sharedInstance] installServiceURL]; - NSString *expectedUrl = [url stringByAppendingString: @"/v1/install"]; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - [Branch setAPIUrl:BNC_API_URL]; -} - -- (void)testSetAPIURL_InvalidHttp { - NSString *url = @"Invalid://www.example.com"; - [Branch setAPIUrl:url]; - - NSString *storedUrl = [[BNCServerAPI sharedInstance] installServiceURL]; - NSString *expectedUrl = [BNC_API_URL stringByAppendingString: @"/v1/install"]; - XCTAssertEqualObjects(storedUrl, expectedUrl); -} - -- (void)testSetAPIURL_InvalidEmpty { - NSString *url = @""; - [Branch setAPIUrl:url]; - - NSString *storedUrl = [[BNCServerAPI sharedInstance] installServiceURL]; - NSString *expectedUrl = [BNC_API_URL stringByAppendingString: @"/v1/install"]; - XCTAssertEqualObjects(storedUrl, expectedUrl); -} - - -- (void)testSetSafeTrackServiceURLWithUserTrackingDomain { - NSString *url = @"https://links.toTestDomain.com"; - NSString *safeTrackUrl = @"https://links.toTestDomain-safeTrack.com"; - - [Branch setAPIUrl:url]; - [Branch setSafetrackAPIURL:safeTrackUrl]; - - BNCServerAPI *serverAPI = [BNCServerAPI sharedInstance]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useTrackingDomain = YES; - - NSString *storedUrl = [[BNCServerAPI sharedInstance] installServiceURL]; - NSString *expectedUrl = @"https://links.toTestDomain-safeTrack.com/v1/install"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] openServiceURL]; - expectedUrl = @"https://links.toTestDomain-safeTrack.com/v1/open"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] standardEventServiceURL]; - expectedUrl = @"https://links.toTestDomain-safeTrack.com/v2/event/standard"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] customEventServiceURL]; - expectedUrl = @"https://links.toTestDomain-safeTrack.com/v2/event/custom"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] linkServiceURL]; - expectedUrl = @"https://links.toTestDomain.com/v1/url"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] qrcodeServiceURL]; - expectedUrl = @"https://links.toTestDomain.com/v1/qr-code"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] latdServiceURL]; - expectedUrl = @"https://links.toTestDomain.com/v1/cpid/latd"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] validationServiceURL]; - expectedUrl = @"https://links.toTestDomain.com/v1/app-link-settings"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - [BNCServerAPI sharedInstance].useTrackingDomain = NO; - [BNCServerAPI sharedInstance].useEUServers = NO; - [BNCServerAPI sharedInstance].automaticallyEnableTrackingDomain = YES; - [BNCServerAPI sharedInstance].customAPIURL = nil; - [BNCServerAPI sharedInstance].customSafeTrackAPIURL = nil; - -} - -- (void)testSetSafeTrackServiceURLWithOutUserTrackingDomain { - NSString *url = @"https://links.toTestDomain.com"; - NSString *safeTrackUrl = @"https://links.toTestDomain-safeTrack.com"; - - [Branch setAPIUrl:url]; - [Branch setSafetrackAPIURL:safeTrackUrl]; - - BNCServerAPI *serverAPI = [BNCServerAPI sharedInstance]; - serverAPI.automaticallyEnableTrackingDomain = NO; - serverAPI.useTrackingDomain = NO; - - NSString *storedUrl = [[BNCServerAPI sharedInstance] installServiceURL]; - NSString *expectedUrl = @"https://links.toTestDomain.com/v1/install"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] openServiceURL]; - expectedUrl = @"https://links.toTestDomain.com/v1/open"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] standardEventServiceURL]; - expectedUrl = @"https://links.toTestDomain.com/v2/event/standard"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] customEventServiceURL]; - expectedUrl = @"https://links.toTestDomain.com/v2/event/custom"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] linkServiceURL]; - expectedUrl = @"https://links.toTestDomain.com/v1/url"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] qrcodeServiceURL]; - expectedUrl = @"https://links.toTestDomain.com/v1/qr-code"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] latdServiceURL]; - expectedUrl = @"https://links.toTestDomain.com/v1/cpid/latd"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - storedUrl = [[BNCServerAPI sharedInstance] validationServiceURL]; - expectedUrl = @"https://links.toTestDomain.com/v1/app-link-settings"; - XCTAssertEqualObjects(storedUrl, expectedUrl); - - [BNCServerAPI sharedInstance].useTrackingDomain = NO; - [BNCServerAPI sharedInstance].useEUServers = NO; - [BNCServerAPI sharedInstance].automaticallyEnableTrackingDomain = YES; - [BNCServerAPI sharedInstance].customAPIURL = nil; - [BNCServerAPI sharedInstance].customSafeTrackAPIURL = nil; - -} - -@end diff --git a/BranchSDKTests/BNCAppleReceiptTests.m b/BranchSDKTests/BNCAppleReceiptTests.m deleted file mode 100644 index faff0ef96..000000000 --- a/BranchSDKTests/BNCAppleReceiptTests.m +++ /dev/null @@ -1,33 +0,0 @@ -// -// BNCAppleReceiptTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 7/15/19. -// Copyright © 2019 Branch, Inc. All rights reserved. -// - -#import -#import "BNCAppleReceipt.h" - -@interface BNCAppleReceiptTests : XCTestCase - -@end - -@implementation BNCAppleReceiptTests - -- (void)setUp { - -} - -- (void)tearDown { - -} - -- (void)testReceiptOnSimulator { - BNCAppleReceipt *receipt = [[BNCAppleReceipt alloc] init]; - // Appears the simulator can have a receipt - //XCTAssertNil([receipt installReceipt]); - XCTAssertFalse([receipt isTestFlight]); -} - -@end diff --git a/BranchSDKTests/BNCApplicationTests.m b/BranchSDKTests/BNCApplicationTests.m deleted file mode 100644 index 147a2a665..000000000 --- a/BranchSDKTests/BNCApplicationTests.m +++ /dev/null @@ -1,75 +0,0 @@ -// -// BNCApplication.Test.m -// Branch-SDK-Tests -// -// Created by Edward on 1/10/18. -// Copyright © 2018 Branch, Inc. All rights reserved. -// - -#import -#import "BNCApplication.h" -#import "BNCKeyChain.h" - -@interface BNCApplicationTests : XCTestCase -@end - -@implementation BNCApplicationTests - -- (void)setUp { - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -- (void)testApplication { - // Test general info: - - if ([UIApplication sharedApplication] == nil) { - NSLog(@"No host application for BNCApplication testing!"); - return; - } - - BNCApplication *application = [BNCApplication currentApplication]; - XCTAssertEqualObjects(application.bundleID, @"branch.BranchSDKTestsHostApp"); - XCTAssertEqualObjects(application.displayName, @"BranchSDKTestsHostApp"); - XCTAssertEqualObjects(application.shortDisplayName, @"BranchSDKTestsHostApp"); - XCTAssertEqualObjects(application.displayVersionString, @"1.0"); - XCTAssertEqualObjects(application.versionString, @"1"); -} - -- (void) testAppDates { - // App dates. Not a great test but tests basic function: - - if ([UIApplication sharedApplication] == nil) { - NSLog(@"No host application for BNCApplication testing!"); - return; - } - - NSTimeInterval const kOneYearAgo = -365.0 * 24.0 * 60.0 * 60.0; - - BNCApplication *application = [BNCApplication currentApplication]; - XCTAssertTrue(application.firstInstallDate && [application.firstInstallDate timeIntervalSinceNow] > kOneYearAgo); - XCTAssertTrue(application.firstInstallBuildDate && [application.firstInstallBuildDate timeIntervalSinceNow] > kOneYearAgo); - XCTAssertTrue(application.currentInstallDate && [application.currentInstallDate timeIntervalSinceNow] > kOneYearAgo); - XCTAssertTrue(application.currentBuildDate && [application.currentBuildDate timeIntervalSinceNow] > kOneYearAgo); - - NSString*const kBranchKeychainService = @"BranchKeychainService"; - NSString*const kBranchKeychainFirstBuildKey = @"BranchKeychainFirstBuild"; - NSString*const kBranchKeychainFirstInstalldKey = @"BranchKeychainFirstInstall"; - - NSDate * firstBuildDate = - [BNCKeyChain retrieveDateForService:kBranchKeychainService - key:kBranchKeychainFirstBuildKey - error:nil]; - XCTAssertEqualObjects(application.firstInstallBuildDate, firstBuildDate); - - NSDate * firstInstallDate = - [BNCKeyChain retrieveDateForService:kBranchKeychainService - key:kBranchKeychainFirstInstalldKey - error:nil]; - XCTAssertEqualObjects(application.firstInstallDate, firstInstallDate); -} - -@end diff --git a/BranchSDKTests/BNCCallbackMapTests.m b/BranchSDKTests/BNCCallbackMapTests.m deleted file mode 100644 index 4d5482499..000000000 --- a/BranchSDKTests/BNCCallbackMapTests.m +++ /dev/null @@ -1,134 +0,0 @@ -// -// BNCCallbackMapTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 2/25/20. -// Copyright © 2020 Branch, Inc. All rights reserved. -// - -#import -#import "BNCCallbackMap.h" -#import "NSError+Branch.h" - -// expose private storage object for state checks -@interface BNCCallbackMap() -@property (nonatomic, strong, readwrite) NSMapTable *callbacks; -@end - -@interface BNCCallbackMapTests : XCTestCase - -@end - -@implementation BNCCallbackMapTests - -- (void)setUp { - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -- (void)testRequestSaveAndCallback { - BNCCallbackMap *map = [BNCCallbackMap new]; - - __block BOOL successResult = NO; - __block NSError *errorResult = nil; - - // store a request and callback block - BNCServerRequest *request = [BNCServerRequest new]; - [map storeRequest:request withCompletion:^(BOOL success, NSError * _Nullable error) { - successResult = success; - errorResult = error; - }]; - - // confirm there's one entry - XCTAssert([map containsRequest:request] != NO); - XCTAssert(map.callbacks.count == 1); - - // call callback - [map callCompletionForRequest:request withSuccessStatus:YES error:nil]; - - // check if variable was updated - XCTAssertTrue(successResult); - XCTAssertNil(errorResult); -} - -- (void)testRequestSaveAndCallbackWithError { - BNCCallbackMap *map = [BNCCallbackMap new]; - - __block BOOL successResult = YES; - __block NSError *errorResult = nil; - - // store a request and callback block - BNCServerRequest *request = [BNCServerRequest new]; - [map storeRequest:request withCompletion:^(BOOL success, NSError * _Nullable error) { - successResult = success; - errorResult = error; - }]; - - // confirm there's one entry - XCTAssert([map containsRequest:request] != NO); - XCTAssert(map.callbacks.count == 1); - - // call callback - [map callCompletionForRequest:request withSuccessStatus:NO error:[NSError branchErrorWithCode:BNCGeneralError localizedMessage:@"Test Error"]]; - - // check if variable was updated - XCTAssertFalse(successResult); - XCTAssert([@"Test Error" isEqualToString:errorResult.localizedFailureReason]); -} - -- (void)testAttemptCallbackWithUnsavedRequest { - BNCCallbackMap *map = [BNCCallbackMap new]; - - __block BOOL successResult = NO; - __block NSError *errorResult = nil; - - // store a request and callback block - BNCServerRequest *request = [BNCServerRequest new]; - [map storeRequest:request withCompletion:^(BOOL success, NSError * _Nullable error) { - successResult = success; - errorResult = error; - }]; - - // confirm there's one entry - XCTAssert([map containsRequest:request] != NO); - XCTAssert(map.callbacks.count == 1); - - // confirm a new request results in no callback - request = [BNCServerRequest new]; - XCTAssert([map containsRequest:request] == NO); - [map callCompletionForRequest:request withSuccessStatus:YES error:nil]; - - // check if variable was updated - XCTAssertFalse(successResult); - XCTAssertNil(errorResult); -} - -- (void)testRequestsGetReleasedAutomatically { - BNCCallbackMap *map = [BNCCallbackMap new]; - - __block int count = 0; - - BNCServerRequest *request = [BNCServerRequest new]; - [map storeRequest:request withCompletion:^(BOOL success, NSError * _Nullable error) { - count++; - }]; - - for (int i=0; i<100; i++) { - BNCServerRequest *tmp = [BNCServerRequest new]; - [map storeRequest:tmp withCompletion:^(BOOL success, NSError * _Nullable error) { - count++; - }]; - } - - // confirm there's less than 100 entries. By not retaining the tmp request, they should be getting ARC'd - XCTAssert(map.callbacks.count < 100); - - // confirm the one request we held does get a callback - [map callCompletionForRequest:request withSuccessStatus:YES error:nil]; - XCTAssert(count == 1); -} - -@end diff --git a/BranchSDKTests/BNCClassSerializationTests.m b/BranchSDKTests/BNCClassSerializationTests.m deleted file mode 100644 index f1af287d9..000000000 --- a/BranchSDKTests/BNCClassSerializationTests.m +++ /dev/null @@ -1,120 +0,0 @@ -// -// BNCClassSerializationTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 3/28/24. -// Copyright © 2024 Branch, Inc. All rights reserved. -// - -#import -#import "BranchEvent.h" -#import "BranchOpenRequest.h" -#import "BranchInstallRequest.h" - -@interface BranchEvent() -// private BranchEvent methods used to build a BranchEventRequest -- (NSDictionary *)buildEventDictionary; -@end - -@interface BranchOpenRequest() -- (NSString *)getActionName; -@end - -@interface BNCClassSerializationTests : XCTestCase - -@end - -// Test serialization of replayable requests -@implementation BNCClassSerializationTests - -- (void)setUp { - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -// BranchEventRequest is creation is tightly coupled with the BranchEvent class -// In order to test building it, we need to expose some private methods. :( -- (BranchEventRequest *)buildBranchEventRequest { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventPurchase]; - NSURL *url = [NSURL URLWithString:@"https://api3.branch.io/v2/event/standard"]; - NSDictionary *eventDictionary = [event buildEventDictionary]; - - BranchEventRequest *request = [[BranchEventRequest alloc] initWithServerURL:url eventDictionary:eventDictionary completion:nil]; - return request; -} - -- (void)testBranchEventRequestArchive { - BranchEventRequest *request = [self buildBranchEventRequest]; - - // archive the event - NSError *error = nil; - NSData *data = [NSKeyedArchiver archivedDataWithRootObject:request requiringSecureCoding:YES error:&error]; - XCTAssertNil(error); - XCTAssertNotNil(data); - - // unarchive the event - id object = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithArray:@[BranchEventRequest.class]] fromData:data error:&error]; - XCTAssertNil(error); - XCTAssertNotNil(object); - - // check object - XCTAssertTrue([object isKindOfClass:BranchEventRequest.class]); - BranchEventRequest *unarchivedRequest = (BranchEventRequest *)object; - - XCTAssertTrue([request.serverURL.absoluteString isEqualToString:unarchivedRequest.serverURL.absoluteString]); - XCTAssertTrue(request.eventDictionary.count == unarchivedRequest.eventDictionary.count); - XCTAssertNil(unarchivedRequest.completion); -} - -- (void)testBranchOpenRequestArchive { - BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:nil]; - request.urlString = @"https://branch.io"; - - // archive the event - NSError *error = nil; - NSData *data = [NSKeyedArchiver archivedDataWithRootObject:request requiringSecureCoding:YES error:&error]; - XCTAssertNil(error); - XCTAssertNotNil(data); - - // unarchive the event - id object = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithArray:@[BranchOpenRequest.class]] fromData:data error:&error]; - XCTAssertNil(error); - XCTAssertNotNil(object); - - // check object - XCTAssertTrue([object isKindOfClass:BranchOpenRequest.class]); - BranchOpenRequest *unarchivedRequest = (BranchOpenRequest *)object; - - XCTAssertTrue([request.urlString isEqualToString:unarchivedRequest.urlString]); - XCTAssertNil(unarchivedRequest.callback); - XCTAssertTrue([@"open" isEqualToString:[unarchivedRequest getActionName]]); -} - -- (void)testBranchInstallRequestArchive { - BranchInstallRequest *request = [[BranchInstallRequest alloc] initWithCallback:nil]; - request.urlString = @"https://branch.io"; - - // archive the event - NSError *error = nil; - NSData *data = [NSKeyedArchiver archivedDataWithRootObject:request requiringSecureCoding:YES error:&error]; - XCTAssertNil(error); - XCTAssertNotNil(data); - - // unarchive the event - id object = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithArray:@[BranchInstallRequest.class]] fromData:data error:&error]; - XCTAssertNil(error); - XCTAssertNotNil(object); - - // check object - XCTAssertTrue([object isKindOfClass:BranchInstallRequest.class]); - BranchInstallRequest *unarchivedRequest = (BranchInstallRequest *)object; - - XCTAssertTrue([request.urlString isEqualToString:unarchivedRequest.urlString]); - XCTAssertNil(unarchivedRequest.callback); - XCTAssertTrue([@"install" isEqualToString:[unarchivedRequest getActionName]]); -} - -@end diff --git a/BranchSDKTests/BNCCrashlyticsWrapperTests.m b/BranchSDKTests/BNCCrashlyticsWrapperTests.m deleted file mode 100644 index 4b9be75a4..000000000 --- a/BranchSDKTests/BNCCrashlyticsWrapperTests.m +++ /dev/null @@ -1,68 +0,0 @@ -// -// BNCCrashlyticsWrapperTest.m -// Branch-TestBed -// -// Created by Jimmy Dee on 7/18/17. -// Copyright © 2017 Branch Metrics. All rights reserved. -// - -#import -#import "BNCCrashlyticsWrapper.h" - -#pragma mark Crashlytics SDK Stand-In - -@interface FIRCrashlytics : NSObject -+ (FIRCrashlytics *)crashlytics; -@property NSMutableDictionary *values; -- (void)setCustomValue:(id)value forKey:(NSString *)key; --(id)getCustomValueForKey:(NSString *)key; -@end - -@implementation FIRCrashlytics - -+ (FIRCrashlytics *)crashlytics { - @synchronized (self) { - static FIRCrashlytics * sharedCrashlytics = nil; - if (!sharedCrashlytics) sharedCrashlytics = [[self alloc] init]; - return sharedCrashlytics; - } -} - -- (void)setCustomValue:(id)value forKey:(NSString *)key { - if (!_values) { - _values = [[NSMutableDictionary alloc] init]; - } - [_values setObject:value forKey:key]; -} - --(id)getCustomValueForKey:(NSString *)key { - return [_values valueForKey:key]; -} -@end - -#pragma mark - BNCCrashlyticsWrapperTest - -@interface BNCCrashlyticsWrapperTests : XCTestCase -@end - -@implementation BNCCrashlyticsWrapperTests - -- (void)setUp { - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -- (void)testSetValue { - BNCCrashlyticsWrapper *wrapper = [BNCCrashlyticsWrapper wrapper]; - NSString *value = @"TestString"; - NSString *key = @"TestKey"; - - [wrapper setCustomValue:value forKey:key]; - - XCTAssertEqual([[FIRCrashlytics crashlytics] getCustomValueForKey:key], value); -} - -@end diff --git a/BranchSDKTests/BNCCurrencyTests.m b/BranchSDKTests/BNCCurrencyTests.m deleted file mode 100644 index ec24da0f8..000000000 --- a/BranchSDKTests/BNCCurrencyTests.m +++ /dev/null @@ -1,194 +0,0 @@ -// -// BNCCurrencyTests.m -// Branch-SDK-Tests -// -// Created by Nipun Singh on 9/21/23. -// Copyright © 2023 Branch, Inc. All rights reserved. -// - -#import -#import "BNCCurrency.h" - -@interface BNCCurrencyTests : XCTestCase -@end - -@implementation BNCCurrencyTests - -- (void)testEnumValues { - XCTAssertEqualObjects(BNCCurrencyAED, @"AED"); - XCTAssertEqualObjects(BNCCurrencyAFN, @"AFN"); - XCTAssertEqualObjects(BNCCurrencyALL, @"ALL"); - XCTAssertEqualObjects(BNCCurrencyAMD, @"AMD"); - XCTAssertEqualObjects(BNCCurrencyANG, @"ANG"); - XCTAssertEqualObjects(BNCCurrencyAOA, @"AOA"); - XCTAssertEqualObjects(BNCCurrencyARS, @"ARS"); - XCTAssertEqualObjects(BNCCurrencyAUD, @"AUD"); - XCTAssertEqualObjects(BNCCurrencyAWG, @"AWG"); - XCTAssertEqualObjects(BNCCurrencyAZN, @"AZN"); - XCTAssertEqualObjects(BNCCurrencyBAM, @"BAM"); - XCTAssertEqualObjects(BNCCurrencyBBD, @"BBD"); - XCTAssertEqualObjects(BNCCurrencyBDT, @"BDT"); - XCTAssertEqualObjects(BNCCurrencyBGN, @"BGN"); - XCTAssertEqualObjects(BNCCurrencyBHD, @"BHD"); - XCTAssertEqualObjects(BNCCurrencyBIF, @"BIF"); - XCTAssertEqualObjects(BNCCurrencyBMD, @"BMD"); - XCTAssertEqualObjects(BNCCurrencyBND, @"BND"); - XCTAssertEqualObjects(BNCCurrencyBOB, @"BOB"); - XCTAssertEqualObjects(BNCCurrencyBOV, @"BOV"); - XCTAssertEqualObjects(BNCCurrencyBRL, @"BRL"); - XCTAssertEqualObjects(BNCCurrencyBSD, @"BSD"); - XCTAssertEqualObjects(BNCCurrencyBTN, @"BTN"); - XCTAssertEqualObjects(BNCCurrencyBWP, @"BWP"); - XCTAssertEqualObjects(BNCCurrencyBYN, @"BYN"); - XCTAssertEqualObjects(BNCCurrencyBYR, @"BYR"); - XCTAssertEqualObjects(BNCCurrencyBZD, @"BZD"); - XCTAssertEqualObjects(BNCCurrencyCAD, @"CAD"); - XCTAssertEqualObjects(BNCCurrencyCDF, @"CDF"); - XCTAssertEqualObjects(BNCCurrencyCHE, @"CHE"); - XCTAssertEqualObjects(BNCCurrencyCHF, @"CHF"); - XCTAssertEqualObjects(BNCCurrencyCHW, @"CHW"); - XCTAssertEqualObjects(BNCCurrencyCLF, @"CLF"); - XCTAssertEqualObjects(BNCCurrencyCLP, @"CLP"); - XCTAssertEqualObjects(BNCCurrencyCNY, @"CNY"); - XCTAssertEqualObjects(BNCCurrencyCOP, @"COP"); - XCTAssertEqualObjects(BNCCurrencyCOU, @"COU"); - XCTAssertEqualObjects(BNCCurrencyCRC, @"CRC"); - XCTAssertEqualObjects(BNCCurrencyCUC, @"CUC"); - XCTAssertEqualObjects(BNCCurrencyCUP, @"CUP"); - XCTAssertEqualObjects(BNCCurrencyCVE, @"CVE"); - XCTAssertEqualObjects(BNCCurrencyCZK, @"CZK"); - XCTAssertEqualObjects(BNCCurrencyDJF, @"DJF"); - XCTAssertEqualObjects(BNCCurrencyDKK, @"DKK"); - XCTAssertEqualObjects(BNCCurrencyDOP, @"DOP"); - XCTAssertEqualObjects(BNCCurrencyDZD, @"DZD"); - XCTAssertEqualObjects(BNCCurrencyEGP, @"EGP"); - XCTAssertEqualObjects(BNCCurrencyERN, @"ERN"); - XCTAssertEqualObjects(BNCCurrencyETB, @"ETB"); - XCTAssertEqualObjects(BNCCurrencyEUR, @"EUR"); - XCTAssertEqualObjects(BNCCurrencyFJD, @"FJD"); - XCTAssertEqualObjects(BNCCurrencyFKP, @"FKP"); - XCTAssertEqualObjects(BNCCurrencyGBP, @"GBP"); - XCTAssertEqualObjects(BNCCurrencyGEL, @"GEL"); - XCTAssertEqualObjects(BNCCurrencyGHS, @"GHS"); - XCTAssertEqualObjects(BNCCurrencyGIP, @"GIP"); - XCTAssertEqualObjects(BNCCurrencyGMD, @"GMD"); - XCTAssertEqualObjects(BNCCurrencyGNF, @"GNF"); - XCTAssertEqualObjects(BNCCurrencyGTQ, @"GTQ"); - XCTAssertEqualObjects(BNCCurrencyGYD, @"GYD"); - XCTAssertEqualObjects(BNCCurrencyHKD, @"HKD"); - XCTAssertEqualObjects(BNCCurrencyHNL, @"HNL"); - XCTAssertEqualObjects(BNCCurrencyHRK, @"HRK"); - XCTAssertEqualObjects(BNCCurrencyHTG, @"HTG"); - XCTAssertEqualObjects(BNCCurrencyHUF, @"HUF"); - XCTAssertEqualObjects(BNCCurrencyIDR, @"IDR"); - XCTAssertEqualObjects(BNCCurrencyILS, @"ILS"); - XCTAssertEqualObjects(BNCCurrencyINR, @"INR"); - XCTAssertEqualObjects(BNCCurrencyIQD, @"IQD"); - XCTAssertEqualObjects(BNCCurrencyIRR, @"IRR"); - XCTAssertEqualObjects(BNCCurrencyISK, @"ISK"); - XCTAssertEqualObjects(BNCCurrencyJMD, @"JMD"); - XCTAssertEqualObjects(BNCCurrencyJOD, @"JOD"); - XCTAssertEqualObjects(BNCCurrencyJPY, @"JPY"); - XCTAssertEqualObjects(BNCCurrencyKES, @"KES"); - XCTAssertEqualObjects(BNCCurrencyKGS, @"KGS"); - XCTAssertEqualObjects(BNCCurrencyKHR, @"KHR"); - XCTAssertEqualObjects(BNCCurrencyKMF, @"KMF"); - XCTAssertEqualObjects(BNCCurrencyKPW, @"KPW"); - XCTAssertEqualObjects(BNCCurrencyKRW, @"KRW"); - XCTAssertEqualObjects(BNCCurrencyKWD, @"KWD"); - XCTAssertEqualObjects(BNCCurrencyKYD, @"KYD"); - XCTAssertEqualObjects(BNCCurrencyKZT, @"KZT"); - XCTAssertEqualObjects(BNCCurrencyLAK, @"LAK"); - XCTAssertEqualObjects(BNCCurrencyLBP, @"LBP"); - XCTAssertEqualObjects(BNCCurrencyLKR, @"LKR"); - XCTAssertEqualObjects(BNCCurrencyLRD, @"LRD"); - XCTAssertEqualObjects(BNCCurrencyLSL, @"LSL"); - XCTAssertEqualObjects(BNCCurrencyLYD, @"LYD"); - XCTAssertEqualObjects(BNCCurrencyMAD, @"MAD"); - XCTAssertEqualObjects(BNCCurrencyMDL, @"MDL"); - XCTAssertEqualObjects(BNCCurrencyMGA, @"MGA"); - XCTAssertEqualObjects(BNCCurrencyMKD, @"MKD"); - XCTAssertEqualObjects(BNCCurrencyMMK, @"MMK"); - XCTAssertEqualObjects(BNCCurrencyMNT, @"MNT"); - XCTAssertEqualObjects(BNCCurrencyMOP, @"MOP"); - XCTAssertEqualObjects(BNCCurrencyMRO, @"MRO"); - XCTAssertEqualObjects(BNCCurrencyMUR, @"MUR"); - XCTAssertEqualObjects(BNCCurrencyMVR, @"MVR"); - XCTAssertEqualObjects(BNCCurrencyMWK, @"MWK"); - XCTAssertEqualObjects(BNCCurrencyMXN, @"MXN"); - XCTAssertEqualObjects(BNCCurrencyMXV, @"MXV"); - XCTAssertEqualObjects(BNCCurrencyMYR, @"MYR"); - XCTAssertEqualObjects(BNCCurrencyMZN, @"MZN"); - XCTAssertEqualObjects(BNCCurrencyNAD, @"NAD"); - XCTAssertEqualObjects(BNCCurrencyNGN, @"NGN"); - XCTAssertEqualObjects(BNCCurrencyNIO, @"NIO"); - XCTAssertEqualObjects(BNCCurrencyNOK, @"NOK"); - XCTAssertEqualObjects(BNCCurrencyNPR, @"NPR"); - XCTAssertEqualObjects(BNCCurrencyNZD, @"NZD"); - XCTAssertEqualObjects(BNCCurrencyOMR, @"OMR"); - XCTAssertEqualObjects(BNCCurrencyPAB, @"PAB"); - XCTAssertEqualObjects(BNCCurrencyPEN, @"PEN"); - XCTAssertEqualObjects(BNCCurrencyPGK, @"PGK"); - XCTAssertEqualObjects(BNCCurrencyPHP, @"PHP"); - XCTAssertEqualObjects(BNCCurrencyPKR, @"PKR"); - XCTAssertEqualObjects(BNCCurrencyPLN, @"PLN"); - XCTAssertEqualObjects(BNCCurrencyPYG, @"PYG"); - XCTAssertEqualObjects(BNCCurrencyQAR, @"QAR"); - XCTAssertEqualObjects(BNCCurrencyRON, @"RON"); - XCTAssertEqualObjects(BNCCurrencyRSD, @"RSD"); - XCTAssertEqualObjects(BNCCurrencyRUB, @"RUB"); - XCTAssertEqualObjects(BNCCurrencyRWF, @"RWF"); - XCTAssertEqualObjects(BNCCurrencySAR, @"SAR"); - XCTAssertEqualObjects(BNCCurrencySBD, @"SBD"); - XCTAssertEqualObjects(BNCCurrencySCR, @"SCR"); - XCTAssertEqualObjects(BNCCurrencySDG, @"SDG"); - XCTAssertEqualObjects(BNCCurrencySEK, @"SEK"); - XCTAssertEqualObjects(BNCCurrencySGD, @"SGD"); - XCTAssertEqualObjects(BNCCurrencySHP, @"SHP"); - XCTAssertEqualObjects(BNCCurrencySLL, @"SLL"); - XCTAssertEqualObjects(BNCCurrencySOS, @"SOS"); - XCTAssertEqualObjects(BNCCurrencySRD, @"SRD"); - XCTAssertEqualObjects(BNCCurrencySSP, @"SSP"); - XCTAssertEqualObjects(BNCCurrencySTD, @"STD"); - XCTAssertEqualObjects(BNCCurrencySYP, @"SYP"); - XCTAssertEqualObjects(BNCCurrencySZL, @"SZL"); - XCTAssertEqualObjects(BNCCurrencyTHB, @"THB"); - XCTAssertEqualObjects(BNCCurrencyTJS, @"TJS"); - XCTAssertEqualObjects(BNCCurrencyTMT, @"TMT"); - XCTAssertEqualObjects(BNCCurrencyTND, @"TND"); - XCTAssertEqualObjects(BNCCurrencyTOP, @"TOP"); - XCTAssertEqualObjects(BNCCurrencyTRY, @"TRY"); - XCTAssertEqualObjects(BNCCurrencyTTD, @"TTD"); - XCTAssertEqualObjects(BNCCurrencyTWD, @"TWD"); - XCTAssertEqualObjects(BNCCurrencyTZS, @"TZS"); - XCTAssertEqualObjects(BNCCurrencyUAH, @"UAH"); - XCTAssertEqualObjects(BNCCurrencyUGX, @"UGX"); - XCTAssertEqualObjects(BNCCurrencyUSD, @"USD"); - XCTAssertEqualObjects(BNCCurrencyUSN, @"USN"); - XCTAssertEqualObjects(BNCCurrencyUYI, @"UYI"); - XCTAssertEqualObjects(BNCCurrencyUYU, @"UYU"); - XCTAssertEqualObjects(BNCCurrencyUZS, @"UZS"); - XCTAssertEqualObjects(BNCCurrencyVEF, @"VEF"); - XCTAssertEqualObjects(BNCCurrencyVND, @"VND"); - XCTAssertEqualObjects(BNCCurrencyVUV, @"VUV"); - XCTAssertEqualObjects(BNCCurrencyWST, @"WST"); - XCTAssertEqualObjects(BNCCurrencyXAF, @"XAF"); - XCTAssertEqualObjects(BNCCurrencyXAG, @"XAG"); - XCTAssertEqualObjects(BNCCurrencyXAU, @"XAU"); - XCTAssertEqualObjects(BNCCurrencyXCD, @"XCD"); - XCTAssertEqualObjects(BNCCurrencyXDR, @"XDR"); - XCTAssertEqualObjects(BNCCurrencyXOF, @"XOF"); - XCTAssertEqualObjects(BNCCurrencyXPD, @"XPD"); - XCTAssertEqualObjects(BNCCurrencyXPF, @"XPF"); - XCTAssertEqualObjects(BNCCurrencyXPT, @"XPT"); - XCTAssertEqualObjects(BNCCurrencyXSU, @"XSU"); - XCTAssertEqualObjects(BNCCurrencyXTS, @"XTS"); - XCTAssertEqualObjects(BNCCurrencyXUA, @"XUA"); - XCTAssertEqualObjects(BNCCurrencyXXX, @"XXX"); - XCTAssertEqualObjects(BNCCurrencyYER, @"YER"); - XCTAssertEqualObjects(BNCCurrencyZAR, @"ZAR"); - XCTAssertEqualObjects(BNCCurrencyZMW, @"ZMW"); -} - - -@end diff --git a/BranchSDKTests/BNCDeviceInfoTests.m b/BranchSDKTests/BNCDeviceInfoTests.m deleted file mode 100644 index 39b4ee5d8..000000000 --- a/BranchSDKTests/BNCDeviceInfoTests.m +++ /dev/null @@ -1,190 +0,0 @@ -// -// BNCDeviceInfoTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 11/21/19. -// Copyright © 2019 Branch, Inc. All rights reserved. -// - -#import -#import "BNCDeviceInfo.h" -#import "BNCUserAgentCollector.h" - -@interface BNCDeviceInfoTests : XCTestCase -@property (nonatomic, strong, readwrite) BNCDeviceInfo *deviceInfo; -@end - -@implementation BNCDeviceInfoTests - -- (void)setUp { - [self workaroundUserAgentLazyLoad]; - self.deviceInfo = [BNCDeviceInfo new]; -} - -// user agent needs to be loaded -- (void)workaroundUserAgentLazyLoad { - __block XCTestExpectation *expectation = [self expectationWithDescription:@"setup"]; - [[BNCUserAgentCollector instance] loadUserAgentWithCompletion:^(NSString * _Nullable userAgent) { - [expectation fulfill]; - }]; - [self waitForExpectationsWithTimeout:5.0 handler:^(NSError * _Nullable error) { }]; -} - -- (void)tearDown { - -} - -- (void)testHardwareId { - XCTAssertNotNil(self.deviceInfo.hardwareId); - - // verify hardwareId is a valid UUID - NSUUID *hardwareId = [[NSUUID alloc] initWithUUIDString:self.deviceInfo.hardwareId]; - XCTAssertNotNil(hardwareId); -} - -- (void)testHardwareIdType { - // without ATT, this is the IDFV. Branch servers expect it as vendor_id - XCTAssert([self.deviceInfo.hardwareIdType isEqualToString:@"vendor_id"]); -} - -- (void)testIsRealHardwareId { - XCTAssert(self.deviceInfo.isRealHardwareId); -} - -- (void)testAdvertiserId { - // the testbed does not show the ATT prompt. - XCTAssertNil(self.deviceInfo.advertiserId); -} - -- (void)testVendorId { - XCTAssertNotNil(self.deviceInfo.vendorId); - - // verify vendorId is a valid UUID - NSUUID *vendorId = [[NSUUID alloc] initWithUUIDString:self.deviceInfo.vendorId]; - XCTAssertNotNil(vendorId); -} - -- (void)testAnonId { - XCTAssertNotNil(self.deviceInfo.anonId); - - // verify anonId is a valid UUID - NSUUID *anonId = [[NSUUID alloc] initWithUUIDString:self.deviceInfo.anonId]; - XCTAssertNotNil(anonId); -} - -- (void)testOptedInStatus { - // the testbed does not show the ATT prompt. - XCTAssert([self.deviceInfo.optedInStatus isEqualToString:@"not_determined"]); -} - -- (void)testIsFirstOptIn { - // the testbed does not show the ATT prompt. - XCTAssert(self.deviceInfo.isFirstOptIn == NO); -} - -- (void)testLocalIPAddress { - NSString *address = [self.deviceInfo localIPAddress]; - XCTAssertNotNil(address); - XCTAssert(address.length > 7); -} - -- (void)testConnectionType { - // simulator is on wifi - XCTAssert([[self.deviceInfo connectionType] isEqualToString:@"wifi"]); -} - -- (void)testBrandName { - XCTAssert([@"Apple" isEqualToString:self.deviceInfo.brandName]); -} - -- (void)testModelName_Simulator { - // intel processor - bool x86_64 = [@"x86_64" isEqualToString:self.deviceInfo.modelName]; - - // apple processor - bool arm64 = [@"arm64" isEqualToString:self.deviceInfo.modelName]; - - XCTAssert(x86_64 || arm64); -} - -- (void)testOSName { - XCTAssertNotNil(self.deviceInfo.osName); - XCTAssert([@"iOS" isEqualToString:self.deviceInfo.osName]); -} - -- (void)testOSVersion { - XCTAssertNotNil(self.deviceInfo.osVersion); - XCTAssert([self.deviceInfo.osVersion isEqualToString:[UIDevice currentDevice].systemVersion]); -} - -- (void)testOSBuildVersion { - XCTAssertNotNil(self.deviceInfo.osBuildVersion); -} - -- (void)testEnvironment { - // currently not running unit tests on extensions - XCTAssert([@"FULL_APP" isEqualToString:self.deviceInfo.environment]); -} - -- (void)testCpuType_Simulator { - // intel processors - bool x86 = [@"7" isEqualToString:self.deviceInfo.cpuType]; - - // apple processors - bool arm = [@"16777228" isEqualToString:self.deviceInfo.cpuType]; - - XCTAssert(x86 || arm); -} - -- (void)testScreenWidth { - XCTAssert(self.deviceInfo.screenWidth.intValue >= 320); -} - -- (void)testScreenHeight { - XCTAssert(self.deviceInfo.screenHeight.intValue >= 320); -} - -- (void)testScreenScale { - XCTAssert(self.deviceInfo.screenScale.intValue >= 1); -} - -- (void)testLocale { - NSString *locale = [NSLocale currentLocale].localeIdentifier; - XCTAssertNotNil(locale); - XCTAssert([locale isEqualToString:self.deviceInfo.locale]); -} - -- (void)testCountry { - NSString *locale = [NSLocale currentLocale].localeIdentifier; - XCTAssertNotNil(locale); - XCTAssert([locale containsString:self.deviceInfo.country]); -} - -- (void)testLanguage { - NSString *locale = [NSLocale currentLocale].localeIdentifier; - XCTAssertNotNil(locale); - XCTAssert([locale containsString:self.deviceInfo.language]); -} - -- (void)testUserAgentString { - XCTAssert([self.deviceInfo.userAgentString containsString:@"AppleWebKit"]); -} - -- (void)testApplicationVersion_TestBed { - XCTAssert([@"1.0" isEqualToString:self.deviceInfo.applicationVersion]); -} - -- (void)testRegisterPluginNameVersion { - XCTAssertNil(self.deviceInfo.pluginName); - XCTAssertNil(self.deviceInfo.pluginVersion); - - NSString *expectedName = @"react native"; - NSString *expectedVersion = @"1.0.0"; - - [self.deviceInfo registerPluginName:expectedName version:expectedVersion]; - - XCTAssert([expectedName isEqualToString:self.deviceInfo.pluginName]); - XCTAssert([expectedVersion isEqualToString:self.deviceInfo.pluginVersion]); -} - -@end diff --git a/BranchSDKTests/BNCDeviceSystemTests.m b/BranchSDKTests/BNCDeviceSystemTests.m deleted file mode 100644 index 0a47b73d9..000000000 --- a/BranchSDKTests/BNCDeviceSystemTests.m +++ /dev/null @@ -1,62 +0,0 @@ -// -// BNCDeviceSystemTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 11/14/19. -// Copyright © 2019 Branch, Inc. All rights reserved. -// - -#import -#import "BNCDeviceSystem.h" - -@interface BNCDeviceSystemTests : XCTestCase - -@property (nonatomic, strong, readwrite) BNCDeviceSystem *deviceSystem; - -@end - -@implementation BNCDeviceSystemTests - -- (void)setUp { - self.deviceSystem = [BNCDeviceSystem new]; -} - -- (void)tearDown { - -} - -- (void)testSystemBuildVersion { - XCTAssertNotNil(self.deviceSystem.systemBuildVersion); - XCTAssert(self.deviceSystem.systemBuildVersion.length > 0); -} - -- (void)testMachine_Simulator { - // intel processor - bool x86_64 = [@"x86_64" isEqualToString:self.deviceSystem.machine]; - - // apple processor - bool arm64 = [@"arm64" isEqualToString:self.deviceSystem.machine]; - - XCTAssert(x86_64 || arm64); -} - -- (void)testCPUType_Simulator { - // intel processor - bool x86 = [@(7) isEqualToNumber:self.deviceSystem.cpuType]; - bool x86_sub = [@(8) isEqualToNumber:self.deviceSystem.cpuSubType]; - - // apple processor - bool arm = [@(16777228) isEqualToNumber:self.deviceSystem.cpuType]; - bool arm_sub = [@(2) isEqualToNumber:self.deviceSystem.cpuSubType]; - - XCTAssert(x86 || arm); - -// cpu subtype is different on cloud runners -// if (x86) { -// XCTAssert(x86_sub); -// } else { -// XCTAssert(arm_sub); -// } -} - -@end diff --git a/BranchSDKTests/BNCDisableAdNetworkCalloutsTests.m b/BranchSDKTests/BNCDisableAdNetworkCalloutsTests.m deleted file mode 100644 index ea277ac39..000000000 --- a/BranchSDKTests/BNCDisableAdNetworkCalloutsTests.m +++ /dev/null @@ -1,59 +0,0 @@ -// -// BNCDisableAdNetworkCalloutsTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 3/2/20. -// Copyright © 2020 Branch, Inc. All rights reserved. -// - -#import -#import "BNCPreferenceHelper.h" -#import "BNCDeviceInfo.h" -#import "BNCServerInterface.h" -@import BranchSDK; - -@interface BNCServerInterface() -- (void)updateDeviceInfoToMutableDictionary:(NSMutableDictionary *)dict; -@end - -@interface BNCDisableAdNetworkCalloutsTests : XCTestCase - -@end - -// These tests are not parallelizable and therefore disabled by default -// This is due to the tight coupling between BNCPreferenceHelper and BNCDeviceInfo -@implementation BNCDisableAdNetworkCalloutsTests -/* -- (void)setUp { - [BNCPreferenceHelper preferenceHelper].disableAdNetworkCallouts = YES; -} - -- (void)tearDown { - [BNCPreferenceHelper preferenceHelper].disableAdNetworkCallouts = NO; -} - -// check on the V2 dictionary -- (void)testV2Dictionary { - NSDictionary *dict = [[BNCDeviceInfo getInstance] v2dictionary]; - XCTAssertNotNil(dict); - XCTAssertNotNil(dict[@"brand"]); - XCTAssertNotNil(dict[@"os"]); - XCTAssertNotNil(dict[@"sdk"]); - XCTAssertNotNil(dict[@"sdk_version"]); - - XCTAssertTrue(dict[@"disable_ad_network_callouts"]); -} - -// check on V1 payload -- (void)testV1Payload { - BNCServerInterface *interface = [BNCServerInterface new]; - interface.preferenceHelper = [BNCPreferenceHelper preferenceHelper]; - - NSMutableDictionary *tmp = [NSMutableDictionary new]; - [interface updateDeviceInfoToMutableDictionary:tmp]; - - XCTAssertNotNil(tmp); - XCTAssertTrue(tmp[@"disable_ad_network_callouts"]); -} -*/ -@end diff --git a/BranchSDKTests/BNCEncodingUtilsTests.m b/BranchSDKTests/BNCEncodingUtilsTests.m deleted file mode 100644 index 0b18fe51a..000000000 --- a/BranchSDKTests/BNCEncodingUtilsTests.m +++ /dev/null @@ -1,609 +0,0 @@ -// -// BNCEncodingUtils.m -// Branch -// -// Created by Graham Mueller on 4/1/15. -// Copyright (c) 2015 Branch Metrics. All rights reserved. -// - -#import -#import "BNCEncodingUtils.h" - -@interface BNCEncodingUtilsTests : XCTestCase -@end - -@implementation BNCEncodingUtilsTests - -- (void)setUp { - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -#pragma mark - EncodeDictionaryToJsonString tests - -- (void)testEncodeDictionaryToJsonStringWithExpectedParams { - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; - [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"]; - NSDate *date = [dateFormatter dateFromString:@"2015-04-01T00:00:00-05:00"]; - NSString *formattedDateString = [dateFormatter stringFromDate:date]; - - NSURL *someUrl = [NSURL URLWithString:@"https://branch.io"]; - NSDictionary *dataDict = @{ - @"foo": @"bar", - @"num": @1, - @"array": @[ @"array", @"items" ], - @"dict": @{ @"sub": @1 }, - @"url": someUrl, - @"date": date - }; - NSString *expectedEncodedString = [NSString stringWithFormat: - @"{\"foo\":\"bar\",\"num\":1,\"array\":[\"array\",\"items\"],\"dict\":{\"sub\":1},\"url\":\"https://branch.io\",\"date\":\"%@\"}", - formattedDateString]; - NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonString:dataDict]; - - XCTAssertEqualObjects(expectedEncodedString, encodedValue); -} - -- (void)testEncodeDictionaryToJsonStringWithUnexpectedParams { - NSObject *arbitraryObj = [[NSObject alloc] init]; - NSDictionary *dataDict = @{ @"foo": @"bar", @"random": arbitraryObj }; - NSString *expectedEncodedString = @"{\"foo\":\"bar\"}"; - - NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonString:dataDict]; - - XCTAssertEqualObjects(expectedEncodedString, encodedValue); -} - -- (void)testEncodeDictionaryToJsonStringStringWithNull { - NSDictionary *dataDict = @{ @"foo": [NSNull null] }; - NSString *expectedEncodedString = @"{\"foo\":null}"; - - NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonString:dataDict]; - - XCTAssertEqualObjects(expectedEncodedString, encodedValue); -} - -- (void)testEncodingNilDictionaryToJsonString { - NSDictionary *dataDict = nil; - NSString *expectedEncodedString = @"{}"; - - NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonString:dataDict]; - - XCTAssertEqualObjects(expectedEncodedString, encodedValue); -} - -- (void)testEncodeDictionaryToJsonStringWithNoKeys { - NSDictionary *emptyDict = @{ }; - NSString *expectedEncodedString = @"{}"; - - NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonString:emptyDict]; - - XCTAssertEqualObjects(expectedEncodedString, encodedValue); -} - -- (void)testEncodeDictionaryToJsonStringWithQuotes { - NSDictionary *dictionaryWithQuotes = @{ @"my\"cool\"key": @"my\"cool\"value" }; - NSString *expectedEncodedString = @"{\"my\\\"cool\\\"key\":\"my\\\"cool\\\"value\"}"; - - NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonString:dictionaryWithQuotes]; - - XCTAssertEqualObjects(expectedEncodedString, encodedValue); -} - -- (void)testSimpleEncodeDictionaryToJsonData { - NSDictionary *dataDict = @{ @"foo": @"bar" }; - NSData *expectedEncodedData = [@"{\"foo\":\"bar\"}" dataUsingEncoding:NSUTF8StringEncoding]; - - NSData *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonData:dataDict]; - - XCTAssertEqualObjects(expectedEncodedData, encodedValue); -} - -- (void)testEncodeDictionaryToQueryString { - NSDictionary *dataDict = @{ @"foo": @"bar", @"something": @"something & something" }; - NSString *expectedEncodedString = @"?foo=bar&something=something%20%26%20something"; - - NSString *encodedValue = [BNCEncodingUtils encodeDictionaryToQueryString:dataDict]; - - XCTAssertEqualObjects(expectedEncodedString, encodedValue); -} - - -#pragma mark - EncodeArrayToJsonString - -- (void)testEncodeArrayToJsonStringWithExpectedParams { - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; - [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"]; - NSDate *date = [dateFormatter dateFromString:@"2015-04-01T00:00:00Z"]; - NSString *formattedDateString = [dateFormatter stringFromDate:date]; - - NSURL *someUrl = [NSURL URLWithString:@"https://branch.io"]; - NSArray *dataArray = @[ @"bar", @1, @[ @"array", @"items" ], @{ @"sub": @1 }, someUrl, date ]; - NSString *expectedEncodedString = [NSString stringWithFormat:@"[\"bar\",1,[\"array\",\"items\"],{\"sub\":1},\"https://branch.io\",\"%@\"]", formattedDateString]; - - NSString *encodedValue = [BNCEncodingUtils encodeArrayToJsonString:dataArray]; - - XCTAssertEqualObjects(expectedEncodedString, encodedValue); -} - -- (void)testEncodeArrayToJsonStringWithUnexpectedParams { - NSObject *arbitraryObj = [[NSObject alloc] init]; - NSArray *dataArray = @[ @"bar", arbitraryObj ]; - NSString *expectedEncodedString = @"[\"bar\"]"; - - NSString *encodedValue = [BNCEncodingUtils encodeArrayToJsonString:dataArray]; - - XCTAssertEqualObjects(expectedEncodedString, encodedValue); -} - -- (void)testEncodeArrayToJsonStringStringWithNull { - NSArray *dataArray = @[ [NSNull null] ]; - NSString *expectedEncodedString = @"[null]"; - - NSString *encodedValue = [BNCEncodingUtils encodeArrayToJsonString:dataArray]; - - XCTAssertEqualObjects(expectedEncodedString, encodedValue); -} - -- (void)testEncodeArrayToJsonStringWithNoValues { - NSArray *emptyArray = @[ ]; - NSString *expectedEncodedString = @"[]"; - - NSString *encodedValue = [BNCEncodingUtils encodeArrayToJsonString:emptyArray]; - - XCTAssertEqualObjects(expectedEncodedString, encodedValue); -} - -- (void)testEncodingEmptyArrayToJsonString { - NSArray *emptyArray = nil; - NSString *expectedEncodedString = @"[]"; - - NSString *encodedValue = [BNCEncodingUtils encodeArrayToJsonString:emptyArray]; - - XCTAssertEqualObjects(expectedEncodedString, encodedValue); -} - -- (void)testEncodeArrayToJsonStringWithQuotes { - NSArray *arrayWithQuotes = @[ @"my\"cool\"value1", @"my\"cool\"value2" ]; - NSString *expectedEncodedString = @"[\"my\\\"cool\\\"value1\",\"my\\\"cool\\\"value2\"]"; - - NSString *encodedValue = [BNCEncodingUtils encodeArrayToJsonString:arrayWithQuotes]; - - XCTAssertEqualObjects(expectedEncodedString, encodedValue); -} - - -#pragma mark - Character Length tests - -- (void)testChineseCharactersWithLengthGreaterThanOne { - NSString *multiCharacterString = @"𥑮"; - NSDictionary *jsonDict = @{ @"foo": multiCharacterString }; - NSString *expectedEncoding = @"{\"foo\":\"𥑮\"}"; - NSInteger expectedLength = [expectedEncoding lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - - NSData *encodedValue = [BNCEncodingUtils encodeDictionaryToJsonData:jsonDict]; - - XCTAssertEqual(expectedLength, [encodedValue length]); -} - - -#pragma mark - DecodeToDictionary tests - -- (void)testDecodeJsonDataToDictionary { - NSData *encodedData = [@"{\"foo\":\"bar\"}" dataUsingEncoding:NSUTF8StringEncoding]; - NSDictionary *expectedDataDict = @{ @"foo": @"bar" }; - - NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonDataToDictionary:encodedData]; - - XCTAssertEqualObjects(decodedValue, expectedDataDict); -} - -- (void)testDecodeJsonStringToDictionary { - NSString *encodedString = @"{\"foo\":\"bar\"}"; - NSDictionary *expectedDataDict = @{ @"foo": @"bar" }; - - NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonStringToDictionary:encodedString]; - - XCTAssertEqualObjects(decodedValue, expectedDataDict); -} - -#if 0 - -// From Ed: See note below -- (void)testDecodeJsonStringToDictionaryWithNilDecodedString { - char badCStr[5] = { '{', 'f', ':', 'o', '}' }; // not nil terminated - NSString *encodedString = [NSString stringWithUTF8String:badCStr]; - NSDictionary *expectedDataDict = @{ }; - - NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonStringToDictionary:encodedString]; - - XCTAssertEqualObjects(decodedValue, expectedDataDict); -} - -#else - -- (void)testDecodeJsonStringToDictionaryWithNilDecodedString { - NSString *encodedString = nil; - NSDictionary *expectedDataDict = @{ }; - NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonStringToDictionary:encodedString]; - XCTAssertEqualObjects(decodedValue, expectedDataDict); -} - -#endif - -- (void)testDecodeBase64EncodedJsonStringToDictionary { - NSString *encodedString = [BNCEncodingUtils base64EncodeStringToString:@"{\"foo\":\"bar\"}"]; - NSDictionary *expectedDataDict = @{ @"foo": @"bar" }; - - NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonStringToDictionary:encodedString]; - - XCTAssertEqualObjects(decodedValue, expectedDataDict); -} - -- (void)testDecodeNonASCIIString { - // Should fail, but not crash. - NSString* result = [BNCEncodingUtils base64DecodeStringToString:@"𝄞"]; - XCTAssertNil(result); -} - -#if 0 - -// From Ed: I don't get the point of this test. -// It reads memory from the stack as a C string and decodes it as an NSString? -// The test itself won't run consistently and may fault sometimes. -- (void)testDecodeBase64JsonStringToDictionaryWithNilDecodedString { - char badCStr[5] = { '{', 'f', ':', 'o', '}' }; // not nil terminated - NSString *encodedString = [NSString stringWithUTF8String:badCStr]; - NSString *base64EncodedString = [BNCEncodingUtils base64EncodeStringToString:encodedString]; - NSDictionary *expectedDataDict = @{ }; - - NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonStringToDictionary:base64EncodedString]; - - XCTAssertEqualObjects(decodedValue, expectedDataDict); -} - -#else - -// This should do the same thing without faulting during the test. -- (void)testDecodeBase64JsonStringToDictionaryWithNilDecodedString { - NSString *base64EncodedString = nil; - NSDictionary *expectedDataDict = @{ }; - NSDictionary *decodedValue = [BNCEncodingUtils decodeJsonStringToDictionary:base64EncodedString]; - XCTAssertEqualObjects(decodedValue, expectedDataDict); -} - -#endif - -- (void)testDecodeQueryStringToDictionary { - NSString *encodedString = @"foo=bar&baz=1&quux=&quo=Hi%20there"; - NSDictionary *expectedDataDict = @{ @"foo": @"bar", @"baz": @"1", @"quo": @"Hi there" }; // always goes to string - - NSDictionary *decodedValue = [BNCEncodingUtils decodeQueryStringToDictionary:encodedString]; - - XCTAssertEqualObjects(decodedValue, expectedDataDict); -} - -#pragma mark - Test Util methods - -- (NSString *)stringForDate:(NSDate *)date { - static NSDateFormatter *dateFormatter = nil; - static dispatch_once_t onceToken = 0; - - dispatch_once(&onceToken, ^{ - dateFormatter = [[NSDateFormatter alloc] init]; - [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; // POSIX to avoid weird issues - [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"]; - }); - - return [dateFormatter stringFromDate:date]; -} - -#pragma mark - Base64EncodeData Tests - -#define _countof(array) (sizeof(array)/sizeof(array[0])) - -- (void)testBase64EncodeData { - NSData *data = nil; - NSString *truth = nil; - NSString *string = nil; - - string = [BNCEncodingUtils base64EncodeData:nil]; - XCTAssertEqualObjects(string, @""); - - string = [BNCEncodingUtils base64EncodeData:[NSData new]]; - XCTAssertEqualObjects(string, @""); - - uint8_t b1[] = {0, 1, 2, 3, 4, 5}; - data = [[NSData alloc] initWithBytes:b1 length:_countof(b1)]; - truth = @"AAECAwQF"; - string = [BNCEncodingUtils base64EncodeData:data]; - XCTAssertEqualObjects(string, truth); - - // Test that 1, 2, 3, 4, 5 length data encode correctly. - - data = [[NSData alloc] initWithBytes:b1 length:1]; - truth = @"AA=="; - string = [BNCEncodingUtils base64EncodeData:data]; - XCTAssertEqualObjects(string, truth); - - data = [[NSData alloc] initWithBytes:b1 length:2]; - truth = @"AAE="; - string = [BNCEncodingUtils base64EncodeData:data]; - XCTAssertEqualObjects(string, truth); - - data = [[NSData alloc] initWithBytes:b1 length:3]; - truth = @"AAEC"; - string = [BNCEncodingUtils base64EncodeData:data]; - XCTAssertEqualObjects(string, truth); - - data = [[NSData alloc] initWithBytes:b1 length:4]; - truth = @"AAECAw=="; - string = [BNCEncodingUtils base64EncodeData:data]; - XCTAssertEqualObjects(string, truth); - - data = [[NSData alloc] initWithBytes:b1 length:5]; - truth = @"AAECAwQ="; - string = [BNCEncodingUtils base64EncodeData:data]; - XCTAssertEqualObjects(string, truth); - - uint8_t b2[] = { - 0x00, 0x10, 0x83, 0x10, 0x51, 0x87, 0x20, 0x92, 0x8B, 0x30, 0xD3, 0x8F, 0x41, 0x14, 0x93, 0x51, - 0x55, 0x97, 0x61, 0x96, 0x9B, 0x71, 0xD7, 0x9F, 0x82, 0x18, 0xA3, 0x92, 0x59, 0xA7, 0xA2, 0x9A, - 0xAB, 0xB2, 0xDB, 0xAF, 0xC3, 0x1C, 0xB3, 0xD3, 0x5D, 0xB7, 0xE3, 0x9E, 0xBB, 0xF3, 0xDF, 0xBF, - }; - data = [[NSData alloc] initWithBytes:b2 length:_countof(b2)]; - truth = @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - string = [BNCEncodingUtils base64EncodeData:data]; - XCTAssertEqualObjects(string, truth); -} - -- (void)testBase64DecodeString { - NSData *data = nil; - - data = [BNCEncodingUtils base64DecodeString:nil]; - XCTAssertEqual(data, nil); - - data = [BNCEncodingUtils base64DecodeString:@""]; - XCTAssertEqualObjects(data, [NSData new]); - - uint8_t truth[] = {0, 1, 2, 3, 4, 5}; - - data = [BNCEncodingUtils base64DecodeString:@"AAECAwQF"]; - XCTAssertTrue( data.length == 6 && memcmp(data.bytes, truth, 6) == 0 ); - - // Test that 1, 2, 3, 4, 5 length data encode correctly. - - #define testDecode(string, dataLength) { \ - data = [BNCEncodingUtils base64DecodeString:string]; \ - XCTAssertTrue( data.length == dataLength && memcmp(data.bytes, truth, dataLength) == 0 ); \ - } - - testDecode(@"AA==", 1); - testDecode(@"AAE=", 2); - testDecode(@"AAEC", 3); - testDecode(@"AAECAw==", 4); - testDecode(@"AAECAwQ=", 5); - - uint8_t b2[] = { - 0x00, 0x10, 0x83, 0x10, 0x51, 0x87, 0x20, 0x92, 0x8B, 0x30, 0xD3, 0x8F, 0x41, 0x14, 0x93, 0x51, - 0x55, 0x97, 0x61, 0x96, 0x9B, 0x71, 0xD7, 0x9F, 0x82, 0x18, 0xA3, 0x92, 0x59, 0xA7, 0xA2, 0x9A, - 0xAB, 0xB2, 0xDB, 0xAF, 0xC3, 0x1C, 0xB3, 0xD3, 0x5D, 0xB7, 0xE3, 0x9E, 0xBB, 0xF3, 0xDF, 0xBF, - }; - data = [BNCEncodingUtils base64DecodeString: - @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"]; - XCTAssertTrue( data.length == _countof(b2) && memcmp(data.bytes, b2, _countof(b2)) == 0 ); - - // Test decode invalid data - data = [BNCEncodingUtils base64DecodeString: - @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcde (Junk:%&*^**) fghijklmnopqrstuvwxyz0123456789+/"]; - XCTAssertEqual(data, nil); -} - -#pragma mark - Hex String Tests - -- (void) testHexStringFromData { - - NSString *s = nil; - - s = [BNCEncodingUtils hexStringFromData:[NSData data]]; - XCTAssertEqualObjects(s, @""); - - unsigned char bytes1[] = { 0x01 }; - s = [BNCEncodingUtils hexStringFromData:[NSData dataWithBytes:bytes1 length:1]]; - XCTAssertEqualObjects(s, @"01"); - - unsigned char bytes2[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef - }; - NSString *truth = - @"000102030405060708090A0B0C0D0E0F" - "E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"; - - s = [BNCEncodingUtils hexStringFromData:[NSData dataWithBytes:bytes2 length:sizeof(bytes2)]]; - XCTAssertEqualObjects(s, truth); -} - -- (void) testDataFromHexString { - - NSData *data = nil; - - // nil - data = [BNCEncodingUtils dataFromHexString:nil]; - XCTAssertEqual(data, nil); - - // empty string - data = [BNCEncodingUtils dataFromHexString:@""]; - XCTAssertEqualObjects(data, [NSData data]); - - // upper string - unsigned char bytes[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef - }; - - NSString *stringUpper = - @"000102030405060708090A0B0C0D0E0F" - "E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"; - - data = [BNCEncodingUtils dataFromHexString:stringUpper]; - XCTAssertEqualObjects(data, [NSData dataWithBytes:bytes length:sizeof(bytes)]); - - // lower string - - NSString *stringLower = - @"000102030405060708090a0b0c0d0e0f" - "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"; - - data = [BNCEncodingUtils dataFromHexString:stringLower]; - XCTAssertEqualObjects(data, [NSData dataWithBytes:bytes length:sizeof(bytes)]); - - // white space - - NSString *stringWS = - @" 000102030405060708090a0b0c0d0e0f\n" - "e0e1e2e3e4e5e6\t\t\te7e8e9eaebeced\vee\ref"; - - data = [BNCEncodingUtils dataFromHexString:stringWS]; - XCTAssertEqualObjects(data, [NSData dataWithBytes:bytes length:sizeof(bytes)]); - - // odd number of charaters - - NSString *stringShort = - @"000102030405060708090a0b0c0d0e0f" - "e0e1e2e3e4e5e6e7e8e9eaebecedeee"; - - data = [BNCEncodingUtils dataFromHexString:stringShort]; - XCTAssertEqual(data, nil); - - // invalid characters - - NSString *stringInvalid = - @"000102030405060708090a0b0c0d0e0fInvalid" - "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"; - - data = [BNCEncodingUtils dataFromHexString:stringInvalid]; - XCTAssertEqual(data, nil); - - // singles - - NSString *stringShortShort1 = @"A"; - data = [BNCEncodingUtils dataFromHexString:stringShortShort1]; - XCTAssertEqual(data, nil); - - NSString *stringShortShort2 = @"af"; - unsigned char stringShortShort2Bytes[] = { 0xaf }; - data = [BNCEncodingUtils dataFromHexString:stringShortShort2]; - XCTAssertEqualObjects(data, [NSData dataWithBytes:stringShortShort2Bytes length:1]); -} - -- (void) testPercentDecoding { - - NSString *s = nil; - s = [BNCEncodingUtils stringByPercentDecodingString:nil]; - XCTAssert(s == nil); - - NSArray* tests = @[ - @"", - @"", - - @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", - @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", - - @"-._~", - @"-._~", - - @"one%20two", - @"one two", - - // @"one+two", - // @"one two", - - @"one%2Btwo", - @"one+two", - - @"%21%23%24%26%27%28%29%2A%2B%2C%3A%3B%3D%40%5B%5D", - @"!#$&'()*+,:;=@[]", - ]; - - for (int i = 0; i < tests.count; i+=2) { - NSString *result = [BNCEncodingUtils stringByPercentDecodingString:tests[i]]; - XCTAssertEqualObjects(result, tests[i+1]); - } -} - -- (void) testQueryItems { - - NSURL *URL = nil; - NSArray* items = nil; - NSArray* expected = nil; - - items = [BNCEncodingUtils queryItems:URL]; - XCTAssert(items != nil && items.count == 0); - - URL = [NSURL URLWithString:@"http://example.com/thus?a=1&a=2&b=3"]; - items = [BNCEncodingUtils queryItems:URL]; - expected = @[ [BNCKeyValue key:@"a" value:@"1"], [BNCKeyValue key:@"a" value:@"2"], [BNCKeyValue key:@"b" value:@"3"] ]; - XCTAssertEqualObjects(items, expected); - - URL = [NSURL URLWithString:@"http://example.com/thus"]; - items = [BNCEncodingUtils queryItems:URL]; - expected = @[ ]; - XCTAssertEqualObjects(items, expected); - - URL = [NSURL URLWithString:@"http://example.com/thus?"]; - items = [BNCEncodingUtils queryItems:URL]; - expected = @[ ]; - XCTAssertEqualObjects(items, expected); - - URL = [NSURL URLWithString:@"http://example.com/thus?="]; - items = [BNCEncodingUtils queryItems:URL]; - expected = @[ ]; - XCTAssertEqualObjects(items, expected); - - URL = [NSURL URLWithString:@"http://example.com/thus?a="]; - items = [BNCEncodingUtils queryItems:URL]; - expected = @[ [BNCKeyValue key:@"a" value:@""] ]; - XCTAssertEqualObjects(items, expected); - - URL = [NSURL URLWithString:@"http://example.com/thus?=1"]; - items = [BNCEncodingUtils queryItems:URL]; - expected = @[ [BNCKeyValue key:@"" value:@"1"] ]; - XCTAssertEqualObjects(items, expected); - - URL = [NSURL URLWithString:@"http://example.com/thus?a=1&"]; - items = [BNCEncodingUtils queryItems:URL]; - expected = @[ [BNCKeyValue key:@"a" value:@"1"] ]; - XCTAssertEqualObjects(items, expected); - - URL = [NSURL URLWithString:@"http://example.com/thus?a=1&&b=2"]; - items = [BNCEncodingUtils queryItems:URL]; - expected = @[ [BNCKeyValue key:@"a" value:@"1"], [BNCKeyValue key:@"b" value:@"2"] ]; - XCTAssertEqualObjects(items, expected); - - URL = [NSURL URLWithString:@"http://example.com/thus?a=1&b==2"]; - items = [BNCEncodingUtils queryItems:URL]; - expected = @[ [BNCKeyValue key:@"a" value:@"1"], [BNCKeyValue key:@"b" value:@"=2"] ]; - XCTAssertEqualObjects(items, expected); -} - -- (void) testSanitzeString { - NSString*test = @"\b\f\n\r\t\"`\\"; - NSString*truth = @"\\b\\f\\n\\r\\t\\\"'\\\\"; - NSString*result = [BNCEncodingUtils sanitizedStringFromString:test]; - XCTAssertEqualObjects(result, truth); -} - -// Branch servers never return a json array at the top level. However, our parser should enforce it. -- (void)testArrayJSON { - NSString *test = @"[\"helloworld\"]"; - NSDictionary *tmp = [BNCEncodingUtils decodeJsonStringToDictionary:test]; - XCTAssert([tmp isKindOfClass:[NSDictionary class]]); -} - -@end diff --git a/BranchSDKTests/BNCJSONUtilityTests.m b/BranchSDKTests/BNCJSONUtilityTests.m deleted file mode 100644 index 7f5f1c1cf..000000000 --- a/BranchSDKTests/BNCJSONUtilityTests.m +++ /dev/null @@ -1,188 +0,0 @@ -// -// BNCJSONUtilityTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 9/17/19. -// Copyright © 2019 Branch, Inc. All rights reserved. -// - -#import -#import "BNCJSONUtility.h" -#import "BNCJsonLoader.h" - -@interface BNCJSONUtilityTests : XCTestCase -@property (nonatomic, strong, readwrite) NSDictionary *json; -@end - -@implementation BNCJSONUtilityTests - -- (void)setUp { - self.json = [BNCJsonLoader dictionaryFromJSONFileNamed:@"example"]; - XCTAssertNotNil(self.json); -} - -- (void)tearDown { - -} - -- (void)testIsNumber { - NSNumber *number = [NSNumber numberWithInt:314]; - XCTAssertTrue([BNCJSONUtility isNumber:number]); -} - -- (void)testIsNumber_Boxed { - XCTAssertTrue([BNCJSONUtility isNumber:@(1.0)]); -} - -- (void)testIsNumber_Nil { - XCTAssertFalse([BNCJSONUtility isNumber:nil]); -} - -- (void)testIsNumber_String { - XCTAssertFalse([BNCJSONUtility isNumber:@"1.0"]); -} - -- (void)testIsString { - XCTAssertTrue([BNCJSONUtility isString:@"1.0"]); -} - -- (void)testIsString_MutableString { - NSMutableString *string = [NSMutableString new]; - XCTAssertTrue([BNCJSONUtility isString:string]); -} - -- (void)testIsString_EmptyString { - XCTAssertTrue([BNCJSONUtility isString:@""]); -} - -- (void)testIsString_Nil { - XCTAssertFalse([BNCJSONUtility isString:nil]); -} - -- (void)testIsString_Number { - XCTAssertFalse([BNCJSONUtility isString:@(1.0)]); -} - -- (void)testIsArray { - NSArray *tmp = @[@1, @2]; - XCTAssertTrue([BNCJSONUtility isArray:tmp]); -} - -- (void)testIsArray_MutableArray { - NSMutableArray *tmp = [NSMutableArray new]; - XCTAssertTrue([BNCJSONUtility isArray:tmp]); -} - -- (void)testIsArray_EmptyArray { - XCTAssertTrue([BNCJSONUtility isArray:@[]]); -} - -- (void)testIsArray_Nil { - XCTAssertFalse([BNCJSONUtility isArray:nil]); -} - -- (void)testIsArray_Dictionary { - XCTAssertFalse([BNCJSONUtility isArray:[NSDictionary new]]); -} - -// successful call on untyped dictionary -- (void)testUntypedDictionary_CorrectType { - NSString *string = self.json[@"user_string"]; - XCTAssertNotNil(string); - XCTAssertTrue(([string isKindOfClass:[NSString class]] || [string isKindOfClass:[NSMutableString class]])); -} - -// demonstrates that an untyped dictionary can lead to type mismatches cause it always returns id -- (void)testUntypedDictionary_IncorrectType { - NSString *string = self.json[@"user_number"]; - XCTAssertNotNil(string); - XCTAssertTrue(([string isKindOfClass:[NSNumber class]])); -} - -- (void)testStringForKey_InvalidKey { - id key = @(1); - NSString *string = [BNCJSONUtility stringForKey:key json:self.json]; - XCTAssertNil(string); -} - -- (void)testStringForKey { - NSString *string = [BNCJSONUtility stringForKey:@"user_string" json:self.json]; - XCTAssertNotNil(string); - XCTAssertTrue(([string isKindOfClass:[NSString class]] || [string isKindOfClass:[NSMutableString class]])); -} - -- (void)testStringForKey_IncorrectType { - NSString *string = [BNCJSONUtility stringForKey:@"user_number" json:self.json]; - XCTAssertNil(string); -} - -- (void)testNumberForKey { - NSNumber *number = [BNCJSONUtility numberForKey:@"user_number" json:self.json]; - XCTAssertNotNil(number); - XCTAssertTrue([number isKindOfClass:[NSNumber class]]); -} - -- (void)testNumberForKey_IncorrectType { - NSNumber *number = [BNCJSONUtility numberForKey:@"user_string" json:self.json]; - XCTAssertNil(number); -} - -- (void)testDictionaryForKey { - NSDictionary *dict = [BNCJSONUtility dictionaryForKey:@"user_dict" json:self.json]; - XCTAssertNotNil(dict); - XCTAssertTrue(([dict isKindOfClass:NSDictionary.class] || [dict isKindOfClass:NSMutableDictionary.class])); -} - -- (void)testDictionaryForKey_IncorrectType { - NSDictionary *dict = [BNCJSONUtility dictionaryForKey:@"user_array" json:self.json]; - XCTAssertNil(dict); -} - -- (void)testArrayForKey { - NSArray *array = [BNCJSONUtility arrayForKey:@"user_array" json:self.json]; - XCTAssertNotNil(array); - XCTAssertTrue(([array isKindOfClass:[NSArray class]] || [array isKindOfClass:[NSMutableArray class]])); -} - -- (void)testArrayForKey_IncorrectType { - NSArray *array = [BNCJSONUtility arrayForKey:@"user_dict" json:self.json]; - XCTAssertNil(array); -} - -- (void)testStringArrayForKey { - NSArray *array = [BNCJSONUtility stringArrayForKey:@"user_array" json:self.json]; - XCTAssertNotNil(array); - XCTAssertTrue(array.count > 0); -} - -- (void)testStringArrayForKey_MixedTypes { - NSArray *array = [BNCJSONUtility stringArrayForKey:@"user_array_mixed" json:self.json]; - XCTAssertNotNil(array); - XCTAssertTrue(array.count > 0); -} - -- (void)testStringArrayForKey_Numbers { - NSArray *array = [BNCJSONUtility stringArrayForKey:@"user_array_numbers" json:self.json]; - XCTAssertNotNil(array); - XCTAssertTrue(array.count == 0); -} - -- (void)testStringDictionaryForKey { - NSDictionary *dict = [BNCJSONUtility stringDictionaryForKey:@"user_dict" json:self.json]; - XCTAssertNotNil(dict); - XCTAssertTrue(dict.count > 0); -} - -- (void)testStringDictionaryForKey_MixedTypes { - NSDictionary *dict = [BNCJSONUtility stringDictionaryForKey:@"user_dict_mixed" json:self.json]; - XCTAssertNotNil(dict); - XCTAssertTrue(dict.count > 0); -} - -- (void)testStringDictionaryForKey_Numbers { - NSDictionary *dict = [BNCJSONUtility stringDictionaryForKey:@"user_dict_numbers" json:self.json]; - XCTAssertNotNil(dict); - XCTAssertTrue(dict.count == 0); -} - -@end diff --git a/BranchSDKTests/BNCJsonLoader.h b/BranchSDKTests/BNCJsonLoader.h deleted file mode 100644 index 6df022300..000000000 --- a/BranchSDKTests/BNCJsonLoader.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// BNCJsonLoader.h -// Branch-TestBed -// -// Created by Ernest Cho on 9/16/19. -// Copyright © 2019 Branch, Inc. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface BNCJsonLoader : NSObject - -// test utility that loads json files from the Test Bundle. only works on hosted tests -+ (NSDictionary *)dictionaryFromJSONFileNamed:(NSString *)fileName; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BranchSDKTests/BNCJsonLoader.m b/BranchSDKTests/BNCJsonLoader.m deleted file mode 100644 index 098798ba8..000000000 --- a/BranchSDKTests/BNCJsonLoader.m +++ /dev/null @@ -1,27 +0,0 @@ -// -// BNCJsonLoader.m -// Branch-TestBed -// -// Created by Ernest Cho on 9/16/19. -// Copyright © 2019 Branch, Inc. All rights reserved. -// - -#import "BNCJsonLoader.h" - -@implementation BNCJsonLoader - -+ (NSDictionary *)dictionaryFromJSONFileNamed:(NSString *)fileName { - - // Since this class is part of the Test target, [self class] returns the Test Bundle - NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"json"]; - - NSString *jsonString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL]; - - id dict = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; - if ([dict isKindOfClass:NSDictionary.class]) { - return dict; - } - return nil; -} - -@end diff --git a/BranchSDKTests/BNCKeyChainTests.m b/BranchSDKTests/BNCKeyChainTests.m deleted file mode 100644 index 07af91a22..000000000 --- a/BranchSDKTests/BNCKeyChainTests.m +++ /dev/null @@ -1,121 +0,0 @@ -// -// BNCKeyChainTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 1/6/22. -// Copyright © 2022 Branch, Inc. All rights reserved. -// - -#import -#import "BNCKeyChain.h" - -@interface BNCKeyChainTests : XCTestCase -@property (nonatomic, copy, readwrite) NSString *serviceName; -@end - -@implementation BNCKeyChainTests - -- (void)setUp { - self.serviceName = @"Service"; -} - -- (void)tearDown { - -} - -- (void)testEnvironment { - // Keychain tests must be hosted in an app, otherwise it won't have security access. - XCTAssertFalse([UIApplication sharedApplication] == nil); - - NSString *group = [BNCKeyChain securityAccessGroup]; - XCTAssertTrue(group.length > 0); -} - -- (void)testRemoveValues_Empty { - NSError *error = [BNCKeyChain removeValuesForService:nil key:nil]; - XCTAssertTrue(error == nil); -} - -- (void)testRetrieveDate_Empty { - NSError *error; - NSDate *date = [BNCKeyChain retrieveDateForService:self.serviceName key:@"testKey" error:&error]; - XCTAssertTrue(date == nil && error.code == errSecItemNotFound); -} - -- (void)testStoreAndRetrieveDate { - NSError *error; - NSString *key = @"testKey"; - NSDate *date = [NSDate date]; - - [BNCKeyChain storeDate:date forService:self.serviceName key:key cloudAccessGroup:nil]; - NSDate *tmp = [BNCKeyChain retrieveDateForService:self.serviceName key:key error:&error]; - XCTAssertNil(error); - XCTAssertTrue([date isEqualToDate:tmp]); - - // cleanup - error = [BNCKeyChain removeValuesForService:self.serviceName key:key]; - XCTAssertNil(error); -} - -- (void)testStore_Nil { - NSError *error; - NSString *key = @"testKey"; - NSDate *date = nil; - - error = [BNCKeyChain storeDate:date forService:self.serviceName key:key cloudAccessGroup:nil]; - XCTAssertTrue(error.code == errSecParam); - - NSDate *tmp = [BNCKeyChain retrieveDateForService:self.serviceName key:key error:&error]; - XCTAssertNil(tmp); - XCTAssertTrue(error.code == errSecItemNotFound); -} - -- (void)testStoreAndRetrieveMultipleDates { - NSError *error; - NSString *keyA = @"testKeyA"; - NSString *keyB = @"testKeyB"; - - NSDate *dateA = [NSDate date]; - NSDate *dateB = [NSDate dateWithTimeIntervalSinceNow:1]; - XCTAssertFalse([dateA isEqualToDate:dateB]); - - [BNCKeyChain storeDate:dateA forService:self.serviceName key:keyA cloudAccessGroup:nil]; - [BNCKeyChain storeDate:dateB forService:self.serviceName key:keyB cloudAccessGroup:nil]; - - NSDate *tmpA = [BNCKeyChain retrieveDateForService:self.serviceName key:keyA error:&error]; - XCTAssertNil(error); - XCTAssertTrue([dateA isEqualToDate:tmpA]); - - NSDate *tmpB = [BNCKeyChain retrieveDateForService:self.serviceName key:keyB error:&error]; - XCTAssertNil(error); - XCTAssertTrue([dateB isEqualToDate:tmpB]); - - XCTAssertFalse([tmpA isEqualToDate:tmpB]); - - // cleanup - error = [BNCKeyChain removeValuesForService:self.serviceName key:keyA]; - XCTAssertNil(error); - error = [BNCKeyChain removeValuesForService:self.serviceName key:keyB]; - XCTAssertNil(error); -} - -- (void)testStoreAndRetrieveDate_retrieveWrongKey { - NSError *error; - NSString *keyA = @"testKeyA"; - NSString *keyB = @"testKeyB"; - NSDate *date = [NSDate date]; - - [BNCKeyChain storeDate:date forService:self.serviceName key:keyA cloudAccessGroup:nil]; - NSDate *tmp = [BNCKeyChain retrieveDateForService:self.serviceName key:keyB error:&error]; - XCTAssertNil(tmp); - XCTAssertTrue(error.code == errSecItemNotFound); - - // cleanup - error = [BNCKeyChain removeValuesForService:self.serviceName key:keyA]; - XCTAssertNil(error); - error = [BNCKeyChain removeValuesForService:self.serviceName key:keyB]; - XCTAssertNil(error); -} - - -@end diff --git a/BranchSDKTests/BNCLinkDataTests.m b/BranchSDKTests/BNCLinkDataTests.m deleted file mode 100644 index 10eb3cb25..000000000 --- a/BranchSDKTests/BNCLinkDataTests.m +++ /dev/null @@ -1,103 +0,0 @@ -// -// BNCLinkDataTests.m -// Branch-TestBed -// -// Created by Graham Mueller on 6/15/15. -// Copyright (c) 2015 Branch Metrics. All rights reserved. -// - -#import -#import "BNCLinkData.h" - -@interface BNCLinkDataTests : XCTestCase -@end - -@implementation BNCLinkDataTests - -- (void)setUp { - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -- (void)testBasicObjectHash { - BNCLinkData *a = [[BNCLinkData alloc] init]; - BNCLinkData *b = [[BNCLinkData alloc] init]; - - XCTAssertEqual([a hash], [b hash]); -} - -- (void)testObjectHashWithSameValuesForKeys { - NSArray * const TAGS = @[ @"foo-tag" ]; - NSString * const ALIAS = @"foo-alias"; - BranchLinkType const LINK_TYPE = BranchLinkTypeOneTimeUse; - NSString * const CHANNEL = @"foo-channel"; - NSString * const FEATURE = @"foo-feature"; - NSString * const STAGE = @"foo-stage"; - NSDictionary * const PARAMS = @{ @"foo-key": @"foo-value" }; - NSInteger const DURATION = 1; - NSString * const IGNORE_UA = @"foo-ua"; - - BNCLinkData *a = [[BNCLinkData alloc] init]; - [a setupTags:TAGS]; - [a setupAlias:ALIAS]; - [a setupType:LINK_TYPE]; - [a setupChannel:CHANNEL]; - [a setupFeature:FEATURE]; - [a setupStage:STAGE]; - [a setupParams:PARAMS]; - [a setupMatchDuration:DURATION]; - [a setupIgnoreUAString:IGNORE_UA]; - - BNCLinkData *b = [[BNCLinkData alloc] init]; - [b setupTags:TAGS]; - [b setupAlias:ALIAS]; - [b setupType:LINK_TYPE]; - [b setupChannel:CHANNEL]; - [b setupFeature:FEATURE]; - [b setupStage:STAGE]; - [b setupParams:PARAMS]; - [b setupMatchDuration:DURATION]; - [b setupIgnoreUAString:IGNORE_UA]; - - XCTAssertEqual([a hash], [b hash]); -} - -- (void)testObjectHashWithDifferentValuesForSameKeys { - BNCLinkData *a = [[BNCLinkData alloc] init]; - [a setupTags:@[ @"foo-tags" ]]; - [a setupAlias:@"foo-alias"]; - [a setupType:BranchLinkTypeOneTimeUse]; - [a setupChannel:@"foo-channel"]; - [a setupFeature:@"foo-feature"]; - [a setupStage:@"foo-stage"]; - [a setupParams:@{ @"foo-key": @"foo-value" }]; - [a setupMatchDuration:1]; - [a setupIgnoreUAString:@"foo-ua"]; - - BNCLinkData *b = [[BNCLinkData alloc] init]; - [b setupTags:@[ @"bar-tag" ]]; - [b setupAlias:@"bar-alias"]; - [b setupType:BranchLinkTypeUnlimitedUse]; - [b setupChannel:@"bar-channel"]; - [b setupFeature:@"bar-feature"]; - [b setupStage:@"bar-stage"]; - [b setupParams:@{ @"bar-key": @"bar-value" }]; - [b setupMatchDuration:2]; - [b setupIgnoreUAString:@"bar-ua"]; - - XCTAssertNotEqual([a hash], [b hash]); -} - -- (void)testObjectHashWithDifferentCasedValues { - BNCLinkData *a = [[BNCLinkData alloc] init]; - [a setupAlias:@"foo-alias"]; - BNCLinkData *b = [[BNCLinkData alloc] init]; - [b setupAlias:@"FOO-ALIAS"]; - - XCTAssertNotEqual([a hash], [b hash]); -} - -@end diff --git a/BranchSDKTests/BNCNetworkInterfaceTests.m b/BranchSDKTests/BNCNetworkInterfaceTests.m deleted file mode 100644 index 8869ecc37..000000000 --- a/BranchSDKTests/BNCNetworkInterfaceTests.m +++ /dev/null @@ -1,82 +0,0 @@ -// -// BNCNetworkInterfaceTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 3/10/23. -// Copyright © 2023 Branch, Inc. All rights reserved. -// - -#import -#import -#import "BNCNetworkInterface.h" - -// Category using inet_pton to validate -@implementation NSString (Test) - -- (BOOL)isValidIPAddress { - const char *utf8 = [self UTF8String]; - int success; - - struct in_addr dst; - success = inet_pton(AF_INET, utf8, &dst); - if (success != 1) { - struct in6_addr dst6; - success = inet_pton(AF_INET6, utf8, &dst6); - } - - return success == 1; -} - -@end - -@interface BNCNetworkInterfaceTests : XCTestCase - -@end - -@implementation BNCNetworkInterfaceTests - -- (void)setUp { - -} - -- (void)tearDown { - -} - -// verify tooling method works -- (void)testIPValidationCategory { - XCTAssert(![@"" isValidIPAddress]); - - // ipv4 - XCTAssert([@"0.0.0.0" isValidIPAddress]); - XCTAssert([@"127.0.0.1" isValidIPAddress]); - XCTAssert([@"10.1.2.3" isValidIPAddress]); - XCTAssert([@"172.0.0.0" isValidIPAddress]); - XCTAssert([@"192.0.0.0" isValidIPAddress]); - XCTAssert([@"255.255.255.255" isValidIPAddress]); - - // invalid ipv4 - XCTAssert(![@"-1.0.0.0" isValidIPAddress]); - XCTAssert(![@"256.0.0.0" isValidIPAddress]); - - // ipv6 - XCTAssert([@"2001:0db8:0000:0000:0000:8a2e:0370:7334" isValidIPAddress]); - XCTAssert([@"2001:db8::8a2e:370:7334" isValidIPAddress]); - - // invalid ipv6 - XCTAssert(![@"2001:0db8:0000:0000:0000:8a2e:0370:733g" isValidIPAddress]); - XCTAssert(![@"2001:0db8:0000:0000:0000:8a2e:0370:7330:1234" isValidIPAddress]); -} - -- (void)testLocalIPAddress { - XCTAssert([[BNCNetworkInterface localIPAddress] isValidIPAddress]); -} - -- (void)testAllIPAddresses { - // All IP addresses is a debug method that returns object descriptions - for (NSString *address in BNCNetworkInterface.allIPAddresses) { - XCTAssert([address containsString:@"BNCNetworkInterface"]); - } -} - -@end diff --git a/BranchSDKTests/BNCODMTests.m b/BranchSDKTests/BNCODMTests.m deleted file mode 100644 index 38d1b0cc2..000000000 --- a/BranchSDKTests/BNCODMTests.m +++ /dev/null @@ -1,102 +0,0 @@ -// -// BNCODMTests.m -// Branch-SDK-Tests -// -// Created by Nidhi Dixit on 4/16/25. -// Copyright © 2025 Branch, Inc. All rights reserved. -// - -#import -#import "Branch.h" -#import "BNCPreferenceHelper.h" -#import "BNCRequestFactory.h" -#import "BNCEncodingUtils.h" -#import "BNCODMInfoCollector.h" -#import "NSError+Branch.h" - -@interface BNCODMTests : XCTestCase -@property (nonatomic, strong, readwrite) BNCPreferenceHelper *prefHelper; -@end - -@implementation BNCODMTests - -- (void)setUp { - _prefHelper = [BNCPreferenceHelper sharedInstance]; -} - -- (void)testSetODM { - NSString *odm = @"testODMString"; - NSDate *firstOpenTS = [NSDate date]; - [Branch setODMInfo:odm andFirstOpenTimestamp:firstOpenTS]; - XCTAssertTrue([_prefHelper.odmInfo isEqualToString:odm]); - XCTAssertTrue([_prefHelper.odmInfoInitDate isEqualToDate:firstOpenTS]); - -} - -- (void)testSetODMandSDKRequests { - NSString* requestUUID = [[NSUUID UUID ] UUIDString]; - NSNumber* requestCreationTimeStamp = BNCWireFormatFromDate([NSDate date]); - NSString *odm = @"testODMString"; - NSDate *firstOpenTS = [NSDate date]; - - [Branch setODMInfo:odm andFirstOpenTimestamp:firstOpenTS]; - - [[Branch getInstance] setConsumerProtectionAttributionLevel:BranchAttributionLevelFull]; - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:requestUUID TimeStamp:requestCreationTimeStamp]; - NSDictionary *jsonInstall = [factory dataForInstallWithURLString:@"https://branch.io"]; - XCTAssertTrue([odm isEqualToString:[jsonInstall objectForKey:@"odm_info"]]); - - NSDictionary *jsonOpen = [factory dataForOpenWithURLString:@"https://branch.io"]; - XCTAssertTrue([odm isEqualToString:[jsonOpen objectForKey:@"odm_info"]]); - - NSDictionary *event = @{@"name": @"ADD_TO_CART"}; - NSDictionary *jsonEvent = [factory dataForEventWithEventDictionary:[event mutableCopy]]; - XCTAssertTrue([jsonEvent objectForKey:@"odm_info"] == nil); - - [[Branch getInstance] setConsumerProtectionAttributionLevel:BranchAttributionLevelReduced]; - jsonInstall = [factory dataForInstallWithURLString:@"https://branch.io"]; - XCTAssertTrue([jsonInstall objectForKey:@"odm_info"] == nil); - - jsonOpen = [factory dataForOpenWithURLString:@"https://branch.io"]; - XCTAssertTrue([jsonOpen objectForKey:@"odm_info"] == nil); - - self.prefHelper.odmInfo = nil; - self.prefHelper.odmInfoInitDate = nil; -} - -- (void)testODMTimeOut { - - NSString* requestUUID = [[NSUUID UUID ] UUIDString]; - NSNumber* requestCreationTimeStamp = BNCWireFormatFromDate([NSDate date]); - NSString *odm = @"testODMString"; - NSDate *firstOpenTS = [[NSDate date] dateByAddingTimeInterval:-((180*24*3600) - 5)]; - - [Branch setODMInfo:odm andFirstOpenTimestamp:firstOpenTS]; - - [[Branch getInstance] setConsumerProtectionAttributionLevel:BranchAttributionLevelFull]; - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:requestUUID TimeStamp:requestCreationTimeStamp]; - NSDictionary *jsonInstall = [factory dataForInstallWithURLString:@"https://branch.io"]; - XCTAssertTrue([odm isEqualToString:[jsonInstall objectForKey:@"odm_info"]]); - - sleep(10); - - NSDictionary *jsonOpen = [factory dataForOpenWithURLString:@"https://branch.io"]; - XCTAssertTrue(![odm isEqualToString:[jsonOpen objectForKey:@"odm_info"]]); - - self.prefHelper.odmInfo = nil; - self.prefHelper.odmInfoInitDate = nil; - -} - - -- (void) testODMAPIsNotLoaded { - XCTestExpectation *expectation = [self expectationWithDescription:@"Check if ODCManager class is loaded."]; - [[BNCODMInfoCollector instance ] loadODMInfoWithTimeOut:DISPATCH_TIME_FOREVER andCompletionHandler:^(NSString * _Nullable odmInfo, NSError * _Nullable error) { - if (error.code == BNCClassNotFoundError){ - [expectation fulfill]; - } - }]; - [self waitForExpectationsWithTimeout:15 handler:nil]; -} - -@end diff --git a/BranchSDKTests/BNCPartnerParametersTests.m b/BranchSDKTests/BNCPartnerParametersTests.m deleted file mode 100644 index 7fad38ac2..000000000 --- a/BranchSDKTests/BNCPartnerParametersTests.m +++ /dev/null @@ -1,219 +0,0 @@ -// -// BNCPartnerParametersTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 12/9/20. -// Copyright © 2020 Branch, Inc. All rights reserved. -// - -#import -#import "BNCPartnerParameters.h" - -// expose private methods for testing -@interface BNCPartnerParameters() -- (BOOL)sha256HashSanityCheckValue:(NSString *)value; -- (BOOL)isStringHex:(NSString *)string; -@end - -@interface BNCPartnerParametersTests : XCTestCase -@property (nonatomic, strong, readwrite) BNCPartnerParameters *partnerParams; -@end - -@implementation BNCPartnerParametersTests - -- (void)setUp { - self.partnerParams = [BNCPartnerParameters new]; -} - -- (void)tearDown { - -} - -- (void)testStringHexNil { - XCTAssertFalse([self.partnerParams isStringHex:nil]); -} - -- (void)testStringHexEmpty { - XCTAssertTrue([self.partnerParams isStringHex:@""]); -} - -- (void)testStringHexDash { - XCTAssertFalse([self.partnerParams isStringHex:@"-1"]); -} - -- (void)testStringHexDecimal { - XCTAssertFalse([self.partnerParams isStringHex:@"1.0"]); -} - -- (void)testStringHexFraction { - XCTAssertFalse([self.partnerParams isStringHex:@"2/4"]); -} - -- (void)testStringHexAt { - XCTAssertFalse([self.partnerParams isStringHex:@"test@12345"]); -} - -- (void)testStringHexUpperG { - XCTAssertFalse([self.partnerParams isStringHex:@"0123456789ABCDEFG"]); -} - -- (void)testStringHexLowerG { - XCTAssertFalse([self.partnerParams isStringHex:@"0123456789abcdefg"]); -} - -- (void)testStringHexUpperCase { - XCTAssertTrue([self.partnerParams isStringHex:@"0123456789ABCDEF"]); -} - -- (void)testStringHexLowerCase { - XCTAssertTrue([self.partnerParams isStringHex:@"0123456789abcdef"]); -} - -- (void)testSha256HashSanityCheckValueNil { - XCTAssertFalse([self.partnerParams sha256HashSanityCheckValue:nil]); -} - -- (void)testSha256HashSanityCheckValueEmpty { - XCTAssertFalse([self.partnerParams sha256HashSanityCheckValue:@""]); -} - -- (void)testSha256HashSanityCheckValueTooShort { - // 63 char string - XCTAssertFalse([self.partnerParams sha256HashSanityCheckValue:@"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcde"]); -} - -- (void)testSha256HashSanityCheckValueTooLong { - // 65 char string - XCTAssertFalse([self.partnerParams sha256HashSanityCheckValue:@"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdeff"]); -} - -- (void)testSha256HashSanityCheckValueLowerCase { - // 64 char string - XCTAssertTrue([self.partnerParams sha256HashSanityCheckValue:@"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"]); -} - -- (void)testSha256HashSanityCheckValueUpperCase { - // 64 char string - XCTAssertTrue([self.partnerParams sha256HashSanityCheckValue:@"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"]); -} - -- (void)testSha256HashSanityCheckValueMixedCase { - // 64 char string - XCTAssertTrue([self.partnerParams sha256HashSanityCheckValue:@"0123456789ABCDEF0123456789ABCDEF1234567890abcdef1234567890abcdef"]); -} - -- (void)testJsonEmpty { - NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; - XCTAssertTrue([@"{}" isEqualToString:jsonString]); -} - -- (void)testJsonFBParameterEmpty { - [self.partnerParams addFacebookParameterWithName:@"em" value:@""]; - NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; - XCTAssertTrue([@"{}" isEqualToString:jsonString]); -} - -- (void)testJsonFBParameterShort { - [self.partnerParams addFacebookParameterWithName:@"em" value:@"0123456789ABCDEF0123456789ABCDEF1234567890abcdef1234567890abcde"]; - NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; - XCTAssertTrue([@"{}" isEqualToString:jsonString]); -} - -- (void)testJsonFBParameterPhoneNumberIsIgnored { - [self.partnerParams addFacebookParameterWithName:@"em" value:@"1-555-555-5555"]; - NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; - XCTAssertTrue([@"{}" isEqualToString:jsonString]); -} - -- (void)testJsonFBParameterEmailIsIgnored { - [self.partnerParams addFacebookParameterWithName:@"em" value:@"test@branch.io"]; - NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; - XCTAssertTrue([@"{}" isEqualToString:jsonString]); -} - -- (void)testJsonFBParameterBase64EncodedIsIgnored { - // 123456789012345678901234567890123456789012345678 -> MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4 - [self.partnerParams addFacebookParameterWithName:@"em" value:@"MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4"]; - NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; - XCTAssertTrue([@"{}" isEqualToString:jsonString]); -} - -- (void)testJsonFBParameterHashedValue { - [self.partnerParams addFacebookParameterWithName:@"em" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; - NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; - XCTAssertTrue([@"{\"fb\":{\"em\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\"}}" isEqualToString:jsonString]); -} - -- (void)testJsonFBParameterExample { - [self.partnerParams addFacebookParameterWithName:@"em" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; - [self.partnerParams addFacebookParameterWithName:@"ph" value:@"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b"]; - NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; - - XCTAssertTrue([@"{\"fb\":{\"ph\":\"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b\",\"em\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\"}}" isEqualToString:jsonString]); -} - -- (void)testJsonSnapParameterExample { - [self.partnerParams addSnapParameterWithName:@"hashed_email_address" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; - [self.partnerParams addSnapParameterWithName:@"hashed_phone_number" value:@"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b"]; - NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; - - XCTAssertTrue([@"{\"snap\":{\"hashed_phone_number\":\"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b\",\"hashed_email_address\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\"}}" isEqualToString:jsonString]); -} - - -- (void)testJsonMultipleParameterExample { - [self.partnerParams addFacebookParameterWithName:@"em" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; - [self.partnerParams addFacebookParameterWithName:@"ph" value:@"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b"]; - [self.partnerParams addSnapParameterWithName:@"hashed_email_address" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; - [self.partnerParams addSnapParameterWithName:@"hashed_phone_number" value:@"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b"]; - NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; - - NSString *expectedJsonString = @"{\"snap\":{\"hashed_phone_number\":\"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b\",\"hashed_email_address\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\"},\"fb\":{\"ph\":\"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b\",\"em\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\"}}"; - - XCTAssertTrue([expectedJsonString isEqualToString:jsonString]); -} - -- (void)testParameterClear { - [self.partnerParams addFacebookParameterWithName:@"em" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; - [self.partnerParams addFacebookParameterWithName:@"ph" value:@"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b"]; - [self.partnerParams addSnapParameterWithName:@"hashed_email_address" value:@"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088"]; - [self.partnerParams addSnapParameterWithName:@"hashed_phone_number" value:@"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b"]; - [self.partnerParams clearAllParameters]; - - NSString *jsonString = [self jsonStringFromDictionary:[self.partnerParams parameterJson]]; - XCTAssertTrue([@"{}" isEqualToString:jsonString]); -} - -// sanity check test func on an empty dictionary -- (void)testEmptyJson { - NSString *jsonString = [self jsonStringFromDictionary:@{}]; - XCTAssertTrue([@"{}" isEqualToString:jsonString]); -} - -// sanity check test func on the sample json dictionary -- (void)testSampleJson { - NSString *jsonString = [self jsonStringFromDictionary:@{ - @"fb": @{ - @"ph": @"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b", - @"em": @"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088" - } - }]; - - XCTAssertTrue([@"{\"fb\":{\"ph\":\"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b\",\"em\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\"}}" isEqualToString:jsonString] || [@"{\"fb\":{\"em\":\"11234e56af071e9c79927651156bd7a10bca8ac34672aba121056e2698ee7088\",\"ph\":\"b90598b67534f00b1e3e68e8006631a40d24fba37a3a34e2b84922f1f0b3b29b\"}}" isEqualToString:jsonString]); -} - -// There is an assumption that this code always results in the same string for the same json data. -// This appears to be true, but I haven't found documentation to confirm it. -- (NSString *)jsonStringFromDictionary:(NSDictionary *)dictionary { - NSError *error; - NSData *json = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error]; - - if (!error) { - NSString *tmp = [[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding]; - return tmp; - } else { - return @""; - } -} - -@end diff --git a/BranchSDKTests/BNCPasteboardTests.m b/BranchSDKTests/BNCPasteboardTests.m deleted file mode 100644 index 6a3a4d69c..000000000 --- a/BranchSDKTests/BNCPasteboardTests.m +++ /dev/null @@ -1,170 +0,0 @@ -// -// BNCPasteboardTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 7/19/21. -// Copyright © 2021 Branch, Inc. All rights reserved. -// - -#import -#import "BNCPasteboard.h" -#import "Branch.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 - [UIPasteboard.generalPasteboard setString:self.testString]; -#endif -} - -- (void)addBranchURLToPasteboard { -#if !TARGET_OS_TV - [UIPasteboard.generalPasteboard setURL:self.testBranchURL]; -#endif -} - -- (void)addNonBranchURLToPasteboard { -#if !TARGET_OS_TV - [UIPasteboard.generalPasteboard setURL:[NSURL URLWithString:@"https://www.apple.com"]]; -#endif -} - -- (void)clearPasteboard { -#if !TARGET_OS_TV - // 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 - string = [UIPasteboard.generalPasteboard string]; -#endif - return string; -} - -- (NSURL *)getURLFromPasteboard { - NSURL *url = nil; -#if !TARGET_OS_TV - 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 - XCTAssertFalse([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]); - - [self clearPasteboard]; -} - -- (void)testCheckForBranchLink_nonBranchLink { - [self addNonBranchURLToPasteboard]; - XCTAssertTrue([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); - - NSURL *tmp = [[BNCPasteboard sharedInstance] checkForBranchLink]; - XCTAssertNil(tmp); - - [self clearPasteboard]; -} - -- (void)testCheckForBranchLink_noLink { - [self addStringToPasteboard]; - XCTAssertFalse([[BNCPasteboard sharedInstance] isUrlOnPasteboard]); - - NSURL *tmp = [[BNCPasteboard sharedInstance] checkForBranchLink]; - XCTAssertNil(tmp); - - [self clearPasteboard]; -} - -#if 0 -// This test fails intermittently when executed with other tests - depending upon the order in which its executed -- (void) testPassPasteControl { -#if !TARGET_OS_TV - if (@available(iOS 16.0, macCatalyst 16.0, *)) { - - long long timeStamp = ([[NSDate date] timeIntervalSince1970] - 5*60)*1000; // 5 minute earlier timestamp - NSString *urlString = [NSString stringWithFormat:@"https://bnctestbed-alternate.app.link/9R7MbTmnRtb?__branch_flow_type=viewapp&__branch_flow_id=1105940563590163783&__branch_mobile_deepview_type=1&nl_opt_in=1&_cpts=%lld", timeStamp]; - NSURL *testURL = [[NSURL alloc] initWithString:urlString]; - - NSArray *itemProviders = @[[[NSItemProvider alloc] initWithItem:testURL typeIdentifier:UTTypeURL.identifier]]; - XCTestExpectation *openExpectation = [self expectationWithDescription:@"Test open"]; - - [[Branch getInstance] initSessionWithLaunchOptions:@{} andRegisterDeepLinkHandler:^(NSDictionary *params, NSError *error) { - [openExpectation fulfill]; - XCTAssertNil(error); - }]; - - [[Branch getInstance] passPasteItemProviders:itemProviders]; - [self waitForExpectationsWithTimeout:5.0 handler:NULL]; - - } -#endif -} -#endif - -@end diff --git a/BranchSDKTests/BNCPreferenceHelperTests.m b/BranchSDKTests/BNCPreferenceHelperTests.m deleted file mode 100644 index 5269501b3..000000000 --- a/BranchSDKTests/BNCPreferenceHelperTests.m +++ /dev/null @@ -1,417 +0,0 @@ -// -// BNCPreferenceHelperTests.m -// Branch-TestBed -// -// Created by Graham Mueller on 4/2/15. -// Copyright (c) 2015 Branch Metrics. All rights reserved. -// - -#import -#import "BNCPreferenceHelper.h" -#import "BNCEncodingUtils.h" -#import "Branch.h" -#import "BNCConfig.h" - -@interface BNCPreferenceHelper() - -// expose private methods for testing -- (NSMutableDictionary *)deserializePrefDictFromData:(NSData *)data; -- (NSData *)serializePrefDict:(NSMutableDictionary *)dict; - -@end - -@interface BNCPreferenceHelperTests : XCTestCase -@property (nonatomic, strong, readwrite) BNCPreferenceHelper *prefHelper; -@end - -@implementation BNCPreferenceHelperTests - -- (void)setUp { - self.prefHelper = [BNCPreferenceHelper new]; -} - -- (void)tearDown { - -} - -- (void)testPreferenceDefaults { - XCTAssertEqual(self.prefHelper.timeout, 5.5); - XCTAssertEqual(self.prefHelper.retryInterval, 0); - XCTAssertEqual(self.prefHelper.retryCount, 3); - XCTAssertFalse(self.prefHelper.disableAdNetworkCallouts); -} - -- (void)testPreferenceSets { - self.prefHelper.retryCount = NSIntegerMax; - self.prefHelper.retryInterval = NSIntegerMax; - self.prefHelper.timeout = NSIntegerMax; - - XCTAssertEqual(self.prefHelper.retryCount, NSIntegerMax); - XCTAssertEqual(self.prefHelper.retryInterval, NSIntegerMax); - XCTAssertEqual(self.prefHelper.timeout, NSIntegerMax); -} - -// This test is not reliable when run concurrently with other tests that set the patterListURL -- (void)testURLFilter { - XCTAssertTrue([@"https://cdn.branch.io" isEqualToString:self.prefHelper.patternListURL]); - - NSString *customURL = @"https://banned.branch.io"; - self.prefHelper.patternListURL = customURL; - XCTAssertTrue([customURL isEqualToString:self.prefHelper.patternListURL]); -} - -- (void)testSerializeDict_Nil { - NSMutableDictionary *dict = nil; - NSData *data = [self.prefHelper serializePrefDict:dict]; - XCTAssert(data == nil); -} - -- (void)testSerializeDict_Empty { - NSMutableDictionary *dict = [NSMutableDictionary new]; - NSData *data = [self.prefHelper serializePrefDict:dict]; - NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; - - XCTAssert(tmp != nil); - XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); - XCTAssert(tmp.count == 0); -} - -- (void)testSerializeDict_String { - NSMutableDictionary *dict = [NSMutableDictionary new]; - NSString *value = @"the quick brown fox jumps over the lazy dog"; - NSString *key = @"test"; - [dict setObject:value forKey:key]; - - NSData *data = [self.prefHelper serializePrefDict:dict]; - NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; - - XCTAssert(tmp != nil); - XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); - XCTAssert(tmp.count == 1); - - XCTAssert([[tmp objectForKey:key] isEqualToString:value]); -} - -- (void)testSerializeDict_Date { - NSMutableDictionary *dict = [NSMutableDictionary new]; - NSDate *value = [NSDate date]; - NSString *key = @"test"; - [dict setObject:value forKey:key]; - - NSData *data = [self.prefHelper serializePrefDict:dict]; - NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; - - XCTAssert(tmp != nil); - XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); - XCTAssert(tmp.count == 1); - - XCTAssert([[tmp objectForKey:key] isEqual:value]); -} - -- (void)testSerializeDict_Bool { - NSMutableDictionary *dict = [NSMutableDictionary new]; - bool value = YES; - NSString *key = @"test"; - [dict setObject:@(value) forKey:key]; - - NSData *data = [self.prefHelper serializePrefDict:dict]; - NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; - - XCTAssert(tmp != nil); - XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); - XCTAssert(tmp.count == 1); - - XCTAssert([[tmp objectForKey:key] isEqual:@(value)]); -} - -- (void)testSerializeDict_Integer { - NSMutableDictionary *dict = [NSMutableDictionary new]; - NSInteger value = 1234; - NSString *key = @"test"; - [dict setObject:@(value) forKey:key]; - - NSData *data = [self.prefHelper serializePrefDict:dict]; - NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; - - XCTAssert(tmp != nil); - XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); - XCTAssert(tmp.count == 1); - - XCTAssert([[tmp objectForKey:key] isEqual:@(value)]); -} - -- (void)testSerializeDict_All { - NSMutableDictionary *dict = [NSMutableDictionary new]; - - NSString *value1 = @"the quick brown fox jumps over the lazy dog"; - NSString *key1 = @"test1"; - [dict setObject:value1 forKey:key1]; - - NSDate *value2 = [NSDate date]; - NSString *key2 = @"test2"; - [dict setObject:value2 forKey:key2]; - - bool value3 = YES; - NSString *key3 = @"test3"; - [dict setObject:@(value3) forKey:key3]; - - NSInteger value4 = 1234; - NSString *key4 = @"test4"; - [dict setObject:@(value4) forKey:key4]; - - NSData *data = [self.prefHelper serializePrefDict:dict]; - NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; - - XCTAssert(tmp != nil); - XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); - XCTAssert(tmp.count == 4); - - XCTAssert([[tmp objectForKey:key1] isEqualToString:value1]); - XCTAssert([[tmp objectForKey:key2] isEqual:value2]); - XCTAssert([[tmp objectForKey:key3] isEqual:@(value3)]); - XCTAssert([[tmp objectForKey:key4] isEqual:@(value4)]); -} - -- (void)testURLSkipList { - NSMutableDictionary *dict = [NSMutableDictionary new]; - NSString *key = @"test"; - NSArray *value = @[ - @"^fb\\d+:", - @"^li\\d+:", - @"^pdk\\d+:", - @"^twitterkit-.*:", - @"^com\\.googleusercontent\\.apps\\.\\d+-.*:\\/oauth", - @"^(?i)(?!(http|https):).*(:|:.*\\b)(password|o?auth|o?auth.?token|access|access.?token)\\b", - @"^(?i)((http|https):\\/\\/).*[\\/|?|#].*\\b(password|o?auth|o?auth.?token|access|access.?token)\\b", - ]; - [dict setObject:value forKey:key]; - NSData *data = [self.prefHelper serializePrefDict:dict]; - - NSMutableDictionary *tmp = [self.prefHelper deserializePrefDictFromData:data]; - - XCTAssert(tmp != nil); - XCTAssert([tmp isKindOfClass:NSMutableDictionary.class]); - - NSArray *filter = [tmp objectForKey:key]; - - NSString *filterDesc = filter.description; - NSString *valueDesc = value.description; - XCTAssert([filterDesc isEqualToString:valueDesc]); -} - -- (void)testSetCDNBaseURL_Example { - - NSString *url = @"https://www.example.com/"; - [self.prefHelper setPatternListURL:url]; - - NSString *urlStored = self.prefHelper.patternListURL ; - XCTAssert([url isEqualToString:urlStored]); -} - -- (void)testSetCDNBaseURL_InvalidHttp { - - NSString *url = @"Invalid://www.example.com/"; - [self.prefHelper setPatternListURL:url] ; - - NSString *urlStored = self.prefHelper.patternListURL ; - XCTAssert(![url isEqualToString:urlStored]); - XCTAssert([urlStored isEqualToString:BNC_CDN_URL]); -} - -- (void)testSetCDNBaseURL_InvalidEmpty { - - [self.prefHelper setPatternListURL:@""] ; - - NSString *urlStored = self.prefHelper.patternListURL ; - XCTAssert(![urlStored isEqualToString:@""]); - XCTAssert([urlStored isEqualToString:BNC_CDN_URL]); -} - -- (void)testSetPatternListURL { - NSString *expectedURL = @"https://example.com"; - [self.prefHelper setPatternListURL:expectedURL]; - - NSString *patternListURL = self.prefHelper.patternListURL; - XCTAssert([patternListURL isEqualToString: expectedURL]); -} - -- (void)testSetLastStrongMatchDate { - NSDate *expectedDate = [NSDate date]; - [self.prefHelper setLastStrongMatchDate: expectedDate]; - - NSDate *actualDate = [self.prefHelper lastStrongMatchDate]; - XCTAssertEqualObjects(expectedDate, actualDate); -} - -- (void)testSetAppVersion { - NSString *expectedVersion = @"1.0.0"; - [self.prefHelper setAppVersion: expectedVersion]; - - NSString *actualVersion = [self.prefHelper appVersion]; - XCTAssertEqualObjects(expectedVersion, actualVersion); -} - -- (void)testSetLocalUrl { - NSString *expectedLocalURL = @"https://local.example.com"; - [self.prefHelper setLocalUrl:expectedLocalURL]; - - NSString *localURL = [self.prefHelper localUrl]; - XCTAssertEqualObjects(localURL, expectedLocalURL); -} - -- (void)testSetInitialReferrer { - NSString *expectedReferrer = @"referrer.example.com"; - [self.prefHelper setInitialReferrer:expectedReferrer]; - - NSString *actualReferrer = [self.prefHelper initialReferrer]; - XCTAssertEqualObjects(actualReferrer, expectedReferrer); -} - -- (void)testSetAppleAttributionTokenChecked { - BOOL expectedValue = YES; - [self.prefHelper setAppleAttributionTokenChecked:expectedValue]; - - BOOL actualValue = [self.prefHelper appleAttributionTokenChecked]; - XCTAssertEqual(expectedValue, actualValue); -} - -- (void)testSetHasOptedInBefore { - BOOL expectedValue = YES; - [self.prefHelper setHasOptedInBefore:expectedValue]; - - BOOL actualValue = [self.prefHelper hasOptedInBefore]; - XCTAssertEqual(expectedValue, actualValue); -} - -- (void)testSetHasCalledHandleATTAuthorizationStatus { - BOOL expectedValue = YES; - [self.prefHelper setHasCalledHandleATTAuthorizationStatus:expectedValue]; - - BOOL actualValue = [self.prefHelper hasCalledHandleATTAuthorizationStatus]; - XCTAssertEqual(expectedValue, actualValue); -} - -- (void)testSetRequestMetadataKeyValidKeyValue { - NSString *key = @"testKey"; - NSString *value = @"testValue"; - - [self.prefHelper setRequestMetadataKey:key value:value]; - - NSObject *retrievedValue = [self.prefHelper.requestMetadataDictionary objectForKey:key]; - XCTAssertEqualObjects(retrievedValue, value); -} - -- (void)testSetRequestMetadataKeyValidKeyNilValue { - NSString *key = @"testKey"; - NSString *value = @"testValue"; - - [self.prefHelper.requestMetadataDictionary setObject:value forKey:key]; - - [self.prefHelper setRequestMetadataKey:key value:nil]; - - NSObject *retrievedValue = [self.prefHelper.requestMetadataDictionary objectForKey:key]; - XCTAssertNil(retrievedValue); -} - -- (void)testSetRequestMetadataKeyValidKeyNilValueKeyNotExists { - NSString *key = @"testKeyNotExists"; - - NSUInteger initialDictCount = [self.prefHelper.requestMetadataDictionary count]; - - [self.prefHelper setRequestMetadataKey:key value:nil]; - - NSUInteger postActionDictCount = [self.prefHelper.requestMetadataDictionary count]; - XCTAssertEqual(initialDictCount, postActionDictCount); -} - -- (void)testSetRequestMetadataKeyNilKey { - NSString *value = @"testValue"; - NSUInteger initialDictCount = [self.prefHelper.requestMetadataDictionary count]; - - [self.prefHelper setRequestMetadataKey:nil value:value]; - - NSUInteger postActionDictCount = [self.prefHelper.requestMetadataDictionary count]; - XCTAssertEqual(initialDictCount, postActionDictCount); -} - -- (void)testSetLimitFacebookTracking { - BOOL expectedValue = YES; - - [self.prefHelper setLimitFacebookTracking:expectedValue]; - - BOOL storedValue = [self.prefHelper limitFacebookTracking]; - - XCTAssertEqual(expectedValue, storedValue); -} - -- (void)testSetTrackingDisabled_YES { - [self.prefHelper setTrackingDisabled:YES]; - - BOOL storedValue = [self.prefHelper trackingDisabled]; - XCTAssertTrue(storedValue); - [self.prefHelper setTrackingDisabled:NO]; -} - -- (void)testSetTrackingDisabled_NO { - [self.prefHelper setTrackingDisabled:NO]; - - BOOL storedValue = [self.prefHelper trackingDisabled]; - XCTAssertFalse(storedValue); -} - -// TODO: rethink this test as these values are not set in a freshly instantiated prefHelper -- (void)testClearTrackingInformation { - [self.prefHelper clearTrackingInformation]; - - XCTAssertNil(self.prefHelper.sessionID); - XCTAssertNil(self.prefHelper.linkClickIdentifier); - XCTAssertNil(self.prefHelper.spotlightIdentifier); - XCTAssertNil(self.prefHelper.referringURL); - XCTAssertNil(self.prefHelper.universalLinkUrl); - XCTAssertNil(self.prefHelper.initialReferrer); - XCTAssertNil(self.prefHelper.installParams); - XCTAssertNil(self.prefHelper.sessionParams); - XCTAssertNil(self.prefHelper.externalIntentURI); - XCTAssertNil(self.prefHelper.savedAnalyticsData); - XCTAssertNil(self.prefHelper.previousAppBuildDate); - XCTAssertEqual(self.prefHelper.requestMetadataDictionary.count, 0); - XCTAssertNil(self.prefHelper.lastStrongMatchDate); - XCTAssertNil(self.prefHelper.userIdentity); - XCTAssertNil(self.prefHelper.referringURLQueryParameters); - XCTAssertNil(self.prefHelper.anonID); -} - -- (void)testSaveBranchAnalyticsData { - NSString *dummySessionID = @"testSession123"; - NSDictionary *dummyAnalyticsData = @{ @"key1": @"value1", @"key2": @"value2" }; - - self.prefHelper.sessionID = dummySessionID; - - [self.prefHelper saveBranchAnalyticsData:dummyAnalyticsData]; - - NSMutableDictionary *retrievedData = [self.prefHelper getBranchAnalyticsData]; - - NSArray *viewDataArray = [retrievedData objectForKey:dummySessionID]; - XCTAssertNotNil(viewDataArray); - XCTAssertEqual(viewDataArray.count, 1); - XCTAssertEqualObjects(viewDataArray.firstObject, dummyAnalyticsData); -} - -- (void)testClearBranchAnalyticsData { - [self.prefHelper clearBranchAnalyticsData]; - - NSMutableDictionary *retrievedData = [self.prefHelper getBranchAnalyticsData]; - XCTAssertEqual(retrievedData.count, 0); -} - -- (void)testSaveContentAnalyticsManifest { - NSDictionary *dummyManifest = @{ @"manifestKey1": @"manifestValue1", @"manifestKey2": @"manifestValue2" }; - - [self.prefHelper saveContentAnalyticsManifest:dummyManifest]; - - NSDictionary *retrievedManifest = [self.prefHelper getContentAnalyticsManifest]; - - XCTAssertEqualObjects(retrievedManifest, dummyManifest); -} - -@end diff --git a/BranchSDKTests/BNCReachabilityTests.m b/BranchSDKTests/BNCReachabilityTests.m deleted file mode 100644 index 3f159c1e3..000000000 --- a/BranchSDKTests/BNCReachabilityTests.m +++ /dev/null @@ -1,45 +0,0 @@ -// -// BNCReachabilityTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 11/18/19. -// Copyright © 2019 Branch, Inc. All rights reserved. -// - -#import -#import "BNCReachability.h" - -@interface BNCReachabilityTests : XCTestCase -@property (nonatomic, strong, readwrite) BNCReachability *reachability; -@end - -@implementation BNCReachabilityTests - -- (void)setUp { - self.reachability = [BNCReachability new]; -} - -- (void)tearDown { - -} - -- (void)testSimulator_WIFI { - NSString *status = [self.reachability reachabilityStatus]; - XCTAssertNotNil(status); - XCTAssert([@"wifi" isEqualToString:status]); -} - -// Only works on a device with cell -//- (void)testDevice_Cell { -// NSString *status = [self.reachability reachabilityStatus]; -// XCTAssertNotNil(status); -// XCTAssert([@"mobile" isEqualToString:status]); -//} - -// Only works on a device in Airplane mode -//- (void)testDevice_AirplaneMode { -// NSString *status = [self.reachability reachabilityStatus]; -// XCTAssertNil(status); -//} - -@end diff --git a/BranchSDKTests/BNCReferringURLUtilityTests.m b/BranchSDKTests/BNCReferringURLUtilityTests.m deleted file mode 100644 index b76f91b4d..000000000 --- a/BranchSDKTests/BNCReferringURLUtilityTests.m +++ /dev/null @@ -1,538 +0,0 @@ -// -// BNCReferringURLUtilityTests.m -// Branch-SDK-Tests -// -// Created by Nipun Singh on 3/9/23. -// Copyright © 2023 Branch, Inc. All rights reserved. -// - -#import -#import "BNCReferringURLUtility.h" -#import "BNCUrlQueryParameter.h" -#import "BNCPreferenceHelper.h" - -@interface BNCReferringURLUtility(Test) -// expose the private data structure so tests can clear it -@property (strong, readwrite, nonatomic) NSMutableDictionary *urlQueryParameters; - -// expose private methods to test data migration -- (void)checkForAndMigrateOldGbraid; -@end - -@interface BNCReferringURLUtilityTests : XCTestCase - -@end - -@implementation BNCReferringURLUtilityTests - -// test constants -static NSString *openEndpoint = @"/v1/open"; -static NSString *eventEndpoint = @"/v2/event"; - -+ (void)tearDown { - // clear test data from global storage - [BNCPreferenceHelper sharedInstance].referringURLQueryParameters = nil; - [BNCPreferenceHelper sharedInstance].referrerGBRAID = nil; - [BNCPreferenceHelper sharedInstance].referrerGBRAIDValidityWindow = 0; - [BNCPreferenceHelper sharedInstance].referrerGBRAIDInitDate = nil; -} - -// workaround for BNCPreferenceHelper being persistent across tests and not currently mockable -- (BNCReferringURLUtility *)referringUtilityForTests { - BNCReferringURLUtility *utility = [BNCReferringURLUtility new]; - utility.urlQueryParameters = [NSMutableDictionary new]; - return utility; -} - -// make gbraid equality check simpler by excluding timestamp -- (NSDictionary *)removeTimestampFromParams:(NSDictionary *)params { - NSMutableDictionary *paramsWithoutTimestamp = [params mutableCopy]; - paramsWithoutTimestamp[@"gbraid_timestamp"] = nil; - return paramsWithoutTimestamp; -} - -// gbraid timestamp is a string representing time in millis -- (void)validateGbraidTimestampInReferringParameters:(NSDictionary *)params { - id timestamp = params[@"gbraid_timestamp"]; - XCTAssert(timestamp != nil); - XCTAssert([timestamp isKindOfClass:NSString.class]); -} - -- (void)expireValidityWindowsInUtility:(BNCReferringURLUtility *)utility { - for (NSString *paramName in utility.urlQueryParameters.allKeys) { - BNCUrlQueryParameter *param = utility.urlQueryParameters[paramName]; - - // currently the longest validity window is 30 days - NSTimeInterval sixtyDaysAgo = -1 * 60 * 24 * 60 * 60; - param.timestamp = [NSDate dateWithTimeIntervalSinceNow:sixtyDaysAgo]; - } -} - -- (void)testReferringURLWithNoParams { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link"]; - NSDictionary *expected = @{}; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testNilReferringURL { - NSURL *url = nil; - NSDictionary *expected = @{}; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLIgnoredParam { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?other=12345"]; - NSDictionary *expected = @{ }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithGclid { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=12345"]; - NSDictionary *expected = @{ - @"gclid": @"12345" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -// NSURL treats URI schemes in a consistent manner with Universal Links -- (void)testReferringURLWithURISchemeSanityCheck{ - NSURL *url = [NSURL URLWithString:@"branchtest://?gclid=12345"]; - NSDictionary *expected = @{ - @"gclid": @"12345" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithGclidCapitalized { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?GCLID=12345"]; - NSDictionary *expected = @{ - @"gclid": @"12345" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithGclidMixedCase { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?GcLiD=12345"]; - NSDictionary *expected = @{ - @"gclid": @"12345" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithGclidNoValue { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid="]; - NSDictionary *expected = @{ - @"gclid": @"" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithGclidValueCasePreserved { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=aAbBcC"]; - NSDictionary *expected = @{ - @"gclid": @"aAbBcC" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithGclidIgnoredParam { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=12345&other=abcde"]; - NSDictionary *expected = @{ - @"gclid": @"12345" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithGclidFragment{ - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=12345#header"]; - NSDictionary *expected = @{ - @"gclid": @"12345" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithGclidAsFragment{ - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?other=abcde#gclid=12345"]; - NSDictionary *expected = @{ }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithGclidOverwritesValue { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=12345"]; - NSDictionary *expected = @{ - @"gclid": @"12345" - }; - - NSURL *url2 = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=abcde"]; - NSDictionary *expected2 = @{ - @"gclid": @"abcde" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - XCTAssert([expected isEqualToDictionary:params]); - - [utility parseReferringURL:url2]; - NSDictionary *params2 = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected2 isEqualToDictionary:params2]); -} - -- (void)testReferringURLWithMetaCampaignIdsAndInvalidURL { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?al_applink_data=[]#target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D"]; - NSDictionary *expected = @{}; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithMetaCampaignIds { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D"]; - NSDictionary *expected = @{ - @"meta_campaign_ids": @"ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithMetaCampaignIdsExpired { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D"]; - NSDictionary *expected = @{ }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - [self expireValidityWindowsInUtility:utility]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithMetaNoCampaignIds { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22test_deeplink%22%3A1%7D"]; - NSDictionary *expected = @{ }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithGbraid { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gbraid=abcde"]; - NSDictionary *expected = @{ - @"gbraid": @"abcde", - @"is_deeplink_gbraid": @(true) - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - [self validateGbraidTimestampInReferringParameters:params]; - NSDictionary *paramsWithoutTimestamp = [self removeTimestampFromParams:params]; - XCTAssert([expected isEqualToDictionary:paramsWithoutTimestamp]); -} - -- (void)testReferringURLWithGbraidOnEvent { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gbraid=abcde"]; - NSDictionary *expected = @{ - @"gbraid": @"abcde" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:eventEndpoint]; - - [self validateGbraidTimestampInReferringParameters:params]; - NSDictionary *paramsWithoutTimestamp = [self removeTimestampFromParams:params]; - XCTAssert([expected isEqualToDictionary:paramsWithoutTimestamp]); -} - -- (void)testReferringURLWithGbraidExpired { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gbraid=abcde"]; - NSDictionary *expected = @{ }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - [self expireValidityWindowsInUtility:utility]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLPreservesNonZeroValidityWindowForGbraid { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gbraid=12345"]; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - - // pretend this object was loaded from disk - // this simulates setting a custom non-zero validity window, only supported for gbraid - BNCUrlQueryParameter *existingParam = [BNCUrlQueryParameter new]; - existingParam.name = @"gbraid"; - existingParam.value = @""; - existingParam.timestamp = [NSDate date]; - existingParam.validityWindow = 5; // not the default gbraid window - utility.urlQueryParameters[@"gbraid"] = existingParam; - - [utility parseReferringURL:url]; - - // verify validity window was not changed - XCTAssert(utility.urlQueryParameters[@"gbraid"].validityWindow == 5); -} - -- (void)testReferringURLOverwritesZeroValidityWindowForGbraid { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gbraid=12345"]; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - - // pretend this object was loaded from disk - // for gbraid, or any param, we overwrite the 0 validity windows with the default - BNCUrlQueryParameter *existingParam = [BNCUrlQueryParameter new]; - existingParam.name = @"gbraid"; - existingParam.value = @""; - existingParam.timestamp = [NSDate date]; - existingParam.validityWindow = 0; - utility.urlQueryParameters[@"gbraid"] = existingParam; - - [utility parseReferringURL:url]; - - // verify validity window was changed - XCTAssert(utility.urlQueryParameters[@"gbraid"].validityWindow != 0); -} - -- (void)testReferringURLWithGclidGbraid { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?gclid=12345&gbraid=abcde"]; - NSDictionary *expected = @{ - @"gclid": @"12345", - @"gbraid": @"abcde", - @"is_deeplink_gbraid": @(true) - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - [self validateGbraidTimestampInReferringParameters:params]; - NSDictionary *paramsWithoutTimestamp = [self removeTimestampFromParams:params]; - XCTAssert([expected isEqualToDictionary:paramsWithoutTimestamp]); -} - -- (void)testGbraidDataMigration { - // Manipulates the global BNCPreferenceHelper. - // This is not safe for concurrent unit tests, so only the happy path is tested. - [self clearCurrentQueryParameters]; - [self addOldGbraidData]; - - NSDictionary *expected = @{ - @"gbraid": @"abcde", - @"is_deeplink_gbraid": @(false) - }; - - BNCReferringURLUtility *utility = [BNCReferringURLUtility new]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - [self validateGbraidTimestampInReferringParameters:params]; - NSDictionary *paramsWithoutTimestamp = [self removeTimestampFromParams:params]; - XCTAssert([expected isEqualToDictionary:paramsWithoutTimestamp]); - - [self verifyOldGbraidDataIsCleared]; -} - -- (void)clearCurrentQueryParameters { - [BNCPreferenceHelper sharedInstance].referringURLQueryParameters = nil; -} - -- (void)addOldGbraidData { - [BNCPreferenceHelper sharedInstance].referrerGBRAID = @"abcde"; - [BNCPreferenceHelper sharedInstance].referrerGBRAIDValidityWindow = 2592000; - [BNCPreferenceHelper sharedInstance].referrerGBRAIDInitDate = [NSDate date]; -} - -- (void)verifyOldGbraidDataIsCleared { - XCTAssertNil([BNCPreferenceHelper sharedInstance].referrerGBRAID); - XCTAssert([BNCPreferenceHelper sharedInstance].referrerGBRAIDValidityWindow == 0); - XCTAssertNil([BNCPreferenceHelper sharedInstance].referrerGBRAIDInitDate); -} - -- (void)testReferringURLWithSccid { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid=12345"]; - NSDictionary *expected = @{ - @"sccid": @"12345" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithSccidMixedCase { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?ScCiD=12345"]; - NSDictionary *expected = @{ - @"sccid": @"12345" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithSccidNoValue { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid="]; - NSDictionary *expected = @{ - @"sccid": @"" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithSccidValueCasePreserved { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid=aAbBcC"]; - NSDictionary *expected = @{ - @"sccid": @"aAbBcC" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithSccidIgnoredParam { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid=12345&other=abcde"]; - NSDictionary *expected = @{ - @"sccid": @"12345" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithSccidFragment{ - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid=12345#header"]; - NSDictionary *expected = @{ - @"sccid": @"12345" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithSccidAsFragment{ - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?other=abcde#sccid=12345"]; - NSDictionary *expected = @{ }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected isEqualToDictionary:params]); -} - -- (void)testReferringURLWithSccidOverwritesValue { - NSURL *url = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid=12345"]; - NSDictionary *expected = @{ - @"sccid": @"12345" - }; - - NSURL *url2 = [NSURL URLWithString:@"https://bnctestbed.app.link?sccid=abcde"]; - NSDictionary *expected2 = @{ - @"sccid": @"abcde" - }; - - BNCReferringURLUtility *utility = [self referringUtilityForTests]; - [utility parseReferringURL:url]; - NSDictionary *params = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - XCTAssert([expected isEqualToDictionary:params]); - - [utility parseReferringURL:url2]; - NSDictionary *params2 = [utility referringURLQueryParamsForEndpoint:openEndpoint]; - - XCTAssert([expected2 isEqualToDictionary:params2]); -} - - -@end diff --git a/BranchSDKTests/BNCRequestFactoryTests.m b/BranchSDKTests/BNCRequestFactoryTests.m deleted file mode 100644 index c28d3b6e0..000000000 --- a/BranchSDKTests/BNCRequestFactoryTests.m +++ /dev/null @@ -1,234 +0,0 @@ -// -// BNCRequestFactoryTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 8/21/23. -// Copyright © 2023 Branch, Inc. All rights reserved. -// - -#import -#import "BNCRequestFactory.h" -#import "BranchConstants.h" -#import "BNCEncodingUtils.h" - -@interface BNCRequestFactoryTests : XCTestCase -@property (nonatomic, copy, readwrite) NSString *requestUUID; -@property (nonatomic, copy, readwrite) NSNumber *requestCreationTimeStamp; -@end - -@implementation BNCRequestFactoryTests - -- (void)setUp { - _requestUUID = [[NSUUID UUID ] UUIDString]; - _requestCreationTimeStamp = BNCWireFormatFromDate([NSDate date]); -} - -- (void)tearDown { - -} - -- (void)testInitWithBranchKeyNil { - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:nil UUID:_requestUUID TimeStamp:_requestCreationTimeStamp]; - NSDictionary *json = [factory dataForInstallWithURLString:@"https://branch.io"]; - XCTAssertNotNil(json); - - // key is omitted when nil - XCTAssertNil([json objectForKey:@"branch_key"]); - XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); - XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); -} - -- (void)testInitWithBranchKeyEmpty { - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; - NSDictionary *json = [factory dataForInstallWithURLString:@"https://branch.io"]; - XCTAssertNotNil(json); - - // empty string is allowed - XCTAssertTrue([@"" isEqualToString:[json objectForKey:@"branch_key"]]); - - XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); - XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); -} - -- (void)testInitWithBranchKey { - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; - NSDictionary *json = [factory dataForInstallWithURLString:@"https://branch.io"]; - XCTAssertNotNil(json); - XCTAssertTrue([@"key_abcd" isEqualToString:[json objectForKey:@"branch_key"]]); - - XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); - XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); -} - -- (void)testDataForInstall { - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; - NSDictionary *json = [factory dataForInstallWithURLString:@"https://branch.io"]; - XCTAssertNotNil(json); - - XCTAssertTrue([@"key_abcd" isEqualToString:[json objectForKey:@"branch_key"]]); - XCTAssertNotNil([json objectForKey:@"sdk"]); - XCTAssertTrue([@"Apple" isEqualToString:[json objectForKey:@"brand"]]); - XCTAssertNotNil([json objectForKey:@"ios_vendor_id"]); - - // not present on installs - XCTAssertNil([json objectForKey:@"randomized_bundle_token"]); - - XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); - XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); -} - -- (void)testDataForOpen { - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; - NSDictionary *json = [factory dataForOpenWithURLString:@"https://branch.io"]; - XCTAssertNotNil(json); - - XCTAssertTrue([@"key_abcd" isEqualToString:[json objectForKey:@"branch_key"]]); - XCTAssertNotNil([json objectForKey:@"sdk"]); - XCTAssertTrue([@"Apple" isEqualToString:[json objectForKey:@"brand"]]); - XCTAssertNotNil([json objectForKey:@"ios_vendor_id"]); - - // Present only on opens. Assumes test runs after the host app completes an install. - // This is not a reliable assumption on test runners - //XCTAssertNotNil([json objectForKey:@"randomized_bundle_token"]); - - XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); - XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); -} - -- (void)testDataForEvent { - NSDictionary *event = @{@"name": @"ADD_TO_CART"}; - - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; - NSDictionary *json = [factory dataForEventWithEventDictionary:[event mutableCopy]]; - XCTAssertNotNil(json); - - XCTAssertTrue([@"ADD_TO_CART" isEqualToString:[json objectForKey:@"name"]]); - - NSDictionary *userData = [json objectForKey:@"user_data"]; - XCTAssertNotNil(userData); - XCTAssertNotNil([userData objectForKey:@"idfv"]); - - XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); - XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); -} - -- (void)testDataForEventWithContentItem { - NSDictionary *event = @{ - @"name": @"ADD_TO_CART", - @"content_items": @[ - @{ - @"$og_title": @"TestTitle", - @"$quantity": @(2), - @"$product_name": @"TestProduct", - @"$price": @(10) - } - ] - }; - - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; - NSDictionary *json = [factory dataForEventWithEventDictionary:[event mutableCopy]]; - XCTAssertNotNil(json); - - XCTAssertTrue([@"ADD_TO_CART" isEqualToString:[json objectForKey:@"name"]]); - - NSDictionary *contentItems = [json objectForKey:@"content_items"]; - XCTAssertNotNil(contentItems); - XCTAssertTrue(contentItems.count == 1); - - NSDictionary *userData = [json objectForKey:@"user_data"]; - XCTAssertNotNil(userData); - XCTAssertNotNil([userData objectForKey:@"idfv"]); - - XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); - XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); -} - -- (void)testDataForEventWithTwoContentItem { - NSDictionary *event = @{ - @"name": @"ADD_TO_CART", - @"content_items": @[ - @{ - @"$og_title": @"TestTitle1", - @"$quantity": @(2), - @"$product_name": @"TestProduct1", - @"$price": @(10) - }, - @{ - @"$og_title": @"TestTitle2", - @"$quantity": @(3), - @"$product_name": @"TestProduct2", - @"$price": @(20) - } - ] - }; - - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; - NSDictionary *json = [factory dataForEventWithEventDictionary:[event mutableCopy]]; - XCTAssertNotNil(json); - - XCTAssertTrue([@"ADD_TO_CART" isEqualToString:[json objectForKey:@"name"]]); - - NSDictionary *contentItems = [json objectForKey:@"content_items"]; - XCTAssertNotNil(contentItems); - XCTAssertTrue(contentItems.count == 2); - - NSDictionary *userData = [json objectForKey:@"user_data"]; - XCTAssertNotNil(userData); - XCTAssertNotNil([userData objectForKey:@"idfv"]); - - XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); - XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); -} - -- (void)testDataForEventEmpty { - NSDictionary *event = @{}; - - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; - NSDictionary *json = [factory dataForEventWithEventDictionary:[event mutableCopy]]; - XCTAssertNotNil(json); - - XCTAssertNil([json objectForKey:@"name"]); - - NSDictionary *userData = [json objectForKey:@"user_data"]; - XCTAssertNotNil(userData); - XCTAssertNotNil([userData objectForKey:@"idfv"]); - - XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); - XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); -} - -- (void)testDataForEventNil { - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; - NSDictionary *json = [factory dataForEventWithEventDictionary:nil]; - XCTAssertNotNil(json); - - XCTAssertNil([json objectForKey:@"name"]); - - NSDictionary *userData = [json objectForKey:@"user_data"]; - XCTAssertNotNil(userData); - XCTAssertNotNil([userData objectForKey:@"idfv"]); - - XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); - XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); -} - - -- (void)testDataForShortURL { - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; - NSDictionary *json = [factory dataForShortURLWithLinkDataDictionary:@{}.mutableCopy isSpotlightRequest:NO]; - XCTAssertNotNil(json); - - XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); - XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); -} - -- (void)testDataForLATD { - BNCRequestFactory *factory = [[BNCRequestFactory alloc] initWithBranchKey:@"key_abcd" UUID:self.requestUUID TimeStamp:self.requestCreationTimeStamp]; - NSDictionary *json = [factory dataForLATDWithDataDictionary:@{}.mutableCopy]; - XCTAssertNotNil(json); - - XCTAssertTrue(self.requestCreationTimeStamp == [json objectForKey:BRANCH_REQUEST_KEY_REQUEST_CREATION_TIME_STAMP]); - XCTAssertTrue([self.requestUUID isEqualToString:[json objectForKey:BRANCH_REQUEST_KEY_REQUEST_UUID]]); -} - -@end diff --git a/BranchSDKTests/BNCSKAdNetworkTests.m b/BranchSDKTests/BNCSKAdNetworkTests.m deleted file mode 100644 index d71cf203a..000000000 --- a/BranchSDKTests/BNCSKAdNetworkTests.m +++ /dev/null @@ -1,264 +0,0 @@ -// -// BNCSKAdNetworkTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 8/13/20. -// Copyright © 2020 Branch, Inc. All rights reserved. -// - -#import -#import "BNCSKAdNetwork.h" -#import "BranchEvent.h" - -// Expose private methods for testing -@interface BNCSKAdNetwork() - -@property (nonatomic, copy, readwrite) NSDate *installDate; - -- (BOOL)shouldAttemptSKAdNetworkCallout; - -@end - -@interface BranchEvent() - -// private BranchEvent methods used to check data before sending to network service. -- (NSDictionary *)buildEventDictionary; -- (BranchEventRequest *)buildRequestWithEventDictionary:(NSDictionary *)eventDictionary; - -@end - - -@interface BNCSKAdNetworkTests : XCTestCase - -@property (nonatomic, strong, readwrite) BNCSKAdNetwork *skAdNetwork; - -@end - -@implementation BNCSKAdNetworkTests - -- (void)setUp { - self.skAdNetwork = [BNCSKAdNetwork new]; - self.skAdNetwork.installDate = [NSDate date]; -} - -- (void)tearDown { - -} - -- (void)testDefaultMaxTimeout { - NSTimeInterval days; - if (@available(iOS 16.1, macCatalyst 16.1, *)) { - days = 3600.0 * 24.0 * 60.0; // one day - } else { - days = 3600.0 * 24.0; // one day - } - XCTAssertTrue(self.skAdNetwork.maxTimeSinceInstall == days); -} - -- (void)testShouldAttemptSKAdNetworkCallout { - XCTAssertTrue([self.skAdNetwork shouldAttemptSKAdNetworkCallout]); -} - -- (void)testShouldAttemptSKAdNetworkCalloutFalse { - self.skAdNetwork.maxTimeSinceInstall = 0.0; - XCTAssertFalse([self.skAdNetwork shouldAttemptSKAdNetworkCallout]); -} - -- (void)testPostbackCall { - - if (@available(iOS 16.1, macCatalyst 16.1, *)) { - self.skAdNetwork.maxTimeSinceInstall = 3600.0 * 24.0 * 60.0; - } else { - self.skAdNetwork.maxTimeSinceInstall = 3600.0 * 24.0; // one day - } - - XCTAssertTrue([self.skAdNetwork shouldAttemptSKAdNetworkCallout]); - - [[BNCSKAdNetwork sharedInstance] registerAppForAdNetworkAttribution]; - - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventInvite]; - NSDictionary *eventDictionary = [event buildEventDictionary]; - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - - XCTestExpectation *expectation = [self expectationWithDescription:@"TestPostback"]; - BNCServerResponse *openInstallResponse = [[BNCServerResponse alloc] init]; - - openInstallResponse.data = @{ @"update_conversion_value": @60 }; - request.completion = ^(NSDictionary*_Nullable response, NSError*_Nullable error){ - [expectation fulfill]; - }; - [request processResponse:openInstallResponse error:Nil]; - - [self waitForExpectationsWithTimeout:5.0 handler:nil]; -} - -- (void)testSKAN4ParamsDefaultValues { - - if (@available(iOS 16.1, macCatalyst 16.1, *)) { - NSString *coarseValue = [[BNCSKAdNetwork sharedInstance] getCoarseConversionValueFromDataResponse:@{}]; - XCTAssertTrue([coarseValue isEqualToString:@"low"]); - - BOOL isLocked = [[BNCSKAdNetwork sharedInstance] getLockedStatusFromDataResponse:@{}]; - XCTAssertFalse(isLocked); - - BOOL ascendingOnly = [[BNCSKAdNetwork sharedInstance] getAscendingOnlyFromDataResponse:@{}]; - XCTAssertTrue(ascendingOnly); - } -} - -- (void)testSKAN4ParamsValues { - - if (@available(iOS 16.1, macCatalyst 16.1, *)) { - - NSDictionary *response = @{@"update_conversion_value": @16, @"coarse_key": @"high", @"locked": @YES, @"ascending_only":@NO }; - BNCSKAdNetwork *adNetwork = [BNCSKAdNetwork sharedInstance]; - - NSString *coarseValue = [adNetwork getCoarseConversionValueFromDataResponse:response]; - XCTAssertTrue([coarseValue isEqualToString:@"high"]); - - BOOL isLocked = [adNetwork getLockedStatusFromDataResponse:response]; - XCTAssertTrue(isLocked); - - BOOL ascendingOnly = [adNetwork getAscendingOnlyFromDataResponse:response]; - XCTAssertFalse(ascendingOnly); - } -} - -- (void)testSKAN4CurrentWindow { - - BNCSKAdNetwork *adNetwork = [BNCSKAdNetwork sharedInstance]; - BNCPreferenceHelper *prefs = [BNCPreferenceHelper sharedInstance]; - - NSDate *currentDateAndTime = [NSDate date]; - prefs.firstAppLaunchTime = [currentDateAndTime dateByAddingTimeInterval:-30]; - NSInteger win = [adNetwork calculateSKANWindowForTime:currentDateAndTime]; - XCTAssertTrue(win == 1); - - win = [adNetwork calculateSKANWindowForTime: [ currentDateAndTime dateByAddingTimeInterval:24*3600*3 ]]; - XCTAssertTrue(win == 2); - - win = [adNetwork calculateSKANWindowForTime: [ currentDateAndTime dateByAddingTimeInterval:24*3600*10 ]]; - XCTAssertTrue(win == 3); - - win = [adNetwork calculateSKANWindowForTime: [ currentDateAndTime dateByAddingTimeInterval:24*3600*36 ]]; - XCTAssertTrue(win == 0); - - prefs.firstAppLaunchTime = nil; - [prefs synchronize]; - win = [adNetwork calculateSKANWindowForTime: currentDateAndTime]; - XCTAssertTrue(win == 0); -} - -- (void)testSKAN4HighestConversionValue { - - BNCSKAdNetwork *adNetwork = [BNCSKAdNetwork sharedInstance]; - BNCPreferenceHelper *prefs = [BNCPreferenceHelper sharedInstance]; - - prefs.highestConversionValueSent = 0; - prefs.skanCurrentWindow = 0; - NSDate *currentDateAndTime = [NSDate date]; - prefs.invokeRegisterApp = YES; - - prefs.firstAppLaunchTime = [currentDateAndTime dateByAddingTimeInterval:-30 ]; - [adNetwork shouldCallPostbackForDataResponse:@{}]; - XCTAssertTrue(prefs.highestConversionValueSent == 0); - - [adNetwork shouldCallPostbackForDataResponse:@{@"update_conversion_value": @6}]; - XCTAssertTrue(prefs.highestConversionValueSent == 6); - - [adNetwork shouldCallPostbackForDataResponse:@{@"update_conversion_value": @3}]; - XCTAssertTrue(prefs.highestConversionValueSent == 6); - - - prefs.firstAppLaunchTime = [currentDateAndTime dateByAddingTimeInterval:-24*3600*3 ]; - [adNetwork shouldCallPostbackForDataResponse:@{}]; - XCTAssertTrue(prefs.highestConversionValueSent == 0); -} - -- (void)testSKAN4ShouldCallPostback { - - BNCSKAdNetwork *adNetwork = [BNCSKAdNetwork sharedInstance]; - BNCPreferenceHelper *prefs = [BNCPreferenceHelper sharedInstance]; - - prefs.firstAppLaunchTime = nil; - [prefs synchronize]; - - NSDictionary *response = @{@"update_conversion_value": @16, @"coarse_key": @"high", @"locked": @YES, @"ascending_only":@NO }; - - BOOL shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; - XCTAssertFalse(shouldCall); - -} - -- (void)testSKAN4ShouldCallPostback2 { - - BNCSKAdNetwork *adNetwork = [BNCSKAdNetwork sharedInstance]; - BNCPreferenceHelper *prefs = [BNCPreferenceHelper sharedInstance]; - - prefs.invokeRegisterApp = YES; - prefs.highestConversionValueSent = 0; - prefs.firstAppLaunchTime = [NSDate date]; - prefs.skanCurrentWindow = 0; - [prefs synchronize]; - - NSMutableDictionary *response = [[NSMutableDictionary alloc] initWithDictionary: - @{@"update_conversion_value": @16, @"coarse_key": @"high", @"locked": @YES, @"ascending_only":@YES }]; - - BOOL shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; - XCTAssertTrue(shouldCall); - - shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; - XCTAssertFalse(shouldCall); - - response[@"update_conversion_value"] = @14; - shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; - XCTAssertFalse(shouldCall); - - response[@"update_conversion_value"] = @18; - shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; - XCTAssertTrue(shouldCall); - - prefs.firstAppLaunchTime = nil; - prefs.firstAppLaunchTime = [[NSDate date] dateByAddingTimeInterval:-24*3600*3]; - shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; - NSLog(@"Conv : %ld", prefs.highestConversionValueSent); - XCTAssertTrue(shouldCall); - - shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; - XCTAssertFalse(shouldCall); -} - -- (void)testSKAN4ShouldCallPostback3 { - BNCSKAdNetwork *adNetwork = [BNCSKAdNetwork sharedInstance]; - BNCPreferenceHelper *prefs = [BNCPreferenceHelper sharedInstance]; - - prefs.invokeRegisterApp = YES; - prefs.highestConversionValueSent = 0; - prefs.firstAppLaunchTime = [NSDate date]; - [prefs synchronize]; - - NSMutableDictionary *response = [[NSMutableDictionary alloc] initWithDictionary: - @{@"update_conversion_value": @16, @"coarse_key": @"high", @"locked": @YES, @"ascending_only":@NO }]; - - BOOL shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; - XCTAssertTrue(shouldCall); - - shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; - XCTAssertTrue(shouldCall); - - response[@"update_conversion_value"] = @14; - shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; - XCTAssertTrue(shouldCall); - - response[@"update_conversion_value"] = @18; - shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; - XCTAssertTrue(shouldCall); - - prefs.firstAppLaunchTime = [[NSDate date] dateByAddingTimeInterval:-24*3600*3]; - //NSLog(@"Conv : %ld", (long)prefs.highestConversionValueSent); - shouldCall = [adNetwork shouldCallPostbackForDataResponse:response]; - NSLog(@"Conv : %ld", prefs.highestConversionValueSent); - XCTAssertTrue(shouldCall); -} - -@end diff --git a/BranchSDKTests/BNCSystemObserverTests.m b/BranchSDKTests/BNCSystemObserverTests.m deleted file mode 100644 index 8cc54f632..000000000 --- a/BranchSDKTests/BNCSystemObserverTests.m +++ /dev/null @@ -1,139 +0,0 @@ -// -// BNCSystemObserverTests.m -// Branch-TestBed -// -// Created by Graham Mueller on 4/22/15. -// Copyright (c) 2015 Branch Metrics. All rights reserved. -// - -#import -#import "BNCSystemObserver.h" - -@interface BNCSystemObserver () -+ (BOOL)compareUriSchemes:(NSString *)serverUriScheme With:(NSArray *)urlTypes; -@end - -@interface BNCSystemObserverTests : XCTestCase - -@end - -@implementation BNCSystemObserverTests - -- (void)testDefaultURIScheme_TestBed { - //ND XCTAssert([[BNCSystemObserver defaultURIScheme] isEqualToString:@"branchtest"]); -} - -- (void)testAppVersion_TestBed { - XCTAssert([[BNCSystemObserver applicationVersion] isEqualToString:@"1.0"]); -} - -- (void)testBundleIdentifier_TestBed { - NSString *bundleId = [BNCSystemObserver bundleIdentifier]; - XCTAssert([bundleId isEqualToString:@"branch.BranchSDKTestsHostApp"]); -} - -- (void)testBrand { - XCTAssert([[BNCSystemObserver brand] isEqualToString:@"Apple"]); -} - -- (void)testModel_Simulator { - // simulator models - NSString *tmp = [BNCSystemObserver model]; - XCTAssert([tmp containsString:@"arm64"] || [tmp containsString:@"x86_64"]); -} - -//- (void)testModelName_iPhone7 { -// XCTAssert([@"iPhone9,3" isEqualToString:[BNCSystemObserver model]]); -//} - -- (void)testOSName { - XCTAssertNotNil([BNCSystemObserver osName]); - - // This is not the system name, but rather the name Branch server expects - // XCTAssert([self.deviceInfo.osName isEqualToString:[UIDevice currentDevice].systemName]); - XCTAssert([@"iOS" isEqualToString:[BNCSystemObserver osName]] || [@"tv_OS" isEqualToString:[BNCSystemObserver osName]]); -} - -- (void)testOSVersion { - XCTAssertNotNil([BNCSystemObserver osVersion]); - XCTAssert([[BNCSystemObserver osVersion] isEqualToString:[UIDevice currentDevice].systemVersion]); -} - -/* - * Sample device screens - * original iPhone 320x480 1 - * iPad Pro (6th gen 12.9") 2048x2732 2 - * iPhone 14 Pro max 1290x2796 3 - */ - -- (void)testScreenWidth { - XCTAssert([BNCSystemObserver screenWidth].intValue >= 320 && [BNCSystemObserver screenWidth].intValue <= 2796); -} - -- (void)testScreenHeight { - XCTAssert([BNCSystemObserver screenHeight].intValue >= 320 && [BNCSystemObserver screenWidth].intValue <= 2796); -} - -- (void)testScreenScale { - XCTAssert([BNCSystemObserver screenScale].intValue >= 1 && [BNCSystemObserver screenScale].intValue <= 3); -} - -- (void)testIsSimulator_Simulator { - XCTAssert([BNCSystemObserver isSimulator]); -} - -- (void)testAdvertiserIdentifier_NoATTPrompt { - XCTAssertNil([BNCSystemObserver advertiserIdentifier]); -} - -- (void)testOptedInStatus_NoATTPrompt { - XCTAssert([[BNCSystemObserver attOptedInStatus] isEqualToString:@"not_determined"]); -} - -- (void)testAppleAttributionToken_Simulator { - NSString *token = [BNCSystemObserver appleAttributionToken]; - XCTAssertNil(token); -} - -- (void)testEnvironment { - // currently not running unit tests on extensions - XCTAssert([@"FULL_APP" isEqualToString:[BNCSystemObserver environment]]); -} - -- (void)testIsAppClip { - // currently not running unit tests on extensions - XCTAssert(![BNCSystemObserver isAppClip]); -} - -- (void)testCompareURIScemes { - - NSString *serverUriScheme = @"bnctest://"; - NSArray *urlTypes = @[@{@"CFBundleURLSchemes" : @[@""]}, @{@"CFBundleURLSchemes" : @[@"bnctest", @"xyzs"]}]; - - XCTAssertTrue([BNCSystemObserver compareUriSchemes:serverUriScheme With:urlTypes]); - - XCTAssertFalse([BNCSystemObserver compareUriSchemes:serverUriScheme With:nil]); - - XCTAssertFalse([BNCSystemObserver compareUriSchemes:nil With:nil]); - - XCTAssertFalse([BNCSystemObserver compareUriSchemes:nil With:urlTypes]); - - serverUriScheme = @":/"; - XCTAssertFalse([BNCSystemObserver compareUriSchemes:serverUriScheme With:urlTypes]); - - serverUriScheme = @"bnctest"; - XCTAssertTrue([BNCSystemObserver compareUriSchemes:serverUriScheme With:urlTypes]); - - serverUriScheme = @"bnctest://"; - urlTypes = @[ @{@"CFBundleURLSchemes" : @[@"bnctestX", @"xyzs"]}]; - XCTAssertFalse([BNCSystemObserver compareUriSchemes:serverUriScheme With:urlTypes]); - - serverUriScheme = @"://"; - XCTAssertFalse([BNCSystemObserver compareUriSchemes:serverUriScheme With:urlTypes]); - - XCTAssertFalse([BNCSystemObserver compareUriSchemes:@"" With:urlTypes]); - - XCTAssertFalse([BNCSystemObserver compareUriSchemes:@"" With:@[@{}]]); -} - -@end diff --git a/BranchSDKTests/BNCURLFilterSkiplistUpgradeTests.m b/BranchSDKTests/BNCURLFilterSkiplistUpgradeTests.m deleted file mode 100644 index ad7d5b029..000000000 --- a/BranchSDKTests/BNCURLFilterSkiplistUpgradeTests.m +++ /dev/null @@ -1,273 +0,0 @@ -// -// BNCURLFilterSkiplistUpgradeTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 4/4/23. -// Copyright © 2023 Branch, Inc. All rights reserved. -// - -#import -#import "BNCURLFilter.h" - -@interface BNCURLFilterSkiplistUpgradeTests : XCTestCase - -@end - -@implementation BNCURLFilterSkiplistUpgradeTests - -- (void)setUp { - -} - -- (void)tearDown { - -} - - // v0 list - // https://cdn.branch.io/sdk/uriskiplist_v0.json -- (NSArray *)v0PatternList { - NSArray *patternList = @[ - @"^fb\\d+:", - @"^li\\d+:", - @"^pdk\\d+:", - @"^twitterkit-.*:", - @"^com\\.googleusercontent\\.apps\\.\\d+-.*:\\/oauth", - @"^(?i)(?!(http|https):).*(:|:.*\\b)(password|o?auth|o?auth.?token|access|access.?token)\\b", - @"^(?i)((http|https):\\/\\/).*[\\/|?|#].*\\b(password|o?auth|o?auth.?token|access|access.?token)\\b" - ]; - return patternList; -} - -// v1 list -// https://cdn.branch.io/sdk/uriskiplist_v1.json -- (NSArray *)v1PatternList { - NSArray *patternList = @[ - @"^fb\\d+:", - @"^li\\d+:", - @"^pdk\\d+:", - @"^twitterkit-.*:", - @"^com\\.googleusercontent\\.apps\\.\\d+-.*:\\/oauth", - @"^(?i)(?!(http|https):).*(:|:.*\\b)(password|o?auth|o?auth.?token|access|access.?token)\\b", - @"^(?i)((http|https):\\/\\/).*[\\/|?|#].*\\b(password|o?auth|o?auth.?token|access|access.?token)\\b" - ]; - return patternList; -} - -// v2 list -// https://cdn.branch.io/sdk/uriskiplist_v2.json -- (NSArray *)v2PatternList { - NSArray *patternList = @[ - @"^fb\\d+:((?!campaign_ids).)*$", - @"^li\\d+:", - @"^pdk\\d+:", - @"^twitterkit-.*:", - @"^com\\.googleusercontent\\.apps\\.\\d+-.*:\\/oauth", - @"^(?i)(?!(http|https):).*(:|:.*\\b)(password|o?auth|o?auth.?token|access|access.?token)\\b", - @"^(?i)((http|https):\\/\\/).*[\\/|?|#].*\\b(password|o?auth|o?auth.?token|access|access.?token)\\b" - ]; - return patternList; -} - -- (BNCURLFilter *)filterWithV0List { - BNCURLFilter *filter = [BNCURLFilter new]; - [self migrateFilter:filter patternList:[self v1PatternList]]; - return filter; -} - -- (BNCURLFilter *)filterWithV1List { - BNCURLFilter *filter = [BNCURLFilter new]; - [self migrateFilter:filter patternList:[self v1PatternList]]; - return filter; -} - -- (BNCURLFilter *)filterWithV2List { - BNCURLFilter *filter = [BNCURLFilter new]; - [self migrateFilter:filter patternList:[self v2PatternList]]; - return filter; -} - -- (void)migrateFilter:(BNCURLFilter *)filter patternList:(NSArray *)patternList { - [filter useCustomPatternList:patternList]; -} - -- (NSArray *)badURLs { - NSArray *kBadURLs = @[ - @"fb123456:login/464646", - @"twitterkit-.4545:", - @"shsh:oauth/login", - @"https://myapp.app.link/oauth_token=fred", - @"https://myapp.app.link/auth_token=fred", - @"https://myapp.app.link/authtoken=fred", - @"https://myapp.app.link/auth=fred", - @"fb1234:", - @"fb1234:/", - @"fb1234:/this-is-some-extra-info/?whatever", - @"fb1234:/this-is-some-extra-info/?whatever:andstuff", - @"myscheme:path/to/resource?oauth=747474", - @"myscheme:oauth=747474", - @"myscheme:/oauth=747474", - @"myscheme://oauth=747474", - @"myscheme://path/oauth=747474", - @"myscheme://path/:oauth=747474", - @"https://google.com/userprofile/devonbanks=oauth?", - ]; - return kBadURLs; -} - -- (NSArray *)goodURLs { - NSArray *kGoodURLs = @[ - @"shshs:/content/path", - @"shshs:content/path", - @"https://myapp.app.link/12345/link", - @"fb123x:/", - @"https://myapp.app.link?authentic=true&tokemonsta=false", - @"myscheme://path/brauth=747474", - ]; - return kGoodURLs; -} - -- (void)testOldBadURLsWithV0 { - BNCURLFilter *filter = [self filterWithV0List]; - NSArray *list = [self badURLs]; - for (NSString *string in list) { - NSURL *url = [NSURL URLWithString:string]; - if (url) { - XCTAssertTrue([filter shouldIgnoreURL:url], @"Checking '%@'.", url); - } - } -} - -- (void)testOldGoodURLsWithV0 { - BNCURLFilter *filter = [self filterWithV0List]; - NSArray *list = [self goodURLs]; - for (NSString *string in list) { - NSURL *url = [NSURL URLWithString:string]; - if (url) { - XCTAssertFalse([filter shouldIgnoreURL:url], @"Checking '%@'.", url); - } - } -} - -- (void)testOldBadURLsWithV2 { - BNCURLFilter *filter = [self filterWithV2List]; - NSArray *list = [self badURLs]; - for (NSString *string in list) { - NSURL *url = [NSURL URLWithString:string]; - if (url) { - XCTAssertTrue([filter shouldIgnoreURL:url], @"Checking '%@'.", url); - } - } -} - -- (void)testOldGoodURLsWithV2 { - BNCURLFilter *filter = [self filterWithV2List]; - NSArray *list = [self goodURLs]; - for (NSString *string in list) { - NSURL *url = [NSURL URLWithString:string]; - if (url) { - XCTAssertFalse([filter shouldIgnoreURL:url], @"Checking '%@'.", url); - } - } -} - -- (void)testMetaAEMWithV0 { - NSString *string = @"fb1://?campaign_ids=a"; - NSURL *url = [NSURL URLWithString:string]; - if (url) { - BNCURLFilter *filter = [self filterWithV0List]; - XCTAssertTrue([filter shouldIgnoreURL:url]); - } -} - -- (void)testMetaAEMWithV2 { - NSString *string = @"fb1://?campaign_ids=a"; - NSURL *url = [NSURL URLWithString:string]; - if (url) { - BNCURLFilter *filter = [self filterWithV2List]; - XCTAssertFalse([filter shouldIgnoreURL:url]); - } -} - -- (void)testMetaAEMWithV2WithTrailingParameters { - NSString *string = @"fb1://?campaign_ids=a&token=abcde"; - NSURL *url = [NSURL URLWithString:string]; - if (url) { - BNCURLFilter *filter = [self filterWithV2List]; - XCTAssertFalse([filter shouldIgnoreURL:url]); - } -} - -- (void)testMetaAEMWithV2WithPrecedingParameters { - NSString *string = @"fb1://?brand=abcde&campaign_ids=a"; - NSURL *url = [NSURL URLWithString:string]; - if (url) { - BNCURLFilter *filter = [self filterWithV2List]; - XCTAssertFalse([filter shouldIgnoreURL:url]); - } -} - -- (void)testMetaAEMWithV2WithPrecedingAndTrailingParameters { - NSString *string = @"fb1://?brand=abcde&campaign_ids=a&link=12345"; - NSURL *url = [NSURL URLWithString:string]; - if (url) { - BNCURLFilter *filter = [self filterWithV2List]; - XCTAssertFalse([filter shouldIgnoreURL:url]); - } -} - -- (void)testSampleMetaAEMWithV0 { - NSString *string = @"fb123456789://products/next?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D"; - NSURL *url = [NSURL URLWithString:string]; - if (url) { - BNCURLFilter *filter = [self filterWithV0List]; - XCTAssertTrue([filter shouldIgnoreURL:url]); - } -} - -- (void)testSampleMetaAEMWithV1 { - NSString *string = @"fb123456789://products/next?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D"; - NSURL *url = [NSURL URLWithString:string]; - if (url) { - BNCURLFilter *filter = [self filterWithV1List]; - XCTAssertTrue([filter shouldIgnoreURL:url]); - } -} - -// This one is not filtered! -- (void)testSampleMetaAEMWithV2 { - NSString *string = @"fb123456789://products/next?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D"; - NSURL *url = [NSURL URLWithString:string]; - if (url) { - BNCURLFilter *filter = [self filterWithV2List]; - XCTAssertFalse([filter shouldIgnoreURL:url]); - } -} - -- (void)testSampleMetaAEMNoCampignIDsWithV0 { - NSString *string = @"fb123456789://products/next?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22test_deeplink%22%3A1%7D"; - NSURL *url = [NSURL URLWithString:string]; - if (url) { - BNCURLFilter *filter = [self filterWithV0List]; - XCTAssertTrue([filter shouldIgnoreURL:url]); - } -} - -- (void)testSampleMetaAEMNoCampignIDsWithV1 { - NSString *string = @"fb123456789://products/next?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22test_deeplink%22%3A1%7D"; - NSURL *url = [NSURL URLWithString:string]; - if (url) { - BNCURLFilter *filter = [self filterWithV1List]; - XCTAssertTrue([filter shouldIgnoreURL:url]); - } -} - -- (void)testSampleMetaAEMNoCampignIDsWithV2 { - NSString *string = @"fb123456789://products/next?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22test_deeplink%22%3A1%7D"; - NSURL *url = [NSURL URLWithString:string]; - if (url) { - BNCURLFilter *filter = [self filterWithV2List]; - XCTAssertTrue([filter shouldIgnoreURL:url]); - } -} - -@end diff --git a/BranchSDKTests/BNCURLFilterTests.m b/BranchSDKTests/BNCURLFilterTests.m deleted file mode 100644 index 1573bc36e..000000000 --- a/BranchSDKTests/BNCURLFilterTests.m +++ /dev/null @@ -1,168 +0,0 @@ -/** - @file BNCURLFilterTests.m - @package Branch-SDK-Tests - @brief BNCURLFilter tests. - - @author Edward Smith - @date February 14, 2018 - @copyright Copyright © 2018 Branch. All rights reserved. -*/ - -#import -#import "BNCURLFilter.h" - -@interface BNCURLFilterTests : XCTestCase -@end - -@implementation BNCURLFilterTests - -- (void)setUp { - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -- (void)testPatternMatchingURL_nil { - BNCURLFilter *filter = [BNCURLFilter new]; - NSURL *url = nil; - NSString *matchingRegex = [filter patternMatchingURL:url]; - XCTAssertNil(matchingRegex); -} - -- (void)testPatternMatchingURL_emptyString { - BNCURLFilter *filter = [BNCURLFilter new]; - NSURL *url = [NSURL URLWithString:@""]; - NSString *matchingRegex = [filter patternMatchingURL:url]; - XCTAssertNil(matchingRegex); -} - -- (void)testPatternMatchingURL_fbRegexMatches { - NSString *pattern = @"^fb\\d+:((?!campaign_ids).)*$"; - NSString *sampleURL = @"fb12345://"; - - BNCURLFilter *filter = [BNCURLFilter new]; - NSURL *url = [NSURL URLWithString:sampleURL]; - NSString *matchingRegex = [filter patternMatchingURL:url]; - XCTAssertTrue([pattern isEqualToString:matchingRegex]); -} - -- (void)testPatternMatchingURL_fbRegexDoesNotMatch { - NSString *pattern = @"^fb\\d+:((?!campaign_ids).)*$"; - NSString *sampleURL = @"fb12345://campaign_ids"; - - BNCURLFilter *filter = [BNCURLFilter new]; - NSURL *url = [NSURL URLWithString:sampleURL]; - NSString *matchingRegex = [filter patternMatchingURL:url]; - XCTAssertFalse([pattern isEqualToString:matchingRegex]); -} - - -- (void)testIgnoredSuspectedAuthURLs { - NSArray *urls = @[ - @"fb123456:login/464646", - @"shsh:oauth/login", - @"https://myapp.app.link/oauth_token=fred", - @"https://myapp.app.link/auth_token=fred", - @"https://myapp.app.link/authtoken=fred", - @"https://myapp.app.link/auth=fred", - @"myscheme:path/to/resource?oauth=747474", - @"myscheme:oauth=747474", - @"myscheme:/oauth=747474", - @"myscheme://oauth=747474", - @"myscheme://path/oauth=747474", - @"myscheme://path/:oauth=747474", - @"https://google.com/userprofile/devonbanks=oauth?" - ]; - - BNCURLFilter *filter = [BNCURLFilter new]; - for (NSString *string in urls) { - NSURL *URL = [NSURL URLWithString:string]; - XCTAssertTrue([filter shouldIgnoreURL:URL], @"Checking '%@'.", URL); - } -} - -- (void)testAllowedURLsSimilarToAuthURLs { - NSArray *urls = @[ - @"shshs:/content/path", - @"shshs:content/path", - @"https://myapp.app.link/12345/link", - @"https://myapp.app.link?authentic=true&tokemonsta=false", - @"myscheme://path/brauth=747474" - ]; - - BNCURLFilter *filter = [BNCURLFilter new]; - for (NSString *string in urls) { - NSURL *URL = [NSURL URLWithString:string]; - XCTAssertFalse([filter shouldIgnoreURL:URL], @"Checking '%@'", URL); - } -} - -- (void)testIgnoredFacebookURLs { - // Most FB URIs are ignored - NSArray *urls = @[ - @"fb123456://login/464646", - @"fb1234:", - @"fb1234:/", - @"fb1234:/this-is-some-extra-info/?whatever", - @"fb1234:/this-is-some-extra-info/?whatever:andstuff" - ]; - - BNCURLFilter *filter = [BNCURLFilter new]; - for (NSString *string in urls) { - NSURL *URL = [NSURL URLWithString:string]; - XCTAssertTrue([filter shouldIgnoreURL:URL], @"Checking '%@'.", URL); - } -} - -- (void)testAllowedFacebookURLs { - NSArray *urls = @[ - // Facebook URIs do not contain letters other than an fb prefix - @"fb123x://", - // FB URIs with campaign ids are allowed - @"fb1234://helloworld?al_applink_data=%7B%22target_url%22%3A%22http%3A%5C%2F%5C%2Fitunes.apple.com%5C%2Fapp%5C%2Fid880047117%22%2C%22extras%22%3A%7B%22fb_app_id%22%3A2020399148181142%7D%2C%22referer_app_link%22%3A%7B%22url%22%3A%22fb%3A%5C%2F%5C%2F%5C%2F%3Fapp_id%3D2020399148181142%22%2C%22app_name%22%3A%22Facebook%22%7D%2C%22acs_token%22%3A%22debuggingtoken%22%2C%22campaign_ids%22%3A%22ARFUlbyOurYrHT2DsknR7VksCSgN4tiH8TzG8RIvVoUQoYog5bVCvADGJil5kFQC6tQm-fFJQH0w8wCi3NbOmEHHrtgCNglkXNY-bECEL0aUhj908hIxnBB0tchJCqwxHjorOUqyk2v4bTF75PyWvxOksZ6uTzBmr7wJq8XnOav0bA%22%2C%22test_deeplink%22%3A1%7D" - ]; - - BNCURLFilter *filter = [BNCURLFilter new]; - for (NSString *string in urls) { - NSURL *URL = [NSURL URLWithString:string]; - XCTAssertFalse([filter shouldIgnoreURL:URL], @"Checking '%@'", URL); - } -} - -- (void)testCustomPatternList { - BNCURLFilter *filter = [BNCURLFilter new]; - - // sanity check default pattern list - XCTAssertTrue([filter shouldIgnoreURL:[NSURL URLWithString:@"fb123://"]]); - XCTAssertFalse([filter shouldIgnoreURL:[NSURL URLWithString:@"branch123://"]]); - - // confirm new pattern list is enforced - [filter useCustomPatternList:@[@"^branch\\d+:"]]; - XCTAssertFalse([filter shouldIgnoreURL:[NSURL URLWithString:@"fb123://"]]); - XCTAssertTrue([filter shouldIgnoreURL:[NSURL URLWithString:@"branch123://"]]); -} - -// This is an end to end test and relies on a server call -- (void)testUpdatePatternListFromServer { - BNCURLFilter *filter = [BNCURLFilter new]; - - // confirm new pattern list is enforced - [filter useCustomPatternList:@[@"^branch\\d+:"]]; - XCTAssertFalse([filter shouldIgnoreURL:[NSURL URLWithString:@"fb123://"]]); - XCTAssertTrue([filter shouldIgnoreURL:[NSURL URLWithString:@"branch123://"]]); - - __block XCTestExpectation *expectation = [self expectationWithDescription:@"List updated"]; - [filter updatePatternListFromServerWithCompletion:^{ - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:5.0 handler:^(NSError * _Nullable error) { }]; - - // the retrieved list should match default pattern list - XCTAssertTrue([filter shouldIgnoreURL:[NSURL URLWithString:@"fb123://"]]); - XCTAssertFalse([filter shouldIgnoreURL:[NSURL URLWithString:@"branch123://"]]); -} - -@end diff --git a/BranchSDKTests/BNCUserAgentCollectorTests.m b/BranchSDKTests/BNCUserAgentCollectorTests.m deleted file mode 100644 index e54cca1bc..000000000 --- a/BranchSDKTests/BNCUserAgentCollectorTests.m +++ /dev/null @@ -1,111 +0,0 @@ -// -// BNCUserAgentCollectorTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 8/29/19. -// Copyright © 2019 Branch, Inc. All rights reserved. -// - -#import -#import "BNCPreferenceHelper.h" -#import "BNCDeviceSystem.h" -#import "BNCUserAgentCollector.h" - -// expose private methods for unit testing -@interface BNCUserAgentCollector() - -- (NSString *)loadUserAgentForSystemBuildVersion:(NSString *)systemBuildVersion; -- (void)saveUserAgent:(NSString *)userAgent forSystemBuildVersion:(NSString *)systemBuildVersion; -- (void)collectUserAgentWithCompletion:(void (^)(NSString * _Nullable userAgent))completion; - -@end - -@interface BNCUserAgentCollectorTests : XCTestCase - -@end - -@implementation BNCUserAgentCollectorTests - -+ (void)setUp { - [BNCUserAgentCollectorTests resetPersistentData]; -} - -- (void)setUp { - -} - -- (void)tearDown { - [BNCUserAgentCollectorTests resetPersistentData]; -} - -+ (void)resetPersistentData { - BNCPreferenceHelper *preferences = [BNCPreferenceHelper sharedInstance]; - preferences.browserUserAgentString = nil; - preferences.lastSystemBuildVersion = nil; -} - -- (void)testResetPersistentData { - BNCPreferenceHelper *preferences = [BNCPreferenceHelper sharedInstance]; - XCTAssertNil(preferences.browserUserAgentString); - XCTAssertNil(preferences.lastSystemBuildVersion); -} - -- (void)testSaveAndLoadUserAgent { - NSString *systemBuildVersion = @"test"; - NSString *userAgent = @"UserAgent"; - - BNCUserAgentCollector *collector = [BNCUserAgentCollector new]; - [collector saveUserAgent:userAgent forSystemBuildVersion:systemBuildVersion]; - NSString *expected = [collector loadUserAgentForSystemBuildVersion:systemBuildVersion]; - XCTAssertTrue([userAgent isEqualToString:expected]); -} - -- (void)testCollectUserAgent { - XCTestExpectation *expectation = [self expectationWithDescription:@"expectation"]; - - BNCUserAgentCollector *collector = [BNCUserAgentCollector new]; - [collector collectUserAgentWithCompletion:^(NSString * _Nullable userAgent) { - XCTAssertNotNil(userAgent); - XCTAssertTrue([userAgent containsString:@"AppleWebKit"]); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:4.0 handler:^(NSError * _Nullable error) { - - }]; -} - -- (void)testLoadUserAgent_EmptyDataStore { - XCTestExpectation *expectation = [self expectationWithDescription:@"expectation"]; - - BNCUserAgentCollector *collector = [BNCUserAgentCollector new]; - [collector loadUserAgentWithCompletion:^(NSString * _Nullable userAgent) { - XCTAssertNotNil(userAgent); - XCTAssertTrue([userAgent containsString:@"AppleWebKit"]); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:2.0 handler:^(NSError * _Nullable error) { - - }]; -} - -- (void)testLoadUserAgent_FilledDataStore { - XCTestExpectation *expectation = [self expectationWithDescription:@"expectation"]; - NSString *savedUserAgent = @"UserAgent"; - - BNCUserAgentCollector *collector = [BNCUserAgentCollector new]; - [collector saveUserAgent:savedUserAgent forSystemBuildVersion:[BNCDeviceSystem new].systemBuildVersion]; - [collector loadUserAgentWithCompletion:^(NSString * _Nullable userAgent) { - XCTAssertNotNil(userAgent); - XCTAssertTrue([userAgent isEqualToString:savedUserAgent]); - XCTAssertFalse([userAgent containsString:@"AppleWebKit"]); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:2.0 handler:^(NSError * _Nullable error) { - - }]; -} - -@end diff --git a/BranchSDKTests/Branch-SDK-Tests-Bridging-Header.h b/BranchSDKTests/Branch-SDK-Tests-Bridging-Header.h deleted file mode 100644 index 169bd50f3..000000000 --- a/BranchSDKTests/Branch-SDK-Tests-Bridging-Header.h +++ /dev/null @@ -1,5 +0,0 @@ -// -// Module headers for Branch SDK unit testing. -// - -#import "Branch.h" diff --git a/BranchSDKTests/BranchActivityItemTests.m b/BranchSDKTests/BranchActivityItemTests.m deleted file mode 100644 index f117859f7..000000000 --- a/BranchSDKTests/BranchActivityItemTests.m +++ /dev/null @@ -1,39 +0,0 @@ -// -// BranchActivityItemTests.m -// Branch-SDK-Tests -// -// Created by Nipun Singh on 9/21/23. -// Copyright © 2023 Branch, Inc. All rights reserved. -// - -#import -#import "Branch.h" - -@interface BranchActivityItemTests: XCTestCase -@end - -@implementation BranchActivityItemTests - -// Rework this test, it's not reliable. -//- (void)testGetBranchActivityItemWithAllParams { -// NSDictionary *params = @{@"key": @"value"}; -// NSString *feature = @"feature4"; -// NSString *stage = @"stage3"; -// NSArray *tags = @[@"tag3", @"tag4"]; -// NSString *campaign = @"campaign1"; -// NSString *alias = [[NSUUID UUID] UUIDString]; -// BranchActivityItemProvider *provider = [Branch getBranchActivityItemWithParams:params feature:feature stage:stage campaign:campaign tags:tags alias:alias]; -// sleep(2000); -// if ([[provider item] isKindOfClass:[NSURL class]]) { -// NSURL *urlObject = (NSURL *)[provider item]; -// NSString *url = [urlObject absoluteString]; -// -// NSLog(@"Provider URL as String: %@", url); -// -// XCTAssertTrue([url isEqualToString:[@"https://bnctestbed.app.link/" stringByAppendingString:alias]]); -// } else { -// XCTFail("Provider Data is not of type NSURL"); -// } -//} - -@end diff --git a/BranchSDKTests/BranchClassTests.m b/BranchSDKTests/BranchClassTests.m deleted file mode 100644 index d1e7713f1..000000000 --- a/BranchSDKTests/BranchClassTests.m +++ /dev/null @@ -1,265 +0,0 @@ -// -// BranchClassTests.m -// Branch-SDK-Tests -// -// Created by Nipun Singh on 9/25/23. -// Copyright © 2023 Branch, Inc. All rights reserved. -// - -#import -#import "Branch.h" -#import "BranchConstants.h" -#import "BNCPasteboard.h" -#import "BNCAppGroupsData.h" -#import "BNCPartnerParameters.h" - -@interface BNCPreferenceHelper(Test) -// Expose internal private method to clear EEA data -- (void)writeObjectToDefaults:(NSString *)key value:(NSObject *)value; -@end - -@interface BranchClassTests : XCTestCase -@property (nonatomic, strong) Branch *branch; -@end - -@implementation BranchClassTests - -- (void)setUp { - [super setUp]; - self.branch = [Branch getInstance]; -} - -- (void)tearDown { - self.branch = nil; - [super tearDown]; -} - -- (void)testIsUserIdentified { - [self.branch setIdentity: @"userId"]; - XCTAssertTrue([self.branch isUserIdentified], @"User should be identified"); -} - -- (void)testDisableAdNetworkCallouts { - [self.branch disableAdNetworkCallouts:YES]; - XCTAssertTrue([BNCPreferenceHelper sharedInstance].disableAdNetworkCallouts, @"AdNetwork callouts should be disabled"); -} - -- (void)testSetNetworkTimeout { - [self.branch setNetworkTimeout:5.0]; - XCTAssertEqual([BNCPreferenceHelper sharedInstance].timeout, 5.0, @"Network timeout should be set to 5.0"); -} - -//- (void)testSetMaxRetries { -// [self.branch setMaxRetries:3]; -// XCTAssertEqual([BNCPreferenceHelper sharedInstance].retryCount, 3, @"Max retries should be set to 3"); -//} - -- (void)testSetRetryInterval { - [self.branch setRetryInterval:2.0]; - XCTAssertEqual([BNCPreferenceHelper sharedInstance].retryInterval, 2.0, @"Retry interval should be set to 2.0"); -} - -- (void)testSetRequestMetadataKeyAndValue { - [self.branch setRequestMetadataKey:@"key" value:@"value"]; - NSDictionary *metadata = [BNCPreferenceHelper sharedInstance].requestMetadataDictionary; - XCTAssertEqualObjects(metadata[@"key"], @"value"); -} - -- (void)testSetTrackingDisabled { - XCTAssertFalse([BNCPreferenceHelper sharedInstance].trackingDisabled); - - [Branch setTrackingDisabled:YES]; - XCTAssertTrue([BNCPreferenceHelper sharedInstance].trackingDisabled); - - [Branch setTrackingDisabled:NO]; - XCTAssertFalse([BNCPreferenceHelper sharedInstance].trackingDisabled); -} - -- (void)testCheckPasteboardOnInstall { - [self.branch checkPasteboardOnInstall]; - BOOL checkOnInstall = [BNCPasteboard sharedInstance].checkOnInstall; - XCTAssertTrue(checkOnInstall); -} - -- (void)testWillShowPasteboardToast_ShouldReturnYes { - [BNCPreferenceHelper sharedInstance].randomizedBundleToken = nil; - [BNCPasteboard sharedInstance].checkOnInstall = YES; - UIPasteboard.generalPasteboard.URL = [NSURL URLWithString:@"https://example.com"]; - - BOOL result = [self.branch willShowPasteboardToast]; - XCTAssertTrue(result); -} - -- (void)testWillShowPasteboardToast_ShouldReturnNo { - [BNCPreferenceHelper sharedInstance].randomizedBundleToken = @"some_token"; - [BNCPasteboard sharedInstance].checkOnInstall = NO; - - BOOL result = [self.branch willShowPasteboardToast]; - XCTAssertFalse(result); -} - -- (void)testSetAppClipAppGroup { - NSString *testAppGroup = @"testAppGroup"; - [self.branch setAppClipAppGroup:testAppGroup]; - NSString *actualAppGroup = [BNCAppGroupsData shared].appGroup; - - XCTAssertEqualObjects(testAppGroup, actualAppGroup); -} - -- (void)testClearPartnerParameters { - [self.branch addFacebookPartnerParameterWithName:@"ph" value:@"123456789"]; - [[BNCPartnerParameters shared] clearAllParameters]; - - NSDictionary *result = [[BNCPartnerParameters shared] parameterJson]; - XCTAssertEqual([result count], 0, @"Parameters should be empty after calling clearAllParameters"); -} - -- (void)testAddFacebookParameterWithName_Value { - [self.branch addFacebookPartnerParameterWithName:@"name" value:@"3D4F2BF07DC1BE38B20C653EE9A7E446158F84E525BBB98FEDF721CB5A40A346"]; - - NSDictionary *result = [[BNCPartnerParameters shared] parameterJson][@"fb"]; - XCTAssertEqualObjects(result[@"name"], @"3D4F2BF07DC1BE38B20C653EE9A7E446158F84E525BBB98FEDF721CB5A40A346", @"Should add parameter for Facebook"); -} - -- (void)testAddSnapParameterWithName_Value { - [self.branch addSnapPartnerParameterWithName:@"name" value:@"3D4F2BF07DC1BE38B20C653EE9A7E446158F84E525BBB98FEDF721CB5A40A346"]; - - NSDictionary *result = [[BNCPartnerParameters shared] parameterJson][@"snap"]; - XCTAssertEqualObjects(result[@"name"], @"3D4F2BF07DC1BE38B20C653EE9A7E446158F84E525BBB98FEDF721CB5A40A346", @"Should add parameter for Snap"); -} - -- (void)testGetFirstReferringBranchUniversalObject_ClickedBranchLink { - NSString *installParamsString = @"{\"$canonical_identifier\":\"content/12345\",\"$creation_timestamp\":1694557342247,\"$desktop_url\":\"https://example.com/home\",\"$og_description\":\"My Content Description\",\"$og_title\":\"My Content Title\",\"+click_timestamp\":1695749249,\"+clicked_branch_link\":1,\"+is_first_session\":1,\"+match_guaranteed\":1,\"custom\":\"data\",\"key1\":\"value1\",\"~campaign\":\"content 123 launch\",\"~channel\":\"facebook\",\"~creation_source\":3,\"~feature\":\"sharing\",\"~id\":1230269548213984984,\"~referring_link\":\"https://bnctestbed.app.link/uSPHktjO2Cb\"}"; - [[BNCPreferenceHelper sharedInstance] setInstallParams: installParamsString]; - - BranchUniversalObject *result = [self.branch getFirstReferringBranchUniversalObject];\ - XCTAssertNotNil(result); - XCTAssertEqualObjects(result.title, @"My Content Title"); - XCTAssertEqualObjects(result.canonicalIdentifier, @"content/12345"); -} - -- (void)testGetFirstReferringBranchUniversalObject_NotClickedBranchLink { - NSString *installParamsString = @"{\"+clicked_branch_link\":false,\"+is_first_session\":true}"; - [[BNCPreferenceHelper sharedInstance] setInstallParams: installParamsString]; - - BranchUniversalObject *result = [self.branch getFirstReferringBranchUniversalObject]; - XCTAssertNil(result); -} - -- (void)testGetFirstReferringBranchLinkProperties_ClickedBranchLink { - NSString *installParamsString = @"{\"+clicked_branch_link\":1,\"+is_first_session\":1,\"~campaign\":\"content 123 launch\"}"; - [[BNCPreferenceHelper sharedInstance] setInstallParams:installParamsString]; - - BranchLinkProperties *result = [self.branch getFirstReferringBranchLinkProperties]; - XCTAssertNotNil(result); - XCTAssertEqualObjects(result.campaign, @"content 123 launch"); -} - -- (void)testGetFirstReferringBranchLinkProperties_NotClickedBranchLink { - NSString *installParamsString = @"{\"+clicked_branch_link\":false,\"+is_first_session\":true}"; - [[BNCPreferenceHelper sharedInstance] setInstallParams:installParamsString]; - - BranchLinkProperties *result = [self.branch getFirstReferringBranchLinkProperties]; - XCTAssertNil(result); -} - -- (void)testGetFirstReferringParams { - NSString *installParamsString = @"{\"+clicked_branch_link\":true,\"+is_first_session\":true}"; - [[BNCPreferenceHelper sharedInstance] setInstallParams:installParamsString]; - - NSDictionary *result = [self.branch getFirstReferringParams]; - XCTAssertEqualObjects([result objectForKey:@"+clicked_branch_link"], @true); -} - -- (void)testGetLatestReferringParams { - NSString *sessionParamsString = @"{\"+clicked_branch_link\":true,\"+is_first_session\":false}"; - [[BNCPreferenceHelper sharedInstance] setSessionParams:sessionParamsString]; - - NSDictionary *result = [self.branch getLatestReferringParams]; - XCTAssertEqualObjects([result objectForKey:@"+clicked_branch_link"], @true); -} - -//- (void)testGetLatestReferringParamsSynchronous { -// NSString *sessionParamsString = @"{\"+clicked_branch_link\":true,\"+is_first_session\":false}"; -// [[BNCPreferenceHelper sharedInstance] setSessionParams:sessionParamsString]; -// -// NSDictionary *result = [self.branch getLatestReferringParamsSynchronous]; -// XCTAssertEqualObjects([result objectForKey:@"+clicked_branch_link"], @true); -//} - -- (void)testGetLatestReferringBranchUniversalObject_ClickedBranchLink { - NSString *sessionParamsString = @"{\"+clicked_branch_link\":1,\"+is_first_session\":false,\"$og_title\":\"My Latest Content\"}"; - [[BNCPreferenceHelper sharedInstance] setSessionParams:sessionParamsString]; - - BranchUniversalObject *result = [self.branch getLatestReferringBranchUniversalObject]; - XCTAssertNotNil(result); - XCTAssertEqualObjects(result.title, @"My Latest Content"); -} - -- (void)testGetLatestReferringBranchLinkProperties_ClickedBranchLink { - NSString *sessionParamsString = @"{\"+clicked_branch_link\":true,\"+is_first_session\":false,\"~campaign\":\"latest campaign\"}"; - [[BNCPreferenceHelper sharedInstance] setSessionParams:sessionParamsString]; - - BranchLinkProperties *result = [self.branch getLatestReferringBranchLinkProperties]; - XCTAssertNotNil(result); - XCTAssertEqualObjects(result.campaign, @"latest campaign"); -} - -- (void)testGetShortURL { - NSString *shortURL = [self.branch getShortURL]; - XCTAssertNotNil(shortURL, @"URL should not be nil"); - XCTAssertTrue([shortURL hasPrefix:@"https://"], @"URL should start with 'https://'"); -} - -- (void)testGetLongURLWithParamsAndChannelAndTagsAndFeatureAndStageAndAlias { - NSDictionary *params = @{@"key": @"value"}; - NSString *channel = @"channel1"; - NSArray *tags = @[@"tag1", @"tag2"]; - NSString *feature = @"feature1"; - NSString *stage = @"stage1"; - NSString *alias = @"alias1"; - - NSString *generatedURL = [self.branch getLongURLWithParams:params andChannel:channel andTags:tags andFeature:feature andStage:stage andAlias:alias]; - NSString *expectedURL = @"https://bnc.lt/a/key_live_hcnegAumkH7Kv18M8AOHhfgiohpXq5tB?tags=tag1&tags=tag2&alias=alias1&feature=feature1&stage=stage1&source=ios&data=eyJrZXkiOiJ2YWx1ZSJ9"; - - XCTAssertEqualObjects(generatedURL, expectedURL, @"URL should match the expected format"); -} - -- (void)testSetDMAParamsForEEA { - XCTAssertFalse([[BNCPreferenceHelper sharedInstance] eeaRegionInitialized]); - - [Branch setDMAParamsForEEA:FALSE AdPersonalizationConsent:TRUE AdUserDataUsageConsent:TRUE]; - XCTAssertTrue([[BNCPreferenceHelper sharedInstance] eeaRegionInitialized]); - XCTAssertFalse([BNCPreferenceHelper sharedInstance].eeaRegion); - XCTAssertTrue([BNCPreferenceHelper sharedInstance].adPersonalizationConsent); - XCTAssertTrue([BNCPreferenceHelper sharedInstance].adUserDataUsageConsent); - - // Manually clear values after testing - // By design, this API is meant to be set once and always set. However, in a test scenario it needs to be cleared. - [[BNCPreferenceHelper sharedInstance] writeObjectToDefaults:@"bnc_dma_eea" value:nil]; - [[BNCPreferenceHelper sharedInstance] writeObjectToDefaults:@"bnc_dma_ad_personalization" value:nil]; - [[BNCPreferenceHelper sharedInstance] writeObjectToDefaults:@"bnc_dma_ad_user_data" value:nil]; -} - -- (void)testSetConsumerProtectionAttributionLevel { - // Set to Reduced and check - Branch *branch = [Branch getInstance]; - [branch setConsumerProtectionAttributionLevel:BranchAttributionLevelReduced]; - XCTAssertEqual([BNCPreferenceHelper sharedInstance].attributionLevel, BranchAttributionLevelReduced); - - // Set to Minimal and check - [branch setConsumerProtectionAttributionLevel:BranchAttributionLevelMinimal]; - XCTAssertEqual([BNCPreferenceHelper sharedInstance].attributionLevel, BranchAttributionLevelMinimal); - - // Set to None and check - [branch setConsumerProtectionAttributionLevel:BranchAttributionLevelNone]; - XCTAssertEqual([BNCPreferenceHelper sharedInstance].attributionLevel, BranchAttributionLevelNone); - - // Set to Full and check - [branch setConsumerProtectionAttributionLevel:BranchAttributionLevelFull]; - XCTAssertEqual([BNCPreferenceHelper sharedInstance].attributionLevel, BranchAttributionLevelFull); - -} - - -@end diff --git a/BranchSDKTests/BranchConfigurationControllerTests.m b/BranchSDKTests/BranchConfigurationControllerTests.m deleted file mode 100644 index 74acc4106..000000000 --- a/BranchSDKTests/BranchConfigurationControllerTests.m +++ /dev/null @@ -1,105 +0,0 @@ -// -// BranchConfigurationControllerTests.m -// Branch-SDK-Tests -// -// Created by Nidhi Dixit on 6/12/25. -// - - -#import -#import "BranchConstants.h" -#import "BNCRequestFactory.h" -#import "BNCEncodingUtils.h" - -#if SWIFT_PACKAGE -@import BranchSwiftSDK; -#else -#import "BranchSDK/BranchSDK-Swift.h" -#endif - -@interface BranchConfigurationControllerTests : XCTestCase -@end - -@implementation BranchConfigurationControllerTests - -- (void)testSingletonInstance { - - ConfigurationController *instance1 = [ConfigurationController shared]; - XCTAssertNotNil(instance1); - - ConfigurationController *instance2 = [ConfigurationController shared]; - XCTAssertEqual(instance1, instance2); -} - -- (void)testPropertySettersAndGetters { - ConfigurationController *configController = [ConfigurationController shared]; - - 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 { - ConfigurationController *configController = [ConfigurationController shared]; - 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 { - ConfigurationController *configController = [ConfigurationController shared]; - 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/BranchSDKTests/BranchEvent.Test.m b/BranchSDKTests/BranchEvent.Test.m deleted file mode 100644 index ddb3d220f..000000000 --- a/BranchSDKTests/BranchEvent.Test.m +++ /dev/null @@ -1,575 +0,0 @@ -// -// BranchEvent.Test.m -// Branch-SDK-Tests -// -// Created by Edward Smith on 8/15/17. -// Copyright © 2017 Branch Metrics. All rights reserved. -// -#import -#import "BNCPreferenceHelper.h" -#import "BranchConstants.h" -#import "BranchEvent.h" -#import "BNCDeviceInfo.h" -#import "NSError+Branch.h" - -@interface Branch (BranchEventTest) -- (void) processNextQueueItem; -@end - -@interface BranchEvent() - -- (NSString *)jsonStringForAdType:(BranchEventAdType)adType; - -// private BranchEvent methods used to check data before sending to network service. -- (NSDictionary *)buildEventDictionary; -- (BranchEventRequest *)buildRequestWithEventDictionary:(NSDictionary *)eventDictionary; - -@end - -@interface BranchEventTest : XCTestCase -@end - -@implementation BranchEventTest - -- (void)setUp { - [BNCPreferenceHelper sharedInstance].randomizedBundleToken = @"575759106028389737"; - [[BNCPreferenceHelper sharedInstance] clearInstrumentationDictionary]; -} - -- (void)tearDown { - -} - -// TODO: fix this test -- (void)testDescription { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventPurchase]; - event.transactionID = @"1234"; - event.currency = BNCCurrencyUSD; - event.revenue = [NSDecimalNumber decimalNumberWithString:@"10.50"]; - event.eventDescription= @"Event description."; - event.customData = (NSMutableDictionary*) @{ - @"Key1": @"Value1" - }; - - NSString *d = event.description; -// BNCTAssertEqualMaskedString(d, -// @""); -} - -- (void)testExampleSyntax { - BranchUniversalObject *contentItem = [BranchUniversalObject new]; - contentItem.canonicalIdentifier = @"item/123"; - contentItem.canonicalUrl = @"https://branch.io/item/123"; - contentItem.contentMetadata.ratingAverage = 5.0; - - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventCompleteRegistration]; - event.eventDescription = @"Product Search"; - event.searchQuery = @"product name"; - event.customData = @{ @"rating": @"5" }; - - [event logEvent]; -} - -- (void)testStandardInviteEvent { - - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventInvite]; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"INVITE"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testCustomInviteEvent { - - BranchEvent *event = [BranchEvent customEventWithName:@"INVITE"]; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"INVITE"]); - XCTAssertNotNil(eventDictionary[@"content_items"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testStandardLoginEvent { - - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventLogin]; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"LOGIN"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testCustomLoginEvent { - - BranchEvent *event = [BranchEvent customEventWithName:@"LOGIN"]; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"LOGIN"]); - XCTAssertNotNil(eventDictionary[@"content_items"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testStandardReserveEvent { - - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventReserve]; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"RESERVE"]); - XCTAssertNotNil(eventDictionary[@"content_items"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testCustomReserveEvent { - - BranchEvent *event = [BranchEvent customEventWithName:@"RESERVE"]; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"RESERVE"]); - XCTAssertNotNil(eventDictionary[@"content_items"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testStandardSubscribeEvent { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventSubscribe]; - event.currency = BNCCurrencyUSD; - event.revenue = [NSDecimalNumber decimalNumberWithString:@"1.0"]; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"SUBSCRIBE"]); - - NSDictionary *eventData = eventDictionary[@"event_data"]; - XCTAssert([eventData[@"currency"] isEqualToString:BNCCurrencyUSD]); - XCTAssert([eventData[@"revenue"] isEqual:[NSDecimalNumber decimalNumberWithString:@"1.0"]]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testCustomSubscribeEvent { - - BranchEvent *event = [BranchEvent customEventWithName:@"SUBSCRIBE"]; - event.currency = BNCCurrencyUSD; - event.revenue = [NSDecimalNumber decimalNumberWithString:@"1.0"]; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"SUBSCRIBE"]); - XCTAssertNotNil(eventDictionary[@"content_items"]); - - NSDictionary *eventData = eventDictionary[@"event_data"]; - XCTAssert([eventData[@"currency"] isEqualToString:BNCCurrencyUSD]); - XCTAssert([eventData[@"revenue"] isEqual:[NSDecimalNumber decimalNumberWithString:@"1.0"]]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testStandardStartTrialEvent { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventStartTrial]; - event.currency = BNCCurrencyUSD; - event.revenue = [NSDecimalNumber decimalNumberWithString:@"1.0"]; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"START_TRIAL"]); - - NSDictionary *eventData = eventDictionary[@"event_data"]; - XCTAssert([eventData[@"currency"] isEqualToString:BNCCurrencyUSD]); - XCTAssert([eventData[@"revenue"] isEqual:[NSDecimalNumber decimalNumberWithString:@"1.0"]]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testCustomStartTrialEvent { - - BranchEvent *event = [BranchEvent customEventWithName:@"START_TRIAL"]; - event.currency = BNCCurrencyUSD; - event.revenue = [NSDecimalNumber decimalNumberWithString:@"1.0"]; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"START_TRIAL"]); - XCTAssertNotNil(eventDictionary[@"content_items"]); - - NSDictionary *eventData = eventDictionary[@"event_data"]; - XCTAssert([eventData[@"currency"] isEqualToString:BNCCurrencyUSD]); - XCTAssert([eventData[@"revenue"] isEqual:[NSDecimalNumber decimalNumberWithString:@"1.0"]]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testStandardClickAdEvent { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventClickAd]; - event.adType = BranchEventAdTypeBanner; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"CLICK_AD"]); - - NSDictionary *eventData = eventDictionary[@"event_data"]; - XCTAssert([eventData[@"ad_type"] isEqual:[event jsonStringForAdType:event.adType]]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testCustomClickAdEvent { - - BranchEvent *event = [BranchEvent customEventWithName:@"CLICK_AD"]; - event.adType = BranchEventAdTypeBanner; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"CLICK_AD"]); - XCTAssertNotNil(eventDictionary[@"content_items"]); - - NSDictionary *eventData = eventDictionary[@"event_data"]; - XCTAssert([eventData[@"ad_type"] isEqual:[event jsonStringForAdType:event.adType]]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testStandardViewAdEvent { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewAd]; - event.adType = BranchEventAdTypeBanner; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"VIEW_AD"]); - - NSDictionary *eventData = eventDictionary[@"event_data"]; - XCTAssert([eventData[@"ad_type"] isEqual:[event jsonStringForAdType:event.adType]]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testCustomViewAdEvent { - - BranchEvent *event = [BranchEvent customEventWithName:@"VIEW_AD"]; - event.adType = BranchEventAdTypeBanner; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - buo.canonicalIdentifier = @"item/12345"; - buo.canonicalUrl = @"https://branch.io/deepviews"; - buo.title = @"My Content Title"; - buo.contentDescription = @"my_product_description1"; - - NSMutableArray *contentItems = [NSMutableArray new]; - [contentItems addObject:buo]; - event.contentItems = contentItems; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"VIEW_AD"]); - XCTAssertNotNil(eventDictionary[@"content_items"]); - - NSDictionary *eventData = eventDictionary[@"event_data"]; - XCTAssert([eventData[@"ad_type"] isEqual:[event jsonStringForAdType:event.adType]]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testStandardOptInEvent { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventOptIn]; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"OPT_IN"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testCustomOptInEvent { - BranchEvent *event = [BranchEvent customEventWithName:@"OPT_IN"]; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"OPT_IN"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testStandardOptOutEvent { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventOptOut]; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"OPT_OUT"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testCustomOptOutEvent { - BranchEvent *event = [BranchEvent customEventWithName:@"OPT_OUT"]; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"OPT_OUT"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - - -- (void)testStandardInitiateStreamEvent { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventInitiateStream]; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"INITIATE_STREAM"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testCustomInitiateStreamEvent { - BranchEvent *event = [BranchEvent customEventWithName:@"INITIATE_STREAM"]; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"INITIATE_STREAM"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testStandardCompleteStreamEvent { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventCompleteStream]; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"COMPLETE_STREAM"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testCustomCompleteStreamEvent { - BranchEvent *event = [BranchEvent customEventWithName:@"COMPLETE_STREAM"]; - - NSDictionary *eventDictionary = [event buildEventDictionary]; - XCTAssertNotNil(eventDictionary); - XCTAssert([eventDictionary[@"name"] isEqualToString:@"COMPLETE_STREAM"]); - - BranchEventRequest *request = [event buildRequestWithEventDictionary:eventDictionary]; - XCTAssert([request.serverURL.absoluteString containsString:@"branch.io/v2/event/standard"]); -} - -- (void)testJsonStringForAdTypeNone { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewAd]; - XCTAssertNil([event jsonStringForAdType:BranchEventAdTypeNone]); -} - -- (void)testJsonStringForAdTypeBanner { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewAd]; - XCTAssertTrue([[event jsonStringForAdType:BranchEventAdTypeBanner] isEqualToString:@"BANNER"]); -} - -- (void)testJsonStringForAdTypeInterstitial { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewAd]; - XCTAssertTrue([[event jsonStringForAdType:BranchEventAdTypeInterstitial] isEqualToString:@"INTERSTITIAL"]); -} - -- (void)testJsonStringForAdTypeRewardedVideo { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewAd]; - XCTAssertTrue([[event jsonStringForAdType:BranchEventAdTypeRewardedVideo] isEqualToString:@"REWARDED_VIDEO"]); -} - -- (void)testJsonStringForAdTypeNative { - BranchEvent *event = [BranchEvent standardEvent:BranchStandardEventViewAd]; - XCTAssertTrue([[event jsonStringForAdType:BranchEventAdTypeNative] isEqualToString:@"NATIVE"]); -} - -- (void) testCustomEventWithContentItem { - BranchUniversalObject *buo = [[BranchUniversalObject new] initWithTitle:@"buoTitle"]; - BranchEvent *event = [BranchEvent customEventWithName:@"testEvent" contentItem:buo]; - - XCTAssertTrue(event.contentItems.count == 1); - XCTAssertTrue([event.contentItems.firstObject.title isEqualToString:@"buoTitle"]); -} - -- (void)testLogEventWithCompletion_InvalidEventName { - XCTestExpectation *expectation = [self expectationWithDescription:@"Logging Event"]; - BranchEvent *event = [BranchEvent customEventWithName:@""]; - - [event logEventWithCompletion:^(BOOL success, NSError * _Nullable error) { - XCTAssertFalse(success, @"Success should be NO for invalid event name"); - XCTAssertNotNil(error, @"Error should not be nil for invalid event name"); - XCTAssertEqual(error.code, BNCGeneralError, @"Error code should match expected value for invalid event name"); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:5 handler:nil]; -} - - -@end diff --git a/BranchSDKTests/BranchEvent.Test.swift b/BranchSDKTests/BranchEvent.Test.swift deleted file mode 100644 index 49d819cc9..000000000 --- a/BranchSDKTests/BranchEvent.Test.swift +++ /dev/null @@ -1,129 +0,0 @@ -// -// BranchEvent.Test.swift -// Branch-SDK-Tests -// -// Created by edward on 10/9/17. -// Copyright © 2017 Branch, Inc. All rights reserved. -// - -import XCTest -/* -// TODO: fix this test class, requires modules which our testbed is not using -final class BranchEventTestSwift : XCTestCase { - - override func setUpWithError() throws { - // Put setup code here. This method is called before the invocation of each test method in the class. - - Branch.getInstance("key_live_foo") - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - - func testBranchEvent() throws { - - // Set up the Branch Universal Object -- - - let branchUniversalObject = BranchUniversalObject.init() - branchUniversalObject.canonicalIdentifier = "item/12345" - branchUniversalObject.canonicalUrl = "https://branch.io/deepviews" - branchUniversalObject.title = "My Content Title" - branchUniversalObject.contentDescription = "my_product_description1" - branchUniversalObject.imageUrl = "https://test_img_url" - branchUniversalObject.keywords = [ "My_Keyword1", "My_Keyword2" ] - branchUniversalObject.creationDate = Date.init(timeIntervalSince1970:1501869445321.0/1000.0) - branchUniversalObject.expirationDate = Date.init(timeIntervalSince1970:212123232544.0/1000.0) - branchUniversalObject.locallyIndex = true - branchUniversalObject.publiclyIndex = false - - branchUniversalObject.contentMetadata.contentSchema = .commerceProduct - branchUniversalObject.contentMetadata.quantity = 2 - branchUniversalObject.contentMetadata.price = 23.20 - branchUniversalObject.contentMetadata.currency = .USD - branchUniversalObject.contentMetadata.sku = "1994320302" - branchUniversalObject.contentMetadata.productName = "my_product_name1" - branchUniversalObject.contentMetadata.productBrand = "my_prod_Brand1" - branchUniversalObject.contentMetadata.productCategory = .babyToddler - branchUniversalObject.contentMetadata.productVariant = "3T" - branchUniversalObject.contentMetadata.condition = .fair - - branchUniversalObject.contentMetadata.ratingAverage = 5; - branchUniversalObject.contentMetadata.ratingCount = 5; - branchUniversalObject.contentMetadata.ratingMax = 7; - branchUniversalObject.contentMetadata.rating = 6; - branchUniversalObject.contentMetadata.addressStreet = "Street_name1" - branchUniversalObject.contentMetadata.addressCity = "city1" - branchUniversalObject.contentMetadata.addressRegion = "Region1" - branchUniversalObject.contentMetadata.addressCountry = "Country1" - branchUniversalObject.contentMetadata.addressPostalCode = "postal_code" - branchUniversalObject.contentMetadata.latitude = 12.07 - branchUniversalObject.contentMetadata.longitude = -97.5 - branchUniversalObject.contentMetadata.imageCaptions = [ - "my_img_caption1", - "my_img_caption_2" - ] - branchUniversalObject.contentMetadata.customMetadata = [ - "Custom_Content_metadata_key1": "Custom_Content_metadata_val1", - "Custom_Content_metadata_key2": "Custom_Content_metadata_val2" - ] - - // Set up the event properties -- - - let event = BranchEvent.standardEvent(.purchase) - event.transactionID = "12344555" - event.currency = .USD; - event.revenue = 1.5 - event.shipping = 10.2 - event.tax = 12.3 - event.coupon = "test_coupon"; - event.affiliation = "test_affiliation"; - event.eventDescription = "Event _description"; - event.searchQuery = "Query" - event.customData = [ - "Custom_Event_Property_Key1": "Custom_Event_Property_val1", - "Custom_Event_Property_Key2": "Custom_Event_Property_val2" - ] - - var testDictionary = event.dictionary() - var dictionary = self.mutableDictionaryFromBundleJSON(withKey: "V2EventProperties") - XCTAssert((dictionary?.isEqual(to: testDictionary))!) - - testDictionary = branchUniversalObject.dictionary() as! [AnyHashable : Any] - dictionary = self.mutableDictionaryFromBundleJSON(withKey: "BranchUniversalObjectJSON") - dictionary!["$publicly_indexable"] = nil // Remove this value since we don't add false values. - XCTAssert((dictionary?.isEqual(to: testDictionary))!) - - event.contentItems = [ branchUniversalObject ] - event.logEvent() - } - - func testExampleSyntaxSwift() throws { - let contentItem = BranchUniversalObject.init() - contentItem.canonicalIdentifier = "item/123" - contentItem.canonicalUrl = "https://branch.io/item/123" - contentItem.contentMetadata.ratingAverage = 5.0; - - var event = BranchEvent.standardEvent(.spendCredits) - event.transactionID = "tx1234" - event.eventDescription = "Product Search" - event.searchQuery = "user search query terms for product xyz" - event.customData["Custom_Event_Property_Key1"] = "Custom_Event_Property_val1" - event.contentItems = [ contentItem ] - event.logEvent() - - event = BranchEvent.standardEvent(.viewItem) - event.logEvent(); - - // Quickly log an event: - BranchEvent.standardEvent(.viewItem).logEvent() - - // Quickly log an event with content: - let branchUniversalObject = BranchUniversalObject.init() - branchUniversalObject.canonicalIdentifier = "item/12345" - branchUniversalObject.canonicalUrl = "https://branch.io/deepviews" - branchUniversalObject.title = "My Content Title" - BranchEvent.standardEvent(.viewItem, withContentItem: branchUniversalObject).logEvent() - } -} -*/ diff --git a/BranchSDKTests/BranchLastAttributedTouchDataTests.m b/BranchSDKTests/BranchLastAttributedTouchDataTests.m deleted file mode 100644 index 908711125..000000000 --- a/BranchSDKTests/BranchLastAttributedTouchDataTests.m +++ /dev/null @@ -1,63 +0,0 @@ -// -// BranchLastAttributedTouchDataTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 9/18/19. -// Copyright © 2019 Branch, Inc. All rights reserved. -// - -#import -#import "BNCJsonLoader.h" -#import "BranchLastAttributedTouchData.h" - -@interface BranchLastAttributedTouchDataTests : XCTestCase - -@end - -@implementation BranchLastAttributedTouchDataTests - -- (void)setUp { - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -- (void)testBuildFromJSON { - NSDictionary *json = [BNCJsonLoader dictionaryFromJSONFileNamed:@"latd"]; - XCTAssertNotNil(json); - - BranchLastAttributedTouchData *latd = [BranchLastAttributedTouchData buildFromJSON:json]; - XCTAssertNotNil(latd); - XCTAssertNotNil(latd.lastAttributedTouchJSON); - XCTAssertNotNil(latd.attributionWindow); -} - -- (void)testBuildFromJSON_EmptyData { - NSDictionary *json = [BNCJsonLoader dictionaryFromJSONFileNamed:@"latd_empty_data"]; - XCTAssertNotNil(json); - - BranchLastAttributedTouchData *latd = [BranchLastAttributedTouchData buildFromJSON:json]; - XCTAssertNotNil(latd); - XCTAssertTrue(latd.lastAttributedTouchJSON.count == 0); -} - -- (void)testBuildFromJSON_MissingData { - NSDictionary *json = [BNCJsonLoader dictionaryFromJSONFileNamed:@"latd_missing_data"]; - XCTAssertNotNil(json); - - BranchLastAttributedTouchData *latd = [BranchLastAttributedTouchData buildFromJSON:json]; - XCTAssertNil(latd); -} - -- (void)testBuildFromJSON_MissingWindow { - NSDictionary *json = [BNCJsonLoader dictionaryFromJSONFileNamed:@"latd_missing_window"]; - XCTAssertNotNil(json); - - BranchLastAttributedTouchData *latd = [BranchLastAttributedTouchData buildFromJSON:json]; - XCTAssertNotNil(latd); - XCTAssertNil(latd.attributionWindow); -} - -@end diff --git a/BranchSDKTests/BranchLoggerTests.m b/BranchSDKTests/BranchLoggerTests.m deleted file mode 100644 index 1a4be3490..000000000 --- a/BranchSDKTests/BranchLoggerTests.m +++ /dev/null @@ -1,261 +0,0 @@ -// -// BranchLoggerTests.m -// Branch-SDK-Tests -// -// Created by Nipun Singh on 2/5/24. -// Copyright © 2024 Branch, Inc. All rights reserved. -// - -#import -#import "BranchLogger.h" -#import "Branch.h" - -@interface BranchLoggerTests : XCTestCase - -@end - -@implementation BranchLoggerTests - -// public API test -- (void)testEnableLoggingSetsCorrectDefaultLevel { - [[Branch getInstance] enableLogging]; - XCTAssertEqual([BranchLogger shared].logLevelThreshold, BranchLogLevelDebug, "Default log level should be Debug."); -} - -- (void)testLoggingEnabled_NOByDefault { - BranchLogger *logger = [BranchLogger new]; - - __block int count = 0; - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - count = count + 1; - }; - [logger logError:@"msg" error:nil]; - - XCTAssertTrue(count == 0); -} - -- (void)testLoggingEnabled_Yes { - BranchLogger *logger = [BranchLogger new]; - logger.loggingEnabled = YES; - - __block int count = 0; - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - count = count + 1; - }; - - [logger logError:@"msg" error:nil]; - XCTAssertTrue(count == 1); - - [logger logError:@"msg" error:nil]; - XCTAssertTrue(count == 2); -} - -- (void)testLoggingIgnoresNil { - BranchLogger *logger = [BranchLogger new]; - logger.loggingEnabled = YES; - - __block int count = 0; - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - count = count + 1; - }; - - [logger logError:nil error:nil]; - XCTAssertTrue(count == 0); -} - -- (void)testLoggingIgnoresEmptyString { - BranchLogger *logger = [BranchLogger new]; - logger.loggingEnabled = YES; - - __block int count = 0; - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - count = count + 1; - }; - - [logger logError:@"" error:nil]; - XCTAssertTrue(count == 0); -} - -- (void)testLoggingEnabled_YesThenNo { - BranchLogger *logger = [BranchLogger new]; - logger.loggingEnabled = YES; - - __block int count = 0; - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - count = count + 1; - }; - - // one call - [logger logError:@"msg" error:nil]; - XCTAssertTrue(count == 1); - - // disable, second call is ignored - logger.loggingEnabled = NO; - [logger logError:@"msg" error:nil]; - XCTAssertTrue(count == 1); -} - -- (void)testLogLevel_DebugByDefault { - BranchLogger *logger = [BranchLogger new]; - logger.loggingEnabled = YES; - - __block int count = 0; - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - count = count + 1; - }; - - [logger logError:@"msg" error:nil]; - XCTAssertTrue(count == 1); - [logger logWarning:@"msg" error:nil]; - XCTAssertTrue(count == 2); - [logger logDebug:@"msg" error:nil]; - XCTAssertTrue(count == 3); - - // this should be ignored and the counter not incremented - [logger logVerbose:@"msg" error:nil]; - XCTAssertTrue(count == 3); -} - -- (void)testLogLevel_Error { - BranchLogger *logger = [BranchLogger new]; - logger.loggingEnabled = YES; - logger.logLevelThreshold = BranchLogLevelError; - - - __block int count = 0; - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - count = count + 1; - }; - - [logger logError:@"msg" error:nil]; - XCTAssertTrue(count == 1); - - // these should be ignored and the counter not incremented - [logger logWarning:@"msg" error:nil]; - XCTAssertTrue(count == 1); - [logger logDebug:@"msg" error:nil]; - XCTAssertTrue(count == 1); - [logger logVerbose:@"msg" error:nil]; - XCTAssertTrue(count == 1); -} - -- (void)testLogLevel_Warning { - BranchLogger *logger = [BranchLogger new]; - logger.loggingEnabled = YES; - logger.logLevelThreshold = BranchLogLevelWarning; - - - __block int count = 0; - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - count = count + 1; - }; - - [logger logError:@"msg" error:nil]; - XCTAssertTrue(count == 1); - [logger logWarning:@"msg" error:nil]; - XCTAssertTrue(count == 2); - - // this should be ignored and the counter not incremented - [logger logDebug:@"msg" error:nil]; - XCTAssertTrue(count == 2); - [logger logVerbose:@"msg" error:nil]; - XCTAssertTrue(count == 2); -} - -- (void)testLogLevel_Verbose { - BranchLogger *logger = [BranchLogger new]; - logger.loggingEnabled = YES; - logger.logLevelThreshold = BranchLogLevelVerbose; - - - __block int count = 0; - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - count = count + 1; - }; - - [logger logError:@"msg" error:nil]; - XCTAssertTrue(count == 1); - [logger logWarning:@"msg" error:nil]; - XCTAssertTrue(count == 2); - [logger logDebug:@"msg" error:nil]; - XCTAssertTrue(count == 3); - [logger logVerbose:@"msg" error:nil]; - XCTAssertTrue(count == 4); -} - -- (void)testLogFormat_Default { - BranchLogger *logger = [BranchLogger new]; - logger.loggingEnabled = YES; - - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - NSString *expectedMessage = @"[BranchLoggerTests testLogFormat_Default] msg"; - - XCTAssertTrue([expectedMessage isEqualToString:message]); - XCTAssertTrue(logLevel == BranchLogLevelError); - XCTAssertNil(error); - }; - - [logger logError:@"msg" error:nil]; -} - -- (void)testLogFormat_NSError { - __block NSError *originalError = [NSError errorWithDomain:@"com.domain.test" code:200 userInfo:@{@"Error Message": @"Test Error"}]; - - BranchLogger *logger = [BranchLogger new]; - logger.loggingEnabled = YES; - - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - NSString *expectedMessage = @"[BranchLoggerTests testLogFormat_NSError] msg"; - - XCTAssertTrue([expectedMessage isEqualToString:message]); - XCTAssertTrue(logLevel == BranchLogLevelError); - XCTAssertTrue(originalError == error); - }; - - [logger logError:@"msg" error:originalError]; -} - -- (void)testLogFormat_includeCallerDetailsNO { - BranchLogger *logger = [BranchLogger new]; - logger.loggingEnabled = YES; - logger.includeCallerDetails = NO; - - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - NSString *expectedMessage = @"msg"; - - XCTAssertTrue([expectedMessage isEqualToString:message]); - XCTAssertTrue(logLevel == BranchLogLevelError); - XCTAssertNil(error); - }; - - [logger logError:@"msg" error:nil]; -} - -- (void)testLogFormat_includeCallerDetailsNO_NSError { - __block NSError *originalError = [NSError errorWithDomain:@"com.domain.test" code:200 userInfo:@{@"Error Message": @"Test Error"}]; - - BranchLogger *logger = [BranchLogger new]; - logger.loggingEnabled = YES; - logger.includeCallerDetails = NO; - - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - NSString *expectedMessage = @"msg"; - - XCTAssertTrue([expectedMessage isEqualToString:message]); - XCTAssertTrue(logLevel == BranchLogLevelError); - XCTAssertTrue(originalError == error); - }; - - [logger logError:@"msg" error:originalError]; -} - -- (void)testDefaultBranchLogFormat { - NSError *error = [NSError errorWithDomain:@"com.domain.test" code:200 userInfo:@{@"Error Message": @"Test Error"}]; - - NSString *expectedMessage = @"[BranchSDK][Error]msg NSError: Error Domain=com.domain.test Code=200 \"(null)\" UserInfo={Error Message=Test Error}"; - NSString *formattedMessage = [BranchLogger formatMessage:@"msg" logLevel:BranchLogLevelError error:error]; - - XCTAssertTrue([expectedMessage isEqualToString:formattedMessage]); -} - -@end diff --git a/BranchSDKTests/BranchPluginSupportTests.m b/BranchSDKTests/BranchPluginSupportTests.m deleted file mode 100644 index d46b620fc..000000000 --- a/BranchSDKTests/BranchPluginSupportTests.m +++ /dev/null @@ -1,91 +0,0 @@ -// -// BranchPluginSupportTests.m -// Branch-SDK-Tests -// -// Created by Nipun Singh on 1/25/22. -// Copyright © 2022 Branch, Inc. All rights reserved. -// - -#import -#import "BranchPluginSupport.h" - -@interface BranchPluginSupportTests : XCTestCase -@property (nonatomic, strong, readwrite) NSDictionary *deviceDescription; -@end - -@implementation BranchPluginSupportTests - -- (void)setUp { - self.deviceDescription = [[BranchPluginSupport new] deviceDescription]; -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -- (void)testAppVersion { - // checks test app version - XCTAssert([@"1.0" isEqualToString:_deviceDescription[@"app_version"]]); -} - -- (void)testBrandName { - XCTAssert([@"Apple" isEqualToString:_deviceDescription[@"brand"]]); -} - -- (void)testModelName_Simulator { - // intel processor - bool x86_64 = [@"x86_64" isEqualToString:_deviceDescription[@"model"]]; - - // apple processor - bool arm64 = [@"arm64" isEqualToString:_deviceDescription[@"model"]]; - - XCTAssert(x86_64 || arm64); -} - -- (void)testOSName { - XCTAssertNotNil(_deviceDescription[@"os"]); - XCTAssert([_deviceDescription[@"os"] isEqualToString:[UIDevice currentDevice].systemName]); -} - -- (void)testOSVersion { - XCTAssertNotNil(_deviceDescription[@"os_version"]); - XCTAssert([_deviceDescription[@"os_version"] isEqualToString:[UIDevice currentDevice].systemVersion]); -} - -- (void)testEnvironment { - XCTAssert([@"FULL_APP" isEqualToString:_deviceDescription[@"environment"]]); -} - -- (void)testScreenWidth { - XCTAssert(_deviceDescription[@"screen_width"].intValue > 320); -} - -- (void)testScreenHeight { - XCTAssert(_deviceDescription[@"screen_height"].intValue > 320); -} - -- (void)testScreenScale { - XCTAssert(_deviceDescription[@"screen_dpi"].intValue > 0); -} - -- (void)testCountry { - NSString *locale = [NSLocale currentLocale].localeIdentifier; - XCTAssertNotNil(locale); - XCTAssert([locale containsString:_deviceDescription[@"country"]]); -} - -- (void)testLanguage { - NSString *locale = [NSLocale currentLocale].localeIdentifier; - XCTAssertNotNil(locale); - XCTAssert([locale containsString:_deviceDescription[@"language"]]); -} - -- (void)testLocalIPAddress { - NSString *address = _deviceDescription[@"local_ip"]; - XCTAssertNotNil(address); - - // shortest ipv4 is 7 - XCTAssert(address.length >= 7); -} - -@end diff --git a/BranchSDKTests/BranchQRCodeTests.m b/BranchSDKTests/BranchQRCodeTests.m deleted file mode 100644 index 3d1e1ffc6..000000000 --- a/BranchSDKTests/BranchQRCodeTests.m +++ /dev/null @@ -1,154 +0,0 @@ -// -// BranchQRCodeTests.m -// Branch-SDK-Tests -// -// Created by Nipun Singh on 4/14/22. -// Copyright © 2022 Branch, Inc. All rights reserved. -// - -#import -#import "Branch.h" -#import "BranchQRCode.h" -#import "BNCQRCodeCache.h" - -@interface BranchQRCodeTests : XCTestCase - -@end - -@implementation BranchQRCodeTests - -- (void)testNormalQRCodeDataWithAllSettings { - XCTestExpectation *expectation = [self expectationWithDescription:@"Fetching QR Code"]; - - BranchQRCode *qrCode = [BranchQRCode new]; - qrCode.width = @(1000); - qrCode.margin = @(1); - qrCode.codeColor = [UIColor blueColor]; - qrCode.backgroundColor = [UIColor whiteColor]; - qrCode.centerLogo = @"https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg"; - qrCode.imageFormat = BranchQRCodeImageFormatPNG; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - BranchLinkProperties *lp = [BranchLinkProperties new]; - - [qrCode getQRCodeAsData:buo linkProperties:lp completion:^(NSData * _Nonnull qrCode, NSError * _Nonnull error) { - XCTAssertNil(error); - XCTAssertNotNil(qrCode); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:10 handler:^(NSError *error) { - if (error) { - NSLog(@"Error Testing QR Code Cache: %@", error); - XCTFail(); - } - }]; -} - -- (void)testNormalQRCodeAsDataWithNoSettings { - XCTestExpectation *expectation = [self expectationWithDescription:@"Fetching QR Code"]; - - BranchQRCode *qrCode = [BranchQRCode new]; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - BranchLinkProperties *lp = [BranchLinkProperties new]; - - [qrCode getQRCodeAsData:buo linkProperties:lp completion:^(NSData * _Nonnull qrCode, NSError * _Nonnull error) { - XCTAssertNil(error); - XCTAssertNotNil(qrCode); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:10 handler:^(NSError *error) { - if (error) { - NSLog(@"Error Testing QR Code Cache: %@", error); - XCTFail(); - } - }]; -} - -- (void)testNormalQRCodeWithInvalidLogoURL { - XCTestExpectation *expectation = [self expectationWithDescription:@"Fetching QR Code"]; - - BranchQRCode *qrCode = [BranchQRCode new]; - qrCode.centerLogo = @"https://branch.branch/notARealImageURL.jpg"; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - BranchLinkProperties *lp = [BranchLinkProperties new]; - - [qrCode getQRCodeAsData:buo linkProperties:lp completion:^(NSData * _Nonnull qrCode, NSError * _Nonnull error) { - XCTAssertNil(error); - XCTAssertNotNil(qrCode); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:10 handler:^(NSError *error) { - if (error) { - NSLog(@"Error Testing QR Code Cache: %@", error); - XCTFail(); - } - }]; -} - -- (void)testNormalQRCodeAsImage { - XCTestExpectation *expectation = [self expectationWithDescription:@"Fetching QR Code"]; - - BranchQRCode *qrCode = [BranchQRCode new]; - - BranchUniversalObject *buo = [BranchUniversalObject new]; - BranchLinkProperties *lp = [BranchLinkProperties new]; - - [qrCode getQRCodeAsImage:buo linkProperties:lp completion:^(UIImage * _Nonnull qrCode, NSError * _Nonnull error) { - XCTAssertNil(error); - XCTAssertNotNil(qrCode); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:10 handler:^(NSError *error) { - if (error) { - NSLog(@"Error Testing QR Code Cache: %@", error); - XCTFail(); - } - }]; -} - -- (void)testQRCodeCache { - XCTestExpectation *expectation = [self expectationWithDescription:@"Fetching QR Code"]; - - BranchQRCode *myQRCode = [BranchQRCode new]; - BranchUniversalObject *buo = [BranchUniversalObject new]; - BranchLinkProperties *lp = [BranchLinkProperties new]; - - [myQRCode getQRCodeAsData:buo linkProperties:lp completion:^(NSData * _Nonnull qrCode, NSError * _Nonnull error) { - - XCTAssertNil(error); - XCTAssertNotNil(qrCode); - - NSMutableDictionary *parameters = [NSMutableDictionary new]; - NSMutableDictionary *settings = [NSMutableDictionary new]; - - settings[@"image_format"] = @"PNG"; - settings[@"width"] = @(300); - settings[@"margin"] = @(1); - - parameters[@"qr_code_settings"] = settings; - parameters[@"data"] = [NSMutableDictionary new]; - parameters[@"branch_key"] = [Branch branchKey]; - - - NSData *cachedQRCode = [[BNCQRCodeCache sharedInstance] checkQRCodeCache:parameters]; - - XCTAssertEqual(cachedQRCode, qrCode); - [expectation fulfill]; - }]; - - [self waitForExpectationsWithTimeout:10 handler:^(NSError *error) { - if (error) { - NSLog(@"Error Testing QR Code Cache: %@", error); - XCTFail(); - } - }]; -} - - -@end diff --git a/BranchSDKTests/BranchSDKTests.m b/BranchSDKTests/BranchSDKTests.m deleted file mode 100644 index 7a37169d8..000000000 --- a/BranchSDKTests/BranchSDKTests.m +++ /dev/null @@ -1,36 +0,0 @@ -// -// BranchSDKTests.m -// BranchSDKTests -// -// Created by Nidhi Dixit on 7/6/25. -// - -#import - -@interface BranchSDKTests : XCTestCase - -@end - -@implementation BranchSDKTests - -- (void)setUp { - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -- (void)testExample { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. -} - -- (void)testPerformanceExample { - // This is an example of a performance test case. - [self measureBlock:^{ - // Put the code you want to measure the time of here. - }]; -} - -@end diff --git a/BranchSDKTests/BranchSDKTests.xctestplan b/BranchSDKTests/BranchSDKTests.xctestplan deleted file mode 100644 index 445c0d7d4..000000000 --- a/BranchSDKTests/BranchSDKTests.xctestplan +++ /dev/null @@ -1,37 +0,0 @@ -{ - "configurations" : [ - { - "id" : "9EAB663B-7807-43EE-AD4E-658E8734932A", - "name" : "Test Scheme Action", - "options" : { - - } - } - ], - "defaultOptions" : { - "targetForVariableExpansion" : { - "containerPath" : "container:BranchSDK.xcodeproj", - "identifier" : "5F22116E2894A9C000C5B190", - "name" : "TestHost" - } - }, - "testTargets" : [ - { - "parallelizable" : false, - "target" : { - "containerPath" : "container:BranchSDK.xcodeproj", - "identifier" : "E7CA74EA2E1B4F75002EFB40", - "name" : "BranchSDKTests" - } - }, - { - "enabled" : false, - "target" : { - "containerPath" : "container:BranchSDK.xcodeproj", - "identifier" : "5F2211832894A9C100C5B190", - "name" : "TestHostTests" - } - } - ], - "version" : 1 -} diff --git a/BranchSDKTests/BranchShareLinkTests.m b/BranchSDKTests/BranchShareLinkTests.m deleted file mode 100644 index c41fdb618..000000000 --- a/BranchSDKTests/BranchShareLinkTests.m +++ /dev/null @@ -1,38 +0,0 @@ -// -// BranchShareLinkTests.m -// Branch-SDK-Tests -// -// Created by Nipun Singh on 5/5/22. -// Copyright © 2022 Branch, Inc. All rights reserved. -// - -#import -#import "BranchShareLink.h" -#import "BranchLinkProperties.h" -#import "Branch.h" - -@interface BranchShareLinkTests : XCTestCase - -@end - -@implementation BranchShareLinkTests - -- (void)testAddLPLinkMetadata { - BranchUniversalObject *buo = [[BranchUniversalObject alloc] initWithCanonicalIdentifier:@"test/001"]; - BranchLinkProperties *lp = [[BranchLinkProperties alloc] init]; - - BranchShareLink *bsl = [[BranchShareLink alloc] initWithUniversalObject:buo linkProperties:lp]; - - if (@available(iOS 13.0, macCatalyst 13.1, *)) { - NSURL *imageURL = [NSURL URLWithString:@"https://cdn.branch.io/branch-assets/1598575682753-og_image.png"]; - NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; - UIImage *iconImage = [UIImage imageWithData:imageData]; - - [bsl addLPLinkMetadata:@"Test Preview Title" icon:iconImage]; - XCTAssertNotNil([bsl lpMetaData]); - } else { - XCTAssertTrue(true); - } -} - -@end diff --git a/BranchSDKTests/BranchUniversalObjectTests.m b/BranchSDKTests/BranchUniversalObjectTests.m deleted file mode 100644 index 9a7112e31..000000000 --- a/BranchSDKTests/BranchUniversalObjectTests.m +++ /dev/null @@ -1,446 +0,0 @@ -// -// BranchUniversalObjectTests.m -// Branch-TestBed -// -// Created by Edward Smith on 8/15/17. -// Copyright © 2017 Branch Metrics. All rights reserved. -// - -#import -#import "BranchUniversalObject.h" - -@interface BranchUniversalObjectTests : XCTestCase -@end - -@implementation BranchUniversalObjectTests - -- (void)setUp { - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -#pragma mark BranchContentMetadata tests - -- (BranchContentMetadata *)branchContentMetadataWithAllPropertiesSet { - BranchContentMetadata *metadata = [BranchContentMetadata new]; - metadata.contentSchema = BranchContentSchemaOther; - metadata.quantity = 10; - metadata.price = [[NSDecimalNumber alloc] initWithDouble:5.5]; - metadata.currency = BNCCurrencyUSD; - metadata.sku = @"testSKU"; - metadata.productName = @"testProductName"; - metadata.productBrand = @"testProductBrand"; - metadata.productCategory = BNCProductCategoryApparel; - metadata.productVariant = @"testProductVariant"; - metadata.condition = BranchConditionNew; - metadata.ratingAverage = 3.5; - metadata.ratingCount = 2; - metadata.ratingMax = 4; - metadata.rating = 3; - metadata.addressStreet = @"195 Page Mill Road"; - metadata.addressCity = @"Palo Alto"; - metadata.addressRegion = @"CA"; - metadata.addressCountry = @"USA"; - metadata.addressPostalCode = @"94306"; - metadata.latitude = 37.426; - metadata.longitude = -122.138; - - metadata.imageCaptions = @[ - @"Hello World", - @"Goodbye World" - ].mutableCopy; - - metadata.customMetadata = @{ - @"custom0": @"custom data 0" - }.mutableCopy; - - return metadata; -} - -- (void)verifyBranchContentMetadataWithAllProperties:(BranchContentMetadata *)metadata { - XCTAssertNotNil(metadata); - - XCTAssertEqual(BranchContentSchemaOther, metadata.contentSchema); - XCTAssertTrue([@(10) isEqualToNumber:@(metadata.quantity)]); - XCTAssertTrue([[[NSDecimalNumber alloc] initWithDouble:5.5] isEqualToNumber:metadata.price]); - - XCTAssertEqual(BNCCurrencyUSD, metadata.currency); - XCTAssertTrue([@"testSKU" isEqualToString:metadata.sku]); - XCTAssertTrue([@"testProductName" isEqualToString:metadata.productName]); - XCTAssertTrue([@"testProductBrand" isEqualToString:metadata.productBrand]); - XCTAssertEqual(BNCProductCategoryApparel, metadata.productCategory); - XCTAssertTrue([@"testProductVariant" isEqualToString:metadata.productVariant]); - XCTAssertEqual(BranchConditionNew, metadata.condition); - XCTAssertTrue([@(3.5) isEqualToNumber:@(metadata.ratingAverage)]); - XCTAssertTrue([@(2) isEqualToNumber:@(metadata.ratingCount)]); - XCTAssertTrue([@(4) isEqualToNumber:@(metadata.ratingMax)]); - XCTAssertTrue([@(3) isEqualToNumber:@(metadata.rating)]); - - XCTAssertTrue([@"195 Page Mill Road" isEqualToString:metadata.addressStreet]); - XCTAssertTrue([@"Palo Alto" isEqualToString:metadata.addressCity]); - XCTAssertTrue([@"CA" isEqualToString:metadata.addressRegion]); - XCTAssertTrue([@"USA" isEqualToString:metadata.addressCountry]); - XCTAssertTrue([@"94306" isEqualToString:metadata.addressPostalCode]); - - XCTAssertTrue([@(37.426) isEqualToNumber:@(metadata.latitude)]); - XCTAssertTrue([@(-122.138) isEqualToNumber:@(metadata.longitude)]); - - XCTAssertNotNil(metadata.imageCaptions); - XCTAssertTrue(metadata.imageCaptions.count == 2); - XCTAssertTrue([metadata.imageCaptions[0] isEqualToString:@"Hello World"]); - XCTAssertTrue([metadata.imageCaptions[1] isEqualToString:@"Goodbye World"]); - - XCTAssertNotNil(metadata.customMetadata); - XCTAssertTrue(metadata.customMetadata.allKeys.count == 1); -} - -- (void)verifyBranchContentMetadataDictionaryWithAllPropertiesSet:(NSDictionary *)dict { - XCTAssertTrue([@"OTHER" isEqualToString:dict[@"$content_schema"]]); - XCTAssertTrue([@(10) isEqualToNumber:dict[@"$quantity"]]); - XCTAssertTrue([[[NSDecimalNumber alloc] initWithDouble:5.5] isEqualToNumber:dict[@"$price"]]); - XCTAssertTrue([@"USD" isEqualToString:dict[@"$currency"]]); - XCTAssertTrue([@"testSKU" isEqualToString:dict[@"$sku"]]); - XCTAssertTrue([@"testProductName" isEqualToString:dict[@"$product_name"]]); - XCTAssertTrue([@"testProductBrand" isEqualToString:dict[@"$product_brand"]]); - XCTAssertTrue([@"Apparel & Accessories" isEqualToString:dict[@"$product_category"]]); - XCTAssertTrue([@"testProductVariant" isEqualToString:dict[@"$product_variant"]]); - XCTAssertTrue([@"NEW" isEqualToString:dict[@"$condition"]]); - - XCTAssertTrue([@(3.5) isEqualToNumber:dict[@"$rating_average"]]); - XCTAssertTrue([@(2) isEqualToNumber:dict[@"$rating_count"]]); - XCTAssertTrue([@(4) isEqualToNumber:dict[@"$rating_max"]]); - XCTAssertTrue([@(3) isEqualToNumber:dict[@"$rating"]]); - - XCTAssertTrue([@"195 Page Mill Road" isEqualToString:dict[@"$address_street"]]); - XCTAssertTrue([@"Palo Alto" isEqualToString:dict[@"$address_city"]]); - XCTAssertTrue([@"CA" isEqualToString:dict[@"$address_region"]]); - XCTAssertTrue([@"USA" isEqualToString:dict[@"$address_country"]]); - XCTAssertTrue([@"94306" isEqualToString:dict[@"$address_postal_code"]]); - - XCTAssertTrue([@(37.426) isEqualToNumber:dict[@"$latitude"]]); - XCTAssertTrue([@(-122.138) isEqualToNumber:dict[@"$longitude"]]); - - XCTAssertTrue([dict[@"$image_captions"] isKindOfClass:NSArray.class]); - NSArray *tmp = dict[@"$image_captions"]; - XCTAssertTrue(tmp.count == 2); - XCTAssertTrue([tmp[0] isEqualToString:@"Hello World"]); - XCTAssertTrue([tmp[1] isEqualToString:@"Goodbye World"]); - - XCTAssertTrue([@"custom data 0" isEqualToString:dict[@"custom0"]]); -} - -- (void)testBranchContentMetadataCreation_NoPropertiesSet { - BranchContentMetadata *metadata = [BranchContentMetadata new]; - - // most properties default to nil. primitives default to 0 - XCTAssertNil(metadata.contentSchema); - XCTAssertEqual(0, metadata.quantity); - XCTAssertNil(metadata.price); - XCTAssertNil(metadata.currency); - XCTAssertNil(metadata.sku); - XCTAssertNil(metadata.productName); - XCTAssertNil(metadata.productBrand); - XCTAssertNil(metadata.productCategory); - XCTAssertNil(metadata.productVariant); - XCTAssertNil(metadata.condition); - XCTAssertEqual(0, metadata.ratingAverage); - XCTAssertEqual(0, metadata.ratingCount); - XCTAssertEqual(0, metadata.ratingMax); - XCTAssertEqual(0, metadata.rating); - XCTAssertNil(metadata.addressStreet); - XCTAssertNil(metadata.addressCity); - XCTAssertNil(metadata.addressRegion); - XCTAssertNil(metadata.addressCountry); - XCTAssertNil(metadata.addressPostalCode); - XCTAssertEqual(0, metadata.latitude); - XCTAssertEqual(0, metadata.longitude); - - // defaults to an empty array - XCTAssertNotNil(metadata.imageCaptions); - XCTAssertTrue(metadata.imageCaptions.count == 0); - - // defaults to an empty dictionary - XCTAssertNotNil(metadata.customMetadata); - XCTAssertTrue(metadata.customMetadata.allKeys.count == 0); -} - -- (void)testBranchContentMetadataCreation_AllPropertiesSet { - BranchContentMetadata *metadata = [self branchContentMetadataWithAllPropertiesSet]; - [self verifyBranchContentMetadataWithAllProperties:metadata]; -} - -- (void)testBranchContentMetadataDictionary_NoPropertiesSet { - BranchContentMetadata *metadata = [BranchContentMetadata new]; - NSDictionary *dict = metadata.dictionary; - - XCTAssertNotNil(dict); - XCTAssertTrue(dict.allKeys.count == 0); -} - -- (void)testBranchContentMetadataDictionary_AllPropertiesSet { - BranchContentMetadata *metadata = [self branchContentMetadataWithAllPropertiesSet]; - NSDictionary *dict = metadata.dictionary; - - XCTAssertNotNil(dict); - XCTAssertTrue(dict.allKeys.count == 23); - [self verifyBranchContentMetadataDictionaryWithAllPropertiesSet:dict]; -} - -- (void)testBranchContentMetadata_contentMetadataWithDictionary { - BranchContentMetadata *original = [self branchContentMetadataWithAllPropertiesSet]; - NSDictionary *dict = [original dictionary]; - - BranchContentMetadata *metadata = [BranchContentMetadata contentMetadataWithDictionary:dict]; - [self verifyBranchContentMetadataWithAllProperties:metadata]; -} - -- (void)testBranchContentMetadataDescription_NoPropertiesSet { - BranchContentMetadata *metadata = [BranchContentMetadata new]; - NSString *desc = [metadata description]; - XCTAssertTrue([desc containsString:@"BranchContentMetadata"]); - XCTAssertTrue([desc containsString:@"schema: (null) userData: 0 items"]); -} - -- (void)testBranchContentMetadataDescription_AllPropertiesSet { - BranchContentMetadata *metadata = [self branchContentMetadataWithAllPropertiesSet]; - NSString *desc = [metadata description]; - XCTAssertTrue([desc containsString:@"BranchContentMetadata"]); - XCTAssertTrue([desc containsString:@"schema: OTHER userData: 1 items"]); -} - -#pragma mark BranchUniversalObject tests - -- (BranchUniversalObject *)branchUniversalObjectWithAllPropertiesSet { - BranchUniversalObject *buo = [[BranchUniversalObject alloc] initWithCanonicalIdentifier:@"io.branch.testObject"]; - buo.canonicalUrl = @"https://branch.io"; - buo.title = @"Test Title"; - buo.contentDescription = @"the quick brown fox jumps over the lazy dog"; - buo.imageUrl = @"https://branch.io"; - buo.keywords = @[@"keyword1", @"keyword2"]; - buo.expirationDate = [NSDate dateWithTimeIntervalSinceNow:1]; - buo.locallyIndex = YES; - buo.publiclyIndex = YES; - - buo.contentMetadata = [self branchContentMetadataWithAllPropertiesSet]; - return buo; -} - -- (void)verifyBranchUniversalObjectWithAllPropertiesSet:(BranchUniversalObject *)buo { - XCTAssertNotNil(buo); - XCTAssertTrue([@"https://branch.io" isEqualToString:buo.canonicalUrl]); - XCTAssertTrue([@"Test Title" isEqualToString:buo.title]); - XCTAssertTrue([@"the quick brown fox jumps over the lazy dog" isEqualToString:buo.contentDescription]); - XCTAssertTrue([@"https://branch.io" isEqualToString:buo.imageUrl]); - - XCTAssertTrue(buo.keywords.count == 2); - XCTAssertTrue([buo.keywords[0] isEqualToString:@"keyword1"]); - XCTAssertTrue([buo.keywords[1] isEqualToString:@"keyword2"]); - - XCTAssertTrue([buo.creationDate compare:buo.expirationDate] == NSOrderedAscending); - - XCTAssertTrue(buo.locallyIndex); - XCTAssertTrue(buo.publiclyIndex); - - [self verifyBranchContentMetadataWithAllProperties:buo.contentMetadata]; -} - -- (void)verifyBranchUniversalObjectDictionaryWithAllPropertiesSet:(NSDictionary *)dict { - XCTAssertTrue([@"io.branch.testObject" isEqualToString:dict[@"$canonical_identifier"]]); - XCTAssertTrue([@"https://branch.io" isEqualToString:dict[@"$canonical_url"]]); - XCTAssertTrue([@"Test Title" isEqualToString:dict[@"$og_title"]]); - XCTAssertTrue([@"the quick brown fox jumps over the lazy dog" isEqualToString:dict[@"$og_description"]]); - XCTAssertTrue([@"https://branch.io" isEqualToString:dict[@"$og_image_url"]]); - - XCTAssertTrue(dict[@"$locally_indexable"]); - XCTAssertTrue(dict[@"$publicly_indexable"]); - - XCTAssertTrue([dict[@"$creation_timestamp"] isKindOfClass:NSNumber.class]); - XCTAssertTrue([dict[@"$exp_date"] isKindOfClass:NSNumber.class]); - NSNumber *creationDate = dict[@"$creation_timestamp"]; - NSNumber *expirationDate = dict[@"$exp_date"]; - XCTAssertTrue([creationDate compare:expirationDate] == NSOrderedAscending); - - XCTAssertTrue([dict[@"$keywords"] isKindOfClass:NSArray.class]); - NSArray *tmp = dict[@"$keywords"]; - XCTAssertTrue(tmp.count == 2); - XCTAssertTrue([tmp[0] isEqualToString:@"keyword1"]); - XCTAssertTrue([tmp[1] isEqualToString:@"keyword2"]); - - // the BranchContentMetadata dictionary is NOT in a sub dictionary, it is merged in at the top level - [self verifyBranchContentMetadataDictionaryWithAllPropertiesSet:dict]; -} - -- (void)testBranchUniversalObjectCreation { - BranchUniversalObject *buo = [BranchUniversalObject new]; - XCTAssertNotNil(buo); - - XCTAssertNil(buo.canonicalIdentifier); - XCTAssertNil(buo.canonicalUrl); - XCTAssertNil(buo.title); - XCTAssertNil(buo.contentDescription); - XCTAssertNil(buo.imageUrl); - XCTAssertNil(buo.keywords); - XCTAssertNil(buo.creationDate); - XCTAssertNil(buo.expirationDate); - XCTAssertFalse(buo.locallyIndex); - XCTAssertFalse(buo.publiclyIndex); - - XCTAssertNotNil(buo.contentMetadata); -} - -- (void)testBranchUniversalObjectCreation_initWithCanonicalIdentifier { - BranchUniversalObject *buo = [[BranchUniversalObject alloc] initWithCanonicalIdentifier:@"io.branch.testObject"]; - XCTAssertNotNil(buo); - - XCTAssertTrue([@"io.branch.testObject" isEqualToString:buo.canonicalIdentifier]); - XCTAssertNil(buo.canonicalUrl); - XCTAssertNil(buo.title); - XCTAssertNil(buo.contentDescription); - XCTAssertNil(buo.imageUrl); - XCTAssertNil(buo.keywords); - XCTAssertNotNil(buo.creationDate); - XCTAssertNil(buo.expirationDate); - XCTAssertFalse(buo.locallyIndex); - XCTAssertFalse(buo.publiclyIndex); - - XCTAssertNotNil(buo.contentMetadata); -} - -- (void)testBranchUniversalObjectCreation_initWithTitle { - BranchUniversalObject *buo = [[BranchUniversalObject alloc] initWithTitle:@"Test Title"]; - XCTAssertNotNil(buo); - - XCTAssertNil(buo.canonicalIdentifier); - XCTAssertNil(buo.canonicalUrl); - XCTAssertTrue([@"Test Title" isEqualToString:buo.title]); - XCTAssertNil(buo.contentDescription); - XCTAssertNil(buo.imageUrl); - XCTAssertNil(buo.keywords); - XCTAssertNotNil(buo.creationDate); - XCTAssertNil(buo.expirationDate); - XCTAssertFalse(buo.locallyIndex); - XCTAssertFalse(buo.publiclyIndex); - - XCTAssertNotNil(buo.contentMetadata); -} - -- (void)testBranchUniversalObject_AllPropertiesSet { - BranchUniversalObject *buo = [self branchUniversalObjectWithAllPropertiesSet]; - [self verifyBranchUniversalObjectWithAllPropertiesSet:buo]; -} - -- (void)testBranchUniversalObjectDescription_AllPropertiesSet { - BranchUniversalObject *buo = [self branchUniversalObjectWithAllPropertiesSet]; - NSString *desc = buo.description; - - // Verifies a few properties used to generate the description string - XCTAssertTrue([desc containsString:@"BranchUniversalObject"]); - XCTAssertTrue([desc containsString:@"canonicalIdentifier: io.branch.testObject"]); - XCTAssertTrue([desc containsString:@"title: Test Title"]); - XCTAssertTrue([desc containsString:@"contentDescription: the quick brown fox jumps over the lazy dog"]); -} - -- (void)testBranchUniversalObjectDictionary_AllPropertiesSet { - BranchUniversalObject *buo = [self branchUniversalObjectWithAllPropertiesSet]; - NSDictionary *dict = buo.dictionary; - - XCTAssertNotNil(dict); - XCTAssertTrue(dict.allKeys.count == 33); - [self verifyBranchUniversalObjectDictionaryWithAllPropertiesSet:dict]; -} - -- (void)testBranchUniversalObject_objectWithDictionary { - BranchUniversalObject *original = [self branchUniversalObjectWithAllPropertiesSet]; - NSDictionary *dict = [original dictionary]; - - BranchUniversalObject *buo = [BranchUniversalObject objectWithDictionary:dict]; - [self verifyBranchUniversalObjectWithAllPropertiesSet:buo]; -} - -- (void)testBranchUniversalObject_getDictionaryWithCompleteLinkProperties_NoLinkPropertiesSet { - BranchUniversalObject *original = [self branchUniversalObjectWithAllPropertiesSet]; - BranchLinkProperties *linkProperties = [BranchLinkProperties new]; - NSDictionary *dict = [original getDictionaryWithCompleteLinkProperties:linkProperties]; - - XCTAssertNotNil(dict); - XCTAssertTrue([@(0) isEqualToNumber:dict[@"~duration"]]); -} - -- (void)testBranchUniversalObject_getDictionaryWithCompleteLinkProperties_AllLinkPropertiesSet { - BranchUniversalObject *original = [self branchUniversalObjectWithAllPropertiesSet]; - BranchLinkProperties *linkProperties = [BranchLinkProperties new]; - - linkProperties.tags = @[@"tag1", @"tag2"]; - linkProperties.feature = @"test feature"; - linkProperties.alias = @"test alias"; - linkProperties.channel = @"test channel"; - linkProperties.matchDuration = 10; - - // BranchUniversalObject.controlParams overwrites BranchContentMetadata.customMetadata - linkProperties.controlParams = @{ - @"testControlParam": @"test control param", - //@"custom0": @"test control param" - }; - - NSDictionary *dict = [original getDictionaryWithCompleteLinkProperties:linkProperties]; - XCTAssertNotNil(dict); - XCTAssertTrue(dict.allKeys.count == 39); - - XCTAssertTrue([@(10) isEqualToNumber:dict[@"~duration"]]); - XCTAssertTrue([@"test alias" isEqualToString:dict[@"~alias"]]); - XCTAssertTrue([@"test channel" isEqualToString:dict[@"~channel"]]); - XCTAssertTrue([@"test feature" isEqualToString:dict[@"~feature"]]); - - XCTAssertTrue([@"test control param" isEqualToString:dict[@"testControlParam"]]); - - // BranchUniversalObject fields are at the top level of the dictionary - [self verifyBranchUniversalObjectDictionaryWithAllPropertiesSet:dict]; -} - -- (void)testBranchUniversalObject_getParamsForServerRequestWithAddedLinkProperties_NoLinkPropertiesSet { - BranchUniversalObject *original = [self branchUniversalObjectWithAllPropertiesSet]; - BranchLinkProperties *linkProperties = [BranchLinkProperties new]; - - // Nothing is added with this call - NSDictionary *dict = [original getParamsForServerRequestWithAddedLinkProperties:linkProperties]; - - XCTAssertNotNil(dict); - - // BranchUniversalObject fields are at the top level of the dictionary - [self verifyBranchUniversalObjectDictionaryWithAllPropertiesSet:dict]; -} - -- (void)testBranchUniversalObject_getParamsForServerRequestWithAddedLinkProperties_AllLinkPropertiesSet { - BranchUniversalObject *original = [self branchUniversalObjectWithAllPropertiesSet]; - BranchLinkProperties *linkProperties = [BranchLinkProperties new]; - linkProperties.tags = @[@"tag1", @"tag2"]; - linkProperties.feature = @"test feature"; - linkProperties.alias = @"test alias"; - linkProperties.channel = @"test channel"; - linkProperties.matchDuration = 10; - - // BranchUniversalObject.controlParams overwrites BranchContentMetadata.customMetadata - linkProperties.controlParams = @{ - @"testControlParam": @"test control param", - //@"custom0": @"test control param" - }; - - NSDictionary *dict = [original getParamsForServerRequestWithAddedLinkProperties:linkProperties]; - XCTAssertNotNil(dict); - XCTAssertTrue(dict.allKeys.count == 34); - - // only the control parameters are in the dictionary - XCTAssertTrue([@"test control param" isEqualToString:dict[@"testControlParam"]]); - XCTAssertNil(dict[@"~duration"]); - XCTAssertNil(dict[@"~alias"]); - XCTAssertNil(dict[@"~channel"]); - XCTAssertNil(dict[@"~feature"]); - - // BranchUniversalObject fields are at the top level of the dictionary - [self verifyBranchUniversalObjectDictionaryWithAllPropertiesSet:dict]; -} - -@end diff --git a/BranchSDKTests/DispatchToIsolationQueueTests.m b/BranchSDKTests/DispatchToIsolationQueueTests.m deleted file mode 100644 index 89043aa94..000000000 --- a/BranchSDKTests/DispatchToIsolationQueueTests.m +++ /dev/null @@ -1,76 +0,0 @@ -// -// BNCPreInitBlockTests.m -// Branch-SDK-Tests -// -// Created by Benas Klastaitis on 12/9/19. -// Copyright © 2019 Branch, Inc. All rights reserved. -// - -#import -// #import "Branch.h" - -@interface DispatchToIsolationQueueTests : XCTestCase -// @property (nonatomic, strong, readwrite) Branch *branch; -// @property (nonatomic, strong, readwrite) BNCPreferenceHelper *prefHelper; -@end - -// this is an integration test, needs to be moved to a new target -@implementation DispatchToIsolationQueueTests - -- (void)setUp { - // self.branch = [Branch getInstance]; - // self.prefHelper = [[BNCPreferenceHelper alloc] init]; -} - -- (void)tearDown { - // [self.prefHelper setRequestMetadataKey:@"$marketing_cloud_visitor_id" value:@"dummy"]; -} - -- (void)testPreInitBlock { - // __block XCTestExpectation *expectation = [self expectationWithDescription:@""]; - - // [self.branch dispatchToIsolationQueue:^{ - // dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); - // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - // [self.branch setRequestMetadataKey:@"$marketing_cloud_visitor_id" value:@"adobeID123"]; - // dispatch_semaphore_signal(semaphore); - // }); - // dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); - // }]; - - // [self.branch initSessionWithLaunchOptions:nil andRegisterDeepLinkHandlerUsingBranchUniversalObject: - // ^ (BranchUniversalObject * _Nullable universalObject, - // BranchLinkProperties * _Nullable linkProperties, - // NSError * _Nullable error) { - // [expectation fulfill]; - // }]; - - // // test that session initialization blocking works - // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - // id initializationStatus = [self.branch valueForKey:@"initializationStatus"]; - // XCTAssertTrue([self enumIntValueFromId:initializationStatus] == 0);// uninitialized - // XCTAssertNil([[self.prefHelper requestMetadataDictionary] objectForKey:@"$marketing_cloud_visitor_id"]); - // }); - - // // test that initialization does happen afterwards and that pre init block was executed - // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - // id initializationStatus = [self.branch valueForKey:@"initializationStatus"]; - // XCTAssertTrue([self enumIntValueFromId:initializationStatus] == 2);// initialized - - // XCTAssertTrue([[[self.prefHelper requestMetadataDictionary] objectForKey:@"$marketing_cloud_visitor_id"] isEqualToString:@"adobeID123"]); - // }); - - - // [self waitForExpectationsWithTimeout:6 handler:^(NSError * _Nullable error) { - // NSLog(@"%@", error); - // }]; -} - -// -(int)enumIntValueFromId:(id)enumValueId { -// if (![enumValueId respondsToSelector:@selector(intValue)]) -// return -1; - -// return [enumValueId intValue]; -// } - -@end diff --git a/BranchSDKTests/NSErrorBranchTests.m b/BranchSDKTests/NSErrorBranchTests.m deleted file mode 100644 index 4399b7484..000000000 --- a/BranchSDKTests/NSErrorBranchTests.m +++ /dev/null @@ -1,54 +0,0 @@ -/** - @file NSErrorBranchCategoryTests.m - @package Branch-SDK - @brief Branch error tests. - - @author Edward Smith - @date August 2017 - @copyright Copyright © 2017 Branch. All rights reserved. -*/ - -#import -#import "NSError+Branch.h" - -@interface NSErrorBranchTests : XCTestCase -@end - -@implementation NSErrorBranchTests - -- (void)testErrorDomain { - XCTAssertTrue([@"io.branch.sdk.error" isEqualToString:[NSError bncErrorDomain]]); -} - -- (void)testError { - NSError *error = [NSError branchErrorWithCode:BNCInitError]; - XCTAssert(error.domain == [NSError bncErrorDomain]); - XCTAssert(error.code == BNCInitError); - XCTAssert([error.localizedDescription isEqualToString: - @"The Branch user session has not been initialized."] - ); -} - -- (void)testErrorWithUnderlyingError { - NSError *underlyingError = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileNoSuchFileError userInfo:nil]; - NSError *error = [NSError branchErrorWithCode:BNCServerProblemError error:underlyingError]; - - XCTAssert(error.domain == [NSError bncErrorDomain]); - XCTAssert(error.code == BNCServerProblemError); - XCTAssert([error.localizedDescription isEqualToString: @"Trouble reaching the Branch servers, please try again shortly."]); - - XCTAssert(error.userInfo[NSUnderlyingErrorKey] == underlyingError); - XCTAssert([error.localizedFailureReason isEqualToString:@"The file doesn’t exist."]); -} - -- (void)testErrorWithMessage { - NSString *message = [NSString stringWithFormat:@"Network operation of class '%@' does not conform to the BNCNetworkOperationProtocol.", NSStringFromClass([self class])]; - NSError *error = [NSError branchErrorWithCode:BNCNetworkServiceInterfaceError localizedMessage:message]; - - XCTAssert(error.domain == [NSError bncErrorDomain]); - XCTAssert(error.code == BNCNetworkServiceInterfaceError); - XCTAssert([error.localizedDescription isEqualToString: @"The underlying network service does not conform to the BNCNetworkOperationProtocol."]); - XCTAssert([error.localizedFailureReason isEqualToString: @"Network operation of class 'NSErrorBranchTests' does not conform to the BNCNetworkOperationProtocol."]); -} - -@end diff --git a/BranchSDKTests/NSMutableDictionaryBranchTests.m b/BranchSDKTests/NSMutableDictionaryBranchTests.m deleted file mode 100644 index 9fadbefb2..000000000 --- a/BranchSDKTests/NSMutableDictionaryBranchTests.m +++ /dev/null @@ -1,389 +0,0 @@ -// -// NSMutableDictionaryBranchTests.m -// Branch-SDK-Tests -// -// Created by Ernest Cho on 2/9/24. -// Copyright © 2024 Branch, Inc. All rights reserved. -// - -#import -#import "NSMutableDictionary+Branch.h" - -@interface NSMutableDictionaryBranchTests : XCTestCase - -@end - -@implementation NSMutableDictionaryBranchTests - -- (void)setUp { - // Put setup code here. This method is called before the invocation of each test method in the class. -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. -} - -- (void)testSafeSetObject_StringString { - NSMutableDictionary *dict = [NSMutableDictionary new]; - - [dict bnc_safeSetObject:@"foo" forKey:@"bar"]; - XCTAssertTrue(dict.count == 1); - XCTAssertTrue([@"foo" isEqualToString:dict[@"bar"]]); -} - -- (void)testSafeSetObject_NilString { - NSMutableDictionary *dict = [NSMutableDictionary new]; - - [dict bnc_safeSetObject:nil forKey:@"bar"]; - XCTAssertTrue(dict.count == 0); -} - -- (void)testSafeSetObject_StringNil { - NSMutableDictionary *dict = [NSMutableDictionary new]; - - [dict bnc_safeSetObject:@"foo" forKey:nil]; - XCTAssertTrue(dict.count == 0); -} - -- (void)testSafeAddEntriesFromDictionary { - - // NSStrings are never copied, so use NSMutableStrings - NSMutableDictionary *other = [NSMutableDictionary new]; - other[@"foo"] = [[NSMutableString alloc] initWithString:@"bar"]; - other[@"hello"] = [[NSMutableString alloc] initWithString:@"world"]; - - NSMutableDictionary *dict = [NSMutableDictionary new]; - [dict bnc_safeAddEntriesFromDictionary:other]; - - NSArray *keyset = [other allKeys]; - for (id key in keyset) { - id original = other[key]; - id copy = dict[key]; - - // same object value - XCTAssertTrue([original isEqual:copy]); - - // different object instance - XCTAssertTrue(original != copy); - } -} - -- (void)testSafeAddEntriesFromDictionary_NestedArray { - - // NSStrings are never copied, so use NSMutableStrings - NSMutableDictionary *other = [NSMutableDictionary new]; - other[@"foo"] = [[NSMutableString alloc] initWithString:@"bar"]; - other[@"hello"] = [[NSMutableString alloc] initWithString:@"world"]; - - NSMutableArray *array = [NSMutableArray new]; - [array addObject:[[NSMutableString alloc] initWithString:@"dog"]]; - [array addObject:[[NSMutableString alloc] initWithString:@"cat"]]; - [array addObject:[[NSMutableString alloc] initWithString:@"child"]]; - - other[@"good"] = array; - - NSMutableDictionary *dict = [NSMutableDictionary new]; - [dict bnc_safeAddEntriesFromDictionary:other]; - - NSArray *keyset = [other allKeys]; - for (id key in keyset) { - id original = other[key]; - id copy = dict[key]; - - // same object value - XCTAssertTrue([original isEqual:copy]); - - // different object instance - XCTAssertTrue(original != copy); - } - - // confirm that copyItems is a one layer deep copy - NSArray *arrayCopy = dict[@"good"]; - XCTAssertTrue(array.count == arrayCopy.count); - XCTAssertTrue(array != arrayCopy); - - for (int i=0; i -#import "NSString+Branch.h" - -#define _countof(array) (sizeof(array)/sizeof(array[0])) - -@interface NSStringBranchTests : XCTestCase -@end - -@implementation NSStringBranchTests - -- (void)testMaskEqual { - XCTAssertTrue([@"0123" bnc_isEqualToMaskedString:@"0123"]); - XCTAssertFalse([@"0123" bnc_isEqualToMaskedString:@"012"]); - XCTAssertFalse([@"0123" bnc_isEqualToMaskedString:@"01234"]); - XCTAssertTrue([@"0123" bnc_isEqualToMaskedString:@"01*3"]); - XCTAssertFalse([@"0123" bnc_isEqualToMaskedString:@"01*4"]); - XCTAssertTrue([@"0123" bnc_isEqualToMaskedString:@"*123"]); - XCTAssertTrue([@"0123" bnc_isEqualToMaskedString:@"012*"]); - XCTAssertTrue([@"日本語123日本語" bnc_isEqualToMaskedString:@"日本語123日本語"]); - XCTAssertFalse([@"日本語123日本語" bnc_isEqualToMaskedString:@"日本語1234本語"]); - XCTAssertTrue([@"日本語123日本語" bnc_isEqualToMaskedString:@"日本語***日本語"]); - XCTAssertTrue([@"日本語123日本語" bnc_isEqualToMaskedString:@"***123日本語"]); -} - -@end diff --git a/BranchSDKTestsHostApp/AppDelegate.h b/BranchSDKTestsHostApp/AppDelegate.h deleted file mode 100644 index ba35f21cd..000000000 --- a/BranchSDKTestsHostApp/AppDelegate.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// AppDelegate.h -// BranchSDKTestsHostApp -// -// Created by Nidhi Dixit on 7/6/25. -// - -#import - -@interface AppDelegate : UIResponder - - -@end - diff --git a/BranchSDKTestsHostApp/AppDelegate.m b/BranchSDKTestsHostApp/AppDelegate.m deleted file mode 100644 index 3c267c2e5..000000000 --- a/BranchSDKTestsHostApp/AppDelegate.m +++ /dev/null @@ -1,40 +0,0 @@ -// -// AppDelegate.m -// BranchSDKTestsHostApp -// -// Created by Nidhi Dixit on 7/6/25. -// - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - // Override point for customization after application launch. - return YES; -} - - -#pragma mark - UISceneSession lifecycle - - -- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options { - // Called when a new scene session is being created. - // Use this method to select a configuration to create the new scene with. - return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role]; -} - - -- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions { - // Called when the user discards a scene session. - // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. - // Use this method to release any resources that were specific to the discarded scenes, as they will not return. -} - - -@end diff --git a/BranchSDKTestsHostApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/BranchSDKTestsHostApp/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 230588010..000000000 --- a/BranchSDKTestsHostApp/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "tinted" - } - ], - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/BranchSDKTestsHostApp/SceneDelegate.h b/BranchSDKTestsHostApp/SceneDelegate.h deleted file mode 100644 index ae4e37f24..000000000 --- a/BranchSDKTestsHostApp/SceneDelegate.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// SceneDelegate.h -// BranchSDKTestsHostApp -// -// Created by Nidhi Dixit on 7/6/25. -// - -#import - -@interface SceneDelegate : UIResponder - -@property (strong, nonatomic) UIWindow * window; - -@end - diff --git a/BranchSDKTestsHostApp/SceneDelegate.m b/BranchSDKTestsHostApp/SceneDelegate.m deleted file mode 100644 index be25ed27f..000000000 --- a/BranchSDKTestsHostApp/SceneDelegate.m +++ /dev/null @@ -1,57 +0,0 @@ -// -// SceneDelegate.m -// BranchSDKTestsHostApp -// -// Created by Nidhi Dixit on 7/6/25. -// - -#import "SceneDelegate.h" - -@interface SceneDelegate () - -@end - -@implementation SceneDelegate - - -- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { - // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. - // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. - // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). -} - - -- (void)sceneDidDisconnect:(UIScene *)scene { - // Called as the scene is being released by the system. - // This occurs shortly after the scene enters the background, or when its session is discarded. - // Release any resources associated with this scene that can be re-created the next time the scene connects. - // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). -} - - -- (void)sceneDidBecomeActive:(UIScene *)scene { - // Called when the scene has moved from an inactive state to an active state. - // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. -} - - -- (void)sceneWillResignActive:(UIScene *)scene { - // Called when the scene will move from an active state to an inactive state. - // This may occur due to temporary interruptions (ex. an incoming phone call). -} - - -- (void)sceneWillEnterForeground:(UIScene *)scene { - // Called as the scene transitions from the background to the foreground. - // Use this method to undo the changes made on entering the background. -} - - -- (void)sceneDidEnterBackground:(UIScene *)scene { - // Called as the scene transitions from the foreground to the background. - // Use this method to save data, release shared resources, and store enough scene-specific state information - // to restore the scene back to its current state. -} - - -@end diff --git a/BranchSDKTestsHostApp/ViewController.h b/BranchSDKTestsHostApp/ViewController.h deleted file mode 100644 index 83b3d1118..000000000 --- a/BranchSDKTestsHostApp/ViewController.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// ViewController.h -// BranchSDKTestsHostApp -// -// Created by Nidhi Dixit on 7/6/25. -// - -#import - -@interface ViewController : UIViewController - - -@end - diff --git a/BranchSDKTestsHostApp/ViewController.m b/BranchSDKTestsHostApp/ViewController.m deleted file mode 100644 index 0a3c38aa1..000000000 --- a/BranchSDKTestsHostApp/ViewController.m +++ /dev/null @@ -1,22 +0,0 @@ -// -// ViewController.m -// BranchSDKTestsHostApp -// -// Created by Nidhi Dixit on 7/6/25. -// - -#import "ViewController.h" - -@interface ViewController () - -@end - -@implementation ViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - // Do any additional setup after loading the view. -} - - -@end diff --git a/BranchSDKTestsHostApp/cannedData/example.json b/BranchSDKTestsHostApp/cannedData/example.json deleted file mode 100644 index d3be9b233..000000000 --- a/BranchSDKTestsHostApp/cannedData/example.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "user_string": "test user", - "user_number": 3.14, - "user_dict": { - "id": "273e4c5da13b978ee2f78f8997abd972959c184aaffb8cad716721a00a08d32b", - "name": "hello@branch.io" - }, - "user_dict_mixed": { - "id": 123, - "name": "hello@branch.io" - }, - "user_dict_numbers": { - "id": 123, - "name": 42 - }, - "user_array": [ - "123", - "abc", - "xyz" - ], - "user_array_mixed": [ - "abc", - 123, - "xyz" - ], - "user_array_numbers": [ - 1, - 2, - 3 - ] -} diff --git a/BranchSDKTestsHostApp/cannedData/latd.json b/BranchSDKTestsHostApp/cannedData/latd.json deleted file mode 100644 index cc8d42631..000000000 --- a/BranchSDKTestsHostApp/cannedData/latd.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "last_attributed_touch_data": { - "$3p": "hello", - "~campaign": "world" - }, - "attribution_window": 30 -} diff --git a/BranchSDKTestsHostApp/cannedData/latd_empty_data.json b/BranchSDKTestsHostApp/cannedData/latd_empty_data.json deleted file mode 100644 index 5561c6a3c..000000000 --- a/BranchSDKTestsHostApp/cannedData/latd_empty_data.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "last_attributed_touch_data": { }, - "attribution_window": 30 -} diff --git a/BranchSDKTestsHostApp/cannedData/latd_missing_data.json b/BranchSDKTestsHostApp/cannedData/latd_missing_data.json deleted file mode 100644 index 5dfcf058b..000000000 --- a/BranchSDKTestsHostApp/cannedData/latd_missing_data.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "attribution_window": 30 -} diff --git a/BranchSDKTestsHostApp/cannedData/latd_missing_window.json b/BranchSDKTestsHostApp/cannedData/latd_missing_window.json deleted file mode 100644 index 7e4649891..000000000 --- a/BranchSDKTestsHostApp/cannedData/latd_missing_window.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "last_attributed_touch_data": { - "$3p": "hello", - "~campaign": "world" - } -} diff --git a/BranchSDKTestsHostApp/main.m b/BranchSDKTestsHostApp/main.m deleted file mode 100644 index abfb64588..000000000 --- a/BranchSDKTestsHostApp/main.m +++ /dev/null @@ -1,18 +0,0 @@ -// -// main.m -// BranchSDKTestsHostApp -// -// Created by Nidhi Dixit on 7/6/25. -// - -#import -#import "AppDelegate.h" - -int main(int argc, char * argv[]) { - NSString * appDelegateClassName; - @autoreleasepool { - // Setup code that might create autoreleased objects goes here. - appDelegateClassName = NSStringFromClass([AppDelegate class]); - } - return UIApplicationMain(argc, argv, nil, appDelegateClassName); -} diff --git a/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.pbxproj b/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.pbxproj new file mode 100644 index 000000000..6117713fe --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.pbxproj @@ -0,0 +1,586 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 55; + objects = { + +/* Begin PBXBuildFile section */ + 180748E82833A914006DB0FA /* ReadLogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 180748E72833A914006DB0FA /* ReadLogViewController.swift */; }; + 180748EA2833CC85006DB0FA /* ParentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 180748E92833CC85006DB0FA /* ParentViewController.swift */; }; + 182B1F43282E0ECE00EA8C70 /* AddMetaDataVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182B1F42282E0ECE00EA8C70 /* AddMetaDataVC.swift */; }; + 182B1F45282E210B00EA8C70 /* MetaDataTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182B1F44282E210B00EA8C70 /* MetaDataTableViewCell.swift */; }; + 183F6FA2282D109800E293F6 /* TrackContentVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 183F6FA1282D109800E293F6 /* TrackContentVC.swift */; }; + 1877918A283C8D2400229CD5 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18779189283C8D2400229CD5 /* Utils.swift */; }; + 1889ACED283BE1C9009E3601 /* NSURLSessionBranch.m in Sources */ = {isa = PBXBuildFile; fileRef = 1889ACEC283BE1C9009E3601 /* NSURLSessionBranch.m */; }; + 18AC5ADE283F61430098736E /* LogFileListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18AC5ADD283F61430098736E /* LogFileListViewController.swift */; }; + 2A2347C154C6746FA55C3649 /* Pods_DeepLinkDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDBB5A837B0C008CA5BEC1EF /* Pods_DeepLinkDemo.framework */; }; + 7E1A39D42818289B002B302D /* DispalyVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E1A39D32818289B002B302D /* DispalyVC.swift */; }; + 7E2AE639280ED92800142446 /* CreateObjectReferenceObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E2AE638280ED92800142446 /* CreateObjectReferenceObject.swift */; }; + 7E2AE63B280EE1F700142446 /* GenerateURLVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E2AE63A280EE1F700142446 /* GenerateURLVC.swift */; }; + 7E2AE63F280EE23500142446 /* NavigateContentVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E2AE63E280EE23500142446 /* NavigateContentVC.swift */; }; + 7E37E69B280CF9D1003E42DB /* CommonMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E37E69A280CF9D1003E42DB /* CommonMethod.swift */; }; + 7E37E69D280D061E003E42DB /* SIAlertView in Resources */ = {isa = PBXBuildFile; fileRef = 7E37E69C280D061E003E42DB /* SIAlertView */; }; + 7E37E6A1280D12E2003E42DB /* img.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E37E6A0280D12E2003E42DB /* img.png */; }; + 7E6505F6281B003C006179FF /* ReadVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E6505F5281B003C006179FF /* ReadVC.swift */; }; + 7E7477CA2809C46C0088A7D3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E7477C92809C46C0088A7D3 /* AppDelegate.swift */; }; + 7E7477CE2809C46C0088A7D3 /* HomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E7477CD2809C46C0088A7D3 /* HomeViewController.swift */; }; + 7E7477D12809C46C0088A7D3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7E7477CF2809C46C0088A7D3 /* Main.storyboard */; }; + 7E7477D32809C46D0088A7D3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7E7477D22809C46D0088A7D3 /* Assets.xcassets */; }; + 7E7477D62809C46D0088A7D3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7E7477D42809C46D0088A7D3 /* LaunchScreen.storyboard */; }; + 7ED8BFED2835EFA90080C0CB /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ED8BFEC2835EFA90080C0CB /* Reachability.swift */; }; + 7ED8BFEF2835EFB40080C0CB /* CommonAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ED8BFEE2835EFB40080C0CB /* CommonAlert.swift */; }; + 7EE84374281CDFAE00A1561C /* StartupOptionsData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EE84373281CDFAE00A1561C /* StartupOptionsData.swift */; }; + 7EF58D5B2812CF2300BA92D5 /* WebViewVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EF58D5A2812CF2300BA92D5 /* WebViewVC.swift */; }; + B7B7DC2A2859974E00D45FC5 /* TextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7B7DC292859974E00D45FC5 /* TextViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 180748E72833A914006DB0FA /* ReadLogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadLogViewController.swift; sourceTree = ""; }; + 180748E92833CC85006DB0FA /* ParentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParentViewController.swift; sourceTree = ""; }; + 182B1F42282E0ECE00EA8C70 /* AddMetaDataVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddMetaDataVC.swift; sourceTree = ""; }; + 182B1F44282E210B00EA8C70 /* MetaDataTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetaDataTableViewCell.swift; sourceTree = ""; }; + 183F6FA1282D109800E293F6 /* TrackContentVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackContentVC.swift; sourceTree = ""; }; + 18779189283C8D2400229CD5 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; + 1889ACEB283BE1C9009E3601 /* NSURLSessionBranch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSURLSessionBranch.h; sourceTree = ""; }; + 1889ACEC283BE1C9009E3601 /* NSURLSessionBranch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSURLSessionBranch.m; sourceTree = ""; }; + 18AC5ADD283F61430098736E /* LogFileListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogFileListViewController.swift; sourceTree = ""; }; + 7E1A39D32818289B002B302D /* DispalyVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DispalyVC.swift; sourceTree = ""; }; + 7E2AE638280ED92800142446 /* CreateObjectReferenceObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateObjectReferenceObject.swift; sourceTree = ""; }; + 7E2AE63A280EE1F700142446 /* GenerateURLVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenerateURLVC.swift; sourceTree = ""; }; + 7E2AE63E280EE23500142446 /* NavigateContentVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigateContentVC.swift; sourceTree = ""; }; + 7E37E69A280CF9D1003E42DB /* CommonMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonMethod.swift; sourceTree = ""; }; + 7E37E69C280D061E003E42DB /* SIAlertView */ = {isa = PBXFileReference; lastKnownFileType = folder; path = SIAlertView; sourceTree = ""; }; + 7E37E69E280D0676003E42DB /* Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Header.h; sourceTree = ""; }; + 7E37E69F280D06FF003E42DB /* DeepLinkDemo-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DeepLinkDemo-Bridging-Header.h"; sourceTree = ""; }; + 7E37E6A0280D12E2003E42DB /* img.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = img.png; sourceTree = ""; }; + 7E6505F5281B003C006179FF /* ReadVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadVC.swift; sourceTree = ""; }; + 7E7477C62809C46C0088A7D3 /* DeepLinkDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DeepLinkDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7E7477C92809C46C0088A7D3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7E7477CD2809C46C0088A7D3 /* HomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = ""; }; + 7E7477D02809C46C0088A7D3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 7E7477D22809C46D0088A7D3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7E7477D52809C46D0088A7D3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 7E7477D72809C46D0088A7D3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7ED8BFEB2835EFA90080C0CB /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = ""; }; + 7ED8BFEC2835EFA90080C0CB /* Reachability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reachability.swift; sourceTree = ""; }; + 7ED8BFEE2835EFB40080C0CB /* CommonAlert.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommonAlert.swift; sourceTree = ""; }; + 7EE84373281CDFAE00A1561C /* StartupOptionsData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartupOptionsData.swift; sourceTree = ""; }; + 7EF58D5A2812CF2300BA92D5 /* WebViewVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewVC.swift; sourceTree = ""; }; + 7EF58D5C2816D14700BA92D5 /* DeepLinkDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DeepLinkDemo.entitlements; sourceTree = ""; }; + 88EDCA13B444CE5565DC92FA /* Pods-DeepLinkDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DeepLinkDemo.release.xcconfig"; path = "Target Support Files/Pods-DeepLinkDemo/Pods-DeepLinkDemo.release.xcconfig"; sourceTree = ""; }; + B7B7DC292859974E00D45FC5 /* TextViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewController.swift; sourceTree = ""; }; + C06885D21868B25319262FC1 /* Pods-DeepLinkDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DeepLinkDemo.debug.xcconfig"; path = "Target Support Files/Pods-DeepLinkDemo/Pods-DeepLinkDemo.debug.xcconfig"; sourceTree = ""; }; + DDBB5A837B0C008CA5BEC1EF /* Pods_DeepLinkDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DeepLinkDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 7E7477C32809C46C0088A7D3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2A2347C154C6746FA55C3649 /* Pods_DeepLinkDemo.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0D26D1E3284DFA33003FAB18 /* Constants */ = { + isa = PBXGroup; + children = ( + 18779189283C8D2400229CD5 /* Utils.swift */, + 7ED8BFEE2835EFB40080C0CB /* CommonAlert.swift */, + 7E37E69A280CF9D1003E42DB /* CommonMethod.swift */, + ); + path = Constants; + sourceTree = ""; + }; + 29D53CAAE9E9EF2F96296086 /* Frameworks */ = { + isa = PBXGroup; + children = ( + DDBB5A837B0C008CA5BEC1EF /* Pods_DeepLinkDemo.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 7E2AE642280EFF1200142446 /* Controllers */ = { + isa = PBXGroup; + children = ( + 7E7477CD2809C46C0088A7D3 /* HomeViewController.swift */, + B7B7DC292859974E00D45FC5 /* TextViewController.swift */, + 7E2AE638280ED92800142446 /* CreateObjectReferenceObject.swift */, + 7E2AE63A280EE1F700142446 /* GenerateURLVC.swift */, + 7E2AE63E280EE23500142446 /* NavigateContentVC.swift */, + 7E1A39D32818289B002B302D /* DispalyVC.swift */, + 7EF58D5A2812CF2300BA92D5 /* WebViewVC.swift */, + 7E6505F5281B003C006179FF /* ReadVC.swift */, + 183F6FA1282D109800E293F6 /* TrackContentVC.swift */, + 182B1F42282E0ECE00EA8C70 /* AddMetaDataVC.swift */, + 182B1F44282E210B00EA8C70 /* MetaDataTableViewCell.swift */, + 180748E72833A914006DB0FA /* ReadLogViewController.swift */, + 18AC5ADD283F61430098736E /* LogFileListViewController.swift */, + 180748E92833CC85006DB0FA /* ParentViewController.swift */, + ); + path = Controllers; + sourceTree = ""; + }; + 7E7477BD2809C46C0088A7D3 = { + isa = PBXGroup; + children = ( + 7E7477C82809C46C0088A7D3 /* DeepLinkDemo */, + 7E7477C72809C46C0088A7D3 /* Products */, + DB9F65A595474F5DA261D89A /* Pods */, + 29D53CAAE9E9EF2F96296086 /* Frameworks */, + ); + sourceTree = ""; + }; + 7E7477C72809C46C0088A7D3 /* Products */ = { + isa = PBXGroup; + children = ( + 7E7477C62809C46C0088A7D3 /* DeepLinkDemo.app */, + ); + name = Products; + sourceTree = ""; + }; + 7E7477C82809C46C0088A7D3 /* DeepLinkDemo */ = { + isa = PBXGroup; + children = ( + 7E2AE642280EFF1200142446 /* Controllers */, + 1889ACEB283BE1C9009E3601 /* NSURLSessionBranch.h */, + 1889ACEC283BE1C9009E3601 /* NSURLSessionBranch.m */, + 7ED8BFEA2835EF9E0080C0CB /* Reachability */, + 7EF58D5C2816D14700BA92D5 /* DeepLinkDemo.entitlements */, + 7E37E69C280D061E003E42DB /* SIAlertView */, + 7E7477C92809C46C0088A7D3 /* AppDelegate.swift */, + 7EE84373281CDFAE00A1561C /* StartupOptionsData.swift */, + 0D26D1E3284DFA33003FAB18 /* Constants */, + 7E7477CF2809C46C0088A7D3 /* Main.storyboard */, + 7E37E6A0280D12E2003E42DB /* img.png */, + 7E7477D22809C46D0088A7D3 /* Assets.xcassets */, + 7E7477D42809C46D0088A7D3 /* LaunchScreen.storyboard */, + 7E7477D72809C46D0088A7D3 /* Info.plist */, + 7E37E69E280D0676003E42DB /* Header.h */, + 7E37E69F280D06FF003E42DB /* DeepLinkDemo-Bridging-Header.h */, + ); + path = DeepLinkDemo; + sourceTree = ""; + }; + 7ED8BFEA2835EF9E0080C0CB /* Reachability */ = { + isa = PBXGroup; + children = ( + 7ED8BFEB2835EFA90080C0CB /* Reachability.h */, + 7ED8BFEC2835EFA90080C0CB /* Reachability.swift */, + ); + path = Reachability; + sourceTree = ""; + }; + DB9F65A595474F5DA261D89A /* Pods */ = { + isa = PBXGroup; + children = ( + C06885D21868B25319262FC1 /* Pods-DeepLinkDemo.debug.xcconfig */, + 88EDCA13B444CE5565DC92FA /* Pods-DeepLinkDemo.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 7E7477C52809C46C0088A7D3 /* DeepLinkDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7E7477DA2809C46D0088A7D3 /* Build configuration list for PBXNativeTarget "DeepLinkDemo" */; + buildPhases = ( + 8C8C5B24F34C07814525F311 /* [CP] Check Pods Manifest.lock */, + 7E7477C22809C46C0088A7D3 /* Sources */, + 7E7477C32809C46C0088A7D3 /* Frameworks */, + 7E7477C42809C46C0088A7D3 /* Resources */, + 9086714B33BB3D176E3DED70 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DeepLinkDemo; + productName = DeepLinkDemo; + productReference = 7E7477C62809C46C0088A7D3 /* DeepLinkDemo.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 7E7477BE2809C46C0088A7D3 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1330; + LastUpgradeCheck = 1330; + TargetAttributes = { + 7E7477C52809C46C0088A7D3 = { + CreatedOnToolsVersion = 13.3.1; + LastSwiftMigration = 1340; + }; + }; + }; + buildConfigurationList = 7E7477C12809C46C0088A7D3 /* Build configuration list for PBXProject "DeepLinkDemo" */; + compatibilityVersion = "Xcode 13.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 7E7477BD2809C46C0088A7D3; + productRefGroup = 7E7477C72809C46C0088A7D3 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7E7477C52809C46C0088A7D3 /* DeepLinkDemo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 7E7477C42809C46C0088A7D3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7E37E6A1280D12E2003E42DB /* img.png in Resources */, + 7E7477D62809C46D0088A7D3 /* LaunchScreen.storyboard in Resources */, + 7E7477D32809C46D0088A7D3 /* Assets.xcassets in Resources */, + 7E37E69D280D061E003E42DB /* SIAlertView in Resources */, + 7E7477D12809C46C0088A7D3 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 8C8C5B24F34C07814525F311 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-DeepLinkDemo-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 9086714B33BB3D176E3DED70 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-DeepLinkDemo/Pods-DeepLinkDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-DeepLinkDemo/Pods-DeepLinkDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-DeepLinkDemo/Pods-DeepLinkDemo-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 7E7477C22809C46C0088A7D3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 182B1F43282E0ECE00EA8C70 /* AddMetaDataVC.swift in Sources */, + 7E6505F6281B003C006179FF /* ReadVC.swift in Sources */, + 7ED8BFED2835EFA90080C0CB /* Reachability.swift in Sources */, + 7E7477CE2809C46C0088A7D3 /* HomeViewController.swift in Sources */, + 180748E82833A914006DB0FA /* ReadLogViewController.swift in Sources */, + 7E7477CA2809C46C0088A7D3 /* AppDelegate.swift in Sources */, + 7EF58D5B2812CF2300BA92D5 /* WebViewVC.swift in Sources */, + 1877918A283C8D2400229CD5 /* Utils.swift in Sources */, + 1889ACED283BE1C9009E3601 /* NSURLSessionBranch.m in Sources */, + 7E37E69B280CF9D1003E42DB /* CommonMethod.swift in Sources */, + 183F6FA2282D109800E293F6 /* TrackContentVC.swift in Sources */, + 180748EA2833CC85006DB0FA /* ParentViewController.swift in Sources */, + 7E2AE63B280EE1F700142446 /* GenerateURLVC.swift in Sources */, + 7E1A39D42818289B002B302D /* DispalyVC.swift in Sources */, + 182B1F45282E210B00EA8C70 /* MetaDataTableViewCell.swift in Sources */, + 7ED8BFEF2835EFB40080C0CB /* CommonAlert.swift in Sources */, + 7EE84374281CDFAE00A1561C /* StartupOptionsData.swift in Sources */, + 7E2AE639280ED92800142446 /* CreateObjectReferenceObject.swift in Sources */, + 18AC5ADE283F61430098736E /* LogFileListViewController.swift in Sources */, + 7E2AE63F280EE23500142446 /* NavigateContentVC.swift in Sources */, + B7B7DC2A2859974E00D45FC5 /* TextViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 7E7477CF2809C46C0088A7D3 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 7E7477D02809C46C0088A7D3 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 7E7477D42809C46D0088A7D3 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 7E7477D52809C46D0088A7D3 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 7E7477D82809C46D0088A7D3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 7E7477D92809C46D0088A7D3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 7E7477DB2809C46D0088A7D3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C06885D21868B25319262FC1 /* Pods-DeepLinkDemo.debug.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD)"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = R63EM248DP; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = DeepLinkDemo/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = SaaS_SDK_TestBed_iOS; + INFOPLIST_KEY_LSApplicationCategoryType = ""; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = UIInterfaceOrientationPortrait; + INFOPLIST_OUTPUT_FORMAT = "same-as-input"; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Framework", + ); + MARKETING_VERSION = 1.1; + PLIST_FILE_OUTPUT_FORMAT = "same-as-input"; + PRODUCT_BUNDLE_IDENTIFIER = io.branch.saas.sdk.testbed; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "iOS Saas SDK - Dev"; + STRINGS_FILE_OUTPUT_ENCODING = "UTF-8"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; + 7E7477DC2809C46D0088A7D3 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 88EDCA13B444CE5565DC92FA /* Pods-DeepLinkDemo.release.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD)"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 2; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = R63EM248DP; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = DeepLinkDemo/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = SaaS_SDK_TestBed_iOS; + INFOPLIST_KEY_LSApplicationCategoryType = ""; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = UIInterfaceOrientationPortrait; + INFOPLIST_OUTPUT_FORMAT = "same-as-input"; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Framework", + ); + MARKETING_VERSION = 1.1; + ONLY_ACTIVE_ARCH = YES; + PLIST_FILE_OUTPUT_FORMAT = "same-as-input"; + PRODUCT_BUNDLE_IDENTIFIER = io.branch.saas.sdk.testbed; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "iOS Saas SDK - Dev"; + STRINGS_FILE_OUTPUT_ENCODING = "UTF-8"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 7E7477C12809C46C0088A7D3 /* Build configuration list for PBXProject "DeepLinkDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7E7477D82809C46D0088A7D3 /* Debug */, + 7E7477D92809C46D0088A7D3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7E7477DA2809C46D0088A7D3 /* Build configuration list for PBXNativeTarget "DeepLinkDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7E7477DB2809C46D0088A7D3 /* Debug */, + 7E7477DC2809C46D0088A7D3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 7E7477BE2809C46C0088A7D3 /* Project object */; +} diff --git a/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/BranchSDK.xcodeproj/xcshareddata/xcschemes/BranchSDKTests.xcscheme b/DeepLinkDemo/DeepLinkDemo.xcodeproj/xcshareddata/xcschemes/DeepLinkDemo.xcscheme similarity index 58% rename from BranchSDK.xcodeproj/xcshareddata/xcschemes/BranchSDKTests.xcscheme rename to DeepLinkDemo/DeepLinkDemo.xcodeproj/xcshareddata/xcschemes/DeepLinkDemo.xcscheme index 6608b0a6d..a2671aeb8 100644 --- a/BranchSDK.xcodeproj/xcshareddata/xcschemes/BranchSDKTests.xcscheme +++ b/DeepLinkDemo/DeepLinkDemo.xcodeproj/xcshareddata/xcschemes/DeepLinkDemo.xcscheme @@ -1,35 +1,33 @@ + LastUpgradeVersion = "1410" + version = "1.3"> + buildImplicitDependencies = "YES"> + + + + + + - - - - - - - - + BlueprintIdentifier = "7E7477C52809C46C0088A7D3" + BuildableName = "DeepLinkDemo.app" + BlueprintName = "DeepLinkDemo" + ReferencedContainer = "container:DeepLinkDemo.xcodeproj"> @@ -59,15 +57,16 @@ savedToolIdentifier = "" useCustomWorkingDirectory = "NO" debugDocumentVersioning = "YES"> - + + BlueprintIdentifier = "7E7477C52809C46C0088A7D3" + BuildableName = "DeepLinkDemo.app" + BlueprintName = "DeepLinkDemo" + ReferencedContainer = "container:DeepLinkDemo.xcodeproj"> - + diff --git a/DeepLinkDemo/DeepLinkDemo.xcworkspace/contents.xcworkspacedata b/DeepLinkDemo/DeepLinkDemo.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..dbfeee663 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/DeepLinkDemo/DeepLinkDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/DeepLinkDemo/DeepLinkDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/DeepLinkDemo/DeepLinkDemo/AppDelegate.swift b/DeepLinkDemo/DeepLinkDemo/AppDelegate.swift new file mode 100644 index 000000000..bebb005e5 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/AppDelegate.swift @@ -0,0 +1,268 @@ +// +// AppDelegate.swift +// DeepLinkDemo +// +// Created by Rakesh kumar on 4/15/22. +// + +import UIKit +import BranchSDK +import IQKeyboardManager +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? + static var shared: AppDelegate { + return (UIApplication.shared.delegate as? AppDelegate)! + + } + var launchOption = [UIApplication.LaunchOptionsKey : Any]() + var delegate: AppDelegate! + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { + print("didFinishLaunchingWithOptions") + if #available(iOS 10.0, *) { + let center = UNUserNotificationCenter.current() + UNUserNotificationCenter.current().delegate = self + center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in + if granted { + print("Allowed to send Notification") + } else { + print("Not allowed to send Notification") + } + } + }else{ + let notificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) + UIApplication.shared.registerUserNotificationSettings(notificationSettings) + _ = application.beginBackgroundTask(withName: "showNotification", expirationHandler: nil) + } + + Utils.shared.clearAllLogFiles() + Utils.shared.setLogFile("AppLaunch") + IQKeyboardManager.shared().isEnabled = true + StartupOptionsData.setActiveSetDebugEnabled(true) + StartupOptionsData.setPendingSetDebugEnabled(true) + Utils.shared.setLogFile("AppDelegate") + return true + } + + + func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { + + //check for link_click_id + if url.absoluteString.contains("link_click_id") == true{ + return Branch.getInstance().application(app, open: url, options: options) + } + return true + } + + + func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { + // handler for Universal Links + return Branch.getInstance().continue(userActivity) + } + + func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { + // handler for Push Notifications + Branch.getInstance().handlePushNotification(userInfo) + } + + + + func application(_ application: UIApplication, didReceiveRemoteNotification launchOptions: [AnyHashable: Any]) -> Void { + Branch.getInstance().handlePushNotification(launchOptions) + } + + func application(_ application: UIApplication, didReceive notification: UILocalNotification){ + print(#function) + } + + func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, for notification: UILocalNotification, completionHandler: @escaping () -> Void){ + print(#function) + } + + + // Respond to URL scheme links + func application(_ application: UIApplication, + open url: URL, + sourceApplication: String?, + annotation: Any) -> Bool { + + let branchHandled = Branch.getInstance().application(application, + open: url, + sourceApplication: sourceApplication, + annotation: annotation + ) + if(!branchHandled) { + // If not handled by Branch, do other deep link routing for the Facebook SDK, Pinterest SDK, etc + + } + return true + } + + // Respond to Universal Links + func application(_ + application: UIApplication, + continue userActivity: NSUserActivity, + restorationHandler: @escaping ([Any]?) -> Void + ) -> Bool { + let branchHandled = Branch.getInstance().continue(userActivity) + if (userActivity.activityType == NSUserActivityTypeBrowsingWeb) { + if let url = userActivity.webpageURL, + !branchHandled { + + } + } + + // Apply your logic to determine the return value of this method + return true + } + + + func pushNewView() { + if let controller = NavigateContentVC() as? NavigateContentVC { + if let window = self.window, let rootViewController = window.rootViewController { + var currentController = rootViewController + while let presentedController = currentController.presentedViewController { + currentController = presentedController + } + currentController.present(controller, animated: true, completion: nil) + } + } + } + func handleDeepLinkObject(object: BranchUniversalObject, linkProperties:BranchLinkProperties, error:NSError) { + + NSLog("Deep linked with object: %@.", object); + let deeplinkText = object.contentMetadata.customMetadata.value(forKey: "deeplink_text") + let textDetail = "Successfully Deeplinked:\n\n%@\nSession Details:\n\n%@, \(String(describing: deeplinkText)) \(String(describing: Branch.getInstance().getLatestReferringParams()?.description))" + NSLog(textDetail) + self.pushNewView() + } + + + + + func getBranchData(_ launchOptions: [UIApplication.LaunchOptionsKey : Any]?) { + + Branch.getInstance().initSession( + launchOptions: launchOptions, + automaticallyDisplayDeepLinkController: false, + deepLinkHandler: { params, error in + + defer { + let notificationName = Notification.Name("BranchCallbackCompleted") + NotificationCenter.default.post(name: notificationName, object: nil) + } + + guard error == nil else { + NSLog("Branch TestBed: Initialization failed: " + error!.localizedDescription) + return + } + + guard let paramsDictionary = (params as? Dictionary) else { + NSLog("No Branch parameters returned") + return + } + + let clickedBranchLink = params?[BRANCH_INIT_KEY_CLICKED_BRANCH_LINK] as! Bool? + if let referringLink = paramsDictionary["~referring_link"] as! String?, + let trackerId = paramsDictionary["ios_tracker_id"] as! String?, + let clickedBranchLink = clickedBranchLink, + clickedBranchLink { + var adjustUrl = URLComponents(string: referringLink) + var adjust_tracker:URLQueryItem + if referringLink.starts(with: "https://") || referringLink.starts(with: "http://") { + adjust_tracker = URLQueryItem(name: "adjust_t", value: trackerId) + } else { + adjust_tracker = URLQueryItem(name: "adjust_tracker", value: trackerId) + } + let adjust_campaign = URLQueryItem(name: "adjust_campaign", value: paramsDictionary[BRANCH_INIT_KEY_CAMPAIGN] as? String) + let adjust_adgroup = URLQueryItem(name: "adjust_adgroup", value: paramsDictionary[BRANCH_INIT_KEY_CHANNEL] as? String) + let adjust_creative = URLQueryItem(name: "adjust_creative", value: paramsDictionary[BRANCH_INIT_KEY_FEATURE] as? String) + let queryItems = [adjust_tracker,adjust_campaign,adjust_adgroup,adjust_creative] + adjustUrl?.queryItems = queryItems +// if let url = adjustUrl?.url { +// //Adjust.appWillOpen(url) +// } + } + // Deeplinking logic for use when automaticallyDisplayDeepLinkController = false + if let clickedBranchLink = clickedBranchLink, + clickedBranchLink { + let nc = self.window!.rootViewController as! UINavigationController + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "DispalyVC") as? DispalyVC { + let linkurl = UserDefaults.standard.value(forKey: "link") as? String ?? "" + //let referringLink = paramsDictionary["~referring_link"] as! String + let content = String(format:"\nReferring link: %@ \n\nSession Details:\n %@", linkurl, paramsDictionary.jsonStringRepresentation!) + vc.textDescription = content + vc.appData = paramsDictionary + vc.linkURL = linkurl + nc.pushViewController(vc, animated: true) + } + } else { + NSLog("Branch TestBed: Finished init with params\n%@", paramsDictionary.description) + } + }) + } + + + func handleURL(_ url: URL) { + guard url.pathComponents.count >= 3 else { return } + + let section = url.pathComponents[1] + let detail = url.pathComponents[2] + + switch section { + case "post": + guard let id = Int(detail) else { break } + // navigateToItem(id) + case "settings": + //navigateToSettings(detail) + break + default: break + } + } + +} + + +@available(iOS 10.0, *) +extension AppDelegate: UNUserNotificationCenterDelegate{ + + func getApprovalForSendingNotification(){ + if #available(iOS 11.0, *) { + let center = UNUserNotificationCenter.current() + UNUserNotificationCenter.current().delegate = self + center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in + if granted { + print("Allowed to send Notification") + } else { + print("Not allowed to send Notification") + } + } + }else{ + let notificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) + UIApplication.shared.registerUserNotificationSettings(notificationSettings) + } + } + func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { + completionHandler([.alert, .badge, .sound]) + } + func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { + print(response) + let content = response.notification.request.content + print(content.userInfo) + Branch.getInstance().handlePushNotification(content.userInfo) + } + +} +extension Dictionary { + var jsonStringRepresentation: String? { + guard let theJSONData = try? JSONSerialization.data(withJSONObject: self, + options: [.prettyPrinted]) else { + return nil + } + + return String(data: theJSONData, encoding: .ascii) + } +} diff --git a/BranchSDKTestsHostApp/Assets.xcassets/AccentColor.colorset/Contents.json b/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from BranchSDKTestsHostApp/Assets.xcassets/AccentColor.colorset/Contents.json rename to DeepLinkDemo/DeepLinkDemo/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/AppIcon.appiconset/Contents.json b/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..9221b9bb1 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BranchSDKTestsHostApp/Assets.xcassets/Contents.json b/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/Contents.json similarity index 100% rename from BranchSDKTestsHostApp/Assets.xcassets/Contents.json rename to DeepLinkDemo/DeepLinkDemo/Assets.xcassets/Contents.json diff --git a/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/Contents.json b/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/Contents.json new file mode 100644 index 000000000..d18ba8435 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "icons8-left-100.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/icons8-left-100.png b/DeepLinkDemo/DeepLinkDemo/Assets.xcassets/back_img.imageset/icons8-left-100.png new file mode 100644 index 0000000000000000000000000000000000000000..b1952be8aac5931b6a6676536e7615aba06a0106 GIT binary patch literal 627 zcmeAS@N?(olHy`uVBq!ia0vp^DImkG4uAb{HyJG}WchLAhmo6!devX|_Qw7xQ#Uf4IdbI8LxB(THW}?>TAq~j%z$~% z(mg$w4GoKDu-yxYJ2rF13`-y8^_tp`r3=i|()fNigio3JQPx6U*tmV~l<6B;Vmdl! z9+rEc`ZP7B2guTUzzSq_0a<(AWP&!&nKgGK#LN&D!d{kPan7nH1y4aJw5UV zwgOo>%yP++p*Q$!7Ov^pw^p%$dq(cwZrPbnPQ3UW#lpAk&gpC0nD{&I_e5QLTXy^A zIk5)^r4|~kPmMaaYi<7Lw9@syip&pWKCD=*Q(G`SO+a~y`qwmFCibXzsp&@bZ)F)i zANY4|_YK2(iLevi>Y|?>CAIGP6Q`IT5PBkdhiK7>g-(5pp(h-7a#?ysDYmcGe)5<@ z^i$(pF5h1s(WcETwPq)s=bJYhEeoz%Qq#dTBk-g=dky0?SJpEbcjB|p9CtmP-M7_S yGU#FMC7ra!*Cx+<$`A1BI3q{lB$buP`x(C7)?)Q@d(;n1MGT&M+U#57K(hy~sWdJ}(^F82E!gCK) zOULBg!Y)8KzN~KaRb(ThbaHT9)9Tv(&A|cT^70R6_YcHv1(?y zs}w8;DQ~w-EcT;gcfEW!^}rc0`=pv)(l~=B#g?nQ7CnSh~Hx zSR<@o+cH*tx}iEgX-v&`nUR;r$zUS#;QvQ?tX@;EAIoxlxQTP<_4j^oBnZzmb#waFwm zU)~#HUbbi^`zsW`DXC=GSbVslopNj6$;bB20|;pl0I|qP(MwKHuK$saOHwukcWOM& zy54sfVG_jiKX=1qFhQMwHd&I@$=&VbJ5;n#V#DC+QT?0~mPI#Kb{2ZER51+IUi7>~ z$QW!L)V&#b=6tJSDN$L|#->eGc9=bpoN%sYII4atHw4dOcyy#1^W7yRXr`Dr(NC~I zE*W>ItkJ&5d^i{DWu20Z zl?V^JPftY-I3K214uKEjEU2A10x&EuaEEd==7jmVH|XF-y^VXB%zA3$7ECq8-eGmr zphe0Lt_}5M1d*vcYALDFM)I5CSj!X;nVCS$GpDdEm|0u8G{zefk~rrqAw=F|^A)Nt z;xbN=(B8ea9IkepCwavQ6h#D{Pt4b{&-NsuOs9|EDzjYbH4}-mvww$VHLPoO+bHXF z(N$%o-TfePs(>kiT>5D;O@2`a)w?TFJr9k|~ zy*QxsU*1?^$!u3{Clbr3UbSXU$v*=sKSk0**-Ah1gGO^ryksz&9khuZsI^4#H$z8T z!YiVfh-dWEorg;OpM&<$tL8 z3JA!7mV8+6Yq;vq#Nj~j(9HB=JZ+}&~``yH~XnX8WKb*5Hr z5X~b6KIqk7&P^`jFXRn@(7mdR*axJ&JhDawe_55POlPO`s3co|wON=VyXp&3*k^?J zywBLw$jO%4dex2m>FVZjL1$o!fe^o0LAo&V6db0001i0SrI#eacZ@b2EH221f&9_z zV#=0Ric@&(T~HkUEN zV)RbTf|-zLc5>W~Dmc;l;nO@_Y?SR*)0Uzi*MB5LS9rBPpZXm4^)FVUEN+5~YE%i* zJlq3k_4%z?syw%DoB3=)ZS|PR6 z&g4u;X`f`Byh_z~lRv5p95Eglxa$bzwaBP2P6gX5y z3u#&T6Glic$5WJzt;ugV8Eo{!j`3h9ppFStneueO!2zf-3+ow5C1?$rN{oG&n0 zZq%I|v62km$sI>YKelr@xzlxWf5EoO)#Z&^e>O?c&q{Xcr_t2Xlw!NTMDD!xjnC6zi5bE>9L<^{-HGW zLb`8=*LM@{qn9{D45PbwF>{w_EG`a7=K_JRYy3UXaw~ zd%{pe%;~C`2u&E*ayBy8&M=E$Nh}B6G4cRn{kXADgykibYxd+lErtS30ow$~uaM8I z-;{+Lq|0v{-(^HM6WvNT#Q~bg%wl{z4Wk#k_=>89Sx96A!9%WN>08OJ;xf~TKBu*2 zq7Lj^OtKA+KzW(FV2Z~t0`F$sy+-8UQMAFj{)zKKWKzRq1-v3U0-k{+a4Prj|3$t0 znY!5>Sku(LP5rqUCk%7U^9wdZ2l`6UW4-;eem5R~e`Qg;E@68zI#x`#IZE zT-DC)LrLi5(^&pVA;RAF~PMX|rG}aY!P7WF*y*QD` z*SLRwoGcik4WAqu#Kk+k}o7o+S`gw_t?&vHq(JaT|;Lt z>gSEa4=jt^t^iWO0T-R?huh;tWQ`SK@ek1QG6!@X_olDIQ)^_4FPuKJR4K{txdEzX zRi(H4hWZCx3ahX3$7vf+!#<-Y)g6lFe~jTZ7cVJozjx81n=Tj(5%~igk-mSXm zspMJi#h9zJ@{)jS`kC7H)6*aB-qwcG=;u}K_~|8oZ<0thZ1XHO%04yv`BJd^0TK6% zac-DTu3@;en`+effxC5~h99wSgh%UQE_BH~3>OuCkfy^eKCBtOwtYzZHR=H0W_uJ; ziVvU&_`H2KGufwkFddL9a=naxz8~@yndXhvKOuNZ5kmq10Zsnba*_TMZ+3PK8=r@T z@Z-gRQYwb1n8N*(#O)WO!t%fzu z$(r1dX;E{+Iur%KrIjJjHYeH@5FQ_bp_uUCU+rK}{kcu+nZc)G{};!f2MR zS;oa~l-zC{dxKxCD`<- z;xM#1D^uPr`3(xJxR?Wd9<{S_u+USPHIq33rBe=qYUsA&Ymj8SMkBZ0m4kl_#V>EV zLcy1cR&v;K**(MAGe4F!-O5gXUA#j>KbBOOq0IjO=1S|9g!*B4KY#%c_wSGcK-yrf JIt@Gc{{RlH+F}3z literal 0 HcmV?d00001 diff --git a/BranchSDKTestsHostApp/Base.lproj/LaunchScreen.storyboard b/DeepLinkDemo/DeepLinkDemo/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from BranchSDKTestsHostApp/Base.lproj/LaunchScreen.storyboard rename to DeepLinkDemo/DeepLinkDemo/Base.lproj/LaunchScreen.storyboard diff --git a/DeepLinkDemo/DeepLinkDemo/Base.lproj/Main.storyboard b/DeepLinkDemo/DeepLinkDemo/Base.lproj/Main.storyboard new file mode 100644 index 000000000..7c5844536 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Base.lproj/Main.storyboard @@ -0,0 +1,2685 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DeepLinkDemo/DeepLinkDemo/Constants/CommonAlert.swift b/DeepLinkDemo/DeepLinkDemo/Constants/CommonAlert.swift new file mode 100644 index 000000000..feb4c06e4 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Constants/CommonAlert.swift @@ -0,0 +1,22 @@ + +import UIKit + +class CommonAlert { + + static let shared = CommonAlert() + + func showActionAlertView(title:String,message:String,actions:[UIAlertAction],preferredStyle:UIAlertController.Style = .alert,viewController:UIViewController?) -> Void { + let alertController = UIAlertController(title: title, message:message, preferredStyle: preferredStyle) + if actions.isEmpty { + alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action: UIAlertAction!) in + viewController?.dismiss(animated: true, completion: nil) + })) + }else{ + for action in actions { + alertController.addAction(action) + } + } + + viewController?.present(alertController, animated: true, completion: nil) + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/Constants/CommonMethod.swift b/DeepLinkDemo/DeepLinkDemo/Constants/CommonMethod.swift new file mode 100644 index 000000000..de52c755b --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Constants/CommonMethod.swift @@ -0,0 +1,59 @@ +// CommonMethod.swift +// DeepLinkDemo +// Created by Rakesh kumar on 4/18/22. + + +import Foundation +import UIKit +import BranchSDK +import SystemConfiguration + + +class CommonMethod { + + static let sharedInstance = CommonMethod() + var branchUniversalObject = BranchUniversalObject() + var linkProperties = BranchLinkProperties() + var contentMetaData : BranchContentMetadata? = nil + + var branchData = [String: AnyObject]() + + func navigatetoContent(onCompletion:@escaping (NSDictionary?) -> Void) -> Void { + guard let data = branchData as? [String: AnyObject] else { return } + onCompletion(data as NSDictionary) + } + + func showActionAlertView(title:String,message:String,actions:[UIAlertAction],preferredStyle:UIAlertController.Style = .alert,viewController:UIViewController?) -> Void { + let alertController = UIAlertController(title: title, message:message, preferredStyle: preferredStyle) + if actions.isEmpty { + alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action: UIAlertAction!) in + viewController?.dismiss(animated: true, completion: nil) + + })) + } else { + for action in actions { + alertController.addAction(action) + } + } + } + + func isInternetAvailable() -> Bool { + var zeroAddress = sockaddr_in() + zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress)) + zeroAddress.sin_family = sa_family_t(AF_INET) + let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) { + $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in + SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress) + } + } + + var flags = SCNetworkReachabilityFlags() + + if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) { + return false + } + let isReachable = flags.contains(.reachable) + let needsConnection = flags.contains(.connectionRequired) + return (isReachable && !needsConnection) + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/Constants/Utils.swift b/DeepLinkDemo/DeepLinkDemo/Constants/Utils.swift new file mode 100644 index 000000000..b0182457b --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Constants/Utils.swift @@ -0,0 +1,87 @@ +// +// Utils.swift +// DeepLinkDemo +// +// Created by Apple on 24/05/22. +// + +import Foundation +import UIKit + +class Utils: NSObject { + + static let shared = Utils() + var logFileName: String? + var prevCommandLogFileName: String? + + func clearAllLogFiles(){ + + let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! + + do { + let fileURLs = try FileManager.default.contentsOfDirectory(at: documentsUrl, + includingPropertiesForKeys: nil, + options: .skipsHiddenFiles) + for fileURL in fileURLs { + try FileManager.default.removeItem(at: fileURL) + } + } catch { + NSLog("Failed to delete the file %@", error.localizedDescription) + } + + } + + + func removeItem(_ relativeFilePath: String) { + guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return } + let absoluteFilePath = documentsDirectory.appendingPathComponent(relativeFilePath) + try? FileManager.default.removeItem(at: absoluteFilePath) + } + + func setLogFile(_ fileName: String?) { + if fileName == nil { + logFileName = nil + return + } + let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).map(\.path)[0] + let pathForLog = "\(documentsDirectory)/\(fileName ?? "app").log" + self.removeItem(pathForLog) + if (logFileName == nil) { + logFileName = pathForLog + prevCommandLogFileName = logFileName + } else { + prevCommandLogFileName = logFileName + logFileName = pathForLog + } + let cstr = (pathForLog as NSString).utf8String + freopen(cstr, "a+", stderr) + + } + + func printLogMessage(_ message: String) { + objc_sync_enter(self) + do { + print(message) // print to console + + if !FileManager.default.fileExists(atPath: logFileName!) { // does it exits? + FileManager.default.createFile(atPath: logFileName!, contents: nil) + } + + if let data = message.data(using: .utf8) { + let fileHandle = try FileHandle(forWritingTo: URL(fileURLWithPath: logFileName!)) + if #available(iOS 13.4, *) { + print(" ============= ********** Writing in file " + logFileName!) + try fileHandle.seekToEnd() + try fileHandle.write(contentsOf: data) + try fileHandle.close() + } else { + print("Unable to write log: iOS Version not supported") + } + } + } catch let error as NSError { // something wrong + print("Unable to write log: \(error.debugDescription)") // debug printout + } + objc_sync_exit(self) + } +} + diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/AddMetaDataVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/AddMetaDataVC.swift new file mode 100644 index 000000000..76884a790 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/AddMetaDataVC.swift @@ -0,0 +1,117 @@ +// +// AddMetaDataVC.swift +// DeepLinkDemo +// +// Created by Apple on 13/05/22. +// + +import UIKit +import BranchSDK + +class AddMetaDataVC: ParentViewController { + + @IBOutlet weak var metaDataTblVw: UITableView! + private var reachability:Reachability? + override func viewDidLoad() { + super.viewDidLoad() + + self.metaDataTblVw.keyboardDismissMode = .onDrag + reachabilityCheck() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + Utils.shared.setLogFile("AddMetadata") + } + + + @IBAction func backBtnAction(){ + self.navigationController?.popToRootViewController(animated: true) + } + + @objc func submitBtnAction(){ + if let cell = metaDataTblVw.cellForRow(at: IndexPath(row: 0, section: 0)) as? MetaDataTableViewCell{ + +// let branchUniversalObject = CommonMethod.sharedInstance.branchUniversalObject +// branchUniversalObject.canonicalIdentifier = branchUniversalObject.canonicalIdentifier +// branchUniversalObject.canonicalUrl = "https://branch.io/item/12345" +// branchUniversalObject.title = branchUniversalObject.title + let contentMetadata = BranchContentMetadata() + let contentSchemaSelected : BranchContentSchema = BranchContentSchema(rawValue: cell.contentSchema.text!) + contentMetadata.contentSchema = contentSchemaSelected + let quantityEntered = Double(cell.quantity.text ?? "0") + contentMetadata.quantity = quantityEntered ?? 0 + let formattedPrice = NSDecimalNumber(string: cell.price.text ?? "0.0") + if cell.price.text != "" { + contentMetadata.price = formattedPrice + let currencySelected: BNCCurrency = BNCCurrency(rawValue: cell.currencyName.text!) + contentMetadata.currency = currencySelected + } + contentMetadata.sku = cell.sku.text + contentMetadata.productName = cell.productName.text + contentMetadata.productBrand = cell.productBrand.text + let productCategorySelected: BNCProductCategory = BNCProductCategory(rawValue: cell.productCategory.text!) + contentMetadata.productCategory = productCategorySelected + contentMetadata.productVariant = cell.productVariant.text + let conditionSelected: BranchCondition = BranchCondition(rawValue: cell.productCondition.text!) + contentMetadata.condition = conditionSelected + contentMetadata.customMetadata = [ + "custom_key1": cell.customMetadata.text!, + ] + contentMetadata.addressStreet = cell.street.text + contentMetadata.addressCity = cell.city.text + contentMetadata.addressRegion = cell.region.text + contentMetadata.addressCountry = cell.country.text + contentMetadata.addressPostalCode = cell.postalCode.text + + contentMetadata.latitude = Double(cell.latitude.text ?? "0.0") ?? 0.0 + contentMetadata.longitude = Double(cell.longitude.text ?? "0.0") ?? 0.0 + + contentMetadata.ratingAverage = Double(cell.averageRating.text ?? "0.0") ?? 0.0 + contentMetadata.ratingMax = Double(cell.maximumRating.text ?? "0.0") ?? 0.0 + contentMetadata.ratingCount = Int(cell.ratingCount.text ?? "0") ?? 0 + contentMetadata.rating = Double(cell.rating.text ?? "0.0") ?? 0.0 + + contentMetadata.imageCaptions = [cell.imageCaption.text ?? ""] + CommonMethod.sharedInstance.contentMetaData = contentMetadata + print("ContentMetaData:", contentMetadata) + + let metadataDetail = String(format: "%@", contentMetadata) + NSLog("Metadata", metadataDetail); + Utils.shared.setLogFile("AddMetadata") + + self.navigationController?.popViewController(animated: true) + } + } + +} + +extension AddMetaDataVC: UITableViewDataSource, UITableViewDelegate{ + func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 1 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if let cell = tableView.dequeueReusableCell(withIdentifier: "MetaDataTableViewCell", for: indexPath) as? MetaDataTableViewCell{ + cell.submitBtn.addTarget(self, action: #selector(submitBtnAction), for: UIControl.Event.touchUpInside) + cell.pickerDelegate = self + return cell + } + return UITableViewCell() + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return UITableView.automaticDimension + } +} + + +extension AddMetaDataVC: PickerViewDelegate{ + func removePickerView() { + self.view.endEditing(true) + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/CreateObjectReferenceObject.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/CreateObjectReferenceObject.swift new file mode 100644 index 000000000..061f256d1 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/CreateObjectReferenceObject.swift @@ -0,0 +1,268 @@ +// CreateObjectReferenceObject.swift +// DeepLinkDemo +// Created by Rakesh kumar on 4/19/22. + +import UIKit +import BranchSDK + + +class CreateObjectReferenceObject: ParentViewController { + @IBOutlet weak var txtFldContentTitle: UITextField! + @IBOutlet weak var txtFldCanonicalIdentifier: UITextField! + @IBOutlet weak var txtFldDescription: UITextField! + @IBOutlet weak var txtFldImageUrl: UITextField! + @IBOutlet weak var scrollViewMain: UIScrollView! + + var screenMode = 0 + var txtFldValue = "" + var responseStatus = "" + + enum ScreenMode { + static let createBUO = 0 + static let readdeeplink = 1 + static let sharedeeplink = 2 + static let navigatetoContent = 3 + static let handlLinkinWebview = 4 + static let createdeeplink = 5 + static let sendnotification = 6 + static let trackContent = 7 + static let displayContent = 8 + } + + override func viewDidLoad() { + super.viewDidLoad() + + uiSetUp() + + super.reachabilityCheck() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + if self.screenMode == ScreenMode.trackContent { + Utils.shared.setLogFile("TrackContent") + } + else { + Utils.shared.setLogFile("CreateBUO") + } + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + scrollViewMain.contentSize.height = scrollViewMain.subviews.sorted(by: { $0.frame.maxY < $1.frame.maxY }).last?.frame.maxY ?? scrollViewMain.contentSize.height + } + + @IBAction func backAction(_ sender: Any) { + self.navigationController?.popToRootViewController(animated: true) + } + + @objc func addMetaDataAction(sender: UIButton) { + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "AddMetaDataVC") as? AddMetaDataVC { + self.navigationController?.pushViewController(vc, animated: true) + } + } + fileprivate func handleOkBtnAction(dict : [String:Any], alertMessage: String) { + Utils.shared.setLogFile("CreateBUO") + if self.screenMode == ScreenMode.displayContent { + launchGenerateURLVC(dict: dict, displayContent: true) + }else if self.screenMode == ScreenMode.trackContent { + NSLog("screenMode:", self.screenMode) + launchGenerateURLVC(dict: dict, message: alertMessage, TrackContent: true) + }else if self.screenMode == ScreenMode.sendnotification { + NSLog("screenMode:", self.screenMode) + launchGenerateURLVC(dict: dict, forNotification: true) + }else if self.screenMode == ScreenMode.createdeeplink { + NSLog("screenMode:", self.screenMode) + launchGenerateURLVC(dict: dict, CreateDeepLink: true) + }else if self.screenMode == ScreenMode.sharedeeplink { + NSLog("screenMode:", self.screenMode) + launchGenerateURLVC(dict: dict, ShareDeepLink: true) + }else if self.screenMode == ScreenMode.readdeeplink { + NSLog("screenMode:", self.screenMode) + launchGenerateURLVC(dict: dict) + }else if self.screenMode == ScreenMode.navigatetoContent { + NSLog("screenMode:", self.screenMode) + launchGenerateURLVC(dict: dict, NavigateToContent: true) + }else if self.screenMode == ScreenMode.handlLinkinWebview { + NSLog("screenMode:", self.screenMode) + launchGenerateURLVC(dict: dict, handleLinkInWebview: true) + }else { + self.navigationController?.popToRootViewController(animated: true) + } + } + + func launchGenerateURLVC(dict: [String:Any], message: String? = "", ShareDeepLink: Bool? = false, displayContent: Bool? = false, NavigateToContent: Bool? = false, TrackContent: Bool? = false, handleLinkInWebview: Bool? = false, CreateDeepLink: Bool? = false, forNotification: Bool? = false) { + if self.screenMode == ScreenMode.trackContent { + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "TextViewController") as? TextViewController { + vc.isTrackContent = TrackContent! + vc.forNotification = forNotification! + vc.isCreateDeepLink = CreateDeepLink! + vc.isShareDeepLink = ShareDeepLink! + vc.isNavigateToContent = NavigateToContent! + vc.handleLinkInWebview = handleLinkInWebview! + vc.isDisplayContent = displayContent! + vc.dictData = dict + vc.textViewText = message! + vc.responseStatus = self.responseStatus + self.navigationController?.pushViewController(vc, animated: true) + } + } else { + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "GenerateURLVC") as? GenerateURLVC { + vc.isTrackContent = TrackContent! + vc.forNotification = forNotification! + vc.isCreateDeepLink = CreateDeepLink! + vc.isShareDeepLink = ShareDeepLink! + vc.isNavigateToContent = NavigateToContent! + vc.handleLinkInWebview = handleLinkInWebview! + vc.isDisplayContent = displayContent! + vc.dictData = dict + self.navigationController?.pushViewController(vc, animated: true) + } + } + } + + @objc func submitAction(sender : UIButton) { + + self.view.endEditing(true) + CommonMethod.sharedInstance.branchUniversalObject = BranchUniversalObject(canonicalIdentifier: txtFldCanonicalIdentifier.text!) + CommonMethod.sharedInstance.branchUniversalObject.title = txtFldContentTitle.text! + CommonMethod.sharedInstance.branchUniversalObject.contentDescription = txtFldDescription.text! + CommonMethod.sharedInstance.branchUniversalObject.imageUrl = txtFldImageUrl.text! + let linkProperties = BranchLinkProperties() + + + var dict = [String:Any]() + dict["$canonicalIdentifier"] = txtFldCanonicalIdentifier.text! + dict["title"] = txtFldContentTitle.text! + dict["description"] = txtFldDescription.text! + dict["imgurl"] = txtFldImageUrl.text! + + CommonMethod.sharedInstance.branchUniversalObject.locallyIndex = true + CommonMethod.sharedInstance.branchUniversalObject.publiclyIndex = true + if CommonMethod.sharedInstance.contentMetaData != nil { + CommonMethod.sharedInstance.branchUniversalObject.contentMetadata = CommonMethod.sharedInstance.contentMetaData! + } + print("universalObject:", CommonMethod.sharedInstance.branchUniversalObject) + NSLog("CommonMethod.sharedInstance.branchUniversalObject:",CommonMethod.sharedInstance.branchUniversalObject) + + if self.screenMode == ScreenMode.trackContent { + let selectedEvent: BranchStandardEvent = BranchStandardEvent(rawValue: txtFldValue) + BranchEvent.standardEvent(selectedEvent, withContentItem: CommonMethod.sharedInstance.branchUniversalObject).logEvent {[weak self] isLogged, loggingErr in + if isLogged { + self?.responseStatus = "Success" + NSLog("BranchEvent Logged") + Utils.shared.setLogFile("TrackContent") + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) { + //AJAY + let alertMessage = self?.getAPIDetailFromLogFile(fileName: "TrackContent.log") + + self?.handleOkBtnAction(dict: dict, alertMessage: alertMessage ?? "") + } + }else{ + NSLog("BranchEvent failed to log \(loggingErr?.localizedDescription ?? "NA")") + } + } + + } + else { + CommonMethod.sharedInstance.branchUniversalObject.listOnSpotlight(with: linkProperties) { (url, error) in + if (error == nil) { + NSLog("Successfully indexed on spotlight \(url)") + } + } + let alert = UIAlertController(title: "Alert", message: "BranchUniversalObject reference created", preferredStyle: .alert) + alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in + UserDefaults.standard.set("buo", forKey: "isStatus") + UserDefaults.standard.set(true, forKey: "isCreatedBUO") + self.handleOkBtnAction(dict: dict, alertMessage: "") + })) + self.present(alert, animated: true, completion: nil) + } + } + + private func loadTextWithFileName(_ fileName: String) -> String? { + if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first { + let fileURL = dir.appendingPathComponent(fileName) + guard let text = try? String(contentsOf: fileURL, encoding: .utf8) else { + return nil + } + return text + } + return nil + } + + fileprivate func getAPIDetailFromLogFile(fileName: String) -> String{ + var alertMessage = "LogFilePath : \(self.getLogFilepath(fileName)!) \n\n" + alertMessage = alertMessage + "\n\n" + if let fileContent = self.loadTextWithFileName(fileName), !fileContent.isEmpty { + + if let startlocation = fileContent.range(of: "BranchSDK API LOG START OF FILE"),let endlocation = fileContent.range(of: "BranchSDK API LOG END OF FILE"){ + let apiResponse = fileContent[startlocation.lowerBound.. String? { + let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first + let fileURL = dir?.appendingPathComponent(fileName) + let fileURLStr = fileURL?.path + return fileURLStr + } +} + +extension CreateObjectReferenceObject { + func uiSetUp() { + + let addMetaDataBtn = UIButton(frame: CGRect(x: self.view.frame.width/2-90, y: txtFldImageUrl.frame.maxY+30, width: 180, height: 55)) + addMetaDataBtn.setTitle("Add Metadata", for: .normal) + addMetaDataBtn.backgroundColor = UIColor(red: 89.0/255.0, green: 12.0/255.0, blue: 228.0/255.0, alpha: 1.0) + addMetaDataBtn.layer.cornerRadius = 8 + addMetaDataBtn.setTitleColor(UIColor.white, for: .normal) + addMetaDataBtn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 22.0) + addMetaDataBtn.addTarget(self, action: #selector(addMetaDataAction), for: .touchUpInside) + scrollViewMain.addSubview(addMetaDataBtn) + + let submitBtn = UIButton(frame: CGRect(x: self.view.frame.width/2-60, y: addMetaDataBtn.frame.maxY+30, width: 120, height: 55)) + submitBtn.setTitle("Submit", for: .normal) + submitBtn.backgroundColor = UIColor(red: 89.0/255.0, green: 12.0/255.0, blue: 228.0/255.0, alpha: 1.0) + submitBtn.layer.cornerRadius = 8 + submitBtn.setTitleColor(UIColor.white, for: .normal) + submitBtn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 22.0) + submitBtn.addTarget(self, action: #selector(self.submitAction), for: .touchUpInside) + scrollViewMain.addSubview(submitBtn) + + + txtFldContentTitle.setLeftPaddingPoints(10) + txtFldDescription.setLeftPaddingPoints(10) + txtFldImageUrl.setLeftPaddingPoints(10) + txtFldCanonicalIdentifier.setLeftPaddingPoints(10) + txtFldCanonicalIdentifier.attributedPlaceholder = NSAttributedString( + string: "Canonical Identifier", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + + txtFldContentTitle.attributedPlaceholder = NSAttributedString( + string: "Content Title", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + + txtFldDescription.attributedPlaceholder = NSAttributedString( + string: "Content Description", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldImageUrl.attributedPlaceholder = NSAttributedString( + string: "Image URL", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/DispalyVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/DispalyVC.swift new file mode 100644 index 000000000..b98f2ccab --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/DispalyVC.swift @@ -0,0 +1,60 @@ +// +// DispalyVC.swift +// DeepLinkDemo +// +// Created by Rakesh kumar on 4/26/22. +// + +import UIKit +import BranchSDK + +class DispalyVC: ParentViewController { + + @IBOutlet weak var pageTitle: UILabel! + + @IBOutlet weak var textViewDescription: UITextView! + + var textDescription = "" + var linkURL = "" + var appData : Dictionary = Dictionary() + private var reachability:Reachability? + override func viewDidLoad() { + super.viewDidLoad() + + debugPrint("textDescription", textDescription) + + if appData["nav_to"] is String { + self.pageTitle.text = "Navigate To Content" + let content = String(format:"\nReferring link: %@ \n\nSession Details:\n %@", linkURL, appData.jsonStringRepresentation!) + self.textViewDescription.text = content + } else if appData["display_Cont"] is String { + self.pageTitle.text = "Display Content" + let content = String(format:"\nReferring link: %@ \n\nSession Details:\n %@", linkURL, appData.jsonStringRepresentation!) + self.textViewDescription.text = content + } + else{ + self.pageTitle.text = "Read Deep Linking" + self.textViewDescription.text = String(format:"%@", textDescription) + } + + reachabilityCheck() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + if appData["nav_to"] is String { + Utils.shared.setLogFile("NavigateContentDetail") + } else if appData["display_Cont"] is String { + Utils.shared.setLogFile("DisplayContentDetail") + } else { + Utils.shared.setLogFile("ReadDeepLinkingDetail") + } + } + + + + @IBAction func backAction(_ sender: Any) { + self.navigationController?.popToRootViewController(animated: true) + } + +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/GenerateURLVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/GenerateURLVC.swift new file mode 100644 index 000000000..a1db4f8f6 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/GenerateURLVC.swift @@ -0,0 +1,257 @@ +// +// GenerateURLVC.swift +// DeepLinkDemo +// Created by Rakesh kumar on 4/19/22. + +import UIKit +import BranchSDK +class GenerateURLVC: ParentViewController { + @IBOutlet weak var txtFldCChannel: UITextField! + @IBOutlet weak var txtFldFeature: UITextField! + @IBOutlet weak var txtFldChampaignName: UITextField! + @IBOutlet weak var txtFldStage: UITextField! + @IBOutlet weak var txtFldDeskTopUrl: UITextField! + @IBOutlet weak var txtFldAndroidUrl: UITextField! + @IBOutlet weak var txtFldiOSTopUrl: UITextField! + @IBOutlet weak var txtFldAdditionalData: UITextField! + @IBOutlet weak var scrollViewMain: UIScrollView! + + var responseStatus = "" + var screenMode = 0 + + var dictData = [String:Any]() + + var isShareDeepLink = false + + var isDisplayContent = false + + var isNavigateToContent = false + + var isTrackContent = false + + var handleLinkInWebview = false + + var isCreateDeepLink = false + + var forNotification = false + + override func viewDidLoad() { + super.viewDidLoad() + uiSetUp() + + NSLog("dictData", dictData) + super.reachabilityCheck() + } + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + scrollViewMain.contentSize.height = scrollViewMain.subviews.sorted(by: { $0.frame.maxY < $1.frame.maxY }).last?.frame.maxY ?? scrollViewMain.contentSize.height + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + Utils.shared.setLogFile("CreateDeeplink") + } + + + @IBAction func backAction(_ sender: Any) { + self.navigationController?.popToRootViewController(animated: true) + } + + func fireLocalNotification(linkurl: String){ + let dict = [ + "aps": [ + "alert":[ + "title":"Hi", + "body":"Hi, How Are You Dear" + ] + ], + "mutable-content" : false, + "branch": "\(linkurl)" + ] as [String : Any] + let notification = UILocalNotification() + notification.fireDate = Date(timeIntervalSinceNow: 1) + notification.alertBody = "Notification for handling deeplink" + notification.alertAction = "TestBed App" + notification.soundName = UILocalNotificationDefaultSoundName + notification.userInfo = dict + UIApplication.shared.scheduleLocalNotification(notification) + // sleep(2) + // self.navigationController?.popToRootViewController(animated: true) + } + + fileprivate func processShortURLGenerated(_ url: String?) { + NSLog("Check out my ShortUrl!! \(url ?? "")") + Utils.shared.setLogFile("CreateDeeplink") + let alertMessage = self.getAPIDetailFromLogFile("CreateDeeplink.log") + DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) { + UserDefaults.standard.set("createdeeplinking", forKey: "isStatus") + UserDefaults.standard.set(true, forKey: "isCreatedDeepLink") + UserDefaults.standard.set("\(url ?? "")", forKey: "link") + if self.forNotification == true { + self.fireLocalNotification(linkurl: "\(url ?? "")") + self.launchTextViewController(url: "\(url ?? "")", message: alertMessage, forNotification: true) + }else if self.isShareDeepLink == true { + let bsl = BranchShareLink(universalObject: CommonMethod.sharedInstance.branchUniversalObject, linkProperties: CommonMethod.sharedInstance.linkProperties) + if #available(iOS 13.0, *) { + let metaData: LPLinkMetadata = LPLinkMetadata() + let iconImage = UIImage(named: "qentelli_logo") + metaData.iconProvider = NSItemProvider(object: iconImage!) + metaData.title = "Share Deeplink from the app" + metaData.url = URL(string: "\(url ?? "")") + bsl.lpMetaData = metaData + } + bsl.presentActivityViewController(from: self, anchor: nil) + } else if self.isTrackContent == true { + self.launchTextViewController(url: "\(url ?? "")", message: alertMessage, TrackContentWeb: true) + } else if self.isNavigateToContent == true { + self.launchTextViewController(url: "\(url ?? "")", message: alertMessage, NavigateToContent: true) + } else if self.isDisplayContent == true { + self.launchTextViewController(url: "\(url ?? "")", message: alertMessage, displayContent: true) + } else if self.handleLinkInWebview == true { + self.launchTextViewController(url: "\(url ?? "")", message: alertMessage, handleLinkInWebview: true) + } else if self.isCreateDeepLink == true{ + self.launchTextViewController(url: "\(url ?? "")", message: alertMessage, CreateDeepLink: true) + } else { + self.launchTextViewController(url: "\(url ?? "")", message: alertMessage) + } + } + } + + func launchTextViewController(url: String? = "",message: String? = "", ShareDeepLink: Bool? = false, displayContent: Bool? = false, NavigateToContent: Bool? = false, TrackContent: Bool? = false, TrackContentWeb: Bool? = false, handleLinkInWebview: Bool? = false, CreateDeepLink: Bool? = false, forNotification: Bool? = false) { + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "TextViewController") as? TextViewController { + vc.isTrackContent = TrackContent! + vc.forNotification = forNotification! + vc.isCreateDeepLink = CreateDeepLink! + vc.isShareDeepLink = ShareDeepLink! + vc.isNavigateToContent = NavigateToContent! + vc.handleLinkInWebview = handleLinkInWebview! + vc.isDisplayContent = displayContent! + vc.isTrackContenttoWeb = TrackContentWeb! + vc.textViewText = message ?? "" + vc.responseStatus = self.responseStatus + vc.url = url ?? "" + self.navigationController?.pushViewController(vc, animated: true) + } + } + + private func loadTextWithFileName(_ fileName: String) -> String? { + if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first { + let fileURL = dir.appendingPathComponent(fileName) + guard let text = try? String(contentsOf: fileURL, encoding: .utf8) else { + return nil + } + return text + } + return nil + } + + fileprivate func getAPIDetailFromLogFile(_ fileName: String) -> String{ + var alertMessage = "LogFilePath : \(self.getLogFilepath(fileName)!) \n\n" + alertMessage = alertMessage + "\n\n" + if let fileContent = self.loadTextWithFileName(fileName), !fileContent.isEmpty { + let startlocation = fileContent.range(of: "BranchSDK API LOG START OF FILE") + let endlocation = fileContent.range(of: "BranchSDK API LOG END OF FILE") + if ((startlocation?.lowerBound != startlocation?.upperBound) && (endlocation?.lowerBound != endlocation?.upperBound)){ + let apiResponse = fileContent[startlocation!.lowerBound.. String? { + let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first + let fileURL = dir?.appendingPathComponent(fileName) + let fileURLStr = fileURL?.path + return fileURLStr + } + + @IBAction func submitAction(sender : UIButton) { + self.view.endEditing(true) + let linkProperties = BranchLinkProperties() + linkProperties.feature = txtFldFeature.text + linkProperties.channel = txtFldCChannel.text + linkProperties.campaign = txtFldChampaignName.text + linkProperties.stage = txtFldStage.text + linkProperties.addControlParam("$desktop_url", withValue: txtFldDeskTopUrl.text) + linkProperties.addControlParam("$ios_url", withValue: txtFldiOSTopUrl.text) + linkProperties.addControlParam("$android_url", withValue: txtFldAndroidUrl.text) + linkProperties.addControlParam("custom", withValue: txtFldAdditionalData.text) + if isNavigateToContent == true { + linkProperties.addControlParam("nav_to", withValue: "landing_page") + } else if isDisplayContent == true { + linkProperties.addControlParam("display_Cont", withValue: "landing_page") + } + + + CommonMethod.sharedInstance.branchUniversalObject.getShortUrl(with: linkProperties, andCallback: {[weak self] url, error in + + if error == nil { + self?.responseStatus = "Success" + self?.processShortURLGenerated(url) + } else { + self?.responseStatus = "Failure" + } + }) + + + } + +} + +extension GenerateURLVC { + func uiSetUp() { + let submitBtn = UIButton(frame: CGRect(x: self.view.frame.width/2-60, y: txtFldAdditionalData.frame.maxY+15, width: 120, height: 55)) + submitBtn.setTitle("Submit", for: .normal) + submitBtn.backgroundColor = UIColor(red: 89.0/255.0, green: 12.0/255.0, blue: 228.0/255.0, alpha: 1.0) + submitBtn.layer.cornerRadius = 8 + submitBtn.setTitleColor(UIColor.white, for: .normal) + submitBtn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 22.0) + submitBtn.addTarget(self, action: #selector(self.submitAction), for: .touchUpInside) + scrollViewMain.addSubview(submitBtn) + + txtFldCChannel.setLeftPaddingPoints(10) + txtFldFeature.setLeftPaddingPoints(10) + txtFldChampaignName.setLeftPaddingPoints(10) + txtFldStage.setLeftPaddingPoints(10) + txtFldDeskTopUrl.setLeftPaddingPoints(10) + txtFldAdditionalData.setLeftPaddingPoints(10) + txtFldAndroidUrl.setLeftPaddingPoints(10) + txtFldiOSTopUrl.setLeftPaddingPoints(10) + + txtFldCChannel.attributedPlaceholder = NSAttributedString( + string: "Channel name like Facebook", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldFeature.attributedPlaceholder = NSAttributedString( + string: "Feature eg: Sharing", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldChampaignName.attributedPlaceholder = NSAttributedString( + string: "Campaign name", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldStage.attributedPlaceholder = NSAttributedString( + string: "Stage", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldDeskTopUrl.attributedPlaceholder = NSAttributedString( + string: "Desktop URL", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldAndroidUrl.attributedPlaceholder = NSAttributedString( + string: "Android URL", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldiOSTopUrl.attributedPlaceholder = NSAttributedString( + string: "iOS URL", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldAdditionalData.attributedPlaceholder = NSAttributedString( + string: "Additional Data", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/HomeViewController.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/HomeViewController.swift new file mode 100644 index 000000000..b4880dce9 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/HomeViewController.swift @@ -0,0 +1,452 @@ +// ViewController.swift +// DeepLinkDemo +// Created by Rakesh kumar on 4/15/22 + +import UIKit +import BranchSDK +class HomeViewController: UITableViewController { + private var reachability:Reachability? + + @IBOutlet weak var btnCreatBUO: UIButton! + @IBOutlet weak var btnTrackingEnabled: UIButton! + @IBOutlet weak var btnCreateDeepLinking: UIButton! + @IBOutlet weak var btnShareLink: UIButton! + @IBOutlet weak var btnSendNotification: UIButton! + @IBOutlet weak var btnTrackUser: UIButton! + @IBOutlet weak var btnLoadWebView: UIButton! + @IBOutlet weak var btReadDeeplink: UIButton! + @IBOutlet weak var btnTrackContent: UIButton! + @IBOutlet weak var btnNavigateToContent: UIButton! + @IBOutlet weak var btnDisplayContent: UIButton! + @IBOutlet weak var btnReadLog: UIButton! + @IBOutlet weak var btnSetDMAParams: UIButton! + @IBOutlet weak var btnSendV2Event: UIButton! + @IBOutlet weak var btnSetAttributionLevel: UIButton! + + @IBOutlet weak var switchControl: UISwitch! + + @IBOutlet weak var labelStatus: UILabel! + + let branchObj:Branch! = nil + var logData: String! = "" + var branchSDKInitialized = false; + + override func viewDidLoad() { + super.viewDidLoad() + + btnTrackingEnabled.layer.cornerRadius = 8.0 + btnCreatBUO.layer.cornerRadius = 8.0 + btnCreateDeepLinking.layer.cornerRadius = 8.0 + btnShareLink.layer.cornerRadius = 8.0 + btnShareLink.layer.cornerRadius = 8.0 + btnTrackUser.layer.cornerRadius = 8.0 + btnSendNotification.layer.cornerRadius = 8.0 + btReadDeeplink.layer.cornerRadius = 8.0 + btnTrackContent.layer.cornerRadius = 8.0 + btnNavigateToContent.layer.cornerRadius = 8.0 + btnReadLog.layer.cornerRadius = 8.0 + btnLoadWebView.layer.cornerRadius = 8.0 + btnSetDMAParams.layer.cornerRadius = 8.0 + btnSendV2Event.layer.cornerRadius = 8.0 + btnSetAttributionLevel.layer.cornerRadius = 8.0 + + NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil) + + reachabilityCheck(textValue:"") + + if Branch.trackingDisabled(){ + switchControl.isOn = false + }else{ + switchControl.isOn = true + } + + btnReadLog.isHidden = true + + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + Utils.shared.setLogFile("Homepage") + } + + func reachabilityCheck(textValue:String?) { + CommonMethod.sharedInstance.contentMetaData = nil + reachability = Reachability()! + reachability!.whenReachable = { reachability in + Branch.setBranchKey("key_test_om2EWe1WBeBYmpz9Z1mdpopouDmoN72T") + DispatchQueue.main.async { + if textValue == "displayContent" { + self.initBranch() + self.launchBUOVC(mode: 8) + } else if textValue == "navigatetoContent" { + self.initBranch() + self.launchBUOVC(mode: 3) + } else if textValue == "sendNotification" { + self.initBranch() + self.launchBUOVC(mode: 6) + } else if textValue == "loadUrlInWeb" { + self.initBranch() + self.launchBUOVC(mode: 4) + } else if textValue == "createDeep" { + self.initBranch() + self.launchBUOVC(mode: 5) + } else if textValue == "shareDeeplinking" { + self.initBranch() + self.launchBUOVC(mode: 2) + } else if textValue == "readDeeplinking" { + self.initBranch() + self.launchBUOVC(mode: 1) + } else if textValue == "trackContent" { + self.initBranch() + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "TrackContentVC") as? TrackContentVC { + self.navigationController?.pushViewController(vc, animated: true) + } + } else if textValue == "trackUser" { + self.initBranch() + Branch.getInstance().setIdentity("qentelli_test_user") { params, error in + + if let referringParams = params as? [String :AnyObject] { + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "TextViewController") as? TextViewController { + vc.isTrackUser = true + vc.textViewText = "Result \(referringParams)" + vc.responseStatus = "Success" + self.navigationController?.pushViewController(vc, animated: true) + } + }else{ + NSLog("track user error--> \(error!.localizedDescription)") + } + } + } else if textValue == "swichAction" { + + } else if textValue == "createObject" { + self.initBranch() + self.launchBUOVC(mode: 0) + } else if textValue == "readSystemLog" { + self.initBranch() + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "LogFileListViewController") as? LogFileListViewController { + self.navigationController?.pushViewController(vc, animated: true) + } + } else if textValue == "setDMAParams" { + self.setDMAParamsWrapper() + } else if textValue == "sendV2Event" { + self.sendV2EventWrapper() + } else if textValue == "setAttributionLevel" { + self.setAttributionLevelWrapper() + } + } + } + + reachability?.whenUnreachable = { reachability in + DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) { + self.networkError() + } + } + do { + try reachability?.startNotifier() + } catch { + NSLog("Unable to start notifier") + } + } + func launchBUOVC(mode: Int) { + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "CreateObjectReferenceObject") as? CreateObjectReferenceObject { + vc.screenMode = mode + self.navigationController?.pushViewController(vc, animated: true) + } + } + + func networkError() { + CommonAlert.shared.showActionAlertView(title: "Failure", message: "Your internet/network connection appears to be offline. Please check your internet/network connection.", actions: [], preferredStyle: .alert, viewController: self) + } + + func enableBranchLogging(callback: @escaping BranchLogCallback){ + Branch.enableLogging(at: .verbose, withCallback: callback) + } + + func initBranch(){ + if branchSDKInitialized { + return + } + self.enableBranchLogging(){(message:String, loglevel:BranchLogLevel, error:Error?)->() in + if (message.contains("BranchSDK")){ + self.logData = self.logData + message + "\n" + Utils.shared.printLogMessage(message + "\n") + } + } + AppDelegate.shared.getBranchData(AppDelegate.shared.launchOption) + branchSDKInitialized = true + } + + func logEvent(){ + let event = BranchEvent.standardEvent(.purchase) + // Add a populated `BranchUniversalObject` to the event + let buo = BranchUniversalObject(canonicalIdentifier: "item/12345") + event.contentItems = [ buo ] + // Add additional event data + event.alias = "my custom alias" + event.transactionID = "12344555" + event.eventDescription = "event_description" + event.searchQuery = "item 123" + event.customData = [ + "Custom_Event_Property_Key1": "Custom_Event_Property_val1", + "Custom_Event_Property_Key2": "Custom_Event_Property_val2" + ] + // Log the event + event.logEvent() + } + + func setAttributionLevelWrapper() { + self.logData = "Error: Missing testData.\n" + + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + let vc = storyBoard.instantiateViewController(withIdentifier: "TextViewController") as? TextViewController + vc?.isSetAttributionLevel = true + + do { + let argCount = ProcessInfo.processInfo.arguments.count + if argCount >= 2 { + + for i in (1 ..< argCount) { + let data = ProcessInfo.processInfo.arguments[i].data(using: .utf8)! + + if let jsonObject = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [String:AnyObject] + { + if jsonObject["consumer_protection_attribution_level"] != nil { + let attribution_level = jsonObject["consumer_protection_attribution_level"] as! String + self.logData = "" + self.enableBranchLogging(){(msg:String,msg2:BranchLogLevel,msg3:Error?)->() in + if (msg.contains("BranchSDK")){ + self.logData = self.logData + msg + "\n" + } + vc?.updateText(msg: self.logData) + } + if(self.branchSDKInitialized){ + Branch.getInstance().resetUserSession() + } + + switch attribution_level { + case "0": + Branch.getInstance().setConsumerProtectionAttributionLevel(.full) + case "1": + Branch.getInstance().setConsumerProtectionAttributionLevel(.reduced) + case "2": + Branch.getInstance().setConsumerProtectionAttributionLevel(.minimal) + case "3": + Branch.getInstance().setConsumerProtectionAttributionLevel(.none) + default: + Branch.getInstance().setConsumerProtectionAttributionLevel(.full) + } + + AppDelegate.shared.getBranchData(AppDelegate.shared.launchOption) + self.branchSDKInitialized = true + } else { + self.logData = "Missing params from JSON Object: \n" + jsonObject.description + } + } else { + self.logData = "Bad JSON : \n" + ProcessInfo.processInfo.arguments[i] + } + } + + + } + } catch let error as NSError { + print(error) + self.logData += error.localizedDescription + } + vc?.updateText(msg: self.logData) + self.navigationController?.pushViewController(vc!, animated: true) + } + + func setDMAParamsWrapper() { + self.logData = "Error: Missing testData.\n" + + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + let vc = storyBoard.instantiateViewController(withIdentifier: "TextViewController") as? TextViewController + vc?.isSetDMAParams = true + + do { + let argCount = ProcessInfo.processInfo.arguments.count + if argCount >= 2 { + + for i in (1 ..< argCount) { + let data = ProcessInfo.processInfo.arguments[i].data(using: .utf8)! + + if let jsonObject = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [String:AnyObject] + { + if ((jsonObject["dma_eea"] != nil) && (jsonObject["dma_eea"] != nil) && (jsonObject["dma_eea"] != nil)) { + let dma_eea = jsonObject["dma_eea"] as! Bool + let dma_ad_personalization = jsonObject["dma_ad_personalization"] as! Bool + let dma_ad_user_data = jsonObject["dma_ad_user_data"] as! Bool + self.logData = "" + self.enableBranchLogging(){(msg:String,msg2:BranchLogLevel,msg3:Error?)->() in + if (msg.contains("BranchSDK")){ + self.logData = self.logData + msg + "\n" + } + vc?.updateText(msg: self.logData) + } + if(self.branchSDKInitialized){ + Branch.getInstance().resetUserSession() + } + + Branch.setDMAParamsForEEA(dma_eea, adPersonalizationConsent: dma_ad_personalization, adUserDataUsageConsent: dma_ad_user_data) + AppDelegate.shared.getBranchData(AppDelegate.shared.launchOption) + self.branchSDKInitialized = true + } else { + self.logData = "Missing params from JSON Object: \n" + jsonObject.description + } + } else { + self.logData = "Bad JSON : \n" + ProcessInfo.processInfo.arguments[i] + } + } + + + } + } catch let error as NSError { + print(error) + self.logData += error.localizedDescription + } + vc?.updateText(msg: self.logData) + self.navigationController?.pushViewController(vc!, animated: true) + } + + func sendV2EventWrapper(){ + self.logData = "" + + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + let vc = storyBoard.instantiateViewController(withIdentifier: "TextViewController") as? TextViewController + + self.enableBranchLogging(){(msg:String,msg2:BranchLogLevel,msg3:Error?)->() in + if (msg.contains("BranchSDK")){ + self.logData = self.logData + msg + "\n" + vc?.updateText(msg: self.logData) + } + } + self.logEvent() + self.navigationController?.pushViewController(vc!, animated: true) + vc?.isSendV2Event = true + vc?.updateText(msg: self.logData) + self.branchSDKInitialized = true + } + + @IBAction func sendNotificationAction(_ sender: Any) { + reachabilityCheck(textValue: "sendNotification") + } + + @objc func methodOfReceivedNotification(notification: Notification) { + + Branch.getInstance().initSession( launchOptions: AppDelegate.shared.launchOption, + andRegisterDeepLinkHandlerUsingBranchUniversalObject: { [self] universalObject, linkProperties, error in + if universalObject != nil { + NSLog("UniversalObject", universalObject ?? "NA") + NSLog("LinkProperties", linkProperties ?? "NA") + NSLog("UniversalObject Metadata:", universalObject?.contentMetadata.customMetadata ?? "NA") + if let isRead = UserDefaults.standard.value(forKey: "isRead") as? Bool, isRead == true { + if let dictData = universalObject?.contentMetadata.customMetadata as? NSDictionary { + let referedlink = dictData.value(forKey: "~referring_link") as? String ?? "" + // let linkurl = UserDefaults.standard.value(forKey: "link") as? String ?? "" + NSLog("referedlink:", referedlink) + UserDefaults.standard.set(referedlink, forKey: "link") + NSLog("Deep linked with object: %@.", universalObject ?? BranchUniversalObject()); + let deeplinkText = universalObject?.contentMetadata.customMetadata.value(forKey: "deeplink_text") + let textDetail = "Successfully Deeplinked:\n\n%@\nSession Details:\n\n%@, \(String(describing: deeplinkText)) \(String(describing: Branch.getInstance().getLatestReferringParams()?.description))" + UserDefaults.standard.setValue(textDetail, forKey: "textDetail") + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "DispalyVC") as? DispalyVC { + vc.textDescription = textDetail + self.navigationController?.pushViewController(vc, animated: true) + } + } + } else { + NSLog("No Deep linked object"); + } + } + }) + } + + @IBAction func displayContentBtnAction(_ sender: Any) { + reachabilityCheck(textValue: "displayContent") + } + + @IBAction func navigatetoContentBtnAction(_ sender: Any) { + reachabilityCheck(textValue: "navigatetoContent") + } + + @IBAction func loadUrlInWebViewAction(_ sender: Any) { + reachabilityCheck(textValue: "loadUrlInWeb") + } + + @IBAction func createDeeplinking(_ sender: Any) { + reachabilityCheck(textValue: "createDeep") + } + + @IBAction func shareDeeplinking(_ sender: Any) { + reachabilityCheck(textValue: "shareDeeplinking") + } + + @IBAction func readDeeplinking(_ sender: Any) { + reachabilityCheck(textValue: "readDeeplinking") + } + + @IBAction func trackContentAction(_ sender: Any) { + reachabilityCheck(textValue: "trackContent") + } + + @IBAction func trackUserAction(_ sender: Any) { + reachabilityCheck(textValue: "trackUser") + } + + @IBAction func swichAction(_ sender: UISwitch) { + reachabilityCheck(textValue: "swichAction") + if sender.isOn == true { + NSLog("is OFF", "ison") + btnTrackingEnabled.setTitle("Tracking Enabled", for: .normal) + btnTrackingEnabled.titleLabel?.font = UIFont.boldSystemFont(ofSize: 36) + Branch.setTrackingDisabled(true) + + } else { + NSLog("is ON", "isOFF") + Branch.setTrackingDisabled(false) + btnTrackingEnabled.setTitle("Tracking Disabled", for: .normal) + btnTrackingEnabled.titleLabel?.font = UIFont(name: "Helvetica", size:36) + } + } + + @IBAction func createObject(_ sender: Any) { + reachabilityCheck(textValue: "createObject") + + } + + @IBAction func readSystemLog(){ + reachabilityCheck(textValue: "readSystemLog") + + + } + + @IBAction func setDMAParams(){ + reachabilityCheck(textValue: "setDMAParams") + } + + @IBAction func sendV2Event(){ + reachabilityCheck(textValue: "sendV2Event") + } + + @IBAction func setAttributionLevel(){ + reachabilityCheck(textValue: "setAttributionLevel") + } +} + +extension UITextField { + func setLeftPaddingPoints(_ amount:CGFloat){ + let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.frame.size.height)) + self.leftView = paddingView + self.leftViewMode = .always + } + func setRightPaddingPoints(_ amount:CGFloat) { + let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.frame.size.height)) + self.rightView = paddingView + self.rightViewMode = .always + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/LogFileListViewController.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/LogFileListViewController.swift new file mode 100644 index 000000000..844af618d --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/LogFileListViewController.swift @@ -0,0 +1,84 @@ +// +// LogFileListViewController.swift +// DeepLinkDemo +// +// Created by Apple on 26/05/22. +// + +import UIKit + +class LogFileListViewController: UIViewController { + + var fileNames = [String]() + + @IBOutlet weak var logFileListTblView: UITableView! + + override func viewDidLoad() { + super.viewDidLoad() + + fileNames = getAllLogFileNames() + } + + func getAllLogFileNames() -> [String]{ + let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! + + do { + var fileName = [String]() + let fileURLs = try FileManager.default.contentsOfDirectory(at: documentsUrl, + includingPropertiesForKeys: nil, + options: .skipsHiddenFiles) + for fileURL in fileURLs { + fileName.append(fileURL.lastPathComponent) + } + + return fileName + } catch { + NSLog("Failed to delete/read the file in document directory %@", error.localizedDescription) + } + return [""] + } + @IBAction func backAction(_ sender: Any) { + self.navigationController?.popToRootViewController(animated: true) + } + + +} + + +extension LogFileListViewController: UITableViewDataSource, UITableViewDelegate{ + func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return fileNames.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if let cell = tableView.dequeueReusableCell(withIdentifier: "LogTableViewCell", for: indexPath) as? LogTableViewCell{ + cell.nameLbl.text = fileNames[indexPath.row] + return cell + } + return UITableViewCell() + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 60 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let selectedFile = fileNames[indexPath.row] + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "ReadLogViewController") as? ReadLogViewController { + vc.selectedFileName = selectedFile + self.navigationController?.pushViewController(vc, animated: true) + } + + } +} + + +class LogTableViewCell: UITableViewCell{ + + @IBOutlet weak var nameLbl: UILabel! +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/MetaDataTableViewCell.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/MetaDataTableViewCell.swift new file mode 100644 index 000000000..bc5170c63 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/MetaDataTableViewCell.swift @@ -0,0 +1,224 @@ +// +// MetaDataTableViewCell.swift +// DeepLinkDemo +// +// Created by Apple on 13/05/22. +// + +import UIKit +import BranchSDK + +protocol PickerViewDelegate{ + func removePickerView() +} +class MetaDataTableViewCell: UITableViewCell { + + var pickerDelegate: PickerViewDelegate! + + private let contentSchemaNames = ["COMMERCE_AUCTION", "COMMERCE_BUSINESS", "COMMERCE_OTHER", + "COMMERCE_PRODUCT", "COMMERCE_RESTAURANT", "COMMERCE_SERVICE", + "COMMERCE_TRAVEL_FLIGHT", "COMMERCE_TRAVEL_HOTEL", "COMMERCE_TRAVEL_OTHER", + "GAME_STATE", "MEDIA_IMAGE", "MEDIA_MIXED", "MEDIA_MUSIC", "MEDIA_OTHER", + "MEDIA_VIDEO", "OTHER", "TEXT_ARTICLE", "TEXT_BLOG", "TEXT_OTHER", + "TEXT_RECIPE", "TEXT_REVIEW", "TEXT_SEARCH_RESULTS", "TEXT_STORY", + "TEXT_TECHNICAL_DOC"] + + private let productCategories = ["Animals & Pet Supplies", "Apparel & Accessories", "Arts & Entertainment", + "Baby & Toddler", "Business & Industrial", "Cameras & Optics", + "Electronics", "Food, Beverages & Tobacco", "Furniture", "Hardware", + "Health & Beauty", "Home & Garden", "Luggage & Bags", "Mature", + "Media", "Media", "Office Supplies", "Religious & Ceremonial", + "Software", "Sporting Goods", "Toys & Games", "Vehicles & Parts"] + + + private let productConditions = ["EXCELLENT", "NEW", "GOOD", "FAIR", "POOR", "USED", "REFURBISHED", "OTHER"] + + + private let currencyNames = ["USD", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BOV", "BRL", "BSD", "BTN", "BWP", "BYN", "BYR", "CAD", "CDF", "CHE", "CHF", "CHW", "CLF", "CLP", "CNY", "COP", "COU", "CRC", "CUC", "CUP", "CVE", "CZK", "DJF", "DKK", "DOP", "DZD", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP", "GEL", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD", "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "INR", "IQD", "IRR", "ISK", "JMD", "JOD", "JPY", "KES", "KGS", "KHR", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LYD", "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP", "MRO", "MUR", "MVR", "MWK", "MXN", "MXV", "MYR", "MZN", "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON", "RSD", "RUB", "RWF", "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "SSP", "STD", "SYP", "SZL", "THB", "TJS", "TMT", "TND", "TOP", "TRY", "TTD", "TWD", "TZS", "UAH", "UGX", "USN", "UYI", "UYU", "UZS", "VEF", "VND", "VUV", "WST", "XAF", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XDR", "XFU", "XOF", "XPD", "XPF", "XPT", "XSU", "XTS", "XUA", "XXX", "YER", "ZAR", "ZMW"] + + private var pickerView = UIPickerView() + + @IBOutlet weak var contentSchema: UITextField! + @IBOutlet weak var productName: UITextField! + @IBOutlet weak var productBrand: UITextField! + @IBOutlet weak var productVariant: UITextField! + @IBOutlet weak var productCategory: UITextField! + @IBOutlet weak var productCondition: UITextField! + @IBOutlet weak var street: UITextField! + @IBOutlet weak var city: UITextField! + @IBOutlet weak var region: UITextField! + @IBOutlet weak var country: UITextField! + @IBOutlet weak var postalCode: UITextField! + @IBOutlet weak var latitude: UITextField! + @IBOutlet weak var longitude: UITextField! + @IBOutlet weak var sku: UITextField! + @IBOutlet weak var rating: UITextField! + @IBOutlet weak var averageRating: UITextField! + @IBOutlet weak var maximumRating: UITextField! + @IBOutlet weak var ratingCount: UITextField! + @IBOutlet weak var imageCaption: UITextField! + @IBOutlet weak var quantity: UITextField! + @IBOutlet weak var price: UITextField! + @IBOutlet weak var currencyName: UITextField! + @IBOutlet weak var customMetadata: UITextField! + + @IBOutlet weak var submitBtn: UIButton! + + fileprivate func setAtrributePlaceHolder(targetField: UITextField, placeholderTxt: String){ + targetField.setLeftPaddingPoints(10) + targetField.attributedPlaceholder = NSAttributedString( + string: placeholderTxt, + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + + } + + fileprivate func prepareUI(){ + self.setAtrributePlaceHolder(targetField: self.productName, placeholderTxt: "Product Name") + self.setAtrributePlaceHolder(targetField: self.productBrand, placeholderTxt: "Product Brand") + self.setAtrributePlaceHolder(targetField: self.productVariant, placeholderTxt: "Product Variant") + self.setAtrributePlaceHolder(targetField: self.street, placeholderTxt: "Street") + self.setAtrributePlaceHolder(targetField: self.city, placeholderTxt: "City") + self.setAtrributePlaceHolder(targetField: self.region, placeholderTxt: "Region") + self.setAtrributePlaceHolder(targetField: self.country, placeholderTxt: "Country") + self.setAtrributePlaceHolder(targetField: self.postalCode, placeholderTxt: "Postal Code") + self.setAtrributePlaceHolder(targetField: self.latitude, placeholderTxt: "Latitude") + self.setAtrributePlaceHolder(targetField: self.longitude, placeholderTxt: "Longitude") + self.setAtrributePlaceHolder(targetField: self.sku, placeholderTxt: "SKU") + self.setAtrributePlaceHolder(targetField: self.rating, placeholderTxt: "Rating") + self.setAtrributePlaceHolder(targetField: self.averageRating, placeholderTxt: "Average Rating") + self.setAtrributePlaceHolder(targetField: self.maximumRating, placeholderTxt: "Maximum Rating") + self.setAtrributePlaceHolder(targetField: self.ratingCount, placeholderTxt: "Rating Count") + self.setAtrributePlaceHolder(targetField: self.imageCaption, placeholderTxt: "Image Caption") + self.setAtrributePlaceHolder(targetField: self.quantity, placeholderTxt: "Quantity") + self.setAtrributePlaceHolder(targetField: self.price, placeholderTxt: "Price") + self.setAtrributePlaceHolder(targetField: self.customMetadata, placeholderTxt: "Custom Metadata") + + } + + fileprivate func setupPickerViewDataSource() { + pickerView.dataSource = self + pickerView.delegate = self + + let toolBar = UIToolbar(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width,height: 44.0)) + let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) + let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(tapDone)) + let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(tapCancel)) + toolBar.setItems([cancelButton, flexibleSpace, doneButton], animated: false) + + contentSchema.inputView = pickerView + contentSchema.inputAccessoryView = toolBar + contentSchema.text = contentSchemaNames.first + + currencyName.inputView = pickerView + currencyName.inputAccessoryView = toolBar + currencyName.text = currencyNames.first + + productCondition.inputView = pickerView + productCondition.inputAccessoryView = toolBar + productCondition.text = productConditions.first + + productCategory.inputView = pickerView + productCategory.inputAccessoryView = toolBar + productCategory.text = productCategories.first + + productCategory.setLeftPaddingPoints(10) + productCondition.setLeftPaddingPoints(10) + currencyName.setLeftPaddingPoints(10) + contentSchema.setLeftPaddingPoints(10) + + + + } + + override func awakeFromNib() { + super.awakeFromNib() + + prepareUI() + + setupPickerViewDataSource() + + self.selectionStyle = .none + } + + @objc func tapDone() { + if contentSchema.isFirstResponder{ + let selectedRow = pickerView.selectedRow(inComponent: 0) + if contentSchemaNames.indices.contains(selectedRow){ + contentSchema.text = contentSchemaNames[selectedRow] + } + contentSchema.resignFirstResponder() + } else if currencyName.isFirstResponder{ + let selectedRow = pickerView.selectedRow(inComponent: 0) + if currencyNames.indices.contains(selectedRow){ + currencyName.text = currencyNames[selectedRow] + } + currencyName.resignFirstResponder() + } else if productCondition.isFirstResponder{ + let selectedRow = pickerView.selectedRow(inComponent: 0) + if productConditions.indices.contains(selectedRow){ + productCondition.text = productConditions[selectedRow] + } + productCondition.resignFirstResponder() + } else if productCategory.isFirstResponder{ + let selectedRow = pickerView.selectedRow(inComponent: 0) + if productCategories.indices.contains(selectedRow){ + productCategory.text = productCategories[selectedRow] + } + productCategory.resignFirstResponder() + } + self.endEditing(true) + } + + @objc func tapCancel() { + self.endEditing(true) + } + + +} + + +extension MetaDataTableViewCell: UIPickerViewDataSource, UIPickerViewDelegate{ + + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + if contentSchema.isFirstResponder{ + return contentSchemaNames.count + } else if currencyName.isFirstResponder{ + return currencyNames.count + } else if productCondition.isFirstResponder{ + return productConditions.count + } else if productCategory.isFirstResponder{ + return productCategories.count + } + return 0 + } + + func numberOfComponents(in pickerView: UIPickerView) -> Int { + return 1 + } + + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + if contentSchema.isFirstResponder{ + return contentSchemaNames[row] + } else if currencyName.isFirstResponder{ + return currencyNames[row] + } else if productCondition.isFirstResponder{ + return productConditions[row] + } else if productCategory.isFirstResponder{ + return productCategories[row] + } + return nil + } + + func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + if contentSchema.isFirstResponder{ + contentSchema.text = contentSchemaNames[row] + } else if currencyName.isFirstResponder{ + currencyName.text = currencyNames[row] + } else if productCondition.isFirstResponder{ + productCondition.text = productConditions[row] + } else if productCategory.isFirstResponder{ + productCategory.text = productCategories[row] + } + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/NavigateContentVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/NavigateContentVC.swift new file mode 100644 index 000000000..225b64e8c --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/NavigateContentVC.swift @@ -0,0 +1,108 @@ +// +// NavigateContentVC.swift +// DeepLinkDemo +// +// Created by Rakesh kumar on 4/19/22. +// + +import UIKit + +class NavigateContentVC: ParentViewController { + @IBOutlet weak var txtFldCChannel: UITextField! + @IBOutlet weak var txtFldFeature: UITextField! + @IBOutlet weak var txtFldChampaignName: UITextField! + @IBOutlet weak var txtFldStage: UITextField! + @IBOutlet weak var txtFldDeskTopUrl: UITextField! + @IBOutlet weak var txtFldAdditionalData: UITextField! + @IBOutlet weak var scrollViewMain: UIScrollView! + private var reachability:Reachability? + + override func viewDidLoad() { + super.viewDidLoad() + uiSetUp() + reachabilityCheck() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + Utils.shared.setLogFile("NavigateContent") + } + + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + scrollViewMain.contentSize.height = scrollViewMain.subviews.sorted(by: { $0.frame.maxY < $1.frame.maxY }).last?.frame.maxY ?? scrollViewMain.contentSize.height + } + + @IBAction func backAction(_ sender: Any) { + self.navigationController?.popToRootViewController(animated: true) + } + + @objc func submitAction(sender : UIButton) { + self.view.endEditing(true) + CommonMethod.sharedInstance.branchUniversalObject.publiclyIndex = true + CommonMethod.sharedInstance.branchUniversalObject.locallyIndex = true + CommonMethod.sharedInstance.branchUniversalObject.contentMetadata.customMetadata["key1"] = txtFldDeskTopUrl.text! + CommonMethod.sharedInstance.linkProperties.channel = txtFldCChannel.text! + CommonMethod.sharedInstance.linkProperties.feature = txtFldFeature.text! + CommonMethod.sharedInstance.linkProperties.campaign = txtFldChampaignName.text! + CommonMethod.sharedInstance.linkProperties.stage = txtFldStage.text! + CommonMethod.sharedInstance.linkProperties.addControlParam("$desktop_url", withValue: txtFldDeskTopUrl.text!) + CommonMethod.sharedInstance.linkProperties.addControlParam("custom_data", withValue: "yes") + CommonMethod.sharedInstance.branchUniversalObject.getShortUrl(with:CommonMethod.sharedInstance.linkProperties, andCallback: { (optUrl: String?, error: Error?) in + if error == nil, let url = optUrl { + NSLog("got my Branch link to share: %@", url) + Utils.shared.setLogFile("NavigateContent") + DispatchQueue.main.async { + UserDefaults.standard.set(true, forKey: "isCreatedDeepLink") + UserDefaults.standard.set(url, forKey: "link") + self.navigationController?.popToRootViewController(animated: true) + } + } + }) + } +} + +extension NavigateContentVC { + + func uiSetUp() { + let submitBtn = UIButton(frame: CGRect(x: self.view.frame.width/2-60, y: txtFldAdditionalData.frame.maxY+30, width: 120, height: 55)) + submitBtn.setTitle("Submit", for: .normal) + submitBtn.backgroundColor = UIColor(red: 89.0/255.0, green: 12.0/255.0, blue: 228.0/255.0, alpha: 1.0) + submitBtn.layer.cornerRadius = 8 + submitBtn.setTitleColor(UIColor.white, for: .normal) + submitBtn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 22.0) + submitBtn.addTarget(self, action: #selector(self.submitAction), for: .touchUpInside) + scrollViewMain.addSubview(submitBtn) + txtFldCChannel.setLeftPaddingPoints(10) + txtFldFeature.setLeftPaddingPoints(10) + txtFldChampaignName.setLeftPaddingPoints(10) + txtFldStage.setLeftPaddingPoints(10) + txtFldDeskTopUrl.setLeftPaddingPoints(10) + txtFldAdditionalData.setLeftPaddingPoints(10) + txtFldCChannel.attributedPlaceholder = NSAttributedString( + string: "Channel name like Facebook", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldFeature.attributedPlaceholder = NSAttributedString( + string: "Feature eg: Sharing", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldChampaignName.attributedPlaceholder = NSAttributedString( + string: "Champaign name", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldStage.attributedPlaceholder = NSAttributedString( + string: "Stage", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldDeskTopUrl.attributedPlaceholder = NSAttributedString( + string: "Desktop URL", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldAdditionalData.attributedPlaceholder = NSAttributedString( + string: "Additional Data", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/ParentViewController.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/ParentViewController.swift new file mode 100644 index 000000000..241dd72e9 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/ParentViewController.swift @@ -0,0 +1,39 @@ +// ParentViewController.swift +// DeepLinkDemo +// Created by Apple on 17/05/22. + +import UIKit +class ParentViewController: UIViewController { + private var reachability:Reachability? + + override func viewDidLoad() { + super.viewDidLoad() + reachabilityCheck() + } + + override var preferredStatusBarStyle: UIStatusBarStyle { + return .lightContent + } + + + func reachabilityCheck() { + reachability = Reachability()! + reachability!.whenReachable = { reachability in + } + reachability?.whenUnreachable = { reachability in + DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { + self.networkError() + } + } + do { + try reachability?.startNotifier() + } catch { + NSLog("Unable to start notifier") + } + } + + func networkError() { + CommonAlert.shared.showActionAlertView(title: "Failure", message: "Your internet/network connection appears to be offline. Please check your internet/network connection.", actions: [], preferredStyle: .alert, viewController: self) + } + +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/ReadDeeplinkingVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/ReadDeeplinkingVC.swift new file mode 100644 index 000000000..6d72dfa49 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/ReadDeeplinkingVC.swift @@ -0,0 +1,108 @@ +// +// ReadDeeplinkingVC.swift +// DeepLinkDemo +// +// Created by Rakesh kumar on 4/19/22. + +import UIKit +import Branch + +class ReadDeeplinkingVC: ParentViewController { + @IBOutlet weak var txtFldCChannel: UITextField! + @IBOutlet weak var txtFldFeature: UITextField! + @IBOutlet weak var txtFldChampaignName: UITextField! + @IBOutlet weak var txtFldStage: UITextField! + @IBOutlet weak var txtFldDeskTopUrl: UITextField! + @IBOutlet weak var txtFldAdditionalData: UITextField! + @IBOutlet weak var scrollViewMain: UIScrollView! + private var reachability:Reachability? + override func viewDidLoad() { + super.viewDidLoad() + uiSetUp() + reachabilityCheck() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + Utils.shared.setLogFile("ReadDeeplinking") + } + + + override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + scrollViewMain.contentSize.height = scrollViewMain.subviews.sorted(by: { $0.frame.maxY < $1.frame.maxY }).last?.frame.maxY ?? scrollViewMain.contentSize.height + } + + @IBAction func backAction(_ sender: Any) { + self.navigationController?.popToRootViewController(animated: true) + } + + @objc func submitAction(sender : UIButton) { + self.view.endEditing(true) + + CommonMethod.sharedInstance.branchUniversalObject.publiclyIndex = true + CommonMethod.sharedInstance.branchUniversalObject.locallyIndex = true + CommonMethod.sharedInstance.branchUniversalObject.contentMetadata.customMetadata["key1"] = txtFldDeskTopUrl.text! + + CommonMethod.sharedInstance.linkProperties.channel = txtFldCChannel.text! + CommonMethod.sharedInstance.linkProperties.feature = txtFldFeature.text! + CommonMethod.sharedInstance.linkProperties.campaign = txtFldChampaignName.text! + CommonMethod.sharedInstance.linkProperties.stage = txtFldStage.text! + CommonMethod.sharedInstance.linkProperties.addControlParam("$desktop_url", withValue: txtFldDeskTopUrl.text!) + CommonMethod.sharedInstance.linkProperties.addControlParam("custom_data", withValue: "yes") + CommonMethod.sharedInstance.branchUniversalObject.getShortUrl(with:CommonMethod.sharedInstance.linkProperties, andCallback: { (optUrl: String?, error: Error?) in + if error == nil, let url = optUrl { + NSLog("got my Branch link to share: %@", url) + DispatchQueue.main.async { + UserDefaults.standard.set(true, forKey: "isCreatedDeepLink") + UserDefaults.standard.set(url, forKey: "link") + self.navigationController?.popToRootViewController(animated: true) + } + } + }) + } +} + +extension ReadDeeplinkingVC { + + func uiSetUp() { + let submitBtn = UIButton(frame: CGRect(x: self.view.frame.width/2-60, y: txtFldAdditionalData.frame.maxY+30, width: 120, height: 55)) + submitBtn.setTitle("Submit", for: .normal) + submitBtn.backgroundColor = UIColor(red: 89.0/255.0, green: 12.0/255.0, blue: 228.0/255.0, alpha: 1.0) + submitBtn.layer.cornerRadius = 8 + submitBtn.setTitleColor(UIColor.white, for: .normal) + submitBtn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 22.0) + submitBtn.addTarget(self, action: #selector(self.submitAction), for: .touchUpInside) + scrollViewMain.addSubview(submitBtn) + txtFldCChannel.setLeftPaddingPoints(10) + txtFldFeature.setLeftPaddingPoints(10) + txtFldChampaignName.setLeftPaddingPoints(10) + txtFldStage.setLeftPaddingPoints(10) + txtFldDeskTopUrl.setLeftPaddingPoints(10) + txtFldAdditionalData.setLeftPaddingPoints(10) + txtFldCChannel.attributedPlaceholder = NSAttributedString( + string: "Channel name like Facebook", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldFeature.attributedPlaceholder = NSAttributedString( + string: "Feature eg: Sharing", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldChampaignName.attributedPlaceholder = NSAttributedString( + string: "Campaign name", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldStage.attributedPlaceholder = NSAttributedString( + string: "Stage", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldDeskTopUrl.attributedPlaceholder = NSAttributedString( + string: "Desktop URL", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + txtFldAdditionalData.attributedPlaceholder = NSAttributedString( + string: "Additional Data", + attributes: [NSAttributedString.Key.foregroundColor: UIColor.darkGray] + ) + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/ReadLogViewController.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/ReadLogViewController.swift new file mode 100644 index 000000000..d88749390 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/ReadLogViewController.swift @@ -0,0 +1,41 @@ +// +// ReadLogViewController.swift +// DeepLinkDemo +// +// Created by Apple on 17/05/22. +// + +import UIKit + +class ReadLogViewController: ParentViewController { + + @IBOutlet weak var textViewDescription: UITextView! + + var selectedFileName = "" + + override func viewDidLoad() { + super.viewDidLoad() + + self.textViewDescription.text = loadTextWithFileName(selectedFileName) + reachabilityCheck() + } + + + @IBAction func backAction(_ sender: Any) { + self.navigationController?.popToRootViewController(animated: true) + } + + private func loadTextWithFileName(_ fileName: String) -> String? { + if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first { + let fileURL = dir.appendingPathComponent(fileName) + guard let text = try? String(contentsOf: fileURL, encoding: .utf8) else { + return nil + } + return text + } + return nil + } + +} + + diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/ReadVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/ReadVC.swift new file mode 100644 index 000000000..08fe32021 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/ReadVC.swift @@ -0,0 +1,50 @@ +// +// ReadVC.swift +// DeepLinkDemo +// +// Created by Rakesh kumar on 4/28/22. +// + +import UIKit +import BranchSDK +class ReadVC: ParentViewController { + + @IBOutlet weak var btnback: UIButton! + @IBOutlet weak var labelTxt: UILabel! + @IBOutlet weak var btnShare: UIButton! + var strTxt = "" + private var reachability:Reachability? + override func viewDidLoad() { + super.viewDidLoad() + labelTxt.text = "Success\nUrl is generated.\nHere is the Short URL\(strTxt)" + btnShare.layer.cornerRadius = 8.0 + let tap = UITapGestureRecognizer(target: self, action: #selector(self.onClicLabel(sender:))) + labelTxt.isUserInteractionEnabled = true + labelTxt.addGestureRecognizer(tap) + reachabilityCheck() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + } + + + // And that's the function :) + @objc func onClicLabel(sender:UITapGestureRecognizer) { + + UserDefaults.standard.set(true, forKey: "isRead") + let anURL = URL(string: strTxt) + Branch.getInstance().handleDeepLink(anURL) + } + + @IBAction func backAction(_ sender: Any) { + self.navigationController?.popToRootViewController(animated: true) + } + + @IBAction func btnrReadDeeplink(_ sender: Any) { + UserDefaults.standard.set(true, forKey: "isRead") + let anURL = URL(string: strTxt) + Branch.getInstance().handleDeepLink(anURL) + } + +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/ShareDynamicallyVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/ShareDynamicallyVC.swift new file mode 100644 index 000000000..cb71f1bed --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/ShareDynamicallyVC.swift @@ -0,0 +1,10 @@ +// +// ShareDynamicallyVC.swift +// DeepLinkDemo +// +// Created by Rakesh kumar on 4/19/22. +// + +import UIKit +class ShareDynamicallyVC: ParentViewController { +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/TextViewController.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/TextViewController.swift new file mode 100644 index 000000000..b55b15c90 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/TextViewController.swift @@ -0,0 +1,101 @@ +// +// TextViewController.swift +// DeepLinkDemo +// +// Created by ajaykumar on 15/06/22. +// + +import Foundation +import UIKit +import CoreSpotlight; +import MobileCoreServices; + +class TextViewController: UIViewController { + + var isShareDeepLink = false + var isNavigateToContent = false + var isDisplayContent = false + var isTrackContent = false + var isTrackContenttoWeb = false + var handleLinkInWebview = false + var isCreateDeepLink = false + var forNotification = false + var isTrackUser = false + var isSetDMAParams = false + var isSendV2Event = false + var isSetAttributionLevel = false + + var url = "" + var responseStatus = "" + var dictData = [String:Any]() + var textViewText = "" + + @IBOutlet weak var statusLabel: UILabel! + + @IBOutlet weak var logDataTextView: UITextView! + + + override func viewDidLoad() { + super.viewDidLoad() + logDataTextView.text = textViewText + statusLabel.text = responseStatus + logDataTextView.isEditable = false + } + + @IBAction func BackButtonAction(_ sender: Any) { + self.navigationController?.popToRootViewController(animated: true) + } + @IBAction func nextButtonAction(_ sender: Any) { + if self.isTrackContent == true { + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "GenerateURLVC") as? GenerateURLVC { + vc.isTrackContent = true + vc.forNotification = false + vc.isCreateDeepLink = false + vc.isShareDeepLink = false + vc.isNavigateToContent = false + vc.dictData = dictData + self.navigationController?.pushViewController(vc, animated: true) + } + } else if self.isTrackUser == true { + self.navigationController?.popToRootViewController(animated: true) + } else if self.forNotification == true { + self.navigationController?.popToRootViewController(animated: true) + } else if self.isTrackContenttoWeb || self.isCreateDeepLink { + launchWebView() + } else if self.isNavigateToContent || self.isDisplayContent || self.handleLinkInWebview { + launchReadVC() + } else if self.isSetDMAParams == true { + self.navigationController?.popToRootViewController(animated: true) + } else if self.isSendV2Event == true { + self.navigationController?.popToRootViewController(animated: true) + } else if self.isSetAttributionLevel == true { + self.navigationController?.popToRootViewController(animated: true) + } + else { + launchReadVC() + } + } + + func launchReadVC(){ + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "ReadVC") as? ReadVC { + vc.strTxt = url + self.navigationController?.pushViewController(vc, animated: true) + } + } + + func launchWebView(){ + //Fixed + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "WebViewVC") as? WebViewVC { + self.navigationController?.pushViewController(vc, animated: true) + } + } + + func updateText(msg: String) -> () { + DispatchQueue.main.async() { + self.logDataTextView?.text = msg + } + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/TrackContentVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/TrackContentVC.swift new file mode 100644 index 000000000..9efe7653d --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/TrackContentVC.swift @@ -0,0 +1,88 @@ +// +// TrackContentVC.swift +// DeepLinkDemo +// +// Created by Apple on 12/05/22. +// + +import UIKit +import BranchSDK + +class TrackContentVC: ParentViewController { + + @IBOutlet weak var txtFldOptions: UITextField! + + var pickerView = UIPickerView() + + var trackContenOptions = [String]() + private var reachability:Reachability? + override func viewDidLoad() { + super.viewDidLoad() + + trackContenOptions = ["ADD_TO_CART", "ADD_TO_WISHLIST", "VIEW_CART", "INITIATE_PURCHASE", "ADD_PAYMENT_INFO", "PURCHASE", "SPEND_CREDITS", "SUBSCRIBE", "START_TRIAL", "CLICK_AD", "VIEW_AD", "SEARCH", "VIEW_ITEM", "VIEW_ITEMS", "RATE", "SHARE", "START_TRIAL", "CLICK_AD", "COMPLETE_REGISTRATION", "COMPLETE_TUTORIAL", "ACHIEVE_LEVEL", "UNLOCK_ACHIEVEMENT", "INVITE", "LOGIN", "RESERVE", "OPT_IN", "OPT_OUT"] + + pickerView.dataSource = self + pickerView.delegate = self + + txtFldOptions.inputView = pickerView + let toolBar = UIToolbar(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width,height: 44.0)) + let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) + let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: target, action: #selector(tapDone)) + let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: target, action: #selector(tapCancel)) + toolBar.setItems([cancelButton, flexibleSpace, doneButton], animated: false) + txtFldOptions.inputAccessoryView = toolBar + + txtFldOptions.text = trackContenOptions.first + reachabilityCheck() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + } + + + @objc func tapDone() { + let selectedRow = pickerView.selectedRow(inComponent: 0) + if trackContenOptions.indices.contains(selectedRow){ + txtFldOptions.text = trackContenOptions[selectedRow] + } + txtFldOptions.resignFirstResponder() + self.view.endEditing(true) + } + @objc func tapCancel() { + self.view.endEditing(true) + } + + @IBAction func backBtnAction(){ + self.navigationController?.popToRootViewController(animated: true) + } + + @IBAction func nextBtnAction(){ + let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) + if let vc = storyBoard.instantiateViewController(withIdentifier: "CreateObjectReferenceObject") as? CreateObjectReferenceObject { + vc.screenMode = 7 + vc.txtFldValue = String(txtFldOptions.text ?? "") + self.navigationController?.pushViewController(vc, animated: true) + } + } + +} + +extension TrackContentVC: UIPickerViewDataSource, UIPickerViewDelegate{ + + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + return trackContenOptions.count + } + + func numberOfComponents(in pickerView: UIPickerView) -> Int { + return 1 + } + + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + return trackContenOptions[row] + } + + func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + txtFldOptions.text = trackContenOptions[row] + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/ViewController.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/ViewController.swift new file mode 100644 index 000000000..359d647da --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/ViewController.swift @@ -0,0 +1,20 @@ +// ViewController.swift +// DeepLinkDemo +// Created by Apple on 17/05/22 +import UIKit + +class ViewController: ParentViewController { + + override func viewDidLoad() { + super.viewDidLoad() + super.reachabilityCheck() + } + + + + override var preferredStatusBarStyle: UIStatusBarStyle { + return .lightContent + } + + +} diff --git a/DeepLinkDemo/DeepLinkDemo/Controllers/WebViewVC.swift b/DeepLinkDemo/DeepLinkDemo/Controllers/WebViewVC.swift new file mode 100644 index 000000000..b244ac66a --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Controllers/WebViewVC.swift @@ -0,0 +1,59 @@ +// +// WebViewVC.swift +// DeepLinkDemo +// +// Created by Rakesh kumar on 4/22/22. +// + +import UIKit +import WebKit +import SafariServices + +class WebViewVC: ParentViewController, WKNavigationDelegate { + + @IBOutlet weak var webViewContainer: UIView! + + var webViewDetail: WKWebView = WKWebView() + private var reachability:Reachability? + + override func viewDidLoad() { + super.viewDidLoad() + + loadWKWebview() + reachabilityCheck() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + Utils.shared.setLogFile("HandleLinksInapp") + } + + fileprivate func loadWKWebview(){ + let webConfiguration = WKWebViewConfiguration() + let customFrame = CGRect.init(origin: CGPoint.zero, size: CGSize.init(width: self.webViewContainer.frame.size.width, height: self.webViewContainer.frame.size.height)) + self.webViewDetail = WKWebView (frame: customFrame , configuration: webConfiguration) + webViewDetail.translatesAutoresizingMaskIntoConstraints = false + self.webViewContainer.addSubview(webViewDetail) + self.view.addConstraint(NSLayoutConstraint(item: webViewDetail, attribute: .trailing, relatedBy: .equal, toItem: self.webViewContainer, attribute: .trailing, multiplier: 1, constant: 0)) + self.view.addConstraint(NSLayoutConstraint(item: webViewDetail, attribute: .leading, relatedBy: .equal, toItem: self.webViewContainer, attribute: .leading, multiplier: 1, constant: 0)) + self.view.addConstraint(NSLayoutConstraint(item: webViewDetail, attribute: .top, relatedBy: .equal, toItem: self.webViewContainer, attribute: .top, multiplier: 1, constant: 0)) + self.view.addConstraint(NSLayoutConstraint(item: webViewDetail, attribute: .bottom, relatedBy: .equal, toItem: self.webViewContainer, attribute: .bottom, multiplier: 1, constant: 0)) + + webViewDetail.navigationDelegate = self + if let deeplinkurl: String = UserDefaults.standard.string(forKey: "link"){ + webViewDetail.load(URLRequest(url: URL(string: deeplinkurl)!)) + } + } + + @IBAction func backBtnTapped(){ + self.navigationController?.popToRootViewController(animated: true) + } + +} + +extension WebViewVC: SFSafariViewControllerDelegate{ + func safariViewControllerDidFinish(_ controller: SFSafariViewController) { + self.dismiss(animated: true) + self.navigationController?.popViewController(animated: true) + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/DeepLinkDemo-Bridging-Header.h b/DeepLinkDemo/DeepLinkDemo/DeepLinkDemo-Bridging-Header.h new file mode 100644 index 000000000..28c03fdc2 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/DeepLinkDemo-Bridging-Header.h @@ -0,0 +1,12 @@ +// +// DeepLinkDemo-Bridging-Header.h +// DeepLinkDemo +// +// Created by Rakesh kumar on 4/18/22. +// + +#ifndef DeepLinkDemo_Bridging_Header_h +#define DeepLinkDemo_Bridging_Header_h +#import "SIAlertView.h" + +#endif /* DeepLinkDemo_Bridging_Header_h */ diff --git a/BranchSDKTestsHostApp/BranchSDKTestsHostAppRelease.entitlements b/DeepLinkDemo/DeepLinkDemo/DeepLinkDemo.entitlements similarity index 50% rename from BranchSDKTestsHostApp/BranchSDKTestsHostAppRelease.entitlements rename to DeepLinkDemo/DeepLinkDemo/DeepLinkDemo.entitlements index 9ad5d115f..51c38f856 100644 --- a/BranchSDKTestsHostApp/BranchSDKTestsHostAppRelease.entitlements +++ b/DeepLinkDemo/DeepLinkDemo/DeepLinkDemo.entitlements @@ -4,11 +4,9 @@ com.apple.developer.associated-domains - applinks:bnc.lt - applinks:bnctestbed.app.link - applinks:bnctestbed.test-app.link - applinks:bnctestbed-alternate.app.link - applinks:bnctestbed-alternate.test-app.link + applinks:timber.test-app.link + applinks:timber.test-app.link + applinks:timber.test-app.link diff --git a/DeepLinkDemo/DeepLinkDemo/Header.h b/DeepLinkDemo/DeepLinkDemo/Header.h new file mode 100644 index 000000000..d3e5fefff --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Header.h @@ -0,0 +1,12 @@ +// +// Header.h +// DeepLinkDemo +// +// Created by Rakesh kumar on 4/18/22. +// + +#ifndef Header_h +#define Header_h +#import "SIAlertView.h" + +#endif /* Header_h */ diff --git a/DeepLinkDemo/DeepLinkDemo/Info.plist b/DeepLinkDemo/DeepLinkDemo/Info.plist new file mode 100644 index 000000000..6ce93adf7 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Info.plist @@ -0,0 +1,54 @@ + + + + + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleURLSchemes + + Timber + + + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + UIBackgroundModes + + fetch + processing + remote-notification + + UIStatusBarStyle + UIStatusBarStyleLightContent + adjust_app_token + x66ziay2jtvk + amplitude_api_key + 3dc11880800fe99b829ca66886abf9e5 + appboy_api_key + d781dccf-9f96-46a8-878a-a1bef7bb6968 + appmetrica_api_key + 4805cb1a-2e2c-4a03-af63-4c712939817b + appsflyer_api_key + 84qHoE3ZXh7SetmHU6boi5 + branch_key + + live + key_live_nf8w3l1WBpzWdlC00KsLNdmbuEccK6Yr + test + key_test_om2EWe1WBeBYmpz9Z1mdpopouDmoN72T + + branch_universal_link_domains + + timber.app.link + timber-alternate.app.link + timber.test.app.link + timber-alternate.test.app.link + + + diff --git a/DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.h b/DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.h new file mode 100644 index 000000000..125b19377 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.h @@ -0,0 +1,16 @@ +// +// NSURLSession+Branch.h +// +// Created by Ernest Cho on 10/11/18. +// Copyright © 2018 Branch Metrics, Inc. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSURLSession (Branch) + +@end + +NS_ASSUME_NONNULL_END diff --git a/DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.m b/DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.m new file mode 100644 index 000000000..379c8e752 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/NSURLSessionBranch.m @@ -0,0 +1,94 @@ +// +// NSURLSession+Branch.m +// +// Created by Ernest Cho on 10/11/18. +// Copyright © 2018 Branch Metrics, Inc. All rights reserved. +// + +#import "NSURLSessionBranch.h" +#import +#import "BranchLogger.h" + +@implementation NSURLSession (Branch) + ++ (void)load { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + [self swizzleSelector:@selector(dataTaskWithRequest:completionHandler:) + withSelector:@selector(xxx_dataTaskWithRequest:completionHandler:)]; + }); +} + +// swaps originalSelector with swizzledSelector ++ (void)swizzleSelector:(SEL)originalSelector withSelector:(SEL)swizzledSelector { + Class class = [self class]; + + Method originalMethod = class_getInstanceMethod(class, originalSelector); + Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); + + method_exchangeImplementations(originalMethod, swizzledMethod); +} + +- (void)logNetworkTrafficRequest:(NSURLRequest *)request data:(NSData *)data response:(NSURLResponse *)response { + [[BranchLogger shared] logDebug: @"BranchSDK API LOG START OF FILE" error:nil]; + + [[BranchLogger shared] logDebug:(@"[LogEntryStart]\n\n") error:nil]; + [[BranchLogger shared] logDebug:(@"---------------------------------------------------------------------BranchSDK LOG START ---------------------------------------------------------------------" ) error:nil]; + [[BranchLogger shared] logDebug:(@"[LogEntryStart]\n\n") error:nil]; + [[BranchLogger shared] logDebug:([NSString stringWithFormat: @"BranchSDK Request log: %@", request]) error:nil]; + + NSData *body = [request HTTPBody]; + if (body) { + [[BranchLogger shared] logDebug:(@"[LogEntryStart]\n\n") error:nil]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"BranchSDK Request Body: %@", [NSString stringWithUTF8String:body.bytes]] error:nil]; + } + + [[BranchLogger shared] logDebug:(@"[LogEntryStart]\n\n") error:nil]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"BranchSDK Response: %@", response] error:nil]; + + if (data.bytes) { + [[BranchLogger shared] logDebug:(@"\n\n") error:nil]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"BranchSDK Response Data: %@", [NSString stringWithUTF8String:data.bytes]] error:nil]; + } + [[BranchLogger shared] logDebug:(@"[LogEntryStart]\n\n") error:nil]; + [[BranchLogger shared] logDebug:(@"---------------------------------------------------------------------BranchSDK LOG END ---------------------------------------------------------------------" ) error:nil]; + [[BranchLogger shared] logDebug:(@"[LogEntryStart]\n\n") error:nil]; + [[BranchLogger shared] logDebug:(@"BranchSDK API LOG END OF FILE") error:nil]; + +} + +// replacement method for dataTaskWithRequest +- (NSURLSessionDataTask *)xxx_dataTaskWithRequest:(NSURLRequest *)request + completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler { + + // create a new block that just calls the original block after logging the request + void (^completionHandlerWithLogging)(NSData *, NSURLResponse *, NSError *) = ^(NSData *data, NSURLResponse *response, NSError *error) { + if (completionHandler) { + + [self logNetworkTrafficRequest:request data:data response:response]; + completionHandler(data, response, error); + } + }; + + return [self xxx_dataTaskWithRequest:request completionHandler:completionHandlerWithLogging]; +} + +- (NSData *)dataFromJSONFileNamed:(NSString *)fileName { + // If this class is part of the Test target, [self class] returns the Test Bundle + // NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"json"]; + + NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:@"json"]; + NSString *jsonString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL]; + return [jsonString dataUsingEncoding:NSUTF8StringEncoding]; +} + +- (NSDictionary *)dictionaryFromJSONFileNamed:(NSString *)fileName { + NSData *jsonData = [self dataFromJSONFileNamed:fileName]; + id dict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil]; + if ([dict isKindOfClass:NSDictionary.class]) { + return dict; + } + return nil; +} + +@end diff --git a/DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.h b/DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.h new file mode 100644 index 000000000..ad32df88d --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.h @@ -0,0 +1,19 @@ +// +// Reachability.h +// Reachability +// +// Created by Yuki Nagai on 11/2/15. +// Copyright © 2015 Ashley Mills. All rights reserved. +// + +#import + +//! Project version number for Reachability. +FOUNDATION_EXPORT double ReachabilityVersionNumber; + +//! Project version string for Reachability. +FOUNDATION_EXPORT const unsigned char ReachabilityVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.swift b/DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.swift new file mode 100644 index 000000000..9f5f4d7ae --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/Reachability/Reachability.swift @@ -0,0 +1,270 @@ +/* + Copyright (c) 2014, Ashley Mills + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +import SystemConfiguration +import Foundation + +public enum ReachabilityError: Error { + case FailedToCreateWithAddress(sockaddr_in) + case FailedToCreateWithHostname(String) + case UnableToSetCallback + case UnableToSetDispatchQueue +} + +public let ReachabilityChangedNotification = NSNotification.Name("ReachabilityChangedNotification") + +func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) { + + guard let info = info else { return } + + let reachability = Unmanaged.fromOpaque(info).takeUnretainedValue() + + DispatchQueue.main.async { + reachability.reachabilityChanged() + } +} + +public class Reachability { + + public typealias NetworkReachable = (Reachability) -> () + public typealias NetworkUnreachable = (Reachability) -> () + + public enum NetworkStatus: CustomStringConvertible { + + case notReachable, reachableViaWiFi, reachableViaWWAN + + public var description: String { + switch self { + case .reachableViaWWAN: return "Cellular" + case .reachableViaWiFi: return "WiFi" + case .notReachable: return "No Connection" + } + } + } + + public var whenReachable: NetworkReachable? + public var whenUnreachable: NetworkUnreachable? + public var reachableOnWWAN: Bool + + // The notification center on which "reachability changed" events are being posted + public var notificationCenter: NotificationCenter = NotificationCenter.default + public var currentReachabilityString: String { + return "\(currentReachabilityStatus)" + } + + public var currentReachabilityStatus: NetworkStatus { + guard isReachable else { return .notReachable } + if isReachableViaWiFi { + return .reachableViaWiFi + } + if isRunningOnDevice { + return .reachableViaWWAN + } + return .notReachable + } + + fileprivate var previousFlags: SCNetworkReachabilityFlags? + fileprivate var isRunningOnDevice: Bool = { + #if (arch(i386) || arch(x86_64)) && os(iOS) + return false + #else + return true + #endif + }() + fileprivate var notifierRunning = false + fileprivate var reachabilityRef: SCNetworkReachability? + fileprivate let reachabilitySerialQueue = DispatchQueue(label: "uk.co.ashleymills.reachability") + required public init(reachabilityRef: SCNetworkReachability) { + reachableOnWWAN = true + self.reachabilityRef = reachabilityRef + } + + public convenience init?(hostname: String) { + guard let ref = SCNetworkReachabilityCreateWithName(nil, hostname) else { return nil } + self.init(reachabilityRef: ref) + } + + public convenience init?() { + var zeroAddress = sockaddr() + zeroAddress.sa_len = UInt8(MemoryLayout.size) + zeroAddress.sa_family = sa_family_t(AF_INET) + guard let ref: SCNetworkReachability = withUnsafePointer(to: &zeroAddress, { + SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)) + }) else { return nil } + self.init(reachabilityRef: ref) + } + + deinit { + stopNotifier() + reachabilityRef = nil + whenReachable = nil + whenUnreachable = nil + } +} + +public extension Reachability { + + // MARK: - *** Notifier methods *** + func startNotifier() throws { + guard let reachabilityRef = reachabilityRef, !notifierRunning else { return } + var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil) + context.info = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) + if !SCNetworkReachabilitySetCallback(reachabilityRef, callback, &context) { + stopNotifier() + throw ReachabilityError.UnableToSetCallback + } + if !SCNetworkReachabilitySetDispatchQueue(reachabilityRef, reachabilitySerialQueue) { + stopNotifier() + throw ReachabilityError.UnableToSetDispatchQueue + } + // Perform an intial check + reachabilitySerialQueue.async { + self.reachabilityChanged() + } + notifierRunning = true + } + + func stopNotifier() { + defer { notifierRunning = false } + guard let reachabilityRef = reachabilityRef else { return } + SCNetworkReachabilitySetCallback(reachabilityRef, nil, nil) + SCNetworkReachabilitySetDispatchQueue(reachabilityRef, nil) + } + + // MARK: - *** Connection test methods *** + var isReachable: Bool { + + guard isReachableFlagSet else { return false } + + if isConnectionRequiredAndTransientFlagSet { + return false + } + if isRunningOnDevice { + if isOnWWANFlagSet && !reachableOnWWAN { + // We don't want to connect when on 3G. + return false + } + } + return true + } + + var isReachableViaWWAN: Bool { + // Check we're not on the simulator, we're REACHABLE and check we're on WWAN + return isRunningOnDevice && isReachableFlagSet && isOnWWANFlagSet + } + + var isReachableViaWiFi: Bool { + // Check we're reachable + guard isReachableFlagSet else { return false } + // If reachable we're reachable, but not on an iOS device (i.e. simulator), we must be on WiFi + guard isRunningOnDevice else { return true } + // Check we're NOT on WWAN + return !isOnWWANFlagSet + } + + var description: String { + + let W = isRunningOnDevice ? (isOnWWANFlagSet ? "W" : "-") : "X" + let R = isReachableFlagSet ? "R" : "-" + let c = isConnectionRequiredFlagSet ? "c" : "-" + let t = isTransientConnectionFlagSet ? "t" : "-" + let i = isInterventionRequiredFlagSet ? "i" : "-" + let C = isConnectionOnTrafficFlagSet ? "C" : "-" + let D = isConnectionOnDemandFlagSet ? "D" : "-" + let l = isLocalAddressFlagSet ? "l" : "-" + let d = isDirectFlagSet ? "d" : "-" + return "\(W)\(R) \(c)\(t)\(i)\(C)\(D)\(l)\(d)" + } +} + +fileprivate extension Reachability { + + func reachabilityChanged() { + let flags = reachabilityFlags + guard previousFlags != flags else { return } + let block = isReachable ? whenReachable : whenUnreachable + block?(self) + if ReachabilityChangedNotification.rawValue != "" { + self.notificationCenter.post(name: ReachabilityChangedNotification, object:self) + } + previousFlags = flags + } + + var isOnWWANFlagSet: Bool { + #if os(iOS) + return reachabilityFlags.contains(.isWWAN) + #else + return false + #endif + } + var isReachableFlagSet: Bool { + return reachabilityFlags.contains(.reachable) + } + var isConnectionRequiredFlagSet: Bool { + return reachabilityFlags.contains(.connectionRequired) + } + var isInterventionRequiredFlagSet: Bool { + return reachabilityFlags.contains(.interventionRequired) + } + var isConnectionOnTrafficFlagSet: Bool { + return reachabilityFlags.contains(.connectionOnTraffic) + } + var isConnectionOnDemandFlagSet: Bool { + return reachabilityFlags.contains(.connectionOnDemand) + } + var isConnectionOnTrafficOrDemandFlagSet: Bool { + return !reachabilityFlags.intersection([.connectionOnTraffic, .connectionOnDemand]).isEmpty + } + var isTransientConnectionFlagSet: Bool { + return reachabilityFlags.contains(.transientConnection) + } + var isLocalAddressFlagSet: Bool { + return reachabilityFlags.contains(.isLocalAddress) + } + var isDirectFlagSet: Bool { + return reachabilityFlags.contains(.isDirect) + } + var isConnectionRequiredAndTransientFlagSet: Bool { + return reachabilityFlags.intersection([.connectionRequired, .transientConnection]) == [.connectionRequired, .transientConnection] + } + + var reachabilityFlags: SCNetworkReachabilityFlags { + + guard let reachabilityRef = reachabilityRef else { return SCNetworkReachabilityFlags() } + + var flags = SCNetworkReachabilityFlags() + let gotFlags = withUnsafeMutablePointer(to: &flags) { + SCNetworkReachabilityGetFlags(reachabilityRef, UnsafeMutablePointer($0)) + } + + if gotFlags { + return flags + } else { + return SCNetworkReachabilityFlags() + } + } +} diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel-d.png b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel-d.png new file mode 100644 index 0000000000000000000000000000000000000000..fa432a55d32f8e321808401315985797224b4ab7 GIT binary patch literal 1041 zcmaJ=PiWIn7|&324kidYY-5MFOmL!2nzYT@usXY@vxQ}puDCi-%#znNcFBv$tIeti z^AAH1**pll^rQ!c?IiwXcu)r(ytsoP4nY{=X&`zM#h0#~9yUXg_uj|%`+dLf&%2Qx zInmnE*+NlNYbq&a$hz12n)i_ZtIXIcSvqhcheuH!mlYdQF%3;XkTR4>n1PBmef|yX zr>I>A^=uC3u>xFU%5+3GO4oQrviHm^4Qej97^OEw<>WMoBO8Jc z6Y!~ijst?gaKVrua7O{}=XlmnUctu&#gHKKeW3o(B$}<|#f&smk3~*Vx`44IvTV6r zX37Bu*^?|6i9|dOp7#+CpEGS@#r2s^PlG{%j%w=`){zN3Mr8t(aFixWH&ZaIEn3s5 zmx&aNbrp-{7{8ZN!%>$1?`jxZ-VV;dzk0VNcCynJWHZn~C0iwp%lCMpEHQ3F1tU9) z&{U&}=>o#YDIg2PM+ML;E2?gKhQl?4EQ=}A!HTKEloX{22czqnD8*u2I3^{6VLrxj z34V|dB&5C=9}Xl!k`#zHuo6;B1~hR4s}XD>7?2{tAWyJ^+hV<8Ff0;Tg0_AEYC|?M zKrLxe-&sq1XDyppZ5u81Jft15ED^(ct^KFf4HKCkZ@V?PUN1*f|2CRbQ2bzfV!^suV~tTY#W=N5bK`B(13jpbRV^1A%s{l~Ph w_N2Os#+T@CW7Xe_Xl?z=(7V%@e};FrQ|{O9`@?5Wc6ygIl^Bth2G3sk11qCa#{d8T literal 0 HcmV?d00001 diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel-d@2x.png b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-cancel-d@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..8f359b8a5ed12145a0cd57d6d154813afae655fe GIT binary patch literal 1245 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%qp275hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)y-fM)1rW~NxVni#uSnwVIcSQt4O8oC-e85z5}m^&I-7`vLf zxEMRb^t$9Hm*%GCmB93-AoM!o)C)=sxdlL*T~doO%TiO^it=+6z@E0s#O)SyoaRCG zrr>sq1x~&CK*#8Vq82HtVM4(417gAxE|3FH`l)%q^j-u^*b^$x{9|BX^!Ide45_%) z66EQ1BtT&8naL@#N;lILEp)!{y<&aCyhYEpZ{7m^2dXTBQ`?>}7{1oAQYlk=UHkc= z^4(t#R9!>&O8r>sd)dWd-gC46?`D{vQGUkwH{o!Marl{b6W{FxSpu70On9sQjPq}= z`7_gQ`>i^sFT9jov@COlj(67WX-`yUEt~jym&kF$%6aV9tv?@na$eWPL$9kz=D6bh z@1EC76=jZ3+_g@4ql#z1lNootImA6ytm-;sAQI|(S!6Cl$-Ce440wwcX*5+cK9tlc z;b>~exh=L$Yl}`d&*25T);(RfTp-DPBfE>o1f`wI9XAYkF1>wm=}<+My66YRHW^Ni z?O9K2e~8|9_`$`k{EuBVeeHR1#bXolw{v%BE?%clb7XN6`_Ho73y#&Dh}u4v}$3MR z%5;i&QT*D$i+bA-4|0y57alwb3SJZxeCgWFgEb_1@BR7xe*e#RerRxS zWBty0ilQ1515%Q#b>6pi3;91uj=UgCGmfY6Fv{S9VneD|Lt_vm3?&PbP|=DfmS7h} zZEDw3X`Gh#iz+f0#ltYJVG%Y(b@jNGqUIq6V=$|mQTpq`V;bmMlpYDme%Xq_oIX&p z;c#g%rIzw)M5BAUL6<8M0Rv(MxW>5Yh;EcF>xyLWnOPc?AvhnUSA$B+Lm-B12trK2 zr}{Y#2m-?eLxRBV0lc5%SwDFN9~Trug2;zK<)Mi;Tg!+^slVcjoT79NV@qV&LZQGE z0t~XVEEkDHJPn@r5roevnpkmtrqfnckf5X5x`lOQ0#8vHLlZbklSo%nFswCM)2Wn+ z6pVEhi{%)RD)VdUhH1!BVj*d;5fZhD4}GDDWdgy~?#RAEAj(nN#Nbxn*115zXy3kWfp5zi8|^^;KRw~+zLNsD^zSOPWm zDqO90EWw&wmIT9kt^KRjRTG&XZ@V_Ql3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)y-fM)1rW~NxVnwq(pyBRu~SQt4O8oC-e85z5}m^&I-7`vLf zxEMRb^t$9Hm*%GCmB93-AoM!n)C)=sxdlL*T~doO%TiO^it=+6z@E0s#O4+gV;4&k z6Wr!O^`>BR3q-FoPPga-9itD5TBN9k2?5g&hzU=)Kn^_Vr{)3Edl4{UJFYEW%)r3N z>*?YcQgLfa(80{Z4gz19D)#UPJabNnrhnjgcQAL>vT2U4%09s_ z_&<2I6*5dWm>)9l`J6AFlY_i^3>R$`%WCSqy-hTG?T*WT8`ewpo9BB?a#^JD%lNB% zQ(BLu8H?OO)6ir3eq6lU6ZHC$|IfT=vApOmo8T3jV9EQ1JdS4%|CsTAS@X5~_hc=m7e!BnMZ~(g>qzIG~ThoM-|pEbAixkE!AqNCHvLU;GGy7`FF> zl1jt0(8o!-N{SAKv{eJKF)Y|=8={m25FY_!iWVX^UcMo4MGg^zUV#>j2*@bClO`CL zjHjf@tQ3%m&JH|ib4Wl1P{eI@T(dYkL=<#6w0F!Dffpb!8zOdsN(%`*qMHEsl5Uqo zGYszYk&MUd^D%8WOEWA*qu1wRJe=3Zv3|Vx5XhS;k8(-AyXXs@LPQ2agQKWiE=T6v zq;8H;Odt?&G+5S!5H2gPLD6<;R!d2N2bN?i22^wncNE1DeFBCE6zNV1s!^8JtYVo^ z!6;iaD2Ak+luAHB_&-!t%V-NG!EU_&6t+@%15im|=@X`e8aLYFxH7ni2}G!yDP12g zRWXs#p>Ab#1CI>&@RNclDVk$wEieRui)j`VH3`J{5P>vEMUlBK+TTtGqCQVM>t~oK z+r_%0yg$sgyQ5y7cSlNGUY90RpurMX-sSo$a-CsN4dj^zrg90$-KMVMg`_#9ax9*T zdPS~WITmk4E`@@joYwx;>XHe~kFzZgE;^J)A82UaO*Gh>SNA2*rI?QK;gtQoFU}l! zkJq~QbCKNC+U)sf&xbm{Og$J{n69fmbMW-a;9|0EOWuC8`mkZW@$KBJyY=jy!+HO) zrF&oJts84i%ejsDx#i6Z=i*ZJ_1fXtaJFW#?!$}Lh2uxl*&jWRe+~xwmxx>6exLdj s{oMR?`*x~%W|;23ymkNV>nqxxYV2Kyr{UL3{kn5eW6?POq-*%vAA8DDApigX literal 0 HcmV?d00001 diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default-d@2x.png b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default-d@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6d21603e14f6b0ac15c21633067c32221c82ce8c GIT binary patch literal 1247 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%qp275hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)y-fM)1rW~Nv<8yLE}nH!s$SQwcb8oC-e85z5}m^&I-7`vLf zxEMRb^t$9Hm*%GCmB93-AoQBy)C)=sxdlL*T~doO%TiO^it=+6z@E0s#O)SioaRCG zrr>sq2~NHGK*#8Vq82HtVM4(417gAxE|3FH`l)%q^j-u^*d6aP#2FYE13g_FLn?07 z1bO?lI0)$OJDh*8NtRRHK(f^Ep5xvIIfvLPnS2BB4?=3kR?L(Z2otzr(BRB*EqnLm zGN)&%{9UW6uFB6dJa5bx8oKjORnk4f^D_khE=+wlBl?;5Bo%fQUXI8qMSo7&EWi9C z<=&**KZ-Fh8yIoA*3WqAewI znt<^$&GFrt!MS3gdlEPEnk9_aH1u*MD?^iOjLp?tza4D$B@pScbS?83{ F1OUq6tL6Xz literal 0 HcmV?d00001 diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default.png b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-default.png new file mode 100644 index 0000000000000000000000000000000000000000..17eab59209babad2fe43fd721463dd754f35cd59 GIT binary patch literal 1035 zcmaJ=O-K|`93POZBr6CKI}Kw{W;q^U4(OZ8 zDhHvJ63^32HN_ywXdG&;ewa4hA%q z2G0jDBH&J1Nc94i+fq@GfU7x%jSOg!zM@)y6DUF9NHP;b_)RsRC4#|3gi)igr;JY{$E!u$!B-0h0wToNzSUxZxJxl`V)4P!V);5RO%< z*jt1MxhdqoXn^A zpe#j`d@Lx3B`GLYxDwPROkkl3SKsFHHM#yUm^St-0mnEG^iBtwWI1WU*ddk_8;!AX zIaX6|i>ud;g{{eDa4?MD+J9PIG2!{~x7ESLhwA793(vcQ2m49W_y)cd7t>NQ=e_C4 zaQmmpePfNBI&|&lr>3{)d)=>H(K}shGc$A31DE$Mo>|=(T>i53dHy5O^l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)y-fM)1rW~Nv<8yLE}nHyW0SQwcb8oC-e85z5}m^&I-7`vLf zxEMRb^t$9Hm*%GCmB93-AoM!o)C)=sxdlL*T~doO%TiO^it=+6z@E0s#O)SyoaRCG zrr>sq1x~&CK*#8Vq82HtVM4(417gAxE|3FH`l)%q^j-u^*vFi^_!$@&c|2VlLn>~~ z2{O!Ub`ZE@%^03wwQJ9TAeG%-at~`1!d@Mz3;e|3{m;Q};xR8J?@C9l7Y0WoIgFa$ zE4eUkbDx!LnO5e1e8sZNmJ^?C4kfeNHEn<3;%CuNUBJC>X=c@vWs3xtNnd&YAg1jj zr`>@+t2gO9Ucx_X%eADQi3%Jpnpd@M?pUR@@tRlc^*g_q-ZSgy-xE3hasR>Q_lXkQ z&Ys$|q_XX8dT**Hqxx6hzid}5bSgu-mAodUTzJtRE5ho1x^v=ti?+UF89Rkcbuc<45>c0kqBrZVc4!-B=Dqjl_xt@n-5x=m=R5Yg=M`P;4xK9g9H%e?7(x- zh+*sYDajN}39YQ8s~*w8cx=@`Yz%7**@h_f0f={lw4!mumq$+sT#-4VBOrJMBMN$z z!^0+MAC4!b;XWxS6QP56qs<}#6+jWU)qc%lZH~z4vS{y^NdnJ7U>`>;2bB`q@ThJA zJmB%UB`-zc4CA5v0fwOt;Ix;bNiTXCH|1vo3`^JH`G-K>Ou2_m@XdK&=)@7d5E?8= zW-=L1#^=$^G)V=6K}Un8-3Z~fvKka^w`Nrr6nJ1sreZ)v*KkKs?A8Y%N1#ZTQ&5c+ zSP$*cj$1hDi$Q$mgFsdii$Y}5oI z)Xk)>_ZOeUTA+RorLf+#7PV{qjdg22W!3yPWqVmwD64UeM8EFY|^_cv2v zAJ5Pf)kH_Uyf4Bx2PnoDjnMVs0+-jNK^17Qz?E0Ik)m8@7*qp!=7FgU0lC@KRXmq8 zs}zr=zNlWFD;JL?Sd>emU`VI6f3><`Li6KnR|XdyRz@FaXx>dU*e_i#explqF2;wG z_I&HvhON`yaz3rjmbk9WS$pG$nvTrFxq&qg)^^5cN=6g-*uu8EHQR6c-;ZZ6yfr_l z+{pg>*WSE7U3Gn8Vc^pAyO1Rl3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)y-fM)1rW~NxVTDV!b8JW5nyO^068oC-e8Mqibxwx4cni)Gg z8Cf{O^t$9Hm*%GCmB93-!1bCL;M5CB47mkBn_W_iGRsm^+=}vZ6~Lah%Eav!7o6rn z^`_u-i>WJ4z4}1M=!2pbDXL*Y!1M!R!V@l#15f&?dBF5u1Wed1Z1aj37#Q6>T^vIy zZcUjK?{(Ng;8=S4=1eBmkG_I7jSuFt?`>LizRR}Z*Neh0EJw=^8gnRV?QLj!uv_

3+>w5_|A|Bj1|*U=&S zL;gbDpZDi2P(JYf+1HBslizWk-8;Si=X8;Mzk=sRO`U2p`A*conznC3HFJc2xfv>| zO`jud%DAdv(ju;%S8b-Bd8KwJoyA?}hmLooUo5j#sG;B!(J2hZ>y2D})7W|XIo@3; zmM}cBL}UVMiqc8zgvBn*61lS#&Ug52YZNjunEQF7Js#5(a`SQBj1ZTPG#dF>w#0|qz4{FT}X8xMgB8c$b0mvv4FO#nR!s&fDU literal 0 HcmV?d00001 diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive.png b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive.png new file mode 100644 index 0000000000000000000000000000000000000000..28f3264e5c4081f75035c44e8565703ae6949ca9 GIT binary patch literal 1033 zcmaJ=O=#0l9M7E0eK;sy{6O@Pm7%aEP1>eyXt%XZ;|gYsuDIS@n!K)|%ZJIE&8E0+ zsIY?vcM-vph(}=}f+$R32%emX2!ib7ZZh;Bc#!$ht(}L>kmSAh=l}ctfB%oSG&Xvn zxBFB#K@h#U5h0J)Bi`59f&XjyiH~?WiLymBZkAC^wjq&H%@PDTU7mt@D66wq-oXSx zwEML}5f!D2ykhEvid0Bn$9=^%c&02AgT9M49Gw(M&uZ_c&NKfIR}vtbt@VU^snE1_3&XtyxGj4d5}#C36NPNvw1y1>I`V8qRK+ zaKUI-wrGY5dMPy>CF%dJy5913P#*5--Iv%Y%vzAnL&u!472LRTpBKvFGd7fwX%|d$ zx>?1siiu38Vp5}z|1BpV9M2}u%jP@1Ol*_ap;*+@DhaAAhY zvgx1@N(*9y;X;`-8%s5@f~m~t&_GSBx`)jii1mg+w{Tw zjfF+V<74;NvV&C*){;6<3ysClUTgnpb<>3B$J@3B7av-q4-Gu;HXiK0=;dGdQe4Xk zse=2Zbp6EUo42oDulKGo!vlxcwiaB*ckd~&L~;F(6K5`!JNiZO_WbsC&yC-IqFbL= z=Qr-xmsf&aKH>uy^gUYi-9n literal 0 HcmV?d00001 diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive@2x.png b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.bundle/button-destructive@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1a82328a00c35f68fad523dcd1e6c703a73632bf GIT binary patch literal 1187 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%qp275hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|81#=KlDb#X~hD#E>34K5C;EJ)Q4 zN-fSWElLJPT$(b-ssbzLqSVBa{GyQj{2W*)24v)y-fM)1rW~NxVTDV!b8JQUyyO^068oC-e8Mqibxwx4cni)Gg z8Cf{O^t$9Hm*%GCmB93-AoQBx)C)=sxdlL*T~doO%TiO^it=+6z@E0s#O)SCoaRCG zrr>sq5l+4OK*#8Vq82HtVM4(417gAxE|3FH`l)%q^j-u^*!=SQTp1V`MLk^{Ln>~~ z39`;RJoFJfdLYyP0iYtRBt&)HJ z(pIK!o0n^kZ+`!_ugq=jR;M-9`GR)u6XbImLQigBO)lW6yQY4*#dE3PGO0)TA3XDt zIm;6MUB3TLJAc+ikriG`MLZ-V0+*-Q{{Et|+gU3!>@NQetwhPE%i1+WuAbKZA^mW{ z1&Ny~)wAR$N=fN3b5&g4`tlLOSra~Hsd$Nvdz30>rMm^j1qs^t-aKLNm^^8JoS@Cw zX~$Z3sOvW^@9dr3Q9S=mZ}v|2-orDF>6=YGn>t@;PS*NU$>+XKSSf1zy-#NOva=Jd v_iHit3I1R_7r9gY-cFhCv;4Hx8QB;<-OYUedI`sEP_g0Z>gTe~DWM4f3PX@d literal 0 HcmV?d00001 diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.h b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.h new file mode 100644 index 000000000..49eaae22f --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.h @@ -0,0 +1,69 @@ +// SIAlertView.h +// SIAlertView +// Created by Kevin Cao on 13-4-29. +// Copyright (c) 2013年 Sumi Interactive. All rights reserved. + +#import +extern NSString *const SIAlertViewWillShowNotification; +extern NSString *const SIAlertViewDidShowNotification; +extern NSString *const SIAlertViewWillDismissNotification; +extern NSString *const SIAlertViewDidDismissNotification; +typedef NS_ENUM(NSInteger, SIAlertViewButtonType) { + SIAlertViewButtonTypeDefault = 0, + SIAlertViewButtonTypeDestructive, + SIAlertViewButtonTypeCancel +}; +typedef NS_ENUM(NSInteger, SIAlertViewBackgroundStyle) { + SIAlertViewBackgroundStyleGradient = 0, + SIAlertViewBackgroundStyleSolid, +}; +typedef NS_ENUM(NSInteger, SIAlertViewButtonsListStyle) { + SIAlertViewButtonsListStyleNormal = 0, + SIAlertViewButtonsListStyleRows +}; +typedef NS_ENUM(NSInteger, SIAlertViewTransitionStyle) { + SIAlertViewTransitionStyleSlideFromBottom = 0, + SIAlertViewTransitionStyleSlideFromTop, + SIAlertViewTransitionStyleFade, + SIAlertViewTransitionStyleBounce, + SIAlertViewTransitionStyleDropDown +}; +@class SIAlertView; +typedef void(^SIAlertViewHandler)(SIAlertView *alertView); +@interface SIAlertView : UIView +@property (nonatomic, copy) NSString *title; +@property (nonatomic, copy) NSString *message; +@property (nonatomic, assign) SIAlertViewTransitionStyle transitionStyle; // default is SIAlertViewTransitionStyleSlideFromBottom +@property (nonatomic, assign) SIAlertViewBackgroundStyle backgroundStyle; // default is SIAlertViewBackgroundStyleGradient +@property (nonatomic, assign) SIAlertViewButtonsListStyle buttonsListStyle; // default is SIAlertViewButtonsListStyleNormal +@property (nonatomic, copy) SIAlertViewHandler willShowHandler; +@property (nonatomic, copy) SIAlertViewHandler didShowHandler; +@property (nonatomic, copy) SIAlertViewHandler willDismissHandler; +@property (nonatomic, copy) SIAlertViewHandler didDismissHandler; +@property (nonatomic, readonly, getter = isVisible) BOOL visible; +@property (nonatomic, readonly, getter = isParallaxEffectEnabled) BOOL enabledParallaxEffect; +@property (nonatomic, strong) UIColor *viewBackgroundColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIColor *titleColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIColor *messageColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIFont *titleFont NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIFont *messageFont NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIFont *buttonFont NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIColor *buttonColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIColor *cancelButtonColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; +@property (nonatomic, strong) UIColor *destructiveButtonColor NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; +@property (nonatomic, assign) CGFloat cornerRadius NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; // default is 2.0 +@property (nonatomic, assign) CGFloat shadowRadius NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; // default is 8.0 + +@property (nonatomic) BOOL shouldRemoveAfterTouch; + +- (void)setDefaultButtonImage:(UIImage *)defaultButtonImage forState:(UIControlState)state NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; +- (void)setCancelButtonImage:(UIImage *)cancelButtonImage forState:(UIControlState)state NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; +- (void)setDestructiveButtonImage:(UIImage *)destructiveButtonImage forState:(UIControlState)state NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; + +- (instancetype)initWithTitle:(NSString *)title andMessage:(NSString *)message NS_DESIGNATED_INITIALIZER; +- (void)addButtonWithTitle:(NSString *)title type:(SIAlertViewButtonType)type handler:(SIAlertViewHandler)handler; + +- (void)show; +- (void)dismissAnimated:(BOOL)animated; + +@end diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.m b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.m new file mode 100644 index 000000000..e2f988e2d --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/SIAlertView/SIAlertView.m @@ -0,0 +1,1253 @@ +// SIAlertView.m +// SIAlertView +// Created by Kevin Cao on 13-4-29. +// Copyright (c) 2013年 Sumi Interactive. All rights reserved. + +#import "SIAlertView.h" +#import "UIWindow+SIUtils.h" +#import +NSString *const SIAlertViewWillShowNotification = @"SIAlertViewWillShowNotification"; +NSString *const SIAlertViewDidShowNotification = @"SIAlertViewDidShowNotification"; +NSString *const SIAlertViewWillDismissNotification = @"SIAlertViewWillDismissNotification"; +NSString *const SIAlertViewDidDismissNotification = @"SIAlertViewDidDismissNotification"; +#define DEBUG_LAYOUT 0 +#define MESSAGE_MIN_LINE_COUNT 3 +#define MESSAGE_MAX_LINE_COUNT 15 +#define GAP 10 +#define CANCEL_BUTTON_PADDING_TOP 5 +#define CONTENT_PADDING_LEFT 10 +#define CONTENT_PADDING_TOP 12 +#define CONTENT_PADDING_BOTTOM 10 +#define BUTTON_HEIGHT 45.0//([[UIScreen mainScreen] bounds].size.height/(2208.0/147.0))//47 +#define CONTAINER_WIDTH 300 + +const UIWindowLevel UIWindowLevelSIAlert = 1996.0; // don't overlap system's alert +const UIWindowLevel UIWindowLevelSIAlertBackground = 1985.0; // below the alert window + +@class SIAlertBackgroundWindow; +static NSMutableArray *__si_alert_queue; +static BOOL __si_alert_animating; +static SIAlertBackgroundWindow *__si_alert_background_window; +static SIAlertView *__si_alert_current_view; + +@interface SIAlertView () + +@property (nonatomic, strong) NSMutableArray *items; +@property (nonatomic, weak) UIWindow *oldKeyWindow; +@property (nonatomic, strong) UIWindow *alertWindow; +#ifdef __IPHONE_7_0 +@property (nonatomic, assign) UIViewTintAdjustmentMode oldTintAdjustmentMode; +#endif +@property (nonatomic, assign, getter = isVisible) BOOL visible; + +@property (nonatomic, strong) UILabel *titleLabel; +@property (nonatomic, strong) UILabel *messageLabel; +@property (nonatomic, strong) UIView *containerView; +@property (nonatomic, strong) NSMutableArray *buttons; + +@property (nonatomic, assign, getter = isLayoutDirty) BOOL layoutDirty; + ++ (NSMutableArray *)sharedQueue; ++ (SIAlertView *)currentAlertView; + ++ (BOOL)isAnimating; ++ (void)setAnimating:(BOOL)animating; + ++ (void)showBackground; ++ (void)hideBackgroundAnimated:(BOOL)animated; + +- (void)setup; +- (void)invalidateLayout; +- (void)resetTransition; + +@end + +#pragma mark - SIBackgroundWindow + +@interface SIAlertBackgroundWindow : UIWindow + +@end + +@interface SIAlertBackgroundWindow () + +@property (nonatomic, assign) SIAlertViewBackgroundStyle style; + +@end + +@implementation SIAlertBackgroundWindow + +- (instancetype)initWithFrame:(CGRect)frame andStyle:(SIAlertViewBackgroundStyle)style +{ + self = [super initWithFrame:frame]; + if (self) { + self.style = style; + self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.opaque = NO; + self.windowLevel = UIWindowLevelSIAlertBackground; + } + return self; +} + +- (void)drawRect:(CGRect)rect +{ + CGContextRef context = UIGraphicsGetCurrentContext(); + switch (self.style) { + case SIAlertViewBackgroundStyleGradient: + { + size_t locationsCount = 2; + CGFloat locations[2] = {0.0f, 1.0f}; + CGFloat colors[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.75f}; + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount); + CGColorSpaceRelease(colorSpace); + + CGPoint center = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2); + CGFloat radius = MIN(self.bounds.size.width, self.bounds.size.height) ; + CGContextDrawRadialGradient (context, gradient, center, 0, center, radius, kCGGradientDrawsAfterEndLocation); + CGGradientRelease(gradient); + break; + } + case SIAlertViewBackgroundStyleSolid: + { + [[UIColor colorWithWhite:0 alpha:0.5] set]; + CGContextFillRect(context, self.bounds); + break; + } + } +} + +@end + +#pragma mark - SIAlertItem +@interface SIAlertItem : NSObject +@property (nonatomic, copy) NSString *title; +@property (nonatomic, assign) SIAlertViewButtonType type; +@property (nonatomic, copy) SIAlertViewHandler action; +@end +@implementation SIAlertItem +@end + +#pragma mark - SIAlertViewController +@interface SIAlertViewController : UIViewController +@property (nonatomic, strong) SIAlertView *alertView; +@end + +@implementation SIAlertViewController + +#pragma mark - View life cycle + +- (void)loadView +{ + self.view = self.alertView; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + [self.alertView setup]; +} + +- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration +{ + [self.alertView resetTransition]; + [self.alertView invalidateLayout]; +} + +#ifdef __IPHONE_7_0 +- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration +{ + if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) { + [self setNeedsStatusBarAppearanceUpdate]; + } +} +#endif + +- (UIInterfaceOrientationMask)supportedInterfaceOrientations +{ + UIViewController *viewController = [self.alertView.oldKeyWindow currentViewController]; + if (viewController) { + return [viewController supportedInterfaceOrientations]; + } + return UIInterfaceOrientationMaskAll; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation +{ + UIViewController *viewController = [self.alertView.oldKeyWindow currentViewController]; + if (viewController) { + return [viewController shouldAutorotateToInterfaceOrientation:toInterfaceOrientation]; + } + return YES; +} + +- (BOOL)shouldAutorotate +{ + UIViewController *viewController = [self.alertView.oldKeyWindow currentViewController]; + if (viewController) { + return [viewController shouldAutorotate]; + } + return YES; +} + +#ifdef __IPHONE_7_0 +- (UIStatusBarStyle)preferredStatusBarStyle +{ + UIWindow *window = self.alertView.oldKeyWindow; + if (!window) { + window = [UIApplication sharedApplication].windows[0]; + } + return [[window viewControllerForStatusBarStyle] preferredStatusBarStyle]; +} + +- (BOOL)prefersStatusBarHidden +{ + UIWindow *window = self.alertView.oldKeyWindow; + if (!window) { + window = [UIApplication sharedApplication].windows[0]; + } + return [[window viewControllerForStatusBarHidden] prefersStatusBarHidden]; +} +#endif + +@end + +#pragma mark - SIAlert + +@implementation SIAlertView + ++ (void)initialize { + if (self != [SIAlertView class]) + return; + SIAlertView *appearance = [self appearance]; + appearance.viewBackgroundColor = [UIColor whiteColor]; + appearance.titleColor = [UIColor blackColor]; + appearance.messageColor = [UIColor darkGrayColor]; + appearance.titleFont = [UIFont fontWithName:@"SegoeUI" size:20.0]; // FONT_MAVEN_REGULAR + appearance.messageFont = [UIFont fontWithName:@"SegoeUI-Light" size:18.0];// FONT_MAVEN_LIGHT_300 + appearance.buttonFont = [UIFont fontWithName:@"SegoeUI" size:20.0];// FONT_MAVEN_REGULAR + appearance.buttonColor = [UIColor whiteColor];//[UIColor colorWithRed:39.0/255.0 green:75.0/255.0 blue:160.0/255.0 alpha:1.0]; + appearance.cancelButtonColor = [UIColor whiteColor]; + appearance.destructiveButtonColor = [UIColor whiteColor];//[UIColor colorWithRed:77.0/255.0 green:184.0/255.0 blue:49.0/255.0 alpha:1.0]; + appearance.destructiveButtonColor = [UIColor whiteColor]; + appearance.cornerRadius = 5.0; + appearance.shadowRadius = 5.0; +} +/* +- (instancetype)init +{ + return [self initWithTitle:nil andMessage:nil]; +}*/ + +- (instancetype)initWithTitle:(NSString *)title andMessage:(NSString *)message { + self = [super initWithFrame:CGRectZero]; + if (self) { + + if (title.length > 0) { // Check Added because nill could not be passed (from swift) + _title = title; + } else { + _title = nil; + } + _message = message; + _enabledParallaxEffect = YES; + self.items = [[NSMutableArray alloc] init]; + } + return self; +} + +#pragma mark - Class methods + ++ (NSMutableArray *)sharedQueue +{ + if (!__si_alert_queue) { + __si_alert_queue = [NSMutableArray array]; + } + return __si_alert_queue; +} + ++ (SIAlertView *)currentAlertView +{ + return __si_alert_current_view; +} + ++ (void)setCurrentAlertView:(SIAlertView *)alertView +{ + __si_alert_current_view = alertView; +} + ++ (BOOL)isAnimating +{ + return __si_alert_animating; +} + ++ (void)setAnimating:(BOOL)animating { + __si_alert_animating = animating; +} + ++ (void)showBackground { + if (!__si_alert_background_window) { + CGRect frame = [UIScreen mainScreen].bounds; + if([[UIScreen mainScreen] respondsToSelector:@selector(fixedCoordinateSpace)]) + { + frame = [[UIScreen mainScreen].fixedCoordinateSpace convertRect:frame fromCoordinateSpace:[UIScreen mainScreen].coordinateSpace]; + } + + __si_alert_background_window = [[SIAlertBackgroundWindow alloc] initWithFrame:frame + andStyle:[SIAlertView currentAlertView].backgroundStyle]; + [__si_alert_background_window makeKeyAndVisible]; + __si_alert_background_window.alpha = 0; + [UIView animateWithDuration:0.3 + animations:^{ + __si_alert_background_window.alpha = 1; + }]; + } +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + UITouch *touch = [touches anyObject]; + CGPoint location = [touch locationInView:self]; +// NSLog(@"%@",self.containerView); + if (self.shouldRemoveAfterTouch && self.containerView) { + if (!(((location.y > CGRectGetMinY(self.containerView.frame)) && (location.y < CGRectGetMaxY(self.containerView.frame))) && ((location.x > CGRectGetMinX(self.containerView.frame)) && (location.x < CGRectGetMaxX(self.containerView.frame))))) { + self.shouldRemoveAfterTouch = NO; + [self dismissAnimated:YES]; + } + } +} + ++ (void)hideBackgroundAnimated:(BOOL)animated +{ + if (!animated) { + [__si_alert_background_window removeFromSuperview]; + __si_alert_background_window = nil; + return; + } + [UIView animateWithDuration:0.3 + animations:^{ + __si_alert_background_window.alpha = 0; + } + completion:^(BOOL finished) { + [__si_alert_background_window removeFromSuperview]; + __si_alert_background_window = nil; + }]; +} + +#pragma mark - Setters + +- (void)setTitle:(NSString *)title +{ + _title = title; + [self invalidateLayout]; +} + +- (void)setMessage:(NSString *)message +{ + _message = message; + [self invalidateLayout]; +} + +#pragma mark - Public + +- (void)addButtonWithTitle:(NSString *)title type:(SIAlertViewButtonType)type handler:(SIAlertViewHandler)handler +{ + SIAlertItem *item = [[SIAlertItem alloc] init]; + item.title = title; + item.type = type; + item.action = handler; + [self.items addObject:item]; +} + +- (void)show +{ + if (self.isVisible) { + return; + } + + self.oldKeyWindow = [UIApplication sharedApplication].keyWindow; +#ifdef __IPHONE_7_0 + if ([self.oldKeyWindow respondsToSelector:@selector(setTintAdjustmentMode:)]) { // for iOS 7 + self.oldTintAdjustmentMode = self.oldKeyWindow.tintAdjustmentMode; + self.oldKeyWindow.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed; + } +#endif + + if (![[SIAlertView sharedQueue] containsObject:self]) { + [[SIAlertView sharedQueue] addObject:self]; + } + + if ([SIAlertView isAnimating]) { + return; // wait for next turn + } + + if ([SIAlertView currentAlertView].isVisible) { + SIAlertView *alert = [SIAlertView currentAlertView]; + [alert dismissAnimated:YES cleanup:NO]; + return; + } + + if (self.willShowHandler) { + self.willShowHandler(self); + } + + [[NSNotificationCenter defaultCenter] postNotificationName:SIAlertViewWillShowNotification object:self userInfo:nil]; + + self.visible = YES; + + [SIAlertView setAnimating:YES]; + [SIAlertView setCurrentAlertView:self]; + + // transition background + [SIAlertView showBackground]; + + SIAlertViewController *viewController = [[SIAlertViewController alloc] initWithNibName:nil bundle:nil]; + viewController.alertView = self; + + if (!self.alertWindow) { + UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; + window.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + window.opaque = NO; + window.windowLevel = UIWindowLevelSIAlert; + window.rootViewController = viewController; + self.alertWindow = window; + } + [self.alertWindow makeKeyAndVisible]; + + [self validateLayout]; + [self.containerView setClipsToBounds:YES]; + + CGFloat yAxisOfBackgroundLayer = self.containerView.frame.size.height - BUTTON_HEIGHT - 0.5; + UIView *backgroundLayerOfButtons = [[UIView alloc] init]; + backgroundLayerOfButtons.frame = CGRectMake(0, yAxisOfBackgroundLayer, self.containerView.frame.size.width, self.containerView.frame.size.height - yAxisOfBackgroundLayer); + backgroundLayerOfButtons.backgroundColor = [UIColor colorWithRed:04.0/255.0 green:202.0/255.0 blue:169.0/255.0 alpha:1.0]; + [self.containerView insertSubview:backgroundLayerOfButtons atIndex:0]; + + [self transitionInCompletion:^{ + if (self.didShowHandler) { + self.didShowHandler(self); + } + [[NSNotificationCenter defaultCenter] postNotificationName:SIAlertViewDidShowNotification object:self userInfo:nil]; + #ifdef __IPHONE_7_0 + [self addParallaxEffect]; + #endif + + [SIAlertView setAnimating:NO]; + + NSInteger index = [[SIAlertView sharedQueue] indexOfObject:self]; + if (index < [SIAlertView sharedQueue].count - 1) { + [self dismissAnimated:YES cleanup:NO]; // dismiss to show next alert view + } + }]; +} + +- (void)dismissAnimated:(BOOL)animated +{ + [self dismissAnimated:animated cleanup:YES]; +} + +- (void)dismissAnimated:(BOOL)animated cleanup:(BOOL)cleanup +{ + BOOL isVisible = self.isVisible; + + if (isVisible) { + if (self.willDismissHandler) { + self.willDismissHandler(self); + } + [[NSNotificationCenter defaultCenter] postNotificationName:SIAlertViewWillDismissNotification object:self userInfo:nil]; + #ifdef __IPHONE_7_0 + [self removeParallaxEffect]; + #endif + } + + void (^dismissComplete)(void) = ^{ + self.visible = NO; + + [self teardown]; + + [SIAlertView setCurrentAlertView:nil]; + + SIAlertView *nextAlertView; + NSInteger index = [[SIAlertView sharedQueue] indexOfObject:self]; + if (index != NSNotFound && index < [SIAlertView sharedQueue].count - 1) { + nextAlertView = [SIAlertView sharedQueue][index + 1]; + } + + if (cleanup) { + [[SIAlertView sharedQueue] removeObject:self]; + } + + [SIAlertView setAnimating:NO]; + + if (isVisible) { + if (self.didDismissHandler) { + self.didDismissHandler(self); + } + [[NSNotificationCenter defaultCenter] postNotificationName:SIAlertViewDidDismissNotification object:self userInfo:nil]; + } + + // check if we should show next alert + if (!isVisible) { + return; + } + + if (nextAlertView) { + [nextAlertView show]; + } else { + // show last alert view + if ([SIAlertView sharedQueue].count > 0) { + SIAlertView *alert = [SIAlertView sharedQueue].lastObject; + [alert show]; + } + } + }; + + if (animated && isVisible) { + [SIAlertView setAnimating:YES]; + [self transitionOutCompletion:dismissComplete]; + + if ([SIAlertView sharedQueue].count == 1) { + [SIAlertView hideBackgroundAnimated:YES]; + } + + } else { + dismissComplete(); + + if ([SIAlertView sharedQueue].count == 0) { + [SIAlertView hideBackgroundAnimated:YES]; + } + } + + UIWindow *window = self.oldKeyWindow; +#ifdef __IPHONE_7_0 + if ([window respondsToSelector:@selector(setTintAdjustmentMode:)]) { + window.tintAdjustmentMode = self.oldTintAdjustmentMode; + } +#endif + if (!window) { + window = [UIApplication sharedApplication].windows[0]; + } + [window makeKeyWindow]; + window.hidden = NO; +} + +#pragma mark - Transitions + +- (void)transitionInCompletion:(void(^)(void))completion +{ + switch (self.transitionStyle) { + case SIAlertViewTransitionStyleSlideFromBottom: + { + CGRect rect = self.containerView.frame; + CGRect originalRect = rect; + rect.origin.y = self.bounds.size.height; + self.containerView.frame = rect; + [UIView animateWithDuration:0.3 + animations:^{ + self.containerView.frame = originalRect; + } + completion:^(BOOL finished) { + if (completion) { + completion(); + } + }]; + } + break; + case SIAlertViewTransitionStyleSlideFromTop: + { + CGRect rect = self.containerView.frame; + CGRect originalRect = rect; + rect.origin.y = -rect.size.height; + self.containerView.frame = rect; + [UIView animateWithDuration:0.3 + animations:^{ + self.containerView.frame = originalRect; + } + completion:^(BOOL finished) { + if (completion) { + completion(); + } + }]; + } + break; + case SIAlertViewTransitionStyleFade: + { + self.containerView.alpha = 0; + [UIView animateWithDuration:0.3 + animations:^{ + self.containerView.alpha = 1; + } + completion:^(BOOL finished) { + if (completion) { + completion(); + } + }]; + } + break; + case SIAlertViewTransitionStyleBounce: + { + CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"]; + animation.values = @[@(0.01), @(1.2), @(0.9), @(1)]; + animation.keyTimes = @[@(0), @(0.4), @(0.6), @(1)]; + animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; + animation.duration = 0.5; + animation.delegate = self; + [animation setValue:completion forKey:@"handler"]; + [self.containerView.layer addAnimation:animation forKey:@"bouce"]; + } + break; + case SIAlertViewTransitionStyleDropDown: + { + CGFloat y = self.containerView.center.y; + CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.y"]; + animation.values = @[@(y - self.bounds.size.height), @(y + 20), @(y - 10), @(y)]; + animation.keyTimes = @[@(0), @(0.5), @(0.75), @(1)]; + animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; + animation.duration = 0.4; + animation.delegate = self; + [animation setValue:completion forKey:@"handler"]; + [self.containerView.layer addAnimation:animation forKey:@"dropdown"]; + } + break; + default: + break; + } +} + +- (void)transitionOutCompletion:(void(^)(void))completion +{ + switch (self.transitionStyle) { + case SIAlertViewTransitionStyleSlideFromBottom: + { + CGRect rect = self.containerView.frame; + rect.origin.y = self.bounds.size.height; + [UIView animateWithDuration:0.3 + delay:0 + options:UIViewAnimationOptionCurveEaseIn + animations:^{ + self.containerView.frame = rect; + } + completion:^(BOOL finished) { + if (completion) { + completion(); + } + }]; + } + break; + case SIAlertViewTransitionStyleSlideFromTop: + { + CGRect rect = self.containerView.frame; + rect.origin.y = -rect.size.height; + [UIView animateWithDuration:0.3 + delay:0 + options:UIViewAnimationOptionCurveEaseIn + animations:^{ + self.containerView.frame = rect; + } + completion:^(BOOL finished) { + if (completion) { + completion(); + } + }]; + } + break; + case SIAlertViewTransitionStyleFade: + { + [UIView animateWithDuration:0.25 + animations:^{ + self.containerView.alpha = 0; + } + completion:^(BOOL finished) { + if (completion) { + completion(); + } + }]; + } + break; + case SIAlertViewTransitionStyleBounce: + { + CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"]; + animation.values = @[@(1), @(1.2), @(0.01)]; + animation.keyTimes = @[@(0), @(0.4), @(1)]; + animation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; + animation.duration = 0.35; + animation.delegate = self; + [animation setValue:completion forKey:@"handler"]; + [self.containerView.layer addAnimation:animation forKey:@"bounce"]; + self.containerView.transform = CGAffineTransformMakeScale(0.01, 0.01); + } + break; + case SIAlertViewTransitionStyleDropDown: + { + CGPoint point = self.containerView.center; + point.y += self.bounds.size.height; + [UIView animateWithDuration:0.3 + delay:0 + options:UIViewAnimationOptionCurveEaseIn + animations:^{ + self.containerView.center = point; + CGFloat angle = ((CGFloat)arc4random_uniform(100) - 50.f) / 100.f; + self.containerView.transform = CGAffineTransformMakeRotation(angle); + } + completion:^(BOOL finished) { + if (completion) { + completion(); + } + }]; + } + break; + default: + break; + } +} + +- (void)resetTransition +{ + [self.containerView.layer removeAllAnimations]; +} + +#pragma mark - Layout + +- (void)layoutSubviews +{ + [super layoutSubviews]; + [self validateLayout]; +} + +- (void)invalidateLayout +{ + self.layoutDirty = YES; + [self setNeedsLayout]; +} + +- (void)validateLayout +{ + if (!self.isLayoutDirty) { + return; + } + self.layoutDirty = NO; +#if DEBUG_LAYOUT +// NSLog(@"%@, %@", self, NSStringFromSelector(_cmd)); +#endif + + CGFloat height = [self preferredHeight]; + CGFloat left = (self.bounds.size.width - CONTAINER_WIDTH) * 0.5; + CGFloat top = (self.bounds.size.height - height) * 0.5; + self.containerView.transform = CGAffineTransformIdentity; + self.containerView.frame = CGRectMake(left, top, CONTAINER_WIDTH, height); + self.containerView.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:self.containerView.bounds cornerRadius:self.containerView.layer.cornerRadius].CGPath; + + CGFloat y = CONTENT_PADDING_TOP; + if (self.titleLabel) { + self.titleLabel.text = self.title; + CGFloat height = [self heightForTitleLabel]; + self.titleLabel.frame = CGRectMake(CONTENT_PADDING_LEFT, y, self.containerView.bounds.size.width - CONTENT_PADDING_LEFT * 2, height); + y += height; + } + if (self.messageLabel) { + if (y > CONTENT_PADDING_TOP) { + y += GAP; + } + self.messageLabel.text = self.message; + CGFloat height = [self heightForMessageLabel]; + self.messageLabel.frame = CGRectMake(CONTENT_PADDING_LEFT, y, self.containerView.bounds.size.width - CONTENT_PADDING_LEFT * 2, height); + y += height; + } + if (self.items.count > 0) { + if (y > CONTENT_PADDING_TOP) { + y += GAP; + } + // y = self.containerView.bounds.size.height - BUTTON_HEIGHT; + if (self.items.count == 2 && self.buttonsListStyle == SIAlertViewButtonsListStyleNormal) { + //CGFloat width = (self.containerView.bounds.size.width - CONTENT_PADDING_LEFT * 2 - GAP) * 0.5; + CGFloat width = (self.containerView.bounds.size.width - 0.5) * 0.5; + UIButton *button = self.buttons[0]; +// button.frame = CGRectMake(CONTENT_PADDING_LEFT, y, width, BUTTON_HEIGHT); + button.frame = CGRectMake(0, y, width, BUTTON_HEIGHT); + button = self.buttons[1]; +// button.frame = CGRectMake(CONTENT_PADDING_LEFT + width + GAP, y, width, BUTTON_HEIGHT); + button.frame = CGRectMake(width + 0.5, y, width, BUTTON_HEIGHT); + } else { + for (NSUInteger i = 0; i < self.buttons.count; i++) { + UIButton *button = self.buttons[i]; +// button.frame = CGRectMake(CONTENT_PADDING_LEFT, y, self.containerView.bounds.size.width - CONTENT_PADDING_LEFT * 2, BUTTON_HEIGHT); + button.frame = CGRectMake(0, y, self.containerView.bounds.size.width, BUTTON_HEIGHT); + if (self.buttons.count > 1) { + if (i == self.buttons.count - 1 && ((SIAlertItem *)self.items[i]).type == SIAlertViewButtonTypeCancel) { + CGRect rect = button.frame; + rect.origin.y += CANCEL_BUTTON_PADDING_TOP; + button.frame = rect; + } + //y += BUTTON_HEIGHT + GAP; + y += BUTTON_HEIGHT + 0.5; + } + } + } + } +} + +- (CGFloat)preferredHeight +{ + CGFloat height = CONTENT_PADDING_TOP; + if (self.title) { + height += [self heightForTitleLabel]; + } + if (self.message) { + if (height > CONTENT_PADDING_TOP) { + height += GAP; + } + height += [self heightForMessageLabel]; + } + if (self.items.count > 0) { + if (height > CONTENT_PADDING_TOP) { + height += GAP; + } + if (self.items.count <= 2 && self.buttonsListStyle == SIAlertViewButtonsListStyleNormal) { + height += BUTTON_HEIGHT; + } else { +// height += (BUTTON_HEIGHT + GAP) * self.items.count - GAP; + height += (BUTTON_HEIGHT + 1.5) * self.items.count - 1.5; + if (self.buttons.count > 2 && ((SIAlertItem *)(self.items).lastObject).type == SIAlertViewButtonTypeCancel) { + height += CANCEL_BUTTON_PADDING_TOP; + } + } + } + //height += CONTENT_PADDING_BOTTOM; + return height; +} + +- (CGFloat)heightForTitleLabel { + if (self.titleLabel) { + float maxHeightOfTitleLabel = 2 * self.titleLabel.font.lineHeight; + (self.titleLabel).numberOfLines = 2; + (self.titleLabel).lineBreakMode = NSLineBreakByWordWrapping; + + #ifdef __IPHONE_7_0 + NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; + paragraphStyle.lineBreakMode = self.titleLabel.lineBreakMode; + + NSDictionary *attributes = @{NSFontAttributeName:self.titleLabel.font, + NSParagraphStyleAttributeName: paragraphStyle.copy}; + + // NSString class method: boundingRectWithSize:options:attributes:context is + // available only on ios7.0 sdk. + CGRect rect = [self.titleLabel.text boundingRectWithSize:CGSizeMake(CONTAINER_WIDTH - CONTENT_PADDING_LEFT * 2, maxHeightOfTitleLabel) + options:NSStringDrawingUsesLineFragmentOrigin + attributes:attributes + context:nil]; + return ceil(rect.size.height); + #else + CGSize size = [self.title sizeWithFont:self.titleLabel.font + minFontSize: + #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 + self.titleLabel.font.pointSize * self.titleLabel.minimumScaleFactor + #else + self.titleLabel.minimumFontSize + #endif + actualFontSize:nil + forWidth:CONTAINER_WIDTH - CONTENT_PADDING_LEFT * 2 + lineBreakMode:self.titleLabel.lineBreakMode]; + return size.height; + #endif + } + + return 0; +} + +- (CGFloat)heightForMessageLabel +{ + CGFloat minHeight = MESSAGE_MIN_LINE_COUNT * self.messageLabel.font.lineHeight; + if (self.messageLabel) { + CGFloat maxHeight = MESSAGE_MAX_LINE_COUNT * self.messageLabel.font.lineHeight; + + #ifdef __IPHONE_7_0 + NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; + paragraphStyle.lineBreakMode = self.messageLabel.lineBreakMode; + + NSDictionary *attributes = @{NSFontAttributeName:self.messageLabel.font, + NSParagraphStyleAttributeName: paragraphStyle.copy}; + + // NSString class method: boundingRectWithSize:options:attributes:context is + // available only on ios7.0 sdk. + //NSLog(@"Text of Message=>%@",self.messageLabel.text); + // NSLog(@"Widthof Expected label =>%d \n and height expected =>%f",(CONTAINER_WIDTH - CONTENT_PADDING_LEFT * 2), maxHeight); + CGRect rect = [self.messageLabel.text boundingRectWithSize:CGSizeMake(CONTAINER_WIDTH - CONTENT_PADDING_LEFT * 2, maxHeight) + options:NSStringDrawingUsesLineFragmentOrigin + attributes:attributes + context:nil]; + // NSLog(@"estimated height of Message label =>%f \n exact height of Message label=>%f",rect.size.height,MAX(minHeight, ceil(rect.size.height))); + return MAX(minHeight, ceil(rect.size.height)); + #else + CGSize size = [self.message sizeWithFont:self.messageLabel.font + constrainedToSize:CGSizeMake(CONTAINER_WIDTH - CONTENT_PADDING_LEFT * 2, maxHeight) + lineBreakMode:self.messageLabel.lineBreakMode]; + + return MAX(minHeight, size.height); + #endif + } + + return minHeight; +} + +#pragma mark - Setup + +- (void)setup +{ + [self setupContainerView]; + [self updateTitleLabel]; + [self updateMessageLabel]; + [self setupButtons]; + [self invalidateLayout]; +} + +- (void)teardown +{ + [self.containerView removeFromSuperview]; + self.containerView = nil; + self.titleLabel = nil; + self.messageLabel = nil; + [self.buttons removeAllObjects]; + [self.alertWindow removeFromSuperview]; + self.alertWindow = nil; + self.layoutDirty = NO; +} + +- (void)setupContainerView +{ + self.containerView = [[UIView alloc] initWithFrame:self.bounds]; + self.containerView.backgroundColor = _viewBackgroundColor ? _viewBackgroundColor : [UIColor whiteColor]; + self.containerView.layer.cornerRadius = self.cornerRadius; + self.containerView.layer.shadowOffset = CGSizeZero; + self.containerView.layer.shadowRadius = self.shadowRadius; + self.containerView.layer.shadowOpacity = 0.5; + [self addSubview:self.containerView]; +} + +- (void)updateTitleLabel +{ + if (self.title) { + if (!self.titleLabel) { + self.titleLabel = [[UILabel alloc] initWithFrame:self.bounds]; + self.titleLabel.textAlignment = NSTextAlignmentCenter; + self.titleLabel.backgroundColor = [UIColor clearColor]; + self.titleLabel.font = self.titleFont; + self.titleLabel.textColor = self.titleColor; + self.titleLabel.adjustsFontSizeToFitWidth = YES; +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 + self.titleLabel.minimumScaleFactor = 0.75; +#else + self.titleLabel.minimumFontSize = self.titleLabel.font.pointSize * 0.75; +#endif + [self.containerView addSubview:self.titleLabel]; +#if DEBUG_LAYOUT + self.titleLabel.backgroundColor = [UIColor redColor]; +#endif + } + self.titleLabel.text = self.title; + } else { + [self.titleLabel removeFromSuperview]; + self.titleLabel = nil; + } + [self invalidateLayout]; +} + +- (void)updateMessageLabel +{ + if (self.message) { + if (!self.messageLabel) { + self.messageLabel = [[UILabel alloc] initWithFrame:self.bounds]; + self.messageLabel.textAlignment = NSTextAlignmentCenter; + self.messageLabel.backgroundColor = [UIColor clearColor]; + self.messageLabel.font = self.messageFont; + self.messageLabel.textColor = self.messageColor; + self.messageLabel.numberOfLines = MESSAGE_MAX_LINE_COUNT; + (self.messageLabel).lineBreakMode = NSLineBreakByWordWrapping; + [self.containerView addSubview:self.messageLabel]; +#if DEBUG_LAYOUT + self.messageLabel.backgroundColor = [UIColor redColor]; +#endif + } + self.messageLabel.text = self.message; + } else { + [self.messageLabel removeFromSuperview]; + self.messageLabel = nil; + } + [self invalidateLayout]; +} + +- (void)setupButtons +{ + self.buttons = [[NSMutableArray alloc] initWithCapacity:self.items.count]; + for (NSUInteger i = 0; i < self.items.count; i++) { + UIButton *button = [self buttonForItemIndex:i]; + [self.buttons addObject:button]; + [self.containerView addSubview:button]; + } +} + +- (UIButton *)buttonForItemIndex:(NSUInteger)index +{ + //CGFloat heightOfButton = [[CommonFunctions shareCommonMethods] targetYOrHeightSize:150.0]; + + SIAlertItem *item = self.items[index]; + UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; + button.tag = index; + button.autoresizingMask = UIViewAutoresizingFlexibleWidth; + button.titleLabel.font = self.buttonFont; + [button setTitle:item.title forState:UIControlStateNormal]; + UIImage *normalImage = nil; + UIImage *highlightedImage = [self imageWithColor:[UIColor clearColor] andFrame:CGRectMake(0, 0, 400, BUTTON_HEIGHT)]; + switch (item.type) { + case SIAlertViewButtonTypeCancel: + //normalImage = [UIImage imageNamed:@"SIAlertView.bundle/button-cancel"]; + //highlightedImage = [UIImage imageNamed:@"SIAlertView.bundle/button-cancel-d"]; + normalImage = [self imageWithColor:[UIColor colorWithRed:04.0/255.0 green:202.0/255.0 blue:169.0/255.0 alpha:1.0] andFrame:CGRectMake(0, 0, 400, BUTTON_HEIGHT)]; + + [button setTitleColor:self.cancelButtonColor forState:UIControlStateNormal]; + //[button setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; + //[button.layer setBorderColor:[COLOR_JUGNOO_MEALS_THEME CGColor]]; + //[button.layer setBorderWidth:2.0]; + break; + case SIAlertViewButtonTypeDestructive: + normalImage = [self imageWithColor:[UIColor colorWithRed:04.0/255.0 green:202.0/255.0 blue:169.0/255.0 alpha:1.0] andFrame:CGRectMake(0, 0, 400, BUTTON_HEIGHT)]; + //highlightedImage = [UIImage imageNamed:@"SIAlertView.bundle/button-destructive-d"]; + [button setTitleColor:self.destructiveButtonColor forState:UIControlStateNormal]; + //[button setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; + //[button.layer setBorderColor:[[UIColor whiteColor] CGColor]]; + //[button.layer setBorderWidth:2.0]; + break; + case SIAlertViewButtonTypeDefault: + default: + //normalImage = [UIImage imageNamed:@"SIAlertView.bundle/button-default"]; + //highlightedImage = [UIImage imageNamed:@"SIAlertView.bundle/button-default-d"]; + normalImage = [self imageWithColor:[UIColor colorWithRed:04.0/255.0 green:202.0/255.0 blue:169.0/255.0 alpha:1.0] andFrame:CGRectMake(0, 0, 400, BUTTON_HEIGHT)]; + [button setTitleColor:self.buttonColor forState:UIControlStateNormal]; + //[button setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; + //[button.layer setBorderColor:[[UIColor whiteColor] CGColor]]; + //[button.layer setBorderWidth:2.0]; + break; + } + /*CGFloat hInset = floorf(normalImage.size.width / 2); + CGFloat vInset = floorf(normalImage.size.height / 2); + UIEdgeInsets insets = UIEdgeInsetsMake(vInset, hInset, vInset, hInset); + normalImage = [normalImage resizableImageWithCapInsets:insets]; + highlightedImage = [highlightedImage resizableImageWithCapInsets:insets];*/ + [button setClipsToBounds:YES]; + //[button.layer setCornerRadius:4.0]; + [button setBackgroundImage:normalImage forState:UIControlStateNormal]; + [button setBackgroundImage:highlightedImage forState:UIControlStateHighlighted]; + // [button setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; + [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside]; + + return button; +} + +- (UIImage *)imageWithColor:(UIColor *)color andFrame:(CGRect)customFrame { + UIGraphicsBeginImageContext(customFrame.size); + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextSetFillColorWithColor(context, [color CGColor]); + CGContextFillRect(context, customFrame); + UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return image; +} + +#pragma mark - Actions + +- (void)buttonAction:(UIButton *)button +{ + [SIAlertView setAnimating:YES]; // set this flag to YES in order to prevent showing another alert in action block + SIAlertItem *item = self.items[button.tag]; + if (item.action) { + item.action(self); + } + [self dismissAnimated:YES]; +} + +#pragma mark - CAAnimation delegate + +- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag +{ + void(^completion)(void) = [anim valueForKey:@"handler"]; + if (completion) { + completion(); + } +} + +#pragma mark - UIAppearance setters + +- (void)setViewBackgroundColor:(UIColor *)viewBackgroundColor +{ + if (_viewBackgroundColor == viewBackgroundColor) { + return; + } + _viewBackgroundColor = viewBackgroundColor; + self.containerView.backgroundColor = viewBackgroundColor; +} + +- (void)setTitleFont:(UIFont *)titleFont +{ + if (_titleFont == titleFont) { + return; + } + _titleFont = titleFont; + self.titleLabel.font = titleFont; + [self invalidateLayout]; +} + +- (void)setMessageFont:(UIFont *)messageFont +{ + if (_messageFont == messageFont) { + return; + } + _messageFont = messageFont; + self.messageLabel.font = messageFont; + [self invalidateLayout]; +} + +- (void)setTitleColor:(UIColor *)titleColor +{ + if (_titleColor == titleColor) { + return; + } + _titleColor = titleColor; + self.titleLabel.textColor = titleColor; +} + +- (void)setMessageColor:(UIColor *)messageColor +{ + if (_messageColor == messageColor) { + return; + } + _messageColor = messageColor; + self.messageLabel.textColor = messageColor; +} + +- (void)setButtonFont:(UIFont *)buttonFont +{ + if (_buttonFont == buttonFont) { + return; + } + _buttonFont = buttonFont; + for (UIButton *button in self.buttons) { + button.titleLabel.font = buttonFont; + } +} + +- (void)setCornerRadius:(CGFloat)cornerRadius +{ + if (_cornerRadius == cornerRadius) { + return; + } + _cornerRadius = cornerRadius; + self.containerView.layer.cornerRadius = cornerRadius; +} + +- (void)setShadowRadius:(CGFloat)shadowRadius +{ + if (_shadowRadius == shadowRadius) { + return; + } + _shadowRadius = shadowRadius; + self.containerView.layer.shadowRadius = shadowRadius; +} + +- (void)setButtonColor:(UIColor *)buttonColor +{ + if (_buttonColor == buttonColor) { + return; + } + _buttonColor = buttonColor; + [self setColor:buttonColor toButtonsOfType:SIAlertViewButtonTypeDefault]; +} + +- (void)setCancelButtonColor:(UIColor *)buttonColor +{ + if (_cancelButtonColor == buttonColor) { + return; + } + _cancelButtonColor = buttonColor; + [self setColor:buttonColor toButtonsOfType:SIAlertViewButtonTypeCancel]; +} + +- (void)setDestructiveButtonColor:(UIColor *)buttonColor +{ + if (_destructiveButtonColor == buttonColor) { + return; + } + _destructiveButtonColor = buttonColor; + [self setColor:buttonColor toButtonsOfType:SIAlertViewButtonTypeDestructive]; +} + + +- (void)setDefaultButtonImage:(UIImage *)defaultButtonImage forState:(UIControlState)state +{ + [self setButtonImage:defaultButtonImage forState:state andButtonType:SIAlertViewButtonTypeDefault]; +} + + +- (void)setCancelButtonImage:(UIImage *)cancelButtonImage forState:(UIControlState)state +{ + [self setButtonImage:cancelButtonImage forState:state andButtonType:SIAlertViewButtonTypeCancel]; +} + + +- (void)setDestructiveButtonImage:(UIImage *)destructiveButtonImage forState:(UIControlState)state +{ + [self setButtonImage:destructiveButtonImage forState:state andButtonType:SIAlertViewButtonTypeDestructive]; +} + + +- (void)setButtonImage:(UIImage *)image forState:(UIControlState)state andButtonType:(SIAlertViewButtonType)type +{ + for (NSUInteger i = 0; i < self.items.count; i++) + { + SIAlertItem *item = self.items[i]; + if(item.type == type) + { + UIButton *button = self.buttons[i]; + [button setBackgroundImage:image forState:state]; + } + } +} + + +-(void)setColor:(UIColor *)color toButtonsOfType:(SIAlertViewButtonType)type { + for (NSUInteger i = 0; i < self.items.count; i++) { + SIAlertItem *item = self.items[i]; + if(item.type == type) { + UIButton *button = self.buttons[i]; + [button setTitleColor:color forState:UIControlStateNormal]; + //[button setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; + } + } +} + +# pragma mark - +# pragma mark Enable parallax effect (iOS7 only) + +#ifdef __IPHONE_7_0 +- (void)addParallaxEffect +{ + if (_enabledParallaxEffect && NSClassFromString(@"UIInterpolatingMotionEffect")) + { + UIInterpolatingMotionEffect *effectHorizontal = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"position.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; + UIInterpolatingMotionEffect *effectVertical = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"position.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; + effectHorizontal.maximumRelativeValue = @(20.0f); + effectHorizontal.minimumRelativeValue = @(-20.0f); + effectVertical.maximumRelativeValue = @(50.0f); + effectVertical.minimumRelativeValue = @(-50.0f); + [self.containerView addMotionEffect:effectHorizontal]; + [self.containerView addMotionEffect:effectVertical]; + } +} + +- (void)removeParallaxEffect +{ + if (_enabledParallaxEffect && NSClassFromString(@"UIInterpolatingMotionEffect")) + { + [self.containerView.motionEffects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + [self.containerView removeMotionEffect:obj]; + }]; + } +} +#endif + +@end diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.h b/DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.h new file mode 100644 index 000000000..3d5abf36f --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.h @@ -0,0 +1,20 @@ +// +// UIWindow+SIUtils.h +// SIAlertView +// +// Created by Kevin Cao on 13-11-1. +// Copyright (c) 2013年 Sumi Interactive. All rights reserved. +// + +#import + +@interface UIWindow (SIUtils) + +- (UIViewController *)currentViewController; + +#ifdef __IPHONE_7_0 +- (UIViewController *)viewControllerForStatusBarStyle; +- (UIViewController *)viewControllerForStatusBarHidden; +#endif + +@end diff --git a/DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.m b/DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.m new file mode 100644 index 000000000..2967def19 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/SIAlertView/UIWindow+SIUtils.m @@ -0,0 +1,42 @@ +// UIWindow+SIUtils.m +// SIAlertView +// Created by Kevin Cao on 13-11-1. +// Copyright (c) 2013年 Sumi Interactive. All rights reserved. + +#import "UIWindow+SIUtils.h" + +@implementation UIWindow (SIUtils) + +- (UIViewController *)currentViewController +{ + UIViewController *viewController = self.rootViewController; + while (viewController.presentedViewController) { + viewController = viewController.presentedViewController; + } + return viewController; +} + +#ifdef __IPHONE_7_0 + +- (UIViewController *)viewControllerForStatusBarStyle { + UIViewController *currentViewController = [self currentViewController]; + + while ([currentViewController childViewControllerForStatusBarStyle]) { + currentViewController = [currentViewController childViewControllerForStatusBarStyle]; + } + return currentViewController; +} + +- (UIViewController *)viewControllerForStatusBarHidden +{ + UIViewController *currentViewController = [self currentViewController]; + + while ([currentViewController childViewControllerForStatusBarHidden]) { + currentViewController = [currentViewController childViewControllerForStatusBarHidden]; + } + return currentViewController; +} + +#endif + +@end diff --git a/DeepLinkDemo/DeepLinkDemo/StartupOptionsData.swift b/DeepLinkDemo/DeepLinkDemo/StartupOptionsData.swift new file mode 100644 index 000000000..f0a6697b4 --- /dev/null +++ b/DeepLinkDemo/DeepLinkDemo/StartupOptionsData.swift @@ -0,0 +1,59 @@ +// +// StartupOptionsData.swift +// TestBed-Swift +// +// Created by David Westgate on 9/17/17. +// Copyright © 2017 Branch Metrics. All rights reserved. +// + +import Foundation + +struct StartupOptionsData { + + static let userDefaults = UserDefaults.standard + + static func getActiveBranchKey() -> String? { + if let value = userDefaults.string(forKey: "activeBranchKey") { + return value + } else { + let value = "" + userDefaults.setValue(value, forKey: "activeBranchKey") + return value + } + } + + static func setActiveBranchKey(_ value: String) { + userDefaults.setValue(value, forKey: "activeBranchKey") + } + + static func getPendingBranchKey() -> String? { + if let value = userDefaults.string(forKey: "pendingBranchKey") { + return value + } else { + let value = "" + userDefaults.setValue(value, forKey: "pendingBranchKey") + return value + } + } + + static func setPendingBranchKey(_ value: String) { + userDefaults.setValue(value, forKey: "pendingBranchKey") + } + + static func getActiveSetDebugEnabled() -> Bool? { + return userDefaults.bool(forKey: "activeSetDebug") + } + + static func setActiveSetDebugEnabled(_ value: Bool) { + userDefaults.setValue(value, forKey: "activeSetDebug") + } + + static func getPendingSetDebugEnabled() -> Bool? { + return userDefaults.bool(forKey: "pendingSetDebug") + } + + static func setPendingSetDebugEnabled(_ value: Bool) { + userDefaults.setValue(value, forKey: "pendingSetDebug") + } + +} diff --git a/DeepLinkDemo/DeepLinkDemo/img.png b/DeepLinkDemo/DeepLinkDemo/img.png new file mode 100644 index 0000000000000000000000000000000000000000..95f2e956295e4d10dbfad931ff5be4d8243c3e36 GIT binary patch literal 4030 zcma)<_ahXJM+U#57K(hy~sWdJ}(^F82E!gCK) zOULBg!Y)8KzN~KaRb(ThbaHT9)9Tv(&A|cT^70R6_YcHv1(?y zs}w8;DQ~w-EcT;gcfEW!^}rc0`=pv)(l~=B#g?nQ7CnSh~Hx zSR<@o+cH*tx}iEgX-v&`nUR;r$zUS#;QvQ?tX@;EAIoxlxQTP<_4j^oBnZzmb#waFwm zU)~#HUbbi^`zsW`DXC=GSbVslopNj6$;bB20|;pl0I|qP(MwKHuK$saOHwukcWOM& zy54sfVG_jiKX=1qFhQMwHd&I@$=&VbJ5;n#V#DC+QT?0~mPI#Kb{2ZER51+IUi7>~ z$QW!L)V&#b=6tJSDN$L|#->eGc9=bpoN%sYII4atHw4dOcyy#1^W7yRXr`Dr(NC~I zE*W>ItkJ&5d^i{DWu20Z zl?V^JPftY-I3K214uKEjEU2A10x&EuaEEd==7jmVH|XF-y^VXB%zA3$7ECq8-eGmr zphe0Lt_}5M1d*vcYALDFM)I5CSj!X;nVCS$GpDdEm|0u8G{zefk~rrqAw=F|^A)Nt z;xbN=(B8ea9IkepCwavQ6h#D{Pt4b{&-NsuOs9|EDzjYbH4}-mvww$VHLPoO+bHXF z(N$%o-TfePs(>kiT>5D;O@2`a)w?TFJr9k|~ zy*QxsU*1?^$!u3{Clbr3UbSXU$v*=sKSk0**-Ah1gGO^ryksz&9khuZsI^4#H$z8T z!YiVfh-dWEorg;OpM&<$tL8 z3JA!7mV8+6Yq;vq#Nj~j(9HB=JZ+}&~``yH~XnX8WKb*5Hr z5X~b6KIqk7&P^`jFXRn@(7mdR*axJ&JhDawe_55POlPO`s3co|wON=VyXp&3*k^?J zywBLw$jO%4dex2m>FVZjL1$o!fe^o0LAo&V6db0001i0SrI#eacZ@b2EH221f&9_z zV#=0Ric@&(T~HkUEN zV)RbTf|-zLc5>W~Dmc;l;nO@_Y?SR*)0Uzi*MB5LS9rBPpZXm4^)FVUEN+5~YE%i* zJlq3k_4%z?syw%DoB3=)ZS|PR6 z&g4u;X`f`Byh_z~lRv5p95Eglxa$bzwaBP2P6gX5y z3u#&T6Glic$5WJzt;ugV8Eo{!j`3h9ppFStneueO!2zf-3+ow5C1?$rN{oG&n0 zZq%I|v62km$sI>YKelr@xzlxWf5EoO)#Z&^e>O?c&q{Xcr_t2Xlw!NTMDD!xjnC6zi5bE>9L<^{-HGW zLb`8=*LM@{qn9{D45PbwF>{w_EG`a7=K_JRYy3UXaw~ zd%{pe%;~C`2u&E*ayBy8&M=E$Nh}B6G4cRn{kXADgykibYxd+lErtS30ow$~uaM8I z-;{+Lq|0v{-(^HM6WvNT#Q~bg%wl{z4Wk#k_=>89Sx96A!9%WN>08OJ;xf~TKBu*2 zq7Lj^OtKA+KzW(FV2Z~t0`F$sy+-8UQMAFj{)zKKWKzRq1-v3U0-k{+a4Prj|3$t0 znY!5>Sku(LP5rqUCk%7U^9wdZ2l`6UW4-;eem5R~e`Qg;E@68zI#x`#IZE zT-DC)LrLi5(^&pVA;RAF~PMX|rG}aY!P7WF*y*QD` z*SLRwoGcik4WAqu#Kk+k}o7o+S`gw_t?&vHq(JaT|;Lt z>gSEa4=jt^t^iWO0T-R?huh;tWQ`SK@ek1QG6!@X_olDIQ)^_4FPuKJR4K{txdEzX zRi(H4hWZCx3ahX3$7vf+!#<-Y)g6lFe~jTZ7cVJozjx81n=Tj(5%~igk-mSXm zspMJi#h9zJ@{)jS`kC7H)6*aB-qwcG=;u}K_~|8oZ<0thZ1XHO%04yv`BJd^0TK6% zac-DTu3@;en`+effxC5~h99wSgh%UQE_BH~3>OuCkfy^eKCBtOwtYzZHR=H0W_uJ; ziVvU&_`H2KGufwkFddL9a=naxz8~@yndXhvKOuNZ5kmq10Zsnba*_TMZ+3PK8=r@T z@Z-gRQYwb1n8N*(#O)WO!t%fzu z$(r1dX;E{+Iur%KrIjJjHYeH@5FQ_bp_uUCU+rK}{kcu+nZc)G{};!f2MR zS;oa~l-zC{dxKxCD`<- z;xM#1D^uPr`3(xJxR?Wd9<{S_u+USPHIq33rBe=qYUsA&Ymj8SMkBZ0m4kl_#V>EV zLcy1cR&v;K**(MAGe4F!-O5gXUA#j>KbBOOq0IjO=1S|9g!*B4KY#%c_wSGcK-yrf JIt@Gc{{RlH+F}3z literal 0 HcmV?d00001 diff --git a/DeepLinkDemo/IPA/Info.plist b/DeepLinkDemo/IPA/Info.plist new file mode 100644 index 000000000..42890b144 --- /dev/null +++ b/DeepLinkDemo/IPA/Info.plist @@ -0,0 +1,27 @@ + + + + + compileBitcode + + destination + export + method + development + provisioningProfiles + + io.branch.saas.sdk.testbed + iOS Saas SDK - Dev + + signingCertificate + Apple Development + signingStyle + manual + stripSwiftSymbols + + teamID + R63EM248DP + thinning + <none> + + diff --git a/DeepLinkDemo/Podfile b/DeepLinkDemo/Podfile new file mode 100644 index 000000000..b7266ceb5 --- /dev/null +++ b/DeepLinkDemo/Podfile @@ -0,0 +1,12 @@ +# Uncomment the next line to define a global platform for your project + platform :ios, '12.0' + +target 'DeepLinkDemo' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + pod 'IQKeyboardManager' + pod 'BranchSDK', :path => './../' + + # Pods for DeepLinkDemo + +end diff --git a/DeepLinkDemo/Podfile.lock b/DeepLinkDemo/Podfile.lock new file mode 100644 index 000000000..e5b283e13 --- /dev/null +++ b/DeepLinkDemo/Podfile.lock @@ -0,0 +1,23 @@ +PODS: + - BranchSDK (3.4.4) + - IQKeyboardManager (6.5.19) + +DEPENDENCIES: + - BranchSDK (from `./../`) + - IQKeyboardManager + +SPEC REPOS: + trunk: + - IQKeyboardManager + +EXTERNAL SOURCES: + BranchSDK: + :path: "./../" + +SPEC CHECKSUMS: + BranchSDK: 28bec34fb99c53ab8e86b7bf69cc55a4505fe0b3 + IQKeyboardManager: c8665b3396bd0b79402b4c573eac345a31c7d485 + +PODFILE CHECKSUM: 8c4b32f5c4a14defd62bc8a2d1e49cee9e7c2173 + +COCOAPODS: 1.15.2 diff --git a/DeepLinkDemo/README.md b/DeepLinkDemo/README.md new file mode 100644 index 000000000..e95c403f6 --- /dev/null +++ b/DeepLinkDemo/README.md @@ -0,0 +1,2 @@ +# Branch SaaS SDK IOS TestApp + diff --git a/BranchSDKTests/BranchConstants.h b/Sources/BranchSDK_ObjC/Public/BranchConstants.h similarity index 100% rename from BranchSDKTests/BranchConstants.h rename to Sources/BranchSDK_ObjC/Public/BranchConstants.h diff --git a/TestDeepLinking/Podfile b/TestDeepLinking/Podfile new file mode 100644 index 000000000..1a6061452 --- /dev/null +++ b/TestDeepLinking/Podfile @@ -0,0 +1,8 @@ +platform :ios, '9.0' + +target 'TestDeepLinking' do + # if swift + use_frameworks! + + pod 'Branch' +end diff --git a/TestDeepLinking/TestDeepLinking.xcodeproj/project.pbxproj b/TestDeepLinking/TestDeepLinking.xcodeproj/project.pbxproj new file mode 100644 index 000000000..31dd25628 --- /dev/null +++ b/TestDeepLinking/TestDeepLinking.xcodeproj/project.pbxproj @@ -0,0 +1,733 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 032DAEE82607431D00891641 /* TestDeepLinkWithoutApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 032DAED2260742D100891641 /* TestDeepLinkWithoutApp.m */; }; + 032DAEFE2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 032DAEFD2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.m */; }; + 033608162605E2110032A5DC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033608152605E2110032A5DC /* AppDelegate.swift */; }; + 033608182605E2110032A5DC /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033608172605E2110032A5DC /* SceneDelegate.swift */; }; + 0336081A2605E2110032A5DC /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 033608192605E2110032A5DC /* ViewController.swift */; }; + 0336081D2605E2110032A5DC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0336081B2605E2110032A5DC /* Main.storyboard */; }; + 0336081F2605E2150032A5DC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0336081E2605E2150032A5DC /* Assets.xcassets */; }; + 033608222605E2150032A5DC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 033608202605E2150032A5DC /* LaunchScreen.storyboard */; }; + 033608302605F1E30032A5DC /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0336082F2605F1E30032A5DC /* CoreServices.framework */; }; + 033608322605F1F10032A5DC /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608312605F1F10032A5DC /* SystemConfiguration.framework */; }; + 033608342605F20C0032A5DC /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608332605F20C0032A5DC /* CoreTelephony.framework */; }; + 033608362605F2130032A5DC /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608352605F2130032A5DC /* WebKit.framework */; }; + 033608382605F21B0032A5DC /* CoreSpotlight.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608372605F21B0032A5DC /* CoreSpotlight.framework */; }; + 0336083B2605F2370032A5DC /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608392605F2370032A5DC /* AdSupport.framework */; }; + 0336083C2605F2370032A5DC /* iAd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0336083A2605F2370032A5DC /* iAd.framework */; }; + 0336083E2605F2880032A5DC /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608392605F2370032A5DC /* AdSupport.framework */; }; + 033608402605F4470032A5DC /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 033608392605F2370032A5DC /* AdSupport.framework */; }; + 03DE13B32606A1B4006D18F5 /* TestDeepLinking.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = 03DE13B22606A0C4006D18F5 /* TestDeepLinking.entitlements */; }; + 03DE13BA2606BFC4006D18F5 /* AdServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03DE13B92606BFC4006D18F5 /* AdServices.framework */; }; + 69BEC330F5B8AF8CE3C32174 /* Pods_TestDeepLinking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 815FC6A40AFE1F218C25C738 /* Pods_TestDeepLinking.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 032DAEDF2607430600891641 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0336080A2605E2100032A5DC /* Project object */; + proxyType = 1; + remoteGlobalIDString = 033608112605E2110032A5DC; + remoteInfo = TestDeepLinking; + }; + 032DAF002607491B00891641 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 0336080A2605E2100032A5DC /* Project object */; + proxyType = 1; + remoteGlobalIDString = 033608112605E2110032A5DC; + remoteInfo = TestDeepLinking; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 032DAED2260742D100891641 /* TestDeepLinkWithoutApp.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestDeepLinkWithoutApp.m; sourceTree = ""; }; + 032DAEDA2607430600891641 /* TestDeepLinkingUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestDeepLinkingUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 032DAEDE2607430600891641 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 032DAEFB2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TestDeepLinkingUITestsWithHostApp.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 032DAEFD2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestDeepLinkingUITestsWithHostApp.m; sourceTree = ""; }; + 032DAEFF2607491B00891641 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 032DAF122607504000891641 /* TestDeepLinking.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = TestDeepLinking.xctestplan; sourceTree = ""; }; + 033608122605E2110032A5DC /* TestDeepLinking.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestDeepLinking.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 033608152605E2110032A5DC /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 033608172605E2110032A5DC /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 033608192605E2110032A5DC /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 0336081C2605E2110032A5DC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 0336081E2605E2150032A5DC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 033608212605E2150032A5DC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 033608232605E2150032A5DC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 0336082F2605F1E30032A5DC /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; + 033608312605F1F10032A5DC /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + 033608332605F20C0032A5DC /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; }; + 033608352605F2130032A5DC /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + 033608372605F21B0032A5DC /* CoreSpotlight.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreSpotlight.framework; path = System/Library/Frameworks/CoreSpotlight.framework; sourceTree = SDKROOT; }; + 033608392605F2370032A5DC /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; + 0336083A2605F2370032A5DC /* iAd.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = iAd.framework; path = System/Library/Frameworks/iAd.framework; sourceTree = SDKROOT; }; + 03DE13B22606A0C4006D18F5 /* TestDeepLinking.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TestDeepLinking.entitlements; sourceTree = ""; }; + 03DE13B92606BFC4006D18F5 /* AdServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdServices.framework; path = ../../AdServices.framework; sourceTree = ""; }; + 0EE470FCEAEA1ECC99DC0A89 /* Pods-TestDeepLinking.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TestDeepLinking.release.xcconfig"; path = "Target Support Files/Pods-TestDeepLinking/Pods-TestDeepLinking.release.xcconfig"; sourceTree = ""; }; + 815FC6A40AFE1F218C25C738 /* Pods_TestDeepLinking.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TestDeepLinking.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 86113F63A46AE44E1E8B1648 /* Pods-TestDeepLinking.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TestDeepLinking.debug.xcconfig"; path = "Target Support Files/Pods-TestDeepLinking/Pods-TestDeepLinking.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 032DAED72607430600891641 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 032DAEF82607491B00891641 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0336080F2605E2110032A5DC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 033608362605F2130032A5DC /* WebKit.framework in Frameworks */, + 033608402605F4470032A5DC /* AdSupport.framework in Frameworks */, + 033608342605F20C0032A5DC /* CoreTelephony.framework in Frameworks */, + 03DE13BA2606BFC4006D18F5 /* AdServices.framework in Frameworks */, + 0336083E2605F2880032A5DC /* AdSupport.framework in Frameworks */, + 033608382605F21B0032A5DC /* CoreSpotlight.framework in Frameworks */, + 033608322605F1F10032A5DC /* SystemConfiguration.framework in Frameworks */, + 033608302605F1E30032A5DC /* CoreServices.framework in Frameworks */, + 0336083B2605F2370032A5DC /* AdSupport.framework in Frameworks */, + 0336083C2605F2370032A5DC /* iAd.framework in Frameworks */, + 69BEC330F5B8AF8CE3C32174 /* Pods_TestDeepLinking.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 032DAEDB2607430600891641 /* TestDeepLinkingUITests */ = { + isa = PBXGroup; + children = ( + 032DAED2260742D100891641 /* TestDeepLinkWithoutApp.m */, + 032DAEDE2607430600891641 /* Info.plist */, + ); + path = TestDeepLinkingUITests; + sourceTree = ""; + }; + 032DAEFC2607491B00891641 /* TestDeepLinkingUITestsWithHostApp */ = { + isa = PBXGroup; + children = ( + 032DAEFD2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.m */, + 032DAEFF2607491B00891641 /* Info.plist */, + ); + path = TestDeepLinkingUITestsWithHostApp; + sourceTree = ""; + }; + 033608092605E2100032A5DC = { + isa = PBXGroup; + children = ( + 033608142605E2110032A5DC /* TestDeepLinking */, + 032DAEDB2607430600891641 /* TestDeepLinkingUITests */, + 032DAEFC2607491B00891641 /* TestDeepLinkingUITestsWithHostApp */, + 033608132605E2110032A5DC /* Products */, + 0336082E2605F1E30032A5DC /* Frameworks */, + FBA3F883B3850B5894EAA121 /* Pods */, + ); + sourceTree = ""; + }; + 033608132605E2110032A5DC /* Products */ = { + isa = PBXGroup; + children = ( + 033608122605E2110032A5DC /* TestDeepLinking.app */, + 032DAEDA2607430600891641 /* TestDeepLinkingUITests.xctest */, + 032DAEFB2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 033608142605E2110032A5DC /* TestDeepLinking */ = { + isa = PBXGroup; + children = ( + 03DE13B22606A0C4006D18F5 /* TestDeepLinking.entitlements */, + 033608152605E2110032A5DC /* AppDelegate.swift */, + 032DAF122607504000891641 /* TestDeepLinking.xctestplan */, + 033608172605E2110032A5DC /* SceneDelegate.swift */, + 033608192605E2110032A5DC /* ViewController.swift */, + 0336081B2605E2110032A5DC /* Main.storyboard */, + 0336081E2605E2150032A5DC /* Assets.xcassets */, + 033608202605E2150032A5DC /* LaunchScreen.storyboard */, + 033608232605E2150032A5DC /* Info.plist */, + ); + path = TestDeepLinking; + sourceTree = ""; + }; + 0336082E2605F1E30032A5DC /* Frameworks */ = { + isa = PBXGroup; + children = ( + 03DE13B92606BFC4006D18F5 /* AdServices.framework */, + 033608392605F2370032A5DC /* AdSupport.framework */, + 0336083A2605F2370032A5DC /* iAd.framework */, + 033608372605F21B0032A5DC /* CoreSpotlight.framework */, + 033608352605F2130032A5DC /* WebKit.framework */, + 033608332605F20C0032A5DC /* CoreTelephony.framework */, + 033608312605F1F10032A5DC /* SystemConfiguration.framework */, + 0336082F2605F1E30032A5DC /* CoreServices.framework */, + 815FC6A40AFE1F218C25C738 /* Pods_TestDeepLinking.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + FBA3F883B3850B5894EAA121 /* Pods */ = { + isa = PBXGroup; + children = ( + 86113F63A46AE44E1E8B1648 /* Pods-TestDeepLinking.debug.xcconfig */, + 0EE470FCEAEA1ECC99DC0A89 /* Pods-TestDeepLinking.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 032DAED92607430600891641 /* TestDeepLinkingUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 032DAEE12607430600891641 /* Build configuration list for PBXNativeTarget "TestDeepLinkingUITests" */; + buildPhases = ( + 032DAED62607430600891641 /* Sources */, + 032DAED72607430600891641 /* Frameworks */, + 032DAED82607430600891641 /* Resources */, + 032DAF0826074B6A00891641 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 032DAEE02607430600891641 /* PBXTargetDependency */, + ); + name = TestDeepLinkingUITests; + productName = TestDeepLinkingUITests; + productReference = 032DAEDA2607430600891641 /* TestDeepLinkingUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 032DAEFA2607491B00891641 /* TestDeepLinkingUITestsWithHostApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 032DAF022607491B00891641 /* Build configuration list for PBXNativeTarget "TestDeepLinkingUITestsWithHostApp" */; + buildPhases = ( + 032DAEF72607491B00891641 /* Sources */, + 032DAEF82607491B00891641 /* Frameworks */, + 032DAEF92607491B00891641 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 032DAF012607491B00891641 /* PBXTargetDependency */, + ); + name = TestDeepLinkingUITestsWithHostApp; + productName = TestDeepLinkingUITestsWithHostApp; + productReference = 032DAEFB2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + 033608112605E2110032A5DC /* TestDeepLinking */ = { + isa = PBXNativeTarget; + buildConfigurationList = 033608262605E2150032A5DC /* Build configuration list for PBXNativeTarget "TestDeepLinking" */; + buildPhases = ( + A6E708B8F29A1D55D1D76DE9 /* [CP] Check Pods Manifest.lock */, + 0336080E2605E2110032A5DC /* Sources */, + 0336080F2605E2110032A5DC /* Frameworks */, + 033608102605E2110032A5DC /* Resources */, + 249508BA477D5282ACF2EE9E /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TestDeepLinking; + productName = TestDeepLinking; + productReference = 033608122605E2110032A5DC /* TestDeepLinking.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0336080A2605E2100032A5DC /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1200; + LastUpgradeCheck = 1200; + TargetAttributes = { + 032DAED92607430600891641 = { + CreatedOnToolsVersion = 12.3; + }; + 032DAEFA2607491B00891641 = { + CreatedOnToolsVersion = 12.3; + TestTargetID = 033608112605E2110032A5DC; + }; + 033608112605E2110032A5DC = { + CreatedOnToolsVersion = 12.0.1; + LastSwiftMigration = 1230; + }; + }; + }; + buildConfigurationList = 0336080D2605E2100032A5DC /* Build configuration list for PBXProject "TestDeepLinking" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 033608092605E2100032A5DC; + productRefGroup = 033608132605E2110032A5DC /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 033608112605E2110032A5DC /* TestDeepLinking */, + 032DAED92607430600891641 /* TestDeepLinkingUITests */, + 032DAEFA2607491B00891641 /* TestDeepLinkingUITestsWithHostApp */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 032DAED82607430600891641 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 032DAEF92607491B00891641 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 033608102605E2110032A5DC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 03DE13B32606A1B4006D18F5 /* TestDeepLinking.entitlements in Resources */, + 033608222605E2150032A5DC /* LaunchScreen.storyboard in Resources */, + 0336081F2605E2150032A5DC /* Assets.xcassets in Resources */, + 0336081D2605E2110032A5DC /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 032DAF0826074B6A00891641 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "xcrun simctl terminate booted io.branch.TestiOSDeepLink\nxcrun simctl uninstall booted io.branch.TestiOSDeepLink\n\n"; + }; + 249508BA477D5282ACF2EE9E /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TestDeepLinking/Pods-TestDeepLinking-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TestDeepLinking/Pods-TestDeepLinking-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TestDeepLinking/Pods-TestDeepLinking-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + A6E708B8F29A1D55D1D76DE9 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-TestDeepLinking-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 032DAED62607430600891641 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 032DAEE82607431D00891641 /* TestDeepLinkWithoutApp.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 032DAEF72607491B00891641 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 032DAEFE2607491B00891641 /* TestDeepLinkingUITestsWithHostApp.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0336080E2605E2110032A5DC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0336081A2605E2110032A5DC /* ViewController.swift in Sources */, + 033608162605E2110032A5DC /* AppDelegate.swift in Sources */, + 033608182605E2110032A5DC /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 032DAEE02607430600891641 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 033608112605E2110032A5DC /* TestDeepLinking */; + targetProxy = 032DAEDF2607430600891641 /* PBXContainerItemProxy */; + }; + 032DAF012607491B00891641 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 033608112605E2110032A5DC /* TestDeepLinking */; + targetProxy = 032DAF002607491B00891641 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 0336081B2605E2110032A5DC /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 0336081C2605E2110032A5DC /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 033608202605E2150032A5DC /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 033608212605E2150032A5DC /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 032DAEE22607430600891641 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = XHGU2TWQZE; + INFOPLIST_FILE = TestDeepLinkingUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.trusona.TestDeepLinkingUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 032DAEE32607430600891641 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = XHGU2TWQZE; + INFOPLIST_FILE = TestDeepLinkingUITests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.trusona.TestDeepLinkingUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 032DAF032607491B00891641 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = XHGU2TWQZE; + INFOPLIST_FILE = TestDeepLinkingUITestsWithHostApp/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.trusona.TestDeepLinkingUITestsWithHostApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = TestDeepLinking; + }; + name = Debug; + }; + 032DAF042607491B00891641 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = XHGU2TWQZE; + INFOPLIST_FILE = TestDeepLinkingUITestsWithHostApp/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.trusona.TestDeepLinkingUITestsWithHostApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = TestDeepLinking; + }; + name = Release; + }; + 033608242605E2150032A5DC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 033608252605E2150032A5DC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 033608272605E2150032A5DC /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 86113F63A46AE44E1E8B1648 /* Pods-TestDeepLinking.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = TestDeepLinking/TestDeepLinking.entitlements; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = R63EM248DP; + EXCLUDED_ARCHS = arm64; + INFOPLIST_FILE = TestDeepLinking/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestiOSDeepLink; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; + 033608282605E2150032A5DC /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0EE470FCEAEA1ECC99DC0A89 /* Pods-TestDeepLinking.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = TestDeepLinking/TestDeepLinking.entitlements; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = R63EM248DP; + EXCLUDED_ARCHS = arm64; + INFOPLIST_FILE = TestDeepLinking/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.branch.TestiOSDeepLink; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 032DAEE12607430600891641 /* Build configuration list for PBXNativeTarget "TestDeepLinkingUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 032DAEE22607430600891641 /* Debug */, + 032DAEE32607430600891641 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 032DAF022607491B00891641 /* Build configuration list for PBXNativeTarget "TestDeepLinkingUITestsWithHostApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 032DAF032607491B00891641 /* Debug */, + 032DAF042607491B00891641 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0336080D2605E2100032A5DC /* Build configuration list for PBXProject "TestDeepLinking" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 033608242605E2150032A5DC /* Debug */, + 033608252605E2150032A5DC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 033608262605E2150032A5DC /* Build configuration list for PBXNativeTarget "TestDeepLinking" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 033608272605E2150032A5DC /* Debug */, + 033608282605E2150032A5DC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0336080A2605E2100032A5DC /* Project object */; +} diff --git a/TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/TestDeepLinking/TestDeepLinking.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/TestDeepLinking/TestDeepLinking.xcodeproj/xcshareddata/xcschemes/TestDeepLinking.xcscheme b/TestDeepLinking/TestDeepLinking.xcodeproj/xcshareddata/xcschemes/TestDeepLinking.xcscheme new file mode 100644 index 000000000..fe40949b8 --- /dev/null +++ b/TestDeepLinking/TestDeepLinking.xcodeproj/xcshareddata/xcschemes/TestDeepLinking.xcscheme @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TestDeepLinking/TestDeepLinking.xcworkspace/contents.xcworkspacedata b/TestDeepLinking/TestDeepLinking.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..ba8e3820e --- /dev/null +++ b/TestDeepLinking/TestDeepLinking.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/TestDeepLinking/TestDeepLinking.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/TestDeepLinking/TestDeepLinking.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/TestDeepLinking/TestDeepLinking.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/TestDeepLinking/TestDeepLinking/AppDelegate.swift b/TestDeepLinking/TestDeepLinking/AppDelegate.swift new file mode 100644 index 000000000..8f1e6984d --- /dev/null +++ b/TestDeepLinking/TestDeepLinking/AppDelegate.swift @@ -0,0 +1,45 @@ +// +// AppDelegate.swift +// TestDeepLinking +// +// Created by Nidhi on 3/20/21. +// + +import UIKit +import Branch + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + BranchScene.shared().initSession(launchOptions: launchOptions, registerDeepLinkHandler: { (params, error, scene) in + let presentedVC : ViewController = UIApplication.shared.keyWindow?.rootViewController as! ViewController + let jsonData = try! JSONSerialization.data(withJSONObject:params, options: JSONSerialization.WritingOptions.prettyPrinted) + + let jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue)! as String + + presentedVC.addText(jsonString) + }) + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/TestDeepLinking/TestDeepLinking/Assets.xcassets/AccentColor.colorset/Contents.json b/TestDeepLinking/TestDeepLinking/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 000000000..eb8789700 --- /dev/null +++ b/TestDeepLinking/TestDeepLinking/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/TestDeepLinking/TestDeepLinking/Assets.xcassets/AppIcon.appiconset/Contents.json b/TestDeepLinking/TestDeepLinking/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..9221b9bb1 --- /dev/null +++ b/TestDeepLinking/TestDeepLinking/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/TestDeepLinking/TestDeepLinking/Assets.xcassets/Contents.json b/TestDeepLinking/TestDeepLinking/Assets.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/TestDeepLinking/TestDeepLinking/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/TestDeepLinking/TestDeepLinking/Base.lproj/LaunchScreen.storyboard b/TestDeepLinking/TestDeepLinking/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..865e9329f --- /dev/null +++ b/TestDeepLinking/TestDeepLinking/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TestDeepLinking/TestDeepLinking/Base.lproj/Main.storyboard b/TestDeepLinking/TestDeepLinking/Base.lproj/Main.storyboard new file mode 100644 index 000000000..99cb43c0a --- /dev/null +++ b/TestDeepLinking/TestDeepLinking/Base.lproj/Main.storyboard @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TestDeepLinking/TestDeepLinking/Info.plist b/TestDeepLinking/TestDeepLinking/Info.plist new file mode 100644 index 000000000..74d99de4a --- /dev/null +++ b/TestDeepLinking/TestDeepLinking/Info.plist @@ -0,0 +1,79 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + testiOSDeepLink + + + + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + branch_key + key_live_fk7pNcsmBjFPVS2VGlvrZaiazxkxxZ7r + + diff --git a/TestDeepLinking/TestDeepLinking/SceneDelegate.swift b/TestDeepLinking/TestDeepLinking/SceneDelegate.swift new file mode 100644 index 000000000..dfeac44f1 --- /dev/null +++ b/TestDeepLinking/TestDeepLinking/SceneDelegate.swift @@ -0,0 +1,64 @@ +// +// SceneDelegate.swift +// TestDeepLinking +// +// Created by Nidhi on 3/20/21. +// + +import UIKit +import Branch + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + if let userActivity = connectionOptions.userActivities.first { + + BranchScene.shared().scene(scene, continue: userActivity) + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { + BranchScene.shared().scene(scene, continue: userActivity) + } + func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { + BranchScene.shared().scene(scene, openURLContexts: URLContexts) + } + + +} + diff --git a/TestDeepLinking/TestDeepLinking/TestDeepLinking.entitlements b/TestDeepLinking/TestDeepLinking/TestDeepLinking.entitlements new file mode 100644 index 000000000..343898fc9 --- /dev/null +++ b/TestDeepLinking/TestDeepLinking/TestDeepLinking.entitlements @@ -0,0 +1,13 @@ + + + + + com.apple.developer.associated-domains + + mnl7s.app.link + mnl7s-alternate.app.link + mnl7s.test-app.link + mnl7s-alternate.test-app.link + + + diff --git a/TestDeepLinking/TestDeepLinking/TestDeepLinking.xctestplan b/TestDeepLinking/TestDeepLinking/TestDeepLinking.xctestplan new file mode 100644 index 000000000..90b72d85e --- /dev/null +++ b/TestDeepLinking/TestDeepLinking/TestDeepLinking.xctestplan @@ -0,0 +1,36 @@ +{ + "configurations" : [ + { + "id" : "21B9F7C4-BF2C-40DB-B313-9320AC57EB78", + "name" : "Configuration 1", + "options" : { + + } + } + ], + "defaultOptions" : { + "codeCoverage" : false, + "targetForVariableExpansion" : { + "containerPath" : "container:TestDeepLinking.xcodeproj", + "identifier" : "033608112605E2110032A5DC", + "name" : "TestDeepLinking" + } + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:TestDeepLinking.xcodeproj", + "identifier" : "032DAED92607430600891641", + "name" : "TestDeepLinkingUITests" + } + }, + { + "target" : { + "containerPath" : "container:TestDeepLinking.xcodeproj", + "identifier" : "032DAEFA2607491B00891641", + "name" : "TestDeepLinkingUITestsWithHostApp" + } + } + ], + "version" : 1 +} diff --git a/TestDeepLinking/TestDeepLinking/ViewController.swift b/TestDeepLinking/TestDeepLinking/ViewController.swift new file mode 100644 index 000000000..0f5a341aa --- /dev/null +++ b/TestDeepLinking/TestDeepLinking/ViewController.swift @@ -0,0 +1,22 @@ +// +// ViewController.swift +// TestDeepLinking +// +// Created by Nidhi on 3/20/21. +// + +import UIKit + +class ViewController: UIViewController { + + @IBOutlet var textView: UITextView! + override func viewDidLoad() { + super.viewDidLoad() + } + + func addText(_ text: String) { + textView.text = "" + textView.insertText(text) + } +} + diff --git a/BranchSDKTests/Info.plist b/TestDeepLinking/TestDeepLinkingUITests/Info.plist similarity index 86% rename from BranchSDKTests/Info.plist rename to TestDeepLinking/TestDeepLinkingUITests/Info.plist index ba72822e8..64d65ca49 100644 --- a/BranchSDKTests/Info.plist +++ b/TestDeepLinking/TestDeepLinkingUITests/Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + $(DEVELOPMENT_LANGUAGE) CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -13,11 +13,9 @@ CFBundleName $(PRODUCT_NAME) CFBundlePackageType - BNDL + $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString 1.0 - CFBundleSignature - ???? CFBundleVersion 1 diff --git a/TestDeepLinking/TestDeepLinkingUITests/TestDeepLinkWithoutApp.m b/TestDeepLinking/TestDeepLinkingUITests/TestDeepLinkWithoutApp.m new file mode 100644 index 000000000..22a741930 --- /dev/null +++ b/TestDeepLinking/TestDeepLinkingUITests/TestDeepLinkWithoutApp.m @@ -0,0 +1,64 @@ +// +// TestDeepLinkWithoutApp.m +// TestDeepLinking +// +// Created by Nidhi on 3/21/21. +// + +#import + +@interface TestDeepLinkWithoutApp : XCTestCase + +@end + +@implementation TestDeepLinkWithoutApp + +- (void)setUp { + self.continueAfterFailure = YES; + [self addUIInterruptionMonitorWithDescription:@"Open App" handler:^BOOL(XCUIElement * _Nonnull interruptingElement) { + [interruptingElement description]; + XCUIElement *button = interruptingElement.buttons[@"Open"]; + if ([button exists]) { + [button tap]; + return YES; + } + return NO; + }]; + +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)test0OpenLinkWithoutApp { + + XCUIApplication *safariApp = [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.mobilesafari"]; + //[safariApp setLaunchArguments: @[@"-u",@"https://ndixit-branch.github.io/TestWebPage.html"]]; + [safariApp launch]; + + sleep(1.0); + [safariApp.buttons[@"URL"] tap]; + //[safariApp.otherElements[@"URL"] tap]; + [safariApp.textFields[@"Search or enter website name"] tap]; + [safariApp typeText:@"https://mnl7s.app.link/CwOJ5aTaNeb"]; + [safariApp.buttons[@"Go"] tap]; + XCUIElement *testBedLink = [[safariApp.webViews descendantsMatchingType:XCUIElementTypeLink] elementBoundByIndex:0]; + + [testBedLink tap]; + + sleep(10); + [safariApp terminate]; + +// XCUIApplication *app = [[XCUIApplication alloc] initWithBundleIdentifier:@"io.branch.TestiOSDeepLink"]; +// +// if ([ app waitForExistenceWithTimeout:5] != NO) { +// NSString *deepLinkData = app.textViews[@"DeepLinkData"].value; +// XCTAssertTrue([deepLinkData containsString:self.deeplinkDataToCheck]); +// } else { +// XCTFail("Application not launched"); +// } +// +} + +@end diff --git a/TestDeepLinking/TestDeepLinkingUITestsWithHostApp/Info.plist b/TestDeepLinking/TestDeepLinkingUITestsWithHostApp/Info.plist new file mode 100644 index 000000000..64d65ca49 --- /dev/null +++ b/TestDeepLinking/TestDeepLinkingUITestsWithHostApp/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/TestDeepLinking/TestDeepLinkingUITestsWithHostApp/TestDeepLinkingUITestsWithHostApp.m b/TestDeepLinking/TestDeepLinkingUITestsWithHostApp/TestDeepLinkingUITestsWithHostApp.m new file mode 100644 index 000000000..7e40b4ba8 --- /dev/null +++ b/TestDeepLinking/TestDeepLinkingUITestsWithHostApp/TestDeepLinkingUITestsWithHostApp.m @@ -0,0 +1,38 @@ +// +// TestDeepLinkingUITestsWithHostApp.m +// TestDeepLinkingUITestsWithHostApp +// +// Created by Nidhi on 3/21/21. +// + +#import + +@interface TestDeepLinkingUITestsWithHostApp : XCTestCase + +@end + +@implementation TestDeepLinkingUITestsWithHostApp + +- (void)setUp { + self.continueAfterFailure = YES; +} + +- (void)tearDown { +} + +- (void)test1OpenApp { + XCUIApplication *app = [[XCUIApplication alloc] init]; + [app launch]; + + sleep(3); + if ([ app waitForExistenceWithTimeout:15] != NO) { + NSString *deepLinkData = app.textViews[@"tvID"].value; + NSLog(@"==== %@" , deepLinkData); + XCTAssertTrue([deepLinkData containsString:@"https:\\/\\/mnl7s.app.link\\/CwOJ5aTaNeb"]); + } else { + XCTFail("Application not launched"); + } +} + + +@end diff --git a/TestHost/AppDelegate.swift b/TestHost/AppDelegate.swift new file mode 100644 index 000000000..c77614d85 --- /dev/null +++ b/TestHost/AppDelegate.swift @@ -0,0 +1,37 @@ +// +// AppDelegate.swift +// TestHost +// +// Created by Ernest Cho on 7/29/22. +// + +import UIKit +import BranchSDK + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/TestHost/Assets.xcassets/AccentColor.colorset/Contents.json b/TestHost/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 000000000..eb8789700 --- /dev/null +++ b/TestHost/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/TestHost/Assets.xcassets/AppIcon.appiconset/Contents.json b/TestHost/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..9221b9bb1 --- /dev/null +++ b/TestHost/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/TestHost/Assets.xcassets/Contents.json b/TestHost/Assets.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/TestHost/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/TestHost/Base.lproj/LaunchScreen.storyboard b/TestHost/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..865e9329f --- /dev/null +++ b/TestHost/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BranchSDKTestsHostApp/Base.lproj/Main.storyboard b/TestHost/Base.lproj/Main.storyboard similarity index 95% rename from BranchSDKTestsHostApp/Base.lproj/Main.storyboard rename to TestHost/Base.lproj/Main.storyboard index 808a21ce7..25a763858 100644 --- a/BranchSDKTestsHostApp/Base.lproj/Main.storyboard +++ b/TestHost/Base.lproj/Main.storyboard @@ -9,7 +9,7 @@ - + diff --git a/BranchSDKTestsHostApp/Info.plist b/TestHost/Info.plist similarity index 59% rename from BranchSDKTestsHostApp/Info.plist rename to TestHost/Info.plist index f0cb4d34f..dd3c9afda 100644 --- a/BranchSDKTestsHostApp/Info.plist +++ b/TestHost/Info.plist @@ -2,17 +2,6 @@ - CFBundleURLTypes - - - CFBundleTypeRole - Editor - CFBundleURLSchemes - - branchtest - - - UIApplicationSceneManifest UIApplicationSupportsMultipleScenes @@ -25,19 +14,12 @@ UISceneConfigurationName Default Configuration UISceneDelegateClassName - SceneDelegate + $(PRODUCT_MODULE_NAME).SceneDelegate UISceneStoryboardFile Main - branch_key - - live - key_live_hcnegAumkH7Kv18M8AOHhfgiohpXq5tB - test - key_test_hdcBLUy1xZ1JD0tKg7qrLcgirFmPPVJc - diff --git a/TestHost/NSURLSession+Branch.h b/TestHost/NSURLSession+Branch.h new file mode 100644 index 000000000..28073f0a1 --- /dev/null +++ b/TestHost/NSURLSession+Branch.h @@ -0,0 +1,17 @@ +// +// NSURLSession+Branch.h +// BranchSearchDemo +// +// Created by Ernest Cho on 10/11/18. +// Copyright © 2018 Branch Metrics, Inc. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSURLSession (Branch) + +@end + +NS_ASSUME_NONNULL_END diff --git a/TestHost/NSURLSession+Branch.m b/TestHost/NSURLSession+Branch.m new file mode 100644 index 000000000..594fc6b11 --- /dev/null +++ b/TestHost/NSURLSession+Branch.m @@ -0,0 +1,64 @@ +// +// NSURLSession+Branch.m +// BranchSearchDemo +// +// Created by Ernest Cho on 8/19/20. +// Copyright © 2020 Branch Metrics, Inc. All rights reserved. +// + +#import "NSURLSession+Branch.h" +#import + +@implementation NSURLSession (Branch) + ++ (void)load { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + [self swizzleSelector:@selector(dataTaskWithRequest:completionHandler:) + withSelector:@selector(xxx_dataTaskWithRequest:completionHandler:)]; + }); +} + +// swaps originalSelector with swizzledSelector ++ (void)swizzleSelector:(SEL)originalSelector withSelector:(SEL)swizzledSelector { + Class class = [self class]; + + Method originalMethod = class_getInstanceMethod(class, originalSelector); + Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); + + method_exchangeImplementations(originalMethod, swizzledMethod); +} + +- (void)logNetworkTrafficRequest:(NSURLRequest *)request data:(NSData *)data response:(NSURLResponse *)response { + NSLog(@"NSURLSessionDataTask Request: %@", request); + + NSData *body = [request HTTPBody]; + if (body) { + NSLog(@"NSURLSessionDataTask Request Body: %@", [NSString stringWithUTF8String:body.bytes]); + } + + NSLog(@"NSURLSessionDataTask Response: %@", response); + + if (data.bytes) { + NSLog(@"NSURLSessionDataTask Response Data: %@", [NSString stringWithUTF8String:data.bytes]); + } +} + +// replacement method for dataTaskWithRequest +- (NSURLSessionDataTask *)xxx_dataTaskWithRequest:(NSURLRequest *)request + completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler { + + // create a new block that just calls the original block after logging the request + void (^completionHandlerWithLogging)(NSData *, NSURLResponse *, NSError *) = ^(NSData *data, NSURLResponse *response, NSError *error) { + if (completionHandler) { + + [self logNetworkTrafficRequest:request data:data response:response]; + + completionHandler(data, response, error); + } + }; + + return [self xxx_dataTaskWithRequest:request completionHandler:completionHandlerWithLogging]; +} + +@end diff --git a/TestHost/SceneDelegate.swift b/TestHost/SceneDelegate.swift new file mode 100644 index 000000000..ee2ca8f1b --- /dev/null +++ b/TestHost/SceneDelegate.swift @@ -0,0 +1,57 @@ +// +// SceneDelegate.swift +// TestHost +// +// Created by Ernest Cho on 7/29/22. +// + +import UIKit +import BranchSDK + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + + if let userActivity = connectionOptions.userActivities.first { + BranchScene.shared().scene(scene, continue: userActivity) + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/TestHost/TestHost-Bridging-Header.h b/TestHost/TestHost-Bridging-Header.h new file mode 100644 index 000000000..1b2cb5d6d --- /dev/null +++ b/TestHost/TestHost-Bridging-Header.h @@ -0,0 +1,4 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + diff --git a/TestHost/ViewController.swift b/TestHost/ViewController.swift new file mode 100644 index 000000000..ab76ab909 --- /dev/null +++ b/TestHost/ViewController.swift @@ -0,0 +1,19 @@ +// +// ViewController.swift +// TestHost +// +// Created by Ernest Cho on 7/29/22. +// + +import UIKit + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + } + + +} + diff --git a/TestHostTests/TestHostTests.swift b/TestHostTests/TestHostTests.swift new file mode 100644 index 000000000..231b61ed4 --- /dev/null +++ b/TestHostTests/TestHostTests.swift @@ -0,0 +1,36 @@ +// +// TestHostTests.swift +// TestHostTests +// +// Created by Ernest Cho on 7/29/22. +// + +import XCTest +@testable import TestHost + +class TestHostTests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + // Any test you write for XCTest can be annotated as throws and async. + // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. + // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/TestHostUITests/TestHostUITests.swift b/TestHostUITests/TestHostUITests.swift new file mode 100644 index 000000000..2f5a1af58 --- /dev/null +++ b/TestHostUITests/TestHostUITests.swift @@ -0,0 +1,41 @@ +// +// TestHostUITests.swift +// TestHostUITests +// +// Created by Ernest Cho on 7/29/22. +// + +import XCTest + +class TestHostUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testLaunchPerformance() throws { + if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } + } +} diff --git a/TestHostUITests/TestHostUITestsLaunchTests.swift b/TestHostUITests/TestHostUITestsLaunchTests.swift new file mode 100644 index 000000000..a49cc5663 --- /dev/null +++ b/TestHostUITests/TestHostUITestsLaunchTests.swift @@ -0,0 +1,32 @@ +// +// TestHostUITestsLaunchTests.swift +// TestHostUITests +// +// Created by Ernest Cho on 7/29/22. +// + +import XCTest + +class TestHostUITestsLaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +} From 8881ac4be0164b2f3b85f3a5db4825eacb3f2436 Mon Sep 17 00:00:00 2001 From: NidhiDixit09 <93544270+NidhiDixit09@users.noreply.github.com> Date: Tue, 15 Jul 2025 23:45:28 +0530 Subject: [PATCH 27/27] Update project.pbxproj --- BranchSDK.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BranchSDK.xcodeproj/project.pbxproj b/BranchSDK.xcodeproj/project.pbxproj index e65db2426..02d51e7fa 100644 --- a/BranchSDK.xcodeproj/project.pbxproj +++ b/BranchSDK.xcodeproj/project.pbxproj @@ -722,7 +722,7 @@ E7931D832E01C8AE0007A374 /* ConfigurationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ConfigurationController.swift; path = ../BranchSDK_Swift/ConfigurationController.swift; 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 = ""; }; - E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BranchConstants.h; path = Sources/BranchSDK_ObjC/Public/BranchConstants.h; sourceTree = ""; }; + E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BranchConstants.h; path = ../../BranchSDK_ObjC/Public/BranchConstants.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -776,7 +776,6 @@ 5F2210132894A0DB00C5B190 = { isa = PBXGroup; children = ( - E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */, 5FCDD36B2B7AC6A100EAF29F /* BranchSDK */, 5F2211702894A9C000C5B190 /* TestHost */, 5F2211872894A9C100C5B190 /* TestHostTests */, @@ -948,6 +947,7 @@ 5FCDD39F2B7AC6A100EAF29F /* BranchSDK.h */, 5FCDD3A52B7AC6A100EAF29F /* BranchShareLink.h */, 5FCDD3AC2B7AC6A100EAF29F /* BranchUniversalObject.h */, + E7FBA85E2E14492600E7AAD9 /* BranchConstants.h */, ); path = Public; sourceTree = "";