From 52172d689d0cc3991b732ff528bfcb1be75393d0 Mon Sep 17 00:00:00 2001 From: echo Date: Fri, 1 Mar 2024 17:02:25 -0800 Subject: [PATCH 01/16] optional NSError on all log levels. change os log level mapping. remove info log level. --- .../Branch-SDK-Tests/BranchLoggerTests.m | 42 ++++++++++--------- Sources/BranchSDK/BNCApplication.m | 2 +- Sources/BranchSDK/BNCEncodingUtils.m | 4 +- Sources/BranchSDK/BNCKeyChain.m | 15 +++---- Sources/BranchSDK/BNCNetworkService.m | 7 ++-- Sources/BranchSDK/BNCPartnerParameters.m | 4 +- Sources/BranchSDK/BNCPreferenceHelper.m | 12 +++--- Sources/BranchSDK/BNCReferringURLUtility.m | 2 +- Sources/BranchSDK/BNCSKAdNetwork.m | 8 ++-- Sources/BranchSDK/BNCServerInterface.m | 12 +++--- Sources/BranchSDK/BNCServerRequestQueue.m | 6 +-- Sources/BranchSDK/BNCSystemObserver.m | 2 +- Sources/BranchSDK/BNCURLFilter.m | 4 +- Sources/BranchSDK/Branch.m | 28 ++++++------- .../BranchCSSearchableItemAttributeSet.m | 2 +- Sources/BranchSDK/BranchEvent.m | 8 ++-- Sources/BranchSDK/BranchJsonConfig.m | 4 +- .../BranchSDK/BranchLastAttributedTouchData.m | 2 +- Sources/BranchSDK/BranchLogger.m | 29 ++++++------- Sources/BranchSDK/BranchOpenRequest.m | 22 +++++----- Sources/BranchSDK/BranchQRCode.m | 14 +++---- Sources/BranchSDK/BranchScene.m | 2 +- Sources/BranchSDK/BranchShareLink.m | 4 +- Sources/BranchSDK/BranchShortUrlSyncRequest.m | 2 +- Sources/BranchSDK/BranchUniversalObject.m | 8 ++-- Sources/BranchSDK/Public/BranchLogger.h | 16 ++++--- 26 files changed, 129 insertions(+), 132 deletions(-) diff --git a/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m b/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m index 0a9539f61..13bfe40f5 100644 --- a/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m +++ b/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m @@ -35,31 +35,33 @@ - (void)testLogLevelThresholdBlocksLowerLevels { } }; - [logger logVerbose:@"This verbose message should not trigger the log callback."]; - [logger logDebug:@"This message should trigger the log callback."]; + [logger logVerbose:@"This verbose message should not trigger the log callback." error:nil]; + [logger logDebug:@"This message should trigger the log callback." error:nil]; [self waitForExpectationsWithTimeout:1 handler:nil]; } - (void)testLogCallbackExecutesWithCorrectParameters { - XCTestExpectation *expectation = [self expectationWithDescription:@"Log callback expectation"]; - NSString *expectedMessage = @"[BranchSDK][Info][BranchLoggerTests testLogCallbackExecutesWithCorrectParameters] Test message"; - BranchLogLevel expectedLevel = BranchLogLevelInfo; - - BranchLogger *logger = [BranchLogger new]; - - logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - XCTAssertEqualObjects(message, expectedMessage, "Logged message does not match expected message."); - XCTAssertEqual(logLevel, expectedLevel, "Logged level does not match expected level."); - XCTAssertNil(error, "Error should be nil."); - [expectation fulfill]; - }; + // TODO: replace this test as info has been removed - logger.loggingEnabled = YES; - logger.logLevelThreshold = BranchLogLevelInfo; - [logger logInfo:@"Test message"]; - - [self waitForExpectationsWithTimeout:1 handler:nil]; +// XCTestExpectation *expectation = [self expectationWithDescription:@"Log callback expectation"]; +// NSString *expectedMessage = @"[BranchSDK][Info][BranchLoggerTests testLogCallbackExecutesWithCorrectParameters] Test message"; +// BranchLogLevel expectedLevel = BranchLogLevelInfo; +// +// BranchLogger *logger = [BranchLogger new]; +// +// logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { +// XCTAssertEqualObjects(message, expectedMessage, "Logged message does not match expected message."); +// XCTAssertEqual(logLevel, expectedLevel, "Logged level does not match expected level."); +// XCTAssertNil(error, "Error should be nil."); +// [expectation fulfill]; +// }; +// +// logger.loggingEnabled = YES; +// logger.logLevelThreshold = BranchLogLevelInfo; +// [logger logInfo:@"Test message"]; +// +// [self waitForExpectationsWithTimeout:1 handler:nil]; } - (void)testLogLevelSpecificityFiltersLowerLevels { @@ -81,7 +83,7 @@ - (void)testLogLevelSpecificityFiltersLowerLevels { callbackCount++; }; - [logger logVerbose:@"This should not be logged due to log level threshold."]; + [logger logVerbose:@"This should not be logged due to log level threshold." error:nil]; [logger logError:@"This should be logged" error:nil]; [self waitForExpectations:@[verboseExpectation, errorExpectation] timeout:2]; diff --git a/Sources/BranchSDK/BNCApplication.m b/Sources/BranchSDK/BNCApplication.m index 2bbecb03a..9d024c219 100644 --- a/Sources/BranchSDK/BNCApplication.m +++ b/Sources/BranchSDK/BNCApplication.m @@ -125,7 +125,7 @@ + (NSDate *) currentInstallDate { #endif if (installDate == nil || [installDate timeIntervalSince1970] <= 0.0) { - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Invalid install date, using [NSDate date]."]]; + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Invalid install date, using [NSDate date]."] error:nil]; } return installDate; } diff --git a/Sources/BranchSDK/BNCEncodingUtils.m b/Sources/BranchSDK/BNCEncodingUtils.m index 57cf9e16c..712b3d15e 100644 --- a/Sources/BranchSDK/BNCEncodingUtils.m +++ b/Sources/BranchSDK/BNCEncodingUtils.m @@ -230,7 +230,7 @@ + (NSString *)encodeDictionaryToJsonString:(NSDictionary *)dictionary { [encodedDictionary appendString:@"}"]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Encoded dictionary: %@.", encodedDictionary]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Encoded dictionary: %@.", encodedDictionary] error:nil]; return encodedDictionary; } @@ -290,7 +290,7 @@ + (NSString *)encodeArrayToJsonString:(NSArray *)array { [encodedArray deleteCharactersInRange:NSMakeRange([encodedArray length] - 1, 1)]; [encodedArray appendString:@"]"]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Encoded array: %@.", encodedArray]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Encoded array: %@.", encodedArray] error:nil]; return encodedArray; } diff --git a/Sources/BranchSDK/BNCKeyChain.m b/Sources/BranchSDK/BNCKeyChain.m index c2e1da340..5b75be5da 100644 --- a/Sources/BranchSDK/BNCKeyChain.m +++ b/Sources/BranchSDK/BNCKeyChain.m @@ -57,7 +57,7 @@ + (NSDate *) retrieveDateForService:(NSString *)service key:(NSString *)key erro OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)dictionary, (CFTypeRef *)&valueData); if (status != errSecSuccess) { NSError *localError = [self errorWithKey:key OSStatus:status]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Can't retrieve key: %@.", localError]]; + [[BranchLogger shared] logDebug:@"Can't retrieve key" error:localError]; if (error) *error = localError; if (valueData) CFRelease(valueData); return nil; @@ -106,7 +106,7 @@ + (NSError *) storeDate:(NSDate *)date OSStatus status = SecItemDelete((__bridge CFDictionaryRef)dictionary); if (status != errSecSuccess && status != errSecItemNotFound) { NSError *error = [self errorWithKey:key OSStatus:status]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Can't clear to store key: %@.", error]]; + [[BranchLogger shared] logDebug:@"Can't clear to store key" error:error]; } dictionary[(__bridge id)kSecValueData] = valueData; @@ -122,7 +122,7 @@ + (NSError *) storeDate:(NSDate *)date status = SecItemAdd((__bridge CFDictionaryRef)dictionary, NULL); if (status) { NSError *error = [self errorWithKey:key OSStatus:status]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Can't store key: %@.", error]]; + [[BranchLogger shared] logDebug:@"Can't store key" error:error]; return error; } return nil; @@ -140,7 +140,7 @@ + (NSError*) removeValuesForService:(NSString *)service key:(NSString *)key { if (status == errSecItemNotFound) status = errSecSuccess; if (status) { NSError *error = [self errorWithKey:key OSStatus:status]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Can't remove key: %@.", error]]; + [[BranchLogger shared] logDebug:@"Can't remove key" error:error]; return error; } return nil; @@ -154,7 +154,9 @@ + (NSString * _Nullable) securityAccessGroup { // First store a value: NSError *error = [self storeDate:[NSDate date] forService:@"BranchKeychainService" key:@"Temp" cloudAccessGroup:nil]; - if (error) [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Error storing temp value: %@.", error]]; + if (error) { + [[BranchLogger shared] logDebug:@"Error storing temp value" error:error]; + } NSDictionary* dictionary = @{ (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, @@ -167,8 +169,7 @@ + (NSString * _Nullable) securityAccessGroup { OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)dictionary, (CFTypeRef*)&resultDictionary); if (status == errSecItemNotFound) return nil; if (status != errSecSuccess) { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Get securityAccessGroup returned(%ld): %@.", - (long) status, [self errorWithKey:nil OSStatus:status]]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Get securityAccessGroup returned(%ld): %@.", (long) status, [self errorWithKey:nil OSStatus:status]] error:nil]; return nil; } NSString*group = diff --git a/Sources/BranchSDK/BNCNetworkService.m b/Sources/BranchSDK/BNCNetworkService.m index ea3ee4d16..58d65035d 100644 --- a/Sources/BranchSDK/BNCNetworkService.m +++ b/Sources/BranchSDK/BNCNetworkService.m @@ -197,13 +197,14 @@ - (void) startOperation:(BNCNetworkOperation*)operation { [[NSDate date] timeIntervalSinceDate:operation.startDate], (long)operation.response.statusCode, operation.error, - operation.stringFromResponseData]]; + operation.stringFromResponseData] error:nil]; } - if (operation.completionBlock) + if (operation.completionBlock) { operation.completionBlock(operation); + } }]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Network start operation %@.", operation.request.URL]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Network start operation %@.", operation.request.URL] error:nil]; [operation.sessionTask resume]; } diff --git a/Sources/BranchSDK/BNCPartnerParameters.m b/Sources/BranchSDK/BNCPartnerParameters.m index 828edc1dc..c8642e488 100644 --- a/Sources/BranchSDK/BNCPartnerParameters.m +++ b/Sources/BranchSDK/BNCPartnerParameters.m @@ -54,7 +54,7 @@ - (void)addFacebookParameterWithName:(NSString *)name value:(NSString *)value { if ([self sha256HashSanityCheckValue:value]) { [self addParameterWithName:name value:value partnerName:@"fb"]; } else { - [[BranchLogger shared] logWarning:@"Partner parameter does not appear to be SHA256 hashed. Dropping the parameter."]; + [[BranchLogger shared] logWarning:@"Partner parameter does not appear to be SHA256 hashed. Dropping the parameter." error:nil]; } } @@ -62,7 +62,7 @@ - (void)addSnapParameterWithName:(NSString *)name value:(NSString *)value { if ([self sha256HashSanityCheckValue:value]) { [self addParameterWithName:name value:value partnerName:@"snap"]; } else { - [[BranchLogger shared] logWarning:@"Partner parameter does not appear to be SHA256 hashed. Dropping the parameter."]; + [[BranchLogger shared] logWarning:@"Partner parameter does not appear to be SHA256 hashed. Dropping the parameter." error:nil]; } } diff --git a/Sources/BranchSDK/BNCPreferenceHelper.m b/Sources/BranchSDK/BNCPreferenceHelper.m index cee6cbbb4..5463c98f7 100644 --- a/Sources/BranchSDK/BNCPreferenceHelper.m +++ b/Sources/BranchSDK/BNCPreferenceHelper.m @@ -168,7 +168,7 @@ - (void)setPatternListURL:(NSString *)url { [self writeObjectToDefaults:BRANCH_PREFS_KEY_PATTERN_LIST_URL value:url]; } } else { - [[BranchLogger shared] logWarning:@"Ignoring invalid custom CDN URL"]; + [[BranchLogger shared] logWarning:@"Ignoring invalid custom CDN URL" error:nil]; } } @@ -923,7 +923,7 @@ - (void)persistPrefsToDisk { NSError *error = nil; [data writeToURL:prefsURL options:NSDataWritingAtomic error:&error]; if (error) { - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Failed to persist preferences: %@.", error]]; + [[BranchLogger shared] logWarning:@"Failed to persist preferences" error:error]; } }]; [_persistPrefsQueue addOperation:newPersistOp]; @@ -938,7 +938,7 @@ - (NSData *)serializePrefDict:(NSMutableDictionary *)dict { @try { data = [NSKeyedArchiver archivedDataWithRootObject:dict requiringSecureCoding:YES error:NULL]; } @catch (id exception) { - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Exception serializing preferences dict: %@.", exception]]; + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Exception serializing preferences dict: %@.", exception] error:nil]; } return data; } @@ -969,10 +969,10 @@ - (NSData *)loadPrefData { NSError *error = nil; data = [NSData dataWithContentsOfURL:self.class.URLForPrefsFile options:0 error:&error]; if (error || !data) { - [[BranchLogger shared] logWarning:@"Failed to load preferences from storage."]; + [[BranchLogger shared] logWarning:@"Failed to load preferences from storage." error:error]; } } @catch (NSException *) { - [[BranchLogger shared] logWarning:@"Failed to load preferences from storage."]; + [[BranchLogger shared] logWarning:@"Failed to load preferences from storage." error:nil]; } return data; } @@ -985,7 +985,7 @@ - (NSMutableDictionary *)deserializePrefDictFromData:(NSData *)data { dict = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:data error:&error]; if (error) { - [[BranchLogger shared] logWarning:@"Failed to load preferences from storage."]; + [[BranchLogger shared] logWarning:@"Failed to load preferences from storage." error:error]; } } diff --git a/Sources/BranchSDK/BNCReferringURLUtility.m b/Sources/BranchSDK/BNCReferringURLUtility.m index c4a9c965a..ced3ec6e4 100644 --- a/Sources/BranchSDK/BNCReferringURLUtility.m +++ b/Sources/BranchSDK/BNCReferringURLUtility.m @@ -286,7 +286,7 @@ - (void)checkForAndMigrateOldGbraid { self.preferenceHelper.referrerGBRAIDValidityWindow = 0; self.preferenceHelper.referrerGBRAIDInitDate = nil; - [[BranchLogger shared] logDebug:@"Updated old Gbraid to new BNCUrlQueryParameter"]; + [[BranchLogger shared] logDebug:@"Updated old Gbraid to new BNCUrlQueryParameter" error:nil]; } } diff --git a/Sources/BranchSDK/BNCSKAdNetwork.m b/Sources/BranchSDK/BNCSKAdNetwork.m index 71ff70b93..e1de4b436 100644 --- a/Sources/BranchSDK/BNCSKAdNetwork.m +++ b/Sources/BranchSDK/BNCSKAdNetwork.m @@ -73,7 +73,7 @@ - (BOOL)shouldAttemptSKAdNetworkCallout { - (void)registerAppForAdNetworkAttribution { if (@available(iOS 14.0, macCatalyst 14.0, *)) { if ([self shouldAttemptSKAdNetworkCallout] && [self.skAdNetworkClass respondsToSelector:self.skAdNetworkRegisterAppForAdNetworkAttribution]) { - [[BranchLogger shared] logDebug:@"Calling registerAppForAdNetworkAttribution"]; + [[BranchLogger shared] logDebug:@"Calling registerAppForAdNetworkAttribution" error:nil]; // Equivalent call [SKAdNetwork registerAppForAdNetworkAttribution]; ((id (*)(id, SEL))[self.skAdNetworkClass methodForSelector:self.skAdNetworkRegisterAppForAdNetworkAttribution])(self.skAdNetworkClass, self.skAdNetworkRegisterAppForAdNetworkAttribution); } @@ -83,7 +83,7 @@ - (void)registerAppForAdNetworkAttribution { - (void)updateConversionValue:(NSInteger)conversionValue { if (@available(iOS 14.0, macCatalyst 14.0, *)) { if ([self shouldAttemptSKAdNetworkCallout] && [self.skAdNetworkClass respondsToSelector:self.skAdNetworkUpdateConversionValue]) { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Calling updateConversionValue:%ld", (long)conversionValue]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Calling updateConversionValue:%ld", (long)conversionValue] error:nil]; // Equivalent call [SKAdNetwork updateConversionValue:conversionValue]; ((id (*)(id, SEL, NSInteger))[self.skAdNetworkClass methodForSelector:self.skAdNetworkUpdateConversionValue])(self.skAdNetworkClass, self.skAdNetworkUpdateConversionValue, conversionValue); @@ -94,7 +94,7 @@ - (void)updateConversionValue:(NSInteger)conversionValue { - (void)updatePostbackConversionValue:(NSInteger)conversionValue completionHandler:(void (^)(NSError *error))completion { if (@available(iOS 15.4, macCatalyst 15.4, *)) { if ([self shouldAttemptSKAdNetworkCallout] && [self.skAdNetworkClass respondsToSelector:self.skAdNetworkUpdatePostbackConversionValue]) { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Calling updatePostbackConversionValue:%ld completionHandler:completion", (long)conversionValue]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Calling updatePostbackConversionValue:%ld completionHandler:completion", (long)conversionValue] error:nil]; // Equivalent call [SKAdNetwork updatePostbackConversionValue:completionHandler:]; ((id (*)(id, SEL, NSInteger,void (^)(NSError *error)))[self.skAdNetworkClass methodForSelector:self.skAdNetworkUpdatePostbackConversionValue])(self.skAdNetworkClass, self.skAdNetworkUpdatePostbackConversionValue, conversionValue, completion); @@ -109,7 +109,7 @@ - (void)updatePostbackConversionValue:(NSInteger)fineValue completionHandler:(void (^)(NSError *error))completion { if (@available(iOS 16.1, macCatalyst 16.1, *)) { if ([self shouldAttemptSKAdNetworkCallout] && [self.skAdNetworkClass respondsToSelector:self.skAdNetworkUpdatePostbackConversionValueCoarseValueLockWindow]) { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Calling updatePostbackConversionValue:%ld coarseValue:%@ lockWindow:%d completionHandler:completion", (long)fineValue, coarseValue, lockWindow]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Calling updatePostbackConversionValue:%ld coarseValue:%@ lockWindow:%d completionHandler:completion", (long)fineValue, coarseValue, lockWindow] error:nil]; // Equivalent call [SKAdNetwork updatePostbackConversionValue:coarseValue:lockWindow:completionHandler:]; ((id (*)(id, SEL, NSInteger, NSString *, BOOL, void (^)(NSError *error)))[self.skAdNetworkClass methodForSelector:self.skAdNetworkUpdatePostbackConversionValueCoarseValueLockWindow])(self.skAdNetworkClass, self.skAdNetworkUpdatePostbackConversionValueCoarseValueLockWindow, fineValue, coarseValue, lockWindow, completion); } diff --git a/Sources/BranchSDK/BNCServerInterface.m b/Sources/BranchSDK/BNCServerInterface.m index 030a993bf..bf6a405bd 100644 --- a/Sources/BranchSDK/BNCServerInterface.m +++ b/Sources/BranchSDK/BNCServerInterface.m @@ -118,7 +118,7 @@ - (void)genericHTTPRequest:(NSURLRequest *)request retryNumber:(NSInteger)retryN dispatch_time(DISPATCH_TIME_NOW, self.preferenceHelper.retryInterval * NSEC_PER_SEC); dispatch_after(dispatchTime, dispatch_get_main_queue(), ^{ if (retryHandler) { - [[BranchLogger shared] logDebug: [NSString stringWithFormat:@"Retrying request with url %@", request.URL.relativePath]]; + [[BranchLogger shared] logDebug: [NSString stringWithFormat:@"Retrying request with url %@", request.URL.relativePath] error:nil]; // Create the next request NSURLRequest *retryRequest = retryHandler(retryNumber); [self genericHTTPRequest:retryRequest @@ -170,7 +170,7 @@ - (void)genericHTTPRequest:(NSURLRequest *)request retryNumber:(NSInteger)retryN if (![self isLinkingRelatedRequest:endpoint]) { [[BNCPreferenceHelper sharedInstance] clearTrackingInformation]; NSError *error = [NSError branchErrorWithCode:BNCTrackingDisabledError]; - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Dropping Request %@: - %@", endpoint, error]]; + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Dropping Request %@: - %@", endpoint, error] error:nil]; if (callback) { callback(nil, error); } @@ -278,7 +278,7 @@ - (NSURLRequest *)prepareGetRequest:(NSDictionary *)params url:(NSString *)url k NSDictionary *tmp = [self addRetryCount:retryNumber toJSON:params]; NSString *requestUrlString = [NSString stringWithFormat:@"%@%@", url, [BNCEncodingUtils encodeDictionaryToQueryString:tmp]]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"URL: %@", requestUrlString]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"URL: %@", requestUrlString] error:nil]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:requestUrlString] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:self.preferenceHelper.timeout]; @@ -295,10 +295,10 @@ - (NSURLRequest *)preparePostRequest:(NSDictionary *)params url:(NSString *)url NSData *postData = [BNCEncodingUtils encodeDictionaryToJsonData:tmp]; NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"URL: %@.\n", url]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"URL: %@.\n", url] error:nil]; [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Body: %@\nJSON: %@.", params, - [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding]]]; + [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding]] error:nil]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] @@ -328,7 +328,7 @@ - (BNCServerResponse *)processServerResponse:(NSURLResponse *)response data:(NSD serverResponse.requestId = requestId; } - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Server returned: %@.", serverResponse]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Server returned: %@.", serverResponse] error:nil]; return serverResponse; } diff --git a/Sources/BranchSDK/BNCServerRequestQueue.m b/Sources/BranchSDK/BNCServerRequestQueue.m index 534946775..f90f0924b 100755 --- a/Sources/BranchSDK/BNCServerRequestQueue.m +++ b/Sources/BranchSDK/BNCServerRequestQueue.m @@ -267,7 +267,7 @@ - (NSData *)archiveObject:(NSObject *)object { data = [NSKeyedArchiver archivedDataWithRootObject:object requiringSecureCoding:YES error:&error]; if (!data && error) { - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Failed to archive: %@", error]]; + [[BranchLogger shared] logWarning:@"Failed to archive: %@" error:error]; } return data; } @@ -317,7 +317,7 @@ - (id)unarchiveObjectFromData:(NSData *)data { id object = [NSKeyedUnarchiver unarchivedObjectOfClasses:[BNCServerRequestQueue encodableClasses] fromData:data error:&error]; if (error) { - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Failed to unarchive: %@", error]]; + [[BranchLogger shared] logWarning:@"Failed to unarchive: %@" error:error]; } return object; @@ -373,7 +373,7 @@ + (instancetype)getInstance { dispatch_once(&onceToken, ^ { sharedQueue = [[BNCServerRequestQueue alloc] init]; [sharedQueue retrieve]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Retrieved from storage: %@.", sharedQueue]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Retrieved from storage: %@.", sharedQueue] error:nil]; }); return sharedQueue; } diff --git a/Sources/BranchSDK/BNCSystemObserver.m b/Sources/BranchSDK/BNCSystemObserver.m index 9944bb409..b9bde203f 100644 --- a/Sources/BranchSDK/BNCSystemObserver.m +++ b/Sources/BranchSDK/BNCSystemObserver.m @@ -54,7 +54,7 @@ + (NSString *)appleAttributionToken { // Apple said this API should respond within 50ms, lets give up after 500 ms dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(500 * NSEC_PER_MSEC))); if (token == nil) { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"AppleAttributionToken request timed out"]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"AppleAttributionToken request timed out"] error:nil]; } } #endif diff --git a/Sources/BranchSDK/BNCURLFilter.m b/Sources/BranchSDK/BNCURLFilter.m index 367ba2ae3..765c5cb2e 100644 --- a/Sources/BranchSDK/BNCURLFilter.m +++ b/Sources/BranchSDK/BNCURLFilter.m @@ -127,12 +127,12 @@ - (BOOL)foundUpdatedURLList:(id)operation { } if (statusCode == 404) { - [[BranchLogger shared] logDebug: [NSString stringWithFormat:@"No update for URL ignore list found."]]; + [[BranchLogger shared] logDebug:@"No update for URL ignore list found." error:nil]; return NO; } else if (statusCode != 200 || error != nil || jsonString == nil) { [[BranchLogger shared] logError:[NSString stringWithFormat:@"Failed to update URL ignore list. error: %@ status: %ld", operation.error, (long)operation.response.statusCode] error:operation.error]; - [[BranchLogger shared] logDebug: [NSString stringWithFormat:@"URL ignore JSON: %@", jsonString]]; + [[BranchLogger shared] logDebug: [NSString stringWithFormat:@"URL ignore JSON: %@", jsonString] error:nil]; return NO; diff --git a/Sources/BranchSDK/Branch.m b/Sources/BranchSDK/Branch.m index 984fbb40d..dd67ddd3b 100644 --- a/Sources/BranchSDK/Branch.m +++ b/Sources/BranchSDK/Branch.m @@ -366,7 +366,7 @@ + (void)setBranchKey:(NSString*)branchKey error:(NSError **)error { if ([branchKey hasPrefix:@"key_test"]) { bnc_useTestBranchKey = YES; - [[BranchLogger shared] logWarning: @"You are using your test app's Branch Key. Remember to change it to live Branch Key for production deployment."]; + [[BranchLogger shared] logWarning: @"You are using your test app's Branch Key. Remember to change it to live Branch Key for production deployment." error:nil]; } else if ([branchKey hasPrefix:@"key_live"]) { bnc_useTestBranchKey = NO; @@ -439,7 +439,7 @@ + (void)setAPIUrl:(NSString *)url { if ([url hasPrefix:@"http://"] || [url hasPrefix:@"https://"] ){ [BNCServerAPI sharedInstance].customAPIURL = url; } else { - [[BranchLogger shared] logWarning:(@"Ignoring invalid custom API URL")]; + [[BranchLogger shared] logWarning:@"Ignoring invalid custom API URL" error:nil]; } } @@ -917,7 +917,7 @@ - (void)handleATTAuthorizationStatus:(NSUInteger)status { - (void)setSKAdNetworkCalloutMaxTimeSinceInstall:(NSTimeInterval)maxTimeInterval { if (@available(iOS 16.1, macCatalyst 16.1, *)) { - [[BranchLogger shared] logDebug:@"This is no longer supported for iOS 16.1+ - SKAN4.0"]; + [[BranchLogger shared] logDebug:@"This is no longer supported for iOS 16.1+ - SKAN4.0" error:nil]; } else { [BNCSKAdNetwork sharedInstance].maxTimeSinceInstall = maxTimeInterval; } @@ -1425,7 +1425,7 @@ + (Branch *)getInstanceInternal:(NSString *)key { // If there was stored key and it isn't the same as the currently used (or doesn't exist), we need to clean up // Note: Link Click Identifier is not cleared because of the potential for that to mess up a deep link if (preferenceHelper.lastRunBranchKey && ![key isEqualToString:preferenceHelper.lastRunBranchKey]) { - [[BranchLogger shared] logWarning:@"The Branch Key has changed, clearing relevant items."]; + [[BranchLogger shared] logWarning:@"The Branch Key has changed, clearing relevant items." error:nil]; preferenceHelper.appVersion = nil; preferenceHelper.randomizedDeviceToken = nil; preferenceHelper.sessionID = nil; @@ -1554,7 +1554,7 @@ - (NSString *)generateShortUrl:(NSArray *)tags linkData:linkData linkCache:self.linkCache]; - [[BranchLogger shared] logDebug:@"Creating a custom URL synchronously."]; + [[BranchLogger shared] logDebug:@"Creating a custom URL synchronously." error:nil]; BNCServerResponse *serverResponse = [req makeRequest:self.serverInterface key:self.class.branchKey]; shortURL = [req processResponse:serverResponse]; @@ -1772,7 +1772,7 @@ - (void) processRequest:(BNCServerRequest*)req } // On network problems, or Branch down, call the other callbacks and stop processing. else { - [[BranchLogger shared] logDebug:@"Network error: failing queued requests."]; + [[BranchLogger shared] logDebug:@"Network error: failing queued requests." error:nil]; // First, gather all the requests to fail NSMutableArray *requestsToFail = [[NSMutableArray alloc] init]; for (int i = 0; i < self.requestQueue.queueDepth; i++) { @@ -1915,7 +1915,7 @@ - (void)notifyNativeToInit { // Some methods require init before they are called. Instead of returning an error, we try to fix the situation by calling init ourselves. - (void)initSafetyCheck { if (self.initializationStatus == BNCInitStatusUninitialized) { - [[BranchLogger shared] logDebug:@"Branch avoided an error by preemptively initializing."]; + [[BranchLogger shared] logDebug:@"Branch avoided an error by preemptively initializing." error:nil]; [self initUserSessionAndCallCallback:NO sceneIdentifier:nil urlString:nil]; } } @@ -1925,7 +1925,7 @@ - (void)initUserSessionAndCallCallback:(BOOL)callCallback sceneIdentifier:(NSStr // ignore lifecycle calls while waiting for a plugin runtime. @synchronized (self) { if (self.deferInitForPluginRuntime) { - [[BranchLogger shared] logDebug:@"Branch init is deferred, ignoring init call."]; + [[BranchLogger shared] logDebug:@"Branch init is deferred, ignoring init call." error:nil]; return; } } @@ -1998,7 +1998,7 @@ - (void)initializeSessionAndCallCallback:(BOOL)callCallback sceneIdentifier:(NSS [self.requestQueue insert:req at:0]; NSString *message = [NSString stringWithFormat:@"request %@ callback %@ link %@", req, req.callback, req.urlString]; - [[BranchLogger shared] logDebug:message]; + [[BranchLogger shared] logDebug:message error:nil]; } else { @@ -2011,9 +2011,9 @@ - (void)initializeSessionAndCallCallback:(BOOL)callCallback sceneIdentifier:(NSS // put it behind the one that's already on queue [self.requestQueue insert:req at:1]; - [[BranchLogger shared] logDebug:@"Link resolution request"]; + [[BranchLogger shared] logDebug:@"Link resolution request" error:nil]; NSString *message = [NSString stringWithFormat:@"request %@ callback %@ link %@", req, req.callback, req.urlString]; - [[BranchLogger shared] logDebug:message]; + [[BranchLogger shared] logDebug:message error:nil]; } } @@ -2082,7 +2082,7 @@ - (void)automaticallyDeeplinkWithReferringParams:(NSDictionary *)latestReferring [branchSharingController configureControlWithData:latestReferringParams]; } else { - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"The automatic deeplink view controller '%@' for key '%@' does not implement 'configureControlWithData:'.", branchSharingController, key]]; + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"The automatic deeplink view controller '%@' for key '%@' does not implement 'configureControlWithData:'.", branchSharingController, key] error:nil]; } self.deepLinkPresentingController = [UIViewController bnc_currentViewController]; @@ -2094,7 +2094,7 @@ - (void)automaticallyDeeplinkWithReferringParams:(NSDictionary *)latestReferring [branchSharingController configureControlWithData:latestReferringParams]; } else { - [[BranchLogger shared] logWarning:@"View controller does not implement configureControlWithData:"]; + [[BranchLogger shared] logWarning:@"View controller does not implement configureControlWithData:" error:nil]; } branchSharingController.deepLinkingCompletionDelegate = self; switch (deepLinkInstance.option) { @@ -2156,7 +2156,7 @@ - (void)automaticallyDeeplinkWithReferringParams:(NSDictionary *)latestReferring [branchSharingController configureControlWithData:latestReferringParams]; } else { - [[BranchLogger shared] logWarning:@"View controller does not implement configureControlWithData:"]; + [[BranchLogger shared] logWarning:@"View controller does not implement configureControlWithData:" error:nil]; } branchSharingController.deepLinkingCompletionDelegate = self; if ([self.deepLinkPresentingController presentedViewController]) { diff --git a/Sources/BranchSDK/BranchCSSearchableItemAttributeSet.m b/Sources/BranchSDK/BranchCSSearchableItemAttributeSet.m index 0465b81f7..b5b94844b 100644 --- a/Sources/BranchSDK/BranchCSSearchableItemAttributeSet.m +++ b/Sources/BranchSDK/BranchCSSearchableItemAttributeSet.m @@ -45,7 +45,7 @@ - (instancetype)initWithItemContentType:(nonnull NSString *)type { - (void)setIdentifier:(NSString *)identifier { if (![identifier hasPrefix:BRANCH_SPOTLIGHT_PREFIX]) { - [[BranchLogger shared] logWarning:@"Do not set BranchCSSearchableItemAttributeSet's identifier. It will be overwritten."]; + [[BranchLogger shared] logWarning:@"Do not set BranchCSSearchableItemAttributeSet's identifier. It will be overwritten." error:nil]; } } diff --git a/Sources/BranchSDK/BranchEvent.m b/Sources/BranchSDK/BranchEvent.m index 392cc9952..81f46abd4 100644 --- a/Sources/BranchSDK/BranchEvent.m +++ b/Sources/BranchSDK/BranchEvent.m @@ -97,13 +97,13 @@ - (void)processResponse:(BNCServerResponse*)response error:(NSError*)error { BOOL lockWin = [[BNCSKAdNetwork sharedInstance] getLockedStatusFromDataResponse:dictionary]; BOOL shouldCallUpdatePostback = [[BNCSKAdNetwork sharedInstance] shouldCallPostbackForDataResponse:dictionary]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"SKAN 4.0 params - conversionValue:%@ coarseValue:%@, locked:%d, shouldCallPostback:%d, currentWindow:%d, firstAppLaunchTime: %@", conversionValue, coarseConversionValue, lockWin, shouldCallUpdatePostback, (int)[BNCPreferenceHelper sharedInstance].skanCurrentWindow, [BNCPreferenceHelper sharedInstance].firstAppLaunchTime]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"SKAN 4.0 params - conversionValue:%@ coarseValue:%@, locked:%d, shouldCallPostback:%d, currentWindow:%d, firstAppLaunchTime: %@", conversionValue, coarseConversionValue, lockWin, shouldCallUpdatePostback, (int)[BNCPreferenceHelper sharedInstance].skanCurrentWindow, [BNCPreferenceHelper sharedInstance].firstAppLaunchTime] error:nil]; if(shouldCallUpdatePostback){ [[BNCSKAdNetwork sharedInstance] updatePostbackConversionValue: conversionValue.longValue coarseValue:coarseConversionValue lockWindow:lockWin completionHandler:^(NSError * _Nullable error) { if (error) { [[BranchLogger shared] logError:[NSString stringWithFormat:@"Update conversion value failed with error - %@", [error description]] error:error]; } else { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Update conversion value was successful. Conversion Value - %@", conversionValue]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Update conversion value was successful. Conversion Value - %@", conversionValue] error:nil]; } }]; } @@ -113,7 +113,7 @@ - (void)processResponse:(BNCServerResponse*)response error:(NSError*)error { if (error) { [[BranchLogger shared] logError:[NSString stringWithFormat:@"Update conversion value failed with error - %@", [error description]] error:error]; } else { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Update conversion value was successful. Conversion Value - %@", conversionValue]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Update conversion value was successful. Conversion Value - %@", conversionValue] error:nil]; } }]; } else { @@ -449,7 +449,7 @@ - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProdu } [self logEvent]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Created and logged event from transaction: %@", self.description]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Created and logged event from transaction: %@", self.description] error:nil]; } else { [[BranchLogger shared] logError:[NSString stringWithFormat:@"Unable to log Branch event from transaction. No products were found with the product ID."] error:nil]; } diff --git a/Sources/BranchSDK/BranchJsonConfig.m b/Sources/BranchSDK/BranchJsonConfig.m index aa3bbb077..9d5366e69 100644 --- a/Sources/BranchSDK/BranchJsonConfig.m +++ b/Sources/BranchSDK/BranchJsonConfig.m @@ -72,7 +72,7 @@ - (void)loadConfigFile - (NSData *)configFileContents { if (!self.configFileURL) return nil; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Loading %@", self.configFileURL.pathComponents.lastObject]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Loading %@", self.configFileURL.pathComponents.lastObject] error:nil]; NSError *error; NSData *data = [NSData dataWithContentsOfURL:self.configFileURL options:0 error:&error]; if (!data || error) { @@ -109,7 +109,7 @@ - (void)findConfigFile } if (!configFileURL) { - [[BranchLogger shared] logDebug:@"No branch.json in app bundle."]; + [[BranchLogger shared] logDebug:@"No branch.json in app bundle." error:nil]; return; } diff --git a/Sources/BranchSDK/BranchLastAttributedTouchData.m b/Sources/BranchSDK/BranchLastAttributedTouchData.m index 99316a32d..dd7538c8e 100644 --- a/Sources/BranchSDK/BranchLastAttributedTouchData.m +++ b/Sources/BranchSDK/BranchLastAttributedTouchData.m @@ -33,7 +33,7 @@ + (void)requestLastTouchAttributedData:(BNCServerInterface *)serverInterface key if (window > -1 && window < 365) { request.attributionWindow = window; } else { - [[BranchLogger shared] logWarning:@"Attribution window is outside the expected range, using 30 days."]; + [[BranchLogger shared] logWarning:@"Attribution window is outside the expected range, using 30 days." error:nil]; } [request makeRequest:serverInterface key:key callback:^(BNCServerResponse *response, NSError *error) { diff --git a/Sources/BranchSDK/BranchLogger.m b/Sources/BranchSDK/BranchLogger.m index e85a16fad..2a1feb70f 100644 --- a/Sources/BranchSDK/BranchLogger.m +++ b/Sources/BranchSDK/BranchLogger.m @@ -40,20 +40,16 @@ - (void)logError:(NSString *)message error:(NSError *_Nullable)error { [self logMessage:message withLevel:BranchLogLevelError error:error]; } -- (void)logWarning:(NSString *)message { - [self logMessage:message withLevel:BranchLogLevelWarning error:nil]; +- (void)logWarning:(NSString *)message error:(NSError *_Nullable)error { + [self logMessage:message withLevel:BranchLogLevelWarning error:error]; } -- (void)logInfo:(NSString *)message { - [self logMessage:message withLevel:BranchLogLevelInfo error:nil]; +- (void)logDebug:(NSString *)message error:(NSError *_Nullable)error { + [self logMessage:message withLevel:BranchLogLevelDebug error:error]; } -- (void)logDebug:(NSString *)message { - [self logMessage:message withLevel:BranchLogLevelDebug error:nil]; -} - -- (void)logVerbose:(NSString *)message { - [self logMessage:message withLevel:BranchLogLevelVerbose error:nil]; +- (void)logVerbose:(NSString *)message error:(NSError *_Nullable)error { + [self logMessage:message withLevel:BranchLogLevelVerbose error:error]; } - (void)logMessage:(NSString *)message withLevel:(BranchLogLevel)level error:(NSError *_Nullable)error { @@ -79,14 +75,14 @@ - (void)logMessage:(NSString *)message withLevel:(BranchLogLevel)level error:(NS } } -//MARK: Helper Methods +// Map the Branch log level to a similar Apple log level - (os_log_type_t)osLogTypeForBranchLogLevel:(BranchLogLevel)level { switch (level) { - case BranchLogLevelError: return OS_LOG_TYPE_FAULT; - case BranchLogLevelWarning: return OS_LOG_TYPE_ERROR; - case BranchLogLevelInfo: return OS_LOG_TYPE_INFO; - case BranchLogLevelDebug: return OS_LOG_TYPE_DEBUG; - case BranchLogLevelVerbose: return OS_LOG_TYPE_DEFAULT; + // TODO: confirm these mappings make sense + case BranchLogLevelError: return OS_LOG_TYPE_ERROR; // "report process-level errors" + case BranchLogLevelWarning: return OS_LOG_TYPE_DEFAULT; // "things that might result in a failure" + case BranchLogLevelDebug: return OS_LOG_TYPE_INFO; // "helpful, but not essential, for troubleshooting errors" + case BranchLogLevelVerbose: return OS_LOG_TYPE_DEBUG; // "useful during development or while troubleshooting a specific problem" default: return OS_LOG_TYPE_DEFAULT; } } @@ -95,7 +91,6 @@ - (NSString *)stringForLogLevel:(BranchLogLevel)level { switch (level) { case BranchLogLevelVerbose: return @"Verbose"; case BranchLogLevelDebug: return @"Debug"; - case BranchLogLevelInfo: return @"Info"; case BranchLogLevelWarning: return @"Warning"; case BranchLogLevelError: return @"Error"; default: return @"Unknown"; diff --git a/Sources/BranchSDK/BranchOpenRequest.m b/Sources/BranchSDK/BranchOpenRequest.m index d7c23af8e..104cb09d5 100644 --- a/Sources/BranchSDK/BranchOpenRequest.m +++ b/Sources/BranchSDK/BranchOpenRequest.m @@ -102,11 +102,11 @@ - (void)processResponse:(BNCServerResponse *)response error:(NSError *)error { if (sessionData == nil || [sessionData isKindOfClass:[NSString class]]) { } else if ([sessionData isKindOfClass:[NSDictionary class]]) { - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Received session data of type '%@' data is '%@'.", NSStringFromClass(sessionData.class), sessionData]]; + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Received session data of type '%@' data is '%@'.", NSStringFromClass(sessionData.class), sessionData] error:nil]; sessionData = [BNCEncodingUtils encodeDictionaryToJsonString:(NSDictionary*)sessionData]; } else if ([sessionData isKindOfClass:[NSArray class]]) { - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Received session data of type '%@' data is '%@'.", NSStringFromClass(sessionData.class), sessionData]]; + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Received session data of type '%@' data is '%@'.", NSStringFromClass(sessionData.class), sessionData] error:nil]; sessionData = [BNCEncodingUtils encodeArrayToJsonString:(NSArray*)sessionData]; } else { [[BranchLogger shared] logError:[NSString stringWithFormat:@"Received session data of type '%@' data is '%@'.", NSStringFromClass(sessionData.class), sessionData] error:error]; @@ -188,7 +188,7 @@ - (void)processResponse:(BNCServerResponse *)response error:(NSError *)error { if (error) { [[BranchLogger shared] logError:[NSString stringWithFormat:@"Update conversion value failed with error - %@", [error description]] error:error]; } else { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Update conversion value was successful for INSTALL Event"]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Update conversion value was successful for INSTALL Event"] error:nil]; } }]; } else if (@available(iOS 15.4, macCatalyst 15.4, *)){ @@ -196,7 +196,7 @@ - (void)processResponse:(BNCServerResponse *)response error:(NSError *)error { if (error) { [[BranchLogger shared] logError:[NSString stringWithFormat:@"Update conversion value failed with error - %@", [error description]] error:error]; } else { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Update conversion value was successful for INSTALL Event"]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Update conversion value was successful for INSTALL Event"] error:nil]; } }]; } @@ -218,14 +218,14 @@ - (void)processResponse:(BNCServerResponse *)response error:(NSError *)error { BOOL lockWin = [[BNCSKAdNetwork sharedInstance] getLockedStatusFromDataResponse:data]; BOOL shouldCallUpdatePostback = [[BNCSKAdNetwork sharedInstance] shouldCallPostbackForDataResponse:data]; - [[BranchLogger shared] logDebug: [NSString stringWithFormat:@"SKAN 4.0 params - conversionValue:%@ coarseValue:%@, locked:%d, shouldCallPostback:%d, currentWindow:%d, firstAppLaunchTime: %@", conversionValue, coarseConversionValue, lockWin, shouldCallUpdatePostback, (int)preferenceHelper.skanCurrentWindow, preferenceHelper.firstAppLaunchTime]]; + [[BranchLogger shared] logDebug: [NSString stringWithFormat:@"SKAN 4.0 params - conversionValue:%@ coarseValue:%@, locked:%d, shouldCallPostback:%d, currentWindow:%d, firstAppLaunchTime: %@", conversionValue, coarseConversionValue, lockWin, shouldCallUpdatePostback, (int)preferenceHelper.skanCurrentWindow, preferenceHelper.firstAppLaunchTime] error:nil]; if(shouldCallUpdatePostback){ [[BNCSKAdNetwork sharedInstance] updatePostbackConversionValue: conversionValue.longValue coarseValue:coarseConversionValue lockWindow:lockWin completionHandler:^(NSError * _Nullable error) { if (error) { [[BranchLogger shared] logError:[NSString stringWithFormat:@"Update conversion value failed with error - %@", [error description]] error:error]; } else { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Update conversion value was successful. Conversion Value - %@", conversionValue]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Update conversion value was successful. Conversion Value - %@", conversionValue] error:nil]; } }]; } @@ -234,7 +234,7 @@ - (void)processResponse:(BNCServerResponse *)response error:(NSError *)error { if (error) { [[BranchLogger shared] logError:[NSString stringWithFormat:@"Update conversion value failed with error - %@", [error description]] error:error]; } else { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Update conversion value was successful. Conversion Value - %@", conversionValue]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Update conversion value was successful. Conversion Value - %@", conversionValue] error:nil]; } }]; } else { @@ -277,7 +277,7 @@ + (void) initialize { + (void) setWaitNeededForOpenResponseLock { @synchronized (self) { if (!openRequestWaitQueueIsSuspended) { - [[BranchLogger shared] logDebug:@"Suspended for openRequestWaitQueue."]; + [[BranchLogger shared] logDebug:@"Suspended for openRequestWaitQueue." error:nil]; openRequestWaitQueueIsSuspended = YES; dispatch_suspend(openRequestWaitQueue); } @@ -285,16 +285,16 @@ + (void) setWaitNeededForOpenResponseLock { } + (void) waitForOpenResponseLock { - [[BranchLogger shared] logDebug:@"Waiting for openRequestWaitQueue."]; + [[BranchLogger shared] logDebug:@"Waiting for openRequestWaitQueue." error:nil]; dispatch_sync(openRequestWaitQueue, ^ { - [[BranchLogger shared] logDebug:@"Finished waitForOpenResponseLock."]; + [[BranchLogger shared] logDebug:@"Finished waitForOpenResponseLock." error:nil]; }); } + (void) releaseOpenResponseLock { @synchronized (self) { if (openRequestWaitQueueIsSuspended) { - [[BranchLogger shared] logDebug:@"Resuming openRequestWaitQueue."]; + [[BranchLogger shared] logDebug:@"Resuming openRequestWaitQueue." error:nil]; openRequestWaitQueueIsSuspended = NO; dispatch_resume(openRequestWaitQueue); } diff --git a/Sources/BranchSDK/BranchQRCode.m b/Sources/BranchSDK/BranchQRCode.m index 1e55e35e4..190ef4675 100644 --- a/Sources/BranchSDK/BranchQRCode.m +++ b/Sources/BranchSDK/BranchQRCode.m @@ -35,11 +35,11 @@ - (instancetype) init { - (void) setMargin:(NSNumber *)margin { if (margin.intValue > 20) { margin = @(20); - [[BranchLogger shared] logWarning:@"QR code margin was reduced to the maximum of 20."]; + [[BranchLogger shared] logWarning:@"QR code margin was reduced to the maximum of 20." error:nil]; } if (margin.intValue < 1) { margin = @(1); - [[BranchLogger shared] logWarning:@"QR code margin was increased to the minimum of 1."]; + [[BranchLogger shared] logWarning:@"QR code margin was increased to the minimum of 1." error:nil]; } _margin = margin; } @@ -47,11 +47,11 @@ - (void) setMargin:(NSNumber *)margin { - (void) setWidth:(NSNumber *)width { if (width.intValue > 2000) { width = @(2000); - [[BranchLogger shared] logWarning:@"QR code width was reduced to the maximum of 2000."]; + [[BranchLogger shared] logWarning:@"QR code width was reduced to the maximum of 2000." error:nil]; } if (width.intValue < 300) { width = @(300); - [[BranchLogger shared] logWarning:@"QR code width was increased to the minimum of 500."]; + [[BranchLogger shared] logWarning:@"QR code width was increased to the minimum of 500." error:nil]; } _width = width; } @@ -73,7 +73,7 @@ - (void)getQRCodeAsData:(nullable BranchUniversalObject *)buo NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString: self.centerLogo]]; UIImage *image=[UIImage imageWithData:data]; if (image == nil) { - [[BranchLogger shared] logWarning:@"QR code center logo was an invalid URL string."]; + [[BranchLogger shared] logWarning:@"QR code center logo was an invalid URL string." error:nil]; } else { settings[@"center_logo_url"] = self.centerLogo; } @@ -137,7 +137,7 @@ - (void)callQRCodeAPI:(nullable NSDictionary *)params NSData *postData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error]; [request setHTTPBody:postData]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Network start operation %@.", request.URL.absoluteString]]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Network start operation %@.", request.URL.absoluteString] error:nil]; NSDate *startDate = [NSDate date]; NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { @@ -155,7 +155,7 @@ - (void)callQRCodeAPI:(nullable NSDictionary *)params [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Network finish operation %@ %1.3fs. Status %ld.", request.URL.absoluteString, [[NSDate date] timeIntervalSinceDate:startDate], - (long)httpResponse.statusCode]]; + (long)httpResponse.statusCode] error:nil]; completion(data, nil); } else { diff --git a/Sources/BranchSDK/BranchScene.m b/Sources/BranchSDK/BranchScene.m index f6c8480b4..c436cdd4b 100644 --- a/Sources/BranchSDK/BranchScene.m +++ b/Sources/BranchSDK/BranchScene.m @@ -40,7 +40,7 @@ - (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivi - (void)scene:(UIScene *)scene openURLContexts:(NSSet *)URLContexts NS_EXTENSION_UNAVAILABLE("BranchScene does not support Extensions") { if (URLContexts.count != 1) { - [[BranchLogger shared] logWarning:@"Branch only supports a single URLContext"]; + [[BranchLogger shared] logWarning:@"Branch only supports a single URLContext" error:nil]; } UIOpenURLContext *context = [URLContexts allObjects].firstObject; diff --git a/Sources/BranchSDK/BranchShareLink.m b/Sources/BranchSDK/BranchShareLink.m index 2cd4b874b..1a24fd706 100644 --- a/Sources/BranchSDK/BranchShareLink.m +++ b/Sources/BranchSDK/BranchShareLink.m @@ -115,7 +115,7 @@ - (void) shareDidComplete:(BOOL)completed activityError:(NSError*)error { // Make sure we can share if (!(self.universalObject.canonicalIdentifier || self.universalObject.canonicalUrl || self.universalObject.title)) { - [[BranchLogger shared] logWarning:@"A canonicalIdentifier, canonicalURL, or title are required to uniquely identify content. In order to not break the end user experience with sharing, Branch SDK will proceed to create a URL, but content analytics may not properly include this URL."]; + [[BranchLogger shared] logWarning:@"A canonicalIdentifier, canonicalURL, or title are required to uniquely identify content. In order to not break the end user experience with sharing, Branch SDK will proceed to create a URL, but content analytics may not properly include this URL." error:nil]; } self.serverParameters = [[self.universalObject getParamsForServerRequestWithAddedLinkProperties:self.linkProperties] mutableCopy]; @@ -201,7 +201,7 @@ - (void) presentActivityViewControllerFromViewController:(UIViewController*_Null [shareViewController setValue:emailSubject forKey:@"subject"]; } @catch (NSException*) { - [[BranchLogger shared] logWarning: @"Unable to setValue 'emailSubject' forKey 'subject' on UIActivityViewController."]; + [[BranchLogger shared] logWarning: @"Unable to setValue 'emailSubject' forKey 'subject' on UIActivityViewController." error:nil]; } } diff --git a/Sources/BranchSDK/BranchShortUrlSyncRequest.m b/Sources/BranchSDK/BranchShortUrlSyncRequest.m index 8f026b8df..3cbf8da64 100644 --- a/Sources/BranchSDK/BranchShortUrlSyncRequest.m +++ b/Sources/BranchSDK/BranchShortUrlSyncRequest.m @@ -63,7 +63,7 @@ - (BNCServerResponse *)makeRequest:(BNCServerInterface *)serverInterface key:(NS - (NSString *)processResponse:(BNCServerResponse *)response { if (![response.statusCode isEqualToNumber:@200]) { [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Short link creation received HTTP status code %@. Using long link instead.", - response.statusCode]]; + response.statusCode] error:nil]; NSString *failedUrl = nil; NSString *userUrl = [BNCPreferenceHelper sharedInstance].userUrl; if (userUrl) { diff --git a/Sources/BranchSDK/BranchUniversalObject.m b/Sources/BranchSDK/BranchUniversalObject.m index a21348065..a8c805e89 100644 --- a/Sources/BranchSDK/BranchUniversalObject.m +++ b/Sources/BranchSDK/BranchUniversalObject.m @@ -331,7 +331,7 @@ - (void)registerViewWithCallback:(callbackWithParams)callback { if (!self.canonicalIdentifier && !self.title) { NSString *message = @"Could not register view."; NSError *error = [NSError branchErrorWithCode:BNCContentIdentifierError localizedMessage:message]; - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"%@", error]]; + [[BranchLogger shared] logWarning:@"TODO: replace this error" error:error]; if (callback) callback([[NSDictionary alloc] init], error); return; } @@ -350,7 +350,7 @@ - (void)registerViewWithCallback:(callbackWithParams)callback { - (NSString *)getShortUrlWithLinkProperties:(BranchLinkProperties *)linkProperties { if (!self.canonicalIdentifier && !self.title) { - [[BranchLogger shared] logWarning:@"A canonicalIdentifier or title are required to uniquely identify content, so could not generate a URL."]; + [[BranchLogger shared] logWarning:@"A canonicalIdentifier or title are required to uniquely identify content, so could not generate a URL." error:nil]; return nil; } @@ -369,7 +369,7 @@ - (void)getShortUrlWithLinkProperties:(BranchLinkProperties *)linkProperties and if (!self.canonicalIdentifier && !self.title) { NSString *message = @"Could not generate a URL."; NSError *error = [NSError branchErrorWithCode:BNCContentIdentifierError localizedMessage:message]; - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"%@", error]]; + [[BranchLogger shared] logWarning:@"TODO: replace this error" error:error]; if (callback) callback([BNCPreferenceHelper sharedInstance].userUrl, error); return; } @@ -389,7 +389,7 @@ - (NSString *)getShortUrlWithLinkPropertiesAndIgnoreFirstClick:(BranchLinkProper if (!self.canonicalIdentifier && !self.title) { NSString *message = @"Could not generate a URL."; NSError *error = [NSError branchErrorWithCode:BNCContentIdentifierError localizedMessage:message]; - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"%@", error]]; + [[BranchLogger shared] logWarning:@"TODO: replace this error" error:error]; return nil; } diff --git a/Sources/BranchSDK/Public/BranchLogger.h b/Sources/BranchSDK/Public/BranchLogger.h index 70c6e55b1..16a5f62d4 100644 --- a/Sources/BranchSDK/Public/BranchLogger.h +++ b/Sources/BranchSDK/Public/BranchLogger.h @@ -9,11 +9,10 @@ #import typedef NS_ENUM(NSUInteger, BranchLogLevel) { - BranchLogLevelVerbose, - BranchLogLevelDebug, - BranchLogLevelInfo, - BranchLogLevelWarning, - BranchLogLevelError, + BranchLogLevelVerbose, // development + BranchLogLevelDebug, // validation and troubleshooting + BranchLogLevelWarning, // potential errors and attempts at recovery + BranchLogLevelError, // unexpected or unhandled errors }; typedef void(^BranchLogCallback)(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error); @@ -32,10 +31,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)disableCallerDetails; - (void)logError:(NSString * _Nonnull)message error:(NSError * _Nullable)error; -- (void)logWarning:(NSString * _Nonnull)message; -- (void)logInfo:(NSString * _Nonnull)message; -- (void)logDebug:(NSString * _Nonnull)message; -- (void)logVerbose:(NSString * _Nonnull)message; +- (void)logWarning:(NSString * _Nonnull)message error:(NSError * _Nullable)error; +- (void)logDebug:(NSString * _Nonnull)message error:(NSError * _Nullable)error; +- (void)logVerbose:(NSString * _Nonnull)message error:(NSError * _Nullable)error; @end From b8d27fc2b4ef017a2f794c1ed72a8219b0258160 Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 4 Mar 2024 10:30:10 -0800 Subject: [PATCH 02/16] Refactor default log format so it does not apply when clients provide their own log handler --- .../Branch-SDK-Tests/BranchLoggerTests.m | 267 ++++++++++++++---- Sources/BranchSDK/BranchLogger.m | 78 ++--- Sources/BranchSDK/Public/BranchLogger.h | 3 + 3 files changed, 259 insertions(+), 89 deletions(-) diff --git a/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m b/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m index 13bfe40f5..feeeb1e22 100644 --- a/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m +++ b/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m @@ -11,101 +11,258 @@ #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)testLogLevelThresholdBlocksLowerLevels { +- (void)testLoggingEnabled_NOByDefault { BranchLogger *logger = [BranchLogger new]; - logger.loggingEnabled = true; - logger.logLevelThreshold = BranchLogLevelDebug; - XCTestExpectation *expectation = [self expectationWithDescription:@"Log callback expectation for message that should pass the threshold"]; + __block int count = 0; + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + count++; + }; + [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) { - if ([message isEqualToString:@"[BranchSDK][Debug][BranchLoggerTests testLogLevelThresholdBlocksLowerLevels] This message should trigger the log callback."] && logLevel >= BranchLogLevelDebug) { - [expectation fulfill]; - } else if (logLevel == BranchLogLevelVerbose) { - XCTFail(); - } + count++; }; - [logger logVerbose:@"This verbose message should not trigger the log callback." error:nil]; - [logger logDebug:@"This message should trigger the log callback." error:nil]; + [logger logError:@"msg" error:nil]; + XCTAssertTrue(count == 1); + + [logger logError:@"msg" error:nil]; + XCTAssertTrue(count == 2); +} - [self waitForExpectationsWithTimeout:1 handler:nil]; +- (void)testLoggingIgnoresNil { + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; + + __block int count = 0; + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + count++; + }; + + [logger logError:nil error:nil]; + XCTAssertTrue(count == 0); } -- (void)testLogCallbackExecutesWithCorrectParameters { - // TODO: replace this test as info has been removed +- (void)testLoggingIgnoresEmptyString { + BranchLogger *logger = [BranchLogger new]; + logger.loggingEnabled = YES; -// XCTestExpectation *expectation = [self expectationWithDescription:@"Log callback expectation"]; -// NSString *expectedMessage = @"[BranchSDK][Info][BranchLoggerTests testLogCallbackExecutesWithCorrectParameters] Test message"; -// BranchLogLevel expectedLevel = BranchLogLevelInfo; -// -// BranchLogger *logger = [BranchLogger new]; -// -// logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { -// XCTAssertEqualObjects(message, expectedMessage, "Logged message does not match expected message."); -// XCTAssertEqual(logLevel, expectedLevel, "Logged level does not match expected level."); -// XCTAssertNil(error, "Error should be nil."); -// [expectation fulfill]; -// }; -// -// logger.loggingEnabled = YES; -// logger.logLevelThreshold = BranchLogLevelInfo; -// [logger logInfo:@"Test message"]; -// -// [self waitForExpectationsWithTimeout:1 handler:nil]; + __block int count = 0; + logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + count++; + }; + + [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 + [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); + + // this should be ignored + [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)testLogLevelSpecificityFiltersLowerLevels { +- (void)testLogLevel_Warning { BranchLogger *logger = [BranchLogger new]; logger.loggingEnabled = YES; logger.logLevelThreshold = BranchLogLevelWarning; - XCTestExpectation *verboseExpectation = [self expectationWithDescription:@"Verbose log callback"]; - verboseExpectation.inverted = YES; - XCTestExpectation *errorExpectation = [self expectationWithDescription:@"Error log callback"]; - __block NSUInteger callbackCount = 0; + __block int count = 0; logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - if (logLevel == BranchLogLevelVerbose) { - [verboseExpectation fulfill]; - } else if (logLevel == BranchLogLevelError) { - [errorExpectation fulfill]; - } - callbackCount++; + count = count + 1; }; - [logger logVerbose:@"This should not be logged due to log level threshold." error:nil]; - [logger logError:@"This should be logged" error:nil]; + [logger logError:@"msg" error:nil]; + XCTAssertTrue(count == 1); + [logger logWarning:@"msg" error:nil]; + XCTAssertTrue(count == 2); + + // this should be ignored + [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; + }; - [self waitForExpectations:@[verboseExpectation, errorExpectation] timeout:2]; - XCTAssertEqual(callbackCount, 1, "Only one log callback should have been invoked."); + [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)testErrorLoggingIncludesErrorDetails { +- (void)testLogFormat_Default { BranchLogger *logger = [BranchLogger new]; logger.loggingEnabled = YES; - XCTestExpectation *expectation = [self expectationWithDescription:@"Error log includes error details"]; + 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; - NSError *testError = [NSError errorWithDomain:@"TestDomain" code:42 userInfo:@{NSLocalizedDescriptionKey: @"Test error description"}]; logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - if ([message containsString:@"Test error description"] && error == testError) { - [expectation fulfill]; - } + NSString *expectedMessage = @"[BranchLoggerTests testLogFormat_NSError] msg"; + + XCTAssertTrue([expectedMessage isEqualToString:message]); + XCTAssertTrue(logLevel == BranchLogLevelError); + XCTAssertTrue(originalError == error); }; - [logger logError:@"Testing error logging" error:testError]; + [logger logError:@"msg" error:originalError]; +} - [self waitForExpectationsWithTimeout:1 handler:nil]; +- (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 { + __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 = @"[BranchSDK][Error][BranchLoggerTests testDefaultBranchLogFormat] msg NSError: The operation couldn’t be completed. (com.domain.test error 200.)"; + NSString *formattedMessage = [BranchLogger formatMessage:message logLevel:logLevel error:error]; + + XCTAssertTrue([expectedMessage isEqualToString:formattedMessage]); + }; + + [logger logError:@"msg" error:originalError]; } @end diff --git a/Sources/BranchSDK/BranchLogger.m b/Sources/BranchSDK/BranchLogger.m index 2a1feb70f..621272d26 100644 --- a/Sources/BranchSDK/BranchLogger.m +++ b/Sources/BranchSDK/BranchLogger.m @@ -16,6 +16,15 @@ - (instancetype)init { _loggingEnabled = NO; _logLevelThreshold = BranchLogLevelDebug; _includeCallerDetails = YES; + + // default callback sends logs to os_log + _logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { + NSString *formattedMessage = [BranchLogger formatMessage:message logLevel:logLevel error:error]; + + os_log_t log = os_log_create("io.branch.sdk", "BranchSDK"); + os_log_type_t osLogType = [BranchLogger osLogTypeForBranchLogLevel:logLevel]; + os_log_with_type(log, osLogType, "%{private}@", formattedMessage); + }; } return self; } @@ -53,41 +62,45 @@ - (void)logVerbose:(NSString *)message error:(NSError *_Nullable)error { } - (void)logMessage:(NSString *)message withLevel:(BranchLogLevel)level error:(NSError *_Nullable)error { - if (!self.loggingEnabled || message.length == 0 || level < self.logLevelThreshold) { + if (!self.loggingEnabled || level < self.logLevelThreshold || message.length == 0) { return; } - NSString *callerDetails = self.includeCallerDetails ? [self callingClass] : @""; - NSString *logLevelString = [self stringForLogLevel:level]; - NSString *logTag = [NSString stringWithFormat:@"[BranchSDK][%@]", logLevelString]; - NSMutableString *fullMessage = [NSMutableString stringWithFormat:@"%@%@ %@", logTag, callerDetails, message]; - - if (error) { - [fullMessage appendFormat:@", Error: %@ (Domain: %@, Code: %ld)", error.localizedDescription, error.domain, (long)error.code]; + NSString *formattedMessage = message; + if (self.includeCallerDetails) { + formattedMessage = [NSString stringWithFormat:@"%@ %@", [self callingClass], message]; } if (self.logCallback) { - self.logCallback(fullMessage, level, error); - } else { - os_log_t log = os_log_create("io.branch.sdk", "BranchSDK"); - os_log_type_t osLogType = [self osLogTypeForBranchLogLevel:level]; - os_log_with_type(log, osLogType, "%{private}@", fullMessage); + self.logCallback(formattedMessage, level, error); } } -// Map the Branch log level to a similar Apple log level -- (os_log_type_t)osLogTypeForBranchLogLevel:(BranchLogLevel)level { - switch (level) { - // TODO: confirm these mappings make sense - case BranchLogLevelError: return OS_LOG_TYPE_ERROR; // "report process-level errors" - case BranchLogLevelWarning: return OS_LOG_TYPE_DEFAULT; // "things that might result in a failure" - case BranchLogLevelDebug: return OS_LOG_TYPE_INFO; // "helpful, but not essential, for troubleshooting errors" - case BranchLogLevelVerbose: return OS_LOG_TYPE_DEBUG; // "useful during development or while troubleshooting a specific problem" - default: return OS_LOG_TYPE_DEFAULT; +- (NSString *)callingClass { + NSArray *stackSymbols = [NSThread callStackSymbols]; + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\[([^\\]]+)\\]" options:0 error:nil]; + if (stackSymbols.count > 3 && regex) { + NSString *callSite = stackSymbols[3]; + NSTextCheckingResult *match = [regex firstMatchInString:callSite options:0 range:NSMakeRange(0, [callSite length])]; + if (match && match.range.location != NSNotFound) { + NSString *callerDetails = [callSite substringWithRange:[match rangeAtIndex:0]]; + return callerDetails; + } + } + return @""; +} + ++ (NSString *)formatMessage:(NSString *)message logLevel:(BranchLogLevel)logLevel error:(NSError *)error { + NSString *logLevelString = [BranchLogger stringForLogLevel:logLevel]; + NSString *logTag = [NSString stringWithFormat:@"[BranchSDK][%@]", logLevelString]; + NSMutableString *fullMessage = [NSMutableString stringWithFormat:@"%@%@", logTag, message]; + if (error) { + [fullMessage appendFormat:@" NSError: %@", error.localizedDescription]; } + return fullMessage; } -- (NSString *)stringForLogLevel:(BranchLogLevel)level { ++ (NSString *)stringForLogLevel:(BranchLogLevel)level { switch (level) { case BranchLogLevelVerbose: return @"Verbose"; case BranchLogLevelDebug: return @"Debug"; @@ -97,18 +110,15 @@ - (NSString *)stringForLogLevel:(BranchLogLevel)level { } } -- (NSString *)callingClass { - NSArray *stackSymbols = [NSThread callStackSymbols]; - NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\[([^\\]]+)\\]" options:0 error:nil]; - if (stackSymbols.count > 3 && regex) { - NSString *callSite = stackSymbols[3]; - NSTextCheckingResult *match = [regex firstMatchInString:callSite options:0 range:NSMakeRange(0, [callSite length])]; - if (match && match.range.location != NSNotFound) { - NSString *callerDetails = [callSite substringWithRange:[match rangeAtIndex:0]]; - return callerDetails; - } +// Map the Branch log level to a similar Apple log level ++ (os_log_type_t)osLogTypeForBranchLogLevel:(BranchLogLevel)level { + switch (level) { + case BranchLogLevelError: return OS_LOG_TYPE_ERROR; // "report process-level errors" + case BranchLogLevelWarning: return OS_LOG_TYPE_DEFAULT; // "things that might result in a failure" + case BranchLogLevelDebug: return OS_LOG_TYPE_INFO; // "helpful, but not essential, for troubleshooting errors" + case BranchLogLevelVerbose: return OS_LOG_TYPE_DEBUG; // "useful during development or while troubleshooting a specific problem" + default: return OS_LOG_TYPE_DEFAULT; } - return @""; } @end diff --git a/Sources/BranchSDK/Public/BranchLogger.h b/Sources/BranchSDK/Public/BranchLogger.h index 16a5f62d4..1b0d7b07d 100644 --- a/Sources/BranchSDK/Public/BranchLogger.h +++ b/Sources/BranchSDK/Public/BranchLogger.h @@ -35,6 +35,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)logDebug:(NSString * _Nonnull)message error:(NSError * _Nullable)error; - (void)logVerbose:(NSString * _Nonnull)message error:(NSError * _Nullable)error; +// default Branch log format ++ (NSString *)formatMessage:(NSString *)message logLevel:(BranchLogLevel)logLevel error:(NSError *)error; + @end NS_ASSUME_NONNULL_END From 18d848f2a712ad86c2cd8ba91b764dd4ebad21b8 Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 7 Mar 2024 16:35:07 -0800 Subject: [PATCH 03/16] change errors to warnings in BNCApplication. Remove telephony from testbed --- .../Branch-TestBed.xcodeproj/project.pbxproj | 2 - Sources/BranchSDK/BNCApplication.m | 58 ++++++++++--------- Sources/BranchSDK/BranchQRCode.m | 3 +- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj b/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj index eb3c8474b..074565a71 100644 --- a/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj +++ b/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj @@ -50,7 +50,6 @@ 5F3D671B233062FD00454FF1 /* BNCJsonLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F3D671A233062FD00454FF1 /* BNCJsonLoader.m */; }; 5F3D671C233062FD00454FF1 /* BNCJsonLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F3D671A233062FD00454FF1 /* BNCJsonLoader.m */; }; 5F42763325DB3694005B9BBC /* AdServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F42763225DB3694005B9BBC /* AdServices.framework */; }; - 5F437E38237DE1320052064B /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F437E37237DE1320052064B /* CoreTelephony.framework */; settings = {ATTRIBUTES = (Required, ); }; }; 5F437E40237E1A560052064B /* BNCDeviceSystemTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F437E3F237E1A560052064B /* BNCDeviceSystemTests.m */; }; 5F5FDA102B7DE20800F14A43 /* BranchLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F5FDA0F2B7DE20800F14A43 /* BranchLogger.m */; }; 5F5FDA122B7DE22A00F14A43 /* BranchLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F5FDA112B7DE22A00F14A43 /* BranchLogger.h */; }; @@ -569,7 +568,6 @@ buildActionMask = 2147483647; files = ( 5F92B2362383644C00CA909B /* SystemConfiguration.framework in Frameworks */, - 5F437E38237DE1320052064B /* CoreTelephony.framework in Frameworks */, 5F205D05231864E800C776D1 /* WebKit.framework in Frameworks */, 5FF7D2862A9549B40049158D /* AdServices.framework in Frameworks */, 466B584F1B17775900A69EDE /* AdSupport.framework in Frameworks */, diff --git a/Sources/BranchSDK/BNCApplication.m b/Sources/BranchSDK/BNCApplication.m index 9d024c219..67c9a6f0d 100644 --- a/Sources/BranchSDK/BNCApplication.m +++ b/Sources/BranchSDK/BNCApplication.m @@ -69,64 +69,66 @@ + (BNCApplication*) createCurrentApplication { return application; } -+ (NSDate*) currentBuildDate { ++ (NSDate *)currentBuildDate { NSURL *appURL = nil; NSURL *bundleURL = [NSBundle mainBundle].bundleURL; NSDictionary *info = [NSBundle mainBundle].infoDictionary; - NSString *appName = info[(__bridge NSString*)kCFBundleExecutableKey]; + NSString *appName = info[(__bridge NSString *)kCFBundleExecutableKey]; if (appName.length > 0 && bundleURL) { appURL = [bundleURL URLByAppendingPathComponent:appName]; } else { NSString *path = [[NSProcessInfo processInfo].arguments firstObject]; - if (path) appURL = [NSURL fileURLWithPath:path]; + if (path) { + appURL = [NSURL fileURLWithPath:path]; + } } - if (appURL == nil) + if (appURL == nil) { + [[BranchLogger shared] logWarning:@"Failed to get build date, app path is nil" error:nil]; return nil; + } NSError *error = nil; NSFileManager *fileManager = [NSFileManager defaultManager]; NSDictionary *attributes = [fileManager attributesOfItemAtPath:appURL.path error:&error]; if (error) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Can't get build date: %@.", error] error:error]; + [[BranchLogger shared] logWarning:@"Failed to get build date" error:error]; return nil; } - NSDate * buildDate = [attributes fileCreationDate]; + NSDate *buildDate = [attributes fileCreationDate]; if (buildDate == nil || [buildDate timeIntervalSince1970] <= 0.0) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Invalid build date: %@.", buildDate] error:nil]; + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Invalid build date: %@", buildDate] error:nil]; } return buildDate; } -+ (NSDate*) firstInstallBuildDate { ++ (NSDate *)firstInstallBuildDate { NSError *error = nil; - NSDate *firstBuildDate = - [BNCKeyChain retrieveDateForService:kBranchKeychainService - key:kBranchKeychainFirstBuildKey - error:&error]; - if (firstBuildDate) + NSDate *firstBuildDate = [BNCKeyChain retrieveDateForService:kBranchKeychainService key:kBranchKeychainFirstBuildKey error:&error]; + if (firstBuildDate) { return firstBuildDate; - + } + firstBuildDate = [self currentBuildDate]; - error = [BNCKeyChain storeDate:firstBuildDate - forService:kBranchKeychainService - key:kBranchKeychainFirstBuildKey - cloudAccessGroup:nil]; - if (error) [[BranchLogger shared] logError:[NSString stringWithFormat:@"Keychain store: %@.", error] error:error]; - + error = [BNCKeyChain storeDate:firstBuildDate forService:kBranchKeychainService key:kBranchKeychainFirstBuildKey cloudAccessGroup:nil]; + if (error) { + [[BranchLogger shared] logWarning:@"Error while saving build date" error:error]; + } return firstBuildDate; } -+ (NSDate *) currentInstallDate { ++ (NSDate *)currentInstallDate { NSDate *installDate = [NSDate date]; #if !TARGET_OS_TV // tvOS always returns a creation date of Unix epoch 0 on device installDate = [self creationDateForLibraryDirectory]; - #endif - if (installDate == nil || [installDate timeIntervalSince1970] <= 0.0) { - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Invalid install date, using [NSDate date]."] error:nil]; + [[BranchLogger shared] logWarning:@"Invalid install date, using [NSDate date]" error:nil]; } + #else + [[BranchLogger shared] logWarning:@"File system creation date not supported on tvOS, using [NSDate date]" error:nil]; + #endif + return installDate; } @@ -136,13 +138,13 @@ + (NSDate *)creationDateForLibraryDirectory { NSURL *directoryURL = [[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] firstObject]; NSDictionary *attributes = [fileManager attributesOfItemAtPath:directoryURL.path error:&error]; if (error) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Can't get creation date for Library directory: %@", error] error:error]; - return nil; + [[BranchLogger shared] logWarning:@"Failed to get creation date for Library directory" error:error]; + return nil; } return [attributes fileCreationDate]; } -+ (NSDate*) firstInstallDate { ++ (NSDate *)firstInstallDate { // check keychain for stored install date, on iOS this is lost on app deletion. NSError *error = nil; NSDate* firstInstallDate = [BNCKeyChain retrieveDateForService:kBranchKeychainService key:kBranchKeychainFirstInstalldKey error:&error]; @@ -156,7 +158,7 @@ + (NSDate*) firstInstallDate { // save filesystem time to keychain error = [BNCKeyChain storeDate:firstInstallDate forService:kBranchKeychainService key:kBranchKeychainFirstInstalldKey cloudAccessGroup:nil]; if (error) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Keychain store: %@.", error] error:error]; + [[BranchLogger shared] logWarning:@"Error while saving install date" error:error]; } return firstInstallDate; } diff --git a/Sources/BranchSDK/BranchQRCode.m b/Sources/BranchSDK/BranchQRCode.m index 190ef4675..43407f0e2 100644 --- a/Sources/BranchSDK/BranchQRCode.m +++ b/Sources/BranchSDK/BranchQRCode.m @@ -143,7 +143,7 @@ - (void)callQRCodeAPI:(nullable NSDictionary *)params NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (error) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"QR Code Post Request Error: %@", [error localizedDescription]] error:error]; + [[BranchLogger shared] logError:@"QR Code request failed" error:error]; completion(nil, error); return; } @@ -151,7 +151,6 @@ - (void)callQRCodeAPI:(nullable NSDictionary *)params NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; if (httpResponse.statusCode == 200) { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Network finish operation %@ %1.3fs. Status %ld.", request.URL.absoluteString, [[NSDate date] timeIntervalSinceDate:startDate], From ac28e380807a0ec0ddc5f47d73333ca6bcbc51e5 Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 7 Mar 2024 17:34:57 -0800 Subject: [PATCH 04/16] Remove test category from BNCApplication. Update logs in BNCApplication --- .../Branch-SDK-Tests/BNCApplication+BNCTest.h | 20 - .../Branch-SDK-Tests/BNCApplication+BNCTest.m | 11 - .../BNCServerInterface.Test.m | 380 ----------------- .../BNCServerRequestQueueOldTests.m | 124 ------ .../Branch-SDK-Tests/BNCTestCase.Test.m | 31 -- Branch-TestBed/Branch-SDK-Tests/BNCTestCase.h | 40 -- Branch-TestBed/Branch-SDK-Tests/BNCTestCase.m | 115 ------ .../Branch-SDK-Tests/BNCTestCase.strings | 255 ------------ .../Branch-SDK-Tests-Bridging-Header.h | 1 - .../BranchInstallRequestTests.m | 318 -------------- .../Branch-SDK-Tests/BranchOpenRequestTests.m | 390 ------------------ .../BranchSDKFunctionalityTests.m | 121 ------ .../Branch-TestBed.xcodeproj/project.pbxproj | 40 -- Sources/BranchSDK/BNCApplication.m | 30 +- 14 files changed, 11 insertions(+), 1865 deletions(-) delete mode 100644 Branch-TestBed/Branch-SDK-Tests/BNCApplication+BNCTest.h delete mode 100644 Branch-TestBed/Branch-SDK-Tests/BNCApplication+BNCTest.m delete mode 100644 Branch-TestBed/Branch-SDK-Tests/BNCServerInterface.Test.m delete mode 100644 Branch-TestBed/Branch-SDK-Tests/BNCServerRequestQueueOldTests.m delete mode 100644 Branch-TestBed/Branch-SDK-Tests/BNCTestCase.Test.m delete mode 100644 Branch-TestBed/Branch-SDK-Tests/BNCTestCase.h delete mode 100644 Branch-TestBed/Branch-SDK-Tests/BNCTestCase.m delete mode 100644 Branch-TestBed/Branch-SDK-Tests/BNCTestCase.strings delete mode 100644 Branch-TestBed/Branch-SDK-Tests/BranchInstallRequestTests.m delete mode 100644 Branch-TestBed/Branch-SDK-Tests/BranchOpenRequestTests.m delete mode 100644 Branch-TestBed/Branch-SDK-Tests/BranchSDKFunctionalityTests.m diff --git a/Branch-TestBed/Branch-SDK-Tests/BNCApplication+BNCTest.h b/Branch-TestBed/Branch-SDK-Tests/BNCApplication+BNCTest.h deleted file mode 100644 index 0c50af6d4..000000000 --- a/Branch-TestBed/Branch-SDK-Tests/BNCApplication+BNCTest.h +++ /dev/null @@ -1,20 +0,0 @@ -/** - @file BNCApplication+BNCTest.h - @package Branch-SDK-Tests - @brief Expose BNCApplication interfaces for testing. - - @author Edward Smith - @date May 4, 2018 - @copyright Copyright © 2018 Branch. All rights reserved. -*/ - -#import -#import "BNCApplication.h" - -@interface BNCApplication (BNCTest) - -- (void) setAppOriginalInstallDate:(NSDate*)originalInstallDate - firstInstallDate:(NSDate*)firstInstallDate - lastUpdateDate:(NSDate*)lastUpdateDate; - -@end diff --git a/Branch-TestBed/Branch-SDK-Tests/BNCApplication+BNCTest.m b/Branch-TestBed/Branch-SDK-Tests/BNCApplication+BNCTest.m deleted file mode 100644 index 72de10fde..000000000 --- a/Branch-TestBed/Branch-SDK-Tests/BNCApplication+BNCTest.m +++ /dev/null @@ -1,11 +0,0 @@ -/** - @file BNCApplication+BNCTest.m - @package Branch-SDK-Tests - @brief Expose BNCApplication interfaces for testing. - - @author Edward Smith - @date May 4, 2018 - @copyright Copyright © 2018 Branch. All rights reserved. -*/ - -#import "BNCApplication+BNCTest.h" diff --git a/Branch-TestBed/Branch-SDK-Tests/BNCServerInterface.Test.m b/Branch-TestBed/Branch-SDK-Tests/BNCServerInterface.Test.m deleted file mode 100644 index 944a792f1..000000000 --- a/Branch-TestBed/Branch-SDK-Tests/BNCServerInterface.Test.m +++ /dev/null @@ -1,380 +0,0 @@ -// -// BNCServerInterface.Test.m -// Branch -// -// Created by Graham Mueller on 3/31/15. -// Copyright (c) 2015 Branch Metrics. All rights reserved. -// - -#import -#import "BNCTestCase.h" -#import "BNCServerInterface.h" -#import "BNCPreferenceHelper.h" -#import "BranchConstants.h" -//#import -//#import -//#import - -//typedef void (^UrlConnectionCallback)(NSURLResponse *, NSData *, NSError *); -// -//@interface BNCServerInterface() -// -//// private BNCServerInterface method/properties to prepare dictionary for requests -//@property (copy, nonatomic) NSString *requestEndpoint; -//- (NSMutableDictionary *)prepareParamDict:(NSDictionary *)params -// key:(NSString *)key -// retryNumber:(NSInteger)retryNumber -// requestType:(NSString *)reqType; -//@end -// -// -// -//@interface BNCServerInterfaceTests : BNCTestCase -//@end -// -//@implementation BNCServerInterfaceTests -// -//#pragma mark - Tear Down -// -//- (void)tearDown { -// [HTTPStubs removeAllStubs]; -// [super tearDown]; -//} -// -// -//#pragma mark - Key tests -// -////================================================================================== -//// TEST 01 -//// This test checks to see that the branch key has been added to the GET request -// -//- (void)testParamAddForBranchKey { -// [HTTPStubs removeAllStubs]; -// BNCServerInterface *serverInterface = [[BNCServerInterface alloc] init]; -// XCTestExpectation* expectation = -// [self expectationWithDescription:@"NSURLSessionDataTask completed"]; -// -// __block int callCount = 0; -// [HTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { -// // We're not sending a request, just verifying a "branch_key=key_xxx" is present. -// callCount++; -// NSLog(@"\n\nCall count %d.\nRequest: %@\n", callCount, request); -// if (callCount == 1) { -// BOOL foundIt = ([request.URL.query rangeOfString:@"branch_key=key_"].location != NSNotFound); -// XCTAssertTrue(foundIt, @"Branch Key not added"); -// BNCAfterSecondsPerformBlockOnMainThread(0.01, ^{ [expectation fulfill]; }); -// return YES; -// } -// return NO; -// } -// withStubResponse:^HTTPStubsResponse *(NSURLRequest *request) { -// NSDictionary* dummyJSONResponse = @{@"key": @"value"}; -// return [HTTPStubsResponse responseWithJSONObject:dummyJSONResponse statusCode:200 headers:nil]; -// } -// ]; -// -// [serverInterface getRequest:nil url:@"http://foo" key:@"key_live_foo" callback:NULL]; -// [self waitForExpectationsWithTimeout:5.0 handler:nil]; -// [HTTPStubs removeAllStubs]; -//} -// -//#pragma mark - Retry tests -// -////================================================================================== -//// TEST 03 -//// This test simulates a poor network, with three failed GET attempts and one final success, -//// for 4 connections. -// -////- (void)testGetRequestAsyncRetriesWhenAppropriate { -//// [HTTPStubs removeAllStubs]; -//// -//// //Set up nsurlsession and data task, catching response -//// BNCServerInterface *serverInterface = [[BNCServerInterface alloc] init]; -//// serverInterface.preferenceHelper = [[BNCPreferenceHelper alloc] init]; -//// serverInterface.preferenceHelper.retryCount = 3; -//// -//// XCTestExpectation* successExpectation = [self expectationWithDescription:@"success"]; -//// -//// __block NSInteger connectionAttempts = 0; -//// __block NSInteger failedConnections = 0; -//// __block NSInteger successfulConnections = 0; -//// -//// [HTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { -//// BOOL foundBranchKey = [request.URL.query rangeOfString:@"branch_key=key_"].location != NSNotFound; -//// XCTAssertEqual(foundBranchKey, TRUE); -//// return foundBranchKey; -//// -//// } withStubResponse:^HTTPStubsResponse*(NSURLRequest *request) { -//// @synchronized (self) { -//// connectionAttempts++; -//// NSLog(@"Attempt # %lu", (unsigned long)connectionAttempts); -//// if (connectionAttempts < 3) { -//// -//// // Return an error the first three times -//// NSDictionary* dummyJSONResponse = @{@"bad": @"data"}; -//// -//// ++failedConnections; -//// return [HTTPStubsResponse responseWithJSONObject:dummyJSONResponse statusCode:504 headers:nil]; -//// -//// } else if (connectionAttempts == 3) { -//// -//// // Return actual data afterwards -//// ++successfulConnections; -//// XCTAssertEqual(connectionAttempts, failedConnections + successfulConnections); -//// BNCAfterSecondsPerformBlockOnMainThread(0.01, ^{ -//// NSLog(@"==> Fullfill."); -//// [successExpectation fulfill]; -//// }); -//// -//// NSDictionary* dummyJSONResponse = @{@"key": @"value"}; -//// return [HTTPStubsResponse responseWithJSONObject:dummyJSONResponse statusCode:200 headers:nil]; -//// -//// } else { -//// -//// XCTFail(@"Too many connection attempts: %ld.", (long) connectionAttempts); -//// return [HTTPStubsResponse responseWithJSONObject:[NSDictionary new] statusCode:200 headers:nil]; -//// -//// } -//// } -//// }]; -//// -//// [serverInterface getRequest:nil url:@"http://foo" key:@"key_live_foo" callback:NULL]; -//// [self waitForExpectationsWithTimeout:10.0 handler:nil]; -////} -// -////================================================================================== -//// TEST 04 -//// This test checks to make sure that GET retries are not attempted when they have a retry -//// count > 0, but retries aren't needed. Based on Test #3 above. -// -//- (void)testGetRequestAsyncRetriesWhenInappropriateResponse { -// [HTTPStubs removeAllStubs]; -// -// BNCServerInterface *serverInterface = [[BNCServerInterface alloc] init]; -// serverInterface.preferenceHelper = [[BNCPreferenceHelper alloc] init]; -// serverInterface.preferenceHelper.retryCount = 3; -// -// XCTestExpectation* successExpectation = [self expectationWithDescription:@"success"]; -// -// __block NSUInteger connectionAttempts = 0; -// -// [HTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { -// BOOL foundBranchKey = [request.URL.query rangeOfString:@"branch_key=key_"].location != NSNotFound; -// XCTAssertEqual(foundBranchKey, TRUE); -// return foundBranchKey; -// -// } withStubResponse:^HTTPStubsResponse*(NSURLRequest *request) { -// @synchronized (self) { -// // Return actual data on first attempt -// NSDictionary* dummyJSONResponse = @{@"key": @"value"}; -// connectionAttempts++; -// XCTAssertEqual(connectionAttempts, 1); -// BNCAfterSecondsPerformBlockOnMainThread(0.01, ^ { -// [successExpectation fulfill]; -// }); -// return [HTTPStubsResponse responseWithJSONObject:dummyJSONResponse statusCode:200 headers:nil]; -// } -// }]; -// -// [serverInterface getRequest:nil url:@"http://foo" key:@"key_live_foo" callback:NULL]; -// [self waitForExpectationsWithTimeout:2.0 handler:nil]; -//} -// -////================================================================================== -//// TEST 05 -//// This test checks to make sure that GET retries are not attempted when they have a retry -//// count == 0, but retries aren't needed. Based on Test #4 above -// -//- (void)testGetRequestAsyncRetriesWhenInappropriateRetryCount { -// [HTTPStubs removeAllStubs]; -// -// BNCServerInterface *serverInterface = [[BNCServerInterface alloc] init]; -// serverInterface.preferenceHelper = [[BNCPreferenceHelper alloc] init]; -// serverInterface.preferenceHelper.retryCount = 0; -// -// XCTestExpectation* successExpectation = [self expectationWithDescription:@"success"]; -// -// __block NSUInteger connectionAttempts = 0; -// -// [HTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { -// BOOL foundBranchKey = [request.URL.query rangeOfString:@"branch_key=key_"].location != NSNotFound; -// XCTAssertEqual(foundBranchKey, TRUE); -// return foundBranchKey; -// -// } withStubResponse:^HTTPStubsResponse*(NSURLRequest *request) { -// @synchronized (self) { -// // Return actual data on first attempt -// NSDictionary* dummyJSONResponse = @{@"key": @"value"}; -// connectionAttempts++; -// XCTAssertEqual(connectionAttempts, 1); -// BNCAfterSecondsPerformBlockOnMainThread(0.01, ^{ -// [successExpectation fulfill]; -// }); -// return [HTTPStubsResponse responseWithJSONObject:dummyJSONResponse statusCode:200 headers:nil]; -// } -// }]; -// -// [serverInterface getRequest:nil url:@"http://foo" key:@"key_live_foo" callback:NULL]; -// [self waitForExpectationsWithTimeout:2.0 handler:nil]; -//} -// -////================================================================================== -//// TEST 06 -//// This test simulates a poor network, with three failed GET attempts and one final success, -//// for 4 connections. Based on Test #3 above -// -//- (void)testPostRequestAsyncRetriesWhenAppropriate { -// [HTTPStubs removeAllStubs]; -// -// //Set up nsurlsession and data task, catching response -// BNCServerInterface *serverInterface = [[BNCServerInterface alloc] init]; -// serverInterface.preferenceHelper = [[BNCPreferenceHelper alloc] init]; -// serverInterface.preferenceHelper.retryCount = 3; -// [serverInterface.preferenceHelper synchronize]; -// -// XCTestExpectation* successExpectation = [self expectationWithDescription:@"success"]; -// -// __block NSUInteger connectionAttempts = 0; -// __block NSUInteger failedConnections = 0; -// __block NSUInteger successfulConnections = 0; -// -// [HTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { -// BOOL foundBranchKey = [request.URL.query rangeOfString:@"branch_key=key_"].location != NSNotFound; -// XCTAssertEqual(foundBranchKey, TRUE); -// return foundBranchKey; -// -// } withStubResponse:^HTTPStubsResponse*(NSURLRequest *request) { -// connectionAttempts++; -// NSLog(@"attempt # %lu", (unsigned long)connectionAttempts); -// if (connectionAttempts < 3) { -// // Return an error the first three times -// NSDictionary* dummyJSONResponse = @{@"bad": @"data"}; -// -// ++failedConnections; -// return [HTTPStubsResponse responseWithJSONObject:dummyJSONResponse statusCode:504 headers:nil]; -// -// } else if (connectionAttempts == 3) { -// -// // Return actual data afterwards -// ++successfulConnections; -// NSDictionary* dummyJSONResponse = @{@"key": @"value"}; -// XCTAssertEqual(connectionAttempts, failedConnections + successfulConnections); -// BNCAfterSecondsPerformBlockOnMainThread(0.01, ^ { -// NSLog(@"==>> Fullfill <<=="); -// [successExpectation fulfill]; -// }); -// return [HTTPStubsResponse responseWithJSONObject:dummyJSONResponse statusCode:200 headers:nil]; -// -// } else { -// -// XCTFail(@"Too many connection attempts: %ld.", (long) connectionAttempts); -// return [HTTPStubsResponse responseWithJSONObject:[NSDictionary new] statusCode:200 headers:nil]; -// -// } -// }]; -// -// [serverInterface postRequest:nil url:@"http://foo" key:@"key_live_foo" callback:NULL]; -// [self waitForExpectationsWithTimeout:5.0 handler:nil]; -//} -// -////================================================================================== -//// TEST 07 -//// This test checks to make sure that POST retries are not attempted when they have a retry -//// count == 0, and retries aren't needed. Based on Test #4 above -// -//- (void)testPostRequestAsyncRetriesWhenInappropriateResponse { -// [HTTPStubs removeAllStubs]; -// -// BNCServerInterface *serverInterface = [[BNCServerInterface alloc] init]; -// serverInterface.preferenceHelper = [[BNCPreferenceHelper alloc] init]; -// serverInterface.preferenceHelper.retryCount = 3; -// -// XCTestExpectation* successExpectation = [self expectationWithDescription:@"success"]; -// -// __block NSUInteger connectionAttempts = 0; -// -// [HTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { -// BOOL foundBranchKey = [request.URL.query rangeOfString:@"branch_key=key_"].location != NSNotFound; -// XCTAssertEqual(foundBranchKey, TRUE); -// return foundBranchKey; -// -// } withStubResponse:^HTTPStubsResponse*(NSURLRequest *request) { -// // Return actual data on first attempt -// NSDictionary* dummyJSONResponse = @{@"key": @"value"}; -// connectionAttempts++; -// XCTAssertEqual(connectionAttempts, 1); -// BNCAfterSecondsPerformBlockOnMainThread(0.01, ^{ [successExpectation fulfill]; }); -// return [HTTPStubsResponse responseWithJSONObject:dummyJSONResponse statusCode:200 headers:nil]; -// -// }]; -// -// [serverInterface postRequest:nil url:@"http://foo" key:@"key_live_foo" callback:NULL]; -// [self waitForExpectationsWithTimeout:1.0 handler:nil]; -// -//} -// -////================================================================================== -//// TEST 08 -//// This test checks to make sure that GET retries are not attempted when they have a retry -//// count == 0, and retries aren't needed. Based on Test #4 above -// -//- (void)testPostRequestAsyncRetriesWhenInappropriateRetryCount { -// [HTTPStubs removeAllStubs]; -// -// BNCServerInterface *serverInterface = [[BNCServerInterface alloc] init]; -// serverInterface.preferenceHelper = [[BNCPreferenceHelper alloc] init]; -// serverInterface.preferenceHelper.retryCount = 0; -// -// XCTestExpectation* successExpectation = [self expectationWithDescription:@"success"]; -// -// __block NSUInteger connectionAttempts = 0; -// -// [HTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { -// BOOL foundBranchKey = [request.URL.query rangeOfString:@"branch_key=key_"].location != NSNotFound; -// XCTAssertEqual(foundBranchKey, TRUE); -// return foundBranchKey; -// -// } withStubResponse:^HTTPStubsResponse*(NSURLRequest *request) { -// // Return actual data on first attempt -// NSDictionary* dummyJSONResponse = @{@"key": @"value"}; -// connectionAttempts++; -// XCTAssertEqual(connectionAttempts, 1); -// BNCAfterSecondsPerformBlockOnMainThread(0.01, ^{ [successExpectation fulfill]; }); -// return [HTTPStubsResponse responseWithJSONObject:dummyJSONResponse statusCode:200 headers:nil]; -// }]; -// -// [serverInterface getRequest:nil url:@"http://foo" key:@"key_live_foo" callback:NULL]; -// [self waitForExpectationsWithTimeout:1.0 handler:nil]; -//} -// -////================================================================================== -//// TEST 10 -//// Test mapping of X-Branch-Request-Id to [BNCServerResponse requestId] -// -//- (void)testRequestIdFromHeader { -// [HTTPStubs removeAllStubs]; -// -// BNCServerInterface *serverInterface = [[BNCServerInterface alloc] init]; -// NSString *requestId = @"1325e434fa294d3bb7d461349118602d-2020102721"; -// -// XCTestExpectation* successExpectation = [self expectationWithDescription:@"success"]; -// -// [HTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { -// // Return the following response for any request -// return YES; -// } withStubResponse:^HTTPStubsResponse *(NSURLRequest *request) { -// // Stub out a response with a X-Branch-Request-Id header -// return [HTTPStubsResponse responseWithJSONObject:@{} statusCode:200 headers:@{@"X-Branch-Request-Id": requestId}]; -// }]; -// -// // POST to trigger the stubbed response. -// [serverInterface postRequest:@{} url:@"https://api.branch.io/v1/open" key:@"key_live_xxxx" callback:^(BNCServerResponse *response, NSError *error) { -// // Verify the request ID value on the BNCServerResponse -// BNCAfterSecondsPerformBlockOnMainThread(0.01, ^{ [successExpectation fulfill]; }); -// XCTAssertEqualObjects(response.requestId, requestId); -// }]; -// -// [self waitForExpectationsWithTimeout:5.0 handler:nil]; -//} -// -//@end diff --git a/Branch-TestBed/Branch-SDK-Tests/BNCServerRequestQueueOldTests.m b/Branch-TestBed/Branch-SDK-Tests/BNCServerRequestQueueOldTests.m deleted file mode 100644 index 43343671d..000000000 --- a/Branch-TestBed/Branch-SDK-Tests/BNCServerRequestQueueOldTests.m +++ /dev/null @@ -1,124 +0,0 @@ -// -// BNCServerRequestQueueTests.m -// Branch-TestBed -// -// Created by Graham Mueller on 6/17/15. -// Copyright (c) 2015 Branch Metrics. All rights reserved. -// - -#import "BNCTestCase.h" -#import "BNCServerRequestQueue.h" -#import "BranchOpenRequest.h" -#import "Branch.h" - -//#import -// -//@interface BNCServerRequestQueue (BNCTests) -//- (void)retrieve; -//- (void)cancelTimer; -//@end -// -//@interface BNCServerRequestQueueOldTests : BNCTestCase -//@end -// -//@implementation BNCServerRequestQueueOldTests -// -//#pragma mark - MoveOpenOrInstallToFront tests -// -//+ (void) setUp { -// [self clearAllBranchSettings]; // Clear any saved data before our tests start. -//// Branch*branch = [Branch getInstance:@"key_live_foo"]; -//// [self clearAllBranchSettings]; -//} -// -//- (void)testMoveOpenOrInstallToFrontWhenEmpty { -// BNCServerRequestQueue *requestQueue = [[BNCServerRequestQueue alloc] init]; -// XCTAssertNoThrow([requestQueue moveInstallOrOpenToFront:0]); -//} -// -//- (void)testMoveOpenOrInstallToFrontWhenNotPresent { -// BNCServerRequestQueue *requestQueue = [[BNCServerRequestQueue alloc] init]; -// [requestQueue insert:[[BNCServerRequest alloc] init] at:0]; -// [requestQueue insert:[[BNCServerRequest alloc] init] at:0]; -// XCTAssertNoThrow([requestQueue moveInstallOrOpenToFront:0]); -//} -// -//- (void)testMoveOpenOrInstallToFrontWhenAlreadyInFrontAndNoRequestsInProgress { -// BNCServerRequestQueue *requestQueue = [[BNCServerRequestQueue alloc] init]; -// [requestQueue insert:[[BranchOpenRequest alloc] init] at:0]; -// -// id requestQueueMock = OCMPartialMock(requestQueue); -// [[requestQueueMock reject] removeAt:0]; -// -// [requestQueue moveInstallOrOpenToFront:0]; -//} -// -//- (void)testMoveOpenOrInstallToFrontWhenAlreadyInFrontWithRequestsInProgress { -// BNCServerRequestQueue *requestQueue = [[BNCServerRequestQueue alloc] init]; -// [requestQueue insert:[[BranchOpenRequest alloc] init] at:0]; -// -// id requestQueueMock = OCMPartialMock(requestQueue); -// [[requestQueueMock reject] removeAt:0]; -// -// [requestQueue moveInstallOrOpenToFront:1]; -//} -// -//- (void)testMoveOpenOrInstallToFrontWhenSecondInLineWithRequestsInProgress { -// BNCServerRequestQueue *requestQueue = [[BNCServerRequestQueue alloc] init]; -// [requestQueue insert:[[BNCServerRequest alloc] init] at:0]; -// [requestQueue insert:[[BranchOpenRequest alloc] init] at:1]; -// -// id requestQueueMock = OCMPartialMock(requestQueue); -// [[requestQueueMock reject] removeAt:1]; -// -// [requestQueue moveInstallOrOpenToFront:1]; -//} -// -//- (void)testMoveOpenOrInstallToFrontWhenSecondInLineWithNoRequestsInProgress { -// BNCServerRequestQueue *requestQueue = [[BNCServerRequestQueue alloc] init]; -// BranchOpenRequest *openRequest = [[BranchOpenRequest alloc] init]; -// [requestQueue insert:[[BNCServerRequest alloc] init] at:0]; -// [requestQueue insert:openRequest at:1]; -// -// id requestQueueMock = OCMPartialMock(requestQueue); -// [[[requestQueueMock expect] andForwardToRealObject] removeAt:1]; -// -// [requestQueue moveInstallOrOpenToFront:0]; -// XCTAssertEqual([requestQueue peek], openRequest); -// -// [requestQueueMock verify]; -//} -// -//- (void)testMoveOpenOrInstallToFrontWhenThirdInLineWithRequestsInProgress { -// BNCServerRequestQueue *requestQueue = [[BNCServerRequestQueue alloc] init]; -// BranchOpenRequest *openRequest = [[BranchOpenRequest alloc] init]; -// [requestQueue insert:[[BNCServerRequest alloc] init] at:0]; -// [requestQueue insert:[[BNCServerRequest alloc] init] at:1]; -// [requestQueue insert:openRequest at:2]; -// -// id requestQueueMock = OCMPartialMock(requestQueue); -// [[[requestQueueMock expect] andForwardToRealObject] removeAt:2]; -// -// [requestQueue moveInstallOrOpenToFront:1]; -// XCTAssertEqual([requestQueue peekAt:1], openRequest); -// -// [requestQueueMock verify]; -//} -// -//- (void)testMoveOpenOrInstallToFrontWhenThirdInLineWithNoRequestsInProgress { -// BNCServerRequestQueue *requestQueue = [[BNCServerRequestQueue alloc] init]; -// BranchOpenRequest *openRequest = [[BranchOpenRequest alloc] init]; -// [requestQueue insert:[[BNCServerRequest alloc] init] at:0]; -// [requestQueue insert:[[BNCServerRequest alloc] init] at:1]; -// [requestQueue insert:openRequest at:2]; -// -// id requestQueueMock = OCMPartialMock(requestQueue); -// [[[requestQueueMock expect] andForwardToRealObject] removeAt:2]; -// -// [requestQueue moveInstallOrOpenToFront:0]; -// XCTAssertEqual([requestQueue peek], openRequest); -// -// [requestQueueMock verify]; -//} -// -//@end diff --git a/Branch-TestBed/Branch-SDK-Tests/BNCTestCase.Test.m b/Branch-TestBed/Branch-SDK-Tests/BNCTestCase.Test.m deleted file mode 100644 index 2bf549088..000000000 --- a/Branch-TestBed/Branch-SDK-Tests/BNCTestCase.Test.m +++ /dev/null @@ -1,31 +0,0 @@ -/** - @file BNCTestCase.Test.m - @package Branch-SDK - @brief Test cases for the underlying Branch test class. - - @author Edward Smith - @date April 2018 - @copyright Copyright © 2018 Branch. All rights reserved. -*/ - -#import "BNCTestCase.h" - -@interface BNCTestCaseTest : BNCTestCase -@end - -@implementation BNCTestCaseTest - -- (void) testFailure { - // Un-comment the next line to test a failure case: - // XCTAssert(NO, @"Testing a test failure!"); - XCTAssertTrue(YES, @"Test passes!"); - NSString * bundleID = [NSBundle mainBundle].bundleIdentifier; - NSLog(@"The test bundleID is '%@'.", bundleID); -} - -- (void) testLoadString { - NSString *string = [self stringFromBundleWithKey:@"BNCTestCaseString"]; - XCTAssertEqualObjects(string, @"Test success!"); -} - -@end diff --git a/Branch-TestBed/Branch-SDK-Tests/BNCTestCase.h b/Branch-TestBed/Branch-SDK-Tests/BNCTestCase.h deleted file mode 100644 index de4afe482..000000000 --- a/Branch-TestBed/Branch-SDK-Tests/BNCTestCase.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - @file BNCTestCase.h - @package Branch-SDK-Tests - @brief The Branch testing framework super class. - - @author Edward Smith - @date April 2017 - @copyright Copyright © 2017 Branch. All rights reserved. -*/ - -#import -#import "NSString+Branch.h" - -#define BNCTAssertEqualMaskedString(string, mask) { \ - if ((id)string != nil && (id)mask != nil && [string bnc_isEqualToMaskedString:mask]) { \ - } else { \ - XCTAssertEqualObjects(string, mask); \ - } \ -} - -extern BOOL BNCTestStringMatchesRegex(NSString *string, NSString *regex); - -#define XCTAssertStringMatchesRegex(string, regex) \ - XCTAssertTrue(BNCTestStringMatchesRegex(string, regex)) - -@interface BNCTestCase : XCTestCase - -- (void)safelyFulfillExpectation:(XCTestExpectation *)expectation; -- (void)awaitExpectations; -- (void)resetExpectations; -- (double) systemVersion; - -// Load Resources from the test bundle: - -- (NSString*)stringFromBundleWithKey:(NSString*)key; -- (NSMutableDictionary*) mutableDictionaryFromBundleJSONWithKey:(NSString*)key; - -+ (void) clearAllBranchSettings; -+ (BOOL) isApplication; -@end diff --git a/Branch-TestBed/Branch-SDK-Tests/BNCTestCase.m b/Branch-TestBed/Branch-SDK-Tests/BNCTestCase.m deleted file mode 100644 index 2afa92010..000000000 --- a/Branch-TestBed/Branch-SDK-Tests/BNCTestCase.m +++ /dev/null @@ -1,115 +0,0 @@ -/** - @file BNCTestCase.m - @package Branch-SDK-Tests - @brief The Branch testing framework super class. - - @author Edward Smith - @date April 2017 - @copyright Copyright © 2017 Branch. All rights reserved. -*/ - -#import "BNCTestCase.h" -#import "Branch.h" -#import "BNCApplication+BNCTest.h" - -#import "BNCUserAgentCollector.h" - -@interface Branch (BNCTest) -+ (void) clearAll; -@end - -NSString* kTestStringResourceName = @"BNCTestCase"; // File is 'BNCTestCase.strings'. Omit the '.string'. - -#pragma mark - BNCTestStringMatchesRegex - -BOOL BNCTestStringMatchesRegex(NSString *string, NSString *regex) { - NSError *error = nil; - NSRegularExpression* nsregex = - [NSRegularExpression regularExpressionWithPattern:regex options:0 error:&error]; - if (error) { - NSLog(@"Error in regex pattern: %@.", error); - return NO; - } - NSRange stringRange = NSMakeRange(0, string.length); - NSTextCheckingResult *match = [nsregex firstMatchInString:string options:0 range:stringRange]; - return NSEqualRanges(match.range, stringRange); -} - -#pragma mark - BNCTestCase - -@interface BNCTestCase () -@property (assign, nonatomic) BOOL hasExceededExpectations; -@end - -@implementation BNCTestCase - -- (void)setUp { - [super setUp]; - [self resetExpectations]; -} - -- (void)resetExpectations { - self.hasExceededExpectations = NO; -} - -- (void)safelyFulfillExpectation:(XCTestExpectation *)expectation { - if (!self.hasExceededExpectations) { - [expectation fulfill]; - } -} - -- (void)awaitExpectations { - [self waitForExpectationsWithTimeout:5 handler:^(NSError *error) { - self.hasExceededExpectations = YES; - }]; -} - -- (NSString*) stringFromBundleWithKey:(NSString*)key { - NSString *const kItemNotFound = @""; - NSString *resource = - [[NSBundle bundleForClass:self.class] - localizedStringForKey:key value:kItemNotFound table:kTestStringResourceName]; - if ([resource isEqualToString:kItemNotFound]) resource = nil; - return resource; -} - -- (NSMutableDictionary*) mutableDictionaryFromBundleJSONWithKey:(NSString*)key { - NSString *jsonString = [self stringFromBundleWithKey:key]; - XCTAssertTrue(jsonString, @"Can't load '%@' resource from bundle JSON!", key); - - NSError *error = nil; - NSDictionary *dictionary = - [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] - options:0 error:&error]; - XCTAssertNil(error); - XCTAssert(dictionary); - NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionary]; - return mutableDictionary; -} - -- (double) systemVersion { - return [UIDevice currentDevice].systemVersion.floatValue; -} - -static NSString* savedRandomizedBundleToken = nil; - -+ (void) initialize { - if (self != [BNCTestCase self]) return; - - savedRandomizedBundleToken = [BNCPreferenceHelper sharedInstance].randomizedBundleToken; - [Branch clearAll]; -} - -+ (void)tearDown { - [BNCPreferenceHelper sharedInstance].randomizedBundleToken = savedRandomizedBundleToken; -} - -+ (void) clearAllBranchSettings { - [Branch clearAll]; -} - -+ (BOOL) isApplication { - return [BNCApplication currentApplication].bundleID.length > 0; -} - -@end diff --git a/Branch-TestBed/Branch-SDK-Tests/BNCTestCase.strings b/Branch-TestBed/Branch-SDK-Tests/BNCTestCase.strings deleted file mode 100644 index 43dc2f622..000000000 --- a/Branch-TestBed/Branch-SDK-Tests/BNCTestCase.strings +++ /dev/null @@ -1,255 +0,0 @@ -/** - @file BNCTestCase.strings - @package Branch-SDK-Tests - @brief String resources for Branch-SDK-Tests. - - @author Edward Smith - @date October 2016 - @copyright Copyright © 2016 Branch. All rights reserved. -*/ - -"BNCTestCaseString" = "Test success!"; - -"DumpClassTest" = -" -Class 0x11a380018 is class 'DumpClass' of class 'NSObject': - Ivar 'stringVar' type 'NSString'. - Ivar 'intVar' type 'int'. - Ivar 'charPtrVar' type 'char*'. - Ivar 'classVar' type 'class'. - Ivar 'floatVar' type 'float'. - Ivar 'doubleVar' type 'double'. - Ivar 'shortVar' type 'short'. - Ivar 'boolVar' type 'BOOL'. - Ivar 'ucharVar' type 'unsigned char'. - Ivar 'uintVar' type 'unsigned int'. - Ivar 'ushortVar' type 'unsigned short'. - Ivar 'ulongVar' type 'unsigned long'. - Ivar 'doubleTroubleVar' type 'long double'. - Ivar 'UnhandledType' type '{UnhandledStruct=\"int1\"i\"int2\"i}' (un-handled type). - Ivar '_intProp' type 'int'. - Ivar '_stringProp' type 'NSString'. - Property name: 'intProp'. - Property name: 'stringProp'. - Class method name: 'classMethod'. - Method name: '.cxx_destruct'. - Method name: 'dealloc'. - Method name: 'init'. - Method name: 'setIntProp:'. - Method name: 'setStringProp:'. - Method name: 'methodThatTakesAnNSString:'. - Method name: 'intProp'. - Method name: 'stringProp'. -"; - -"DumpInstanceTest" = -" -Instance 0x132585f70 is of class 'DumpClass' of class 'NSObject': - Ivar 'stringVar' type '__NSCFConstantString' value 'Yope!'. - Ivar 'intVar' type 'int' value '1'. - Ivar 'charPtrVar' type 'char*' value 'YopeCharString'. - Ivar 'classVar' type 'class' value 'NSNumber'. - Ivar 'floatVar' type 'float' value '2.000000'. - Ivar 'doubleVar' type 'double' value '3.000000'. - Ivar 'shortVar' type 'short' value '4'. - Ivar 'boolVar' type 'BOOL' value 'NO'. - Ivar 'ucharVar' type 'unsigned char' value ''. - Ivar 'uintVar' type 'unsigned int' value '0'. - Ivar 'ushortVar' type 'unsigned short' value '0'. - Ivar 'ulongVar' type 'unsigned long' value '0'. - Ivar 'doubleTroubleVar' type 'long double' value '0.000000'. - Ivar 'UnhandledType' type '{UnhandledStruct=\"int1\"i\"int2\"i}' (un-handled type). - Ivar '_intProp' type 'int' value '5'. - Ivar '_stringProp' type '__NSCFConstantString' value 'Props!'. - Property name: 'intProp'. - Property name: 'stringProp'. - Class method name: 'classMethod'. - Method name: '.cxx_destruct'. - Method name: 'dealloc'. - Method name: 'init'. - Method name: 'setIntProp:'. - Method name: 'setStringProp:'. - Method name: 'methodThatTakesAnNSString:'. - Method name: 'intProp'. - Method name: 'stringProp'. -"; - -"BranchUniversalObjectJSON" = -" -{ - \"$content_schema\": \"COMMERCE_PRODUCT\", - \"$quantity\": 2, - \"$price\": 23.2, - \"$currency\": \"USD\", - \"$sku\": \"1994320302\", - \"$product_name\": \"my_product_name1\", - \"$product_brand\": \"my_prod_Brand1\", - \"$product_category\": \"Baby & Toddler\", - \"$product_variant\": \"3T\", - \"$rating_average\": 5, - \"$rating_count\": 5, - \"$rating_max\": 7, - \"$rating\": 6, - \"$condition\": \"FAIR\", - \"$address_street\": \"Street_name1\", - \"$address_city\": \"city1\", - \"$address_region\": \"Region1\", - \"$address_country\": \"Country1\", - \"$address_postal_code\": \"postal_code\", - \"$latitude\": 12.07, - \"$longitude\": -97.5, - \"$image_captions\": [\"my_img_caption1\", \"my_img_caption_2\"], - \"$og_title\": \"My Content Title\", - \"$canonical_identifier\": \"item\/12345\", - \"$canonical_url\": \"https:\/\/branch.io\/deepviews\", - \"$keywords\": [\"My_Keyword1\", \"My_Keyword2\"], - \"$og_description\": \"my_product_description1\", - \"$og_image_url\": \"https:\/\/test_img_url\", - \"$exp_date\": 212123232544, - \"$publicly_indexable\": false, - \"$locally_indexable\": true, - \"$creation_timestamp\": 1501869445321, - \"Custom_Content_metadata_key1\": \"Custom_Content_metadata_val1\", - \"Custom_Content_metadata_key2\": \"Custom_Content_metadata_val2\" -} -"; -"V2EventProperties" = -" -{ - \"affiliation\": \"test_affiliation\", - \"coupon\": \"test_coupon\", - \"currency\": \"USD\", - \"description\": \"Event _description\", - \"shipping\": 10.2, - \"tax\": 12.3, - \"revenue\": 1.5, - \"search_query\": \"Query\", - \"transaction_id\": \"12344555\", - \"custom_data\": { - \"Custom_Event_Property_Key1\": \"Custom_Event_Property_val1\", - \"Custom_Event_Property_Key2\": \"Custom_Event_Property_val2\" - } -} -"; -"V2EventJSON" = -" -{ - \"name\": \"PURCHASE\", - \"metadata\" : { - \"skan_time_window\": \"5184000.000000\" - }, - \"custom_data\": { - \"Custom_Event_Property_Key1\": \"Custom_Event_Property_val1\", - \"Custom_Event_Property_Key2\": \"Custom_Event_Property_val2\" - }, - \"customer_event_alias\": \"event alias\", - \"event_data\": { - \"affiliation\": \"test_affiliation\", - \"coupon\": \"test_coupon\", - \"currency\": \"USD\", - \"description\": \"Event _description\", - \"shipping\": 10.2, - \"tax\": 12.3, - \"revenue\": 1.5, - \"transaction_id\": \"12344555\", - \"search_query\": \"Query\" - }, - \"content_items\": [{ - \"$content_schema\": \"COMMERCE_PRODUCT\", - \"$quantity\": 2, - \"$price\": 23.2, - \"$currency\": \"USD\", - \"$condition\": \"FAIR\", - \"$sku\": \"1994320302\", - \"$product_name\": \"my_product_name1\", - \"$product_brand\": \"my_prod_Brand1\", - \"$product_category\": \"Baby & Toddler\", - \"$product_variant\": \"3T\", - \"$rating_average\": 5, - \"$rating_count\": 5, - \"$rating_max\": 7, - \"$rating\": 6, - \"$address_street\": \"Street_name1\", - \"$address_city\": \"city1\", - \"$address_region\": \"Region1\", - \"$address_country\": \"Country1\", - \"$address_postal_code\": \"postal_code\", - \"$latitude\": 12.07, - \"$longitude\": -97.5, - \"$image_captions\": [\"my_img_caption1\", \"my_img_caption_2\"], - \"Custom_Content_metadata_key1\": \"Custom_Content_metadata_val1\", - \"Custom_Content_metadata_key2\": \"Custom_Content_metadata_val2\", - \"$og_title\": \"My Content Title\", - \"$canonical_identifier\": \"item\/12345\", - \"$canonical_url\": \"https:\/\/branch.io\/deepviews\", - \"$keywords\": [\"My_Keyword1\", \"My_Keyword2\"], - \"$og_description\": \"my_product_description1\", - \"$og_image_url\": \"https:\/\/test_img_url\", - \"$exp_date\": 212123232544, - \"$locally_indexable\": true, - \"$creation_timestamp\": 1501869445321 - }], - \"user_data\": { - \"os\": \"iOS\", - \"os_version\": 25, - \"environment\": \"FULL_APP\", - \"idfa\": \"\", - \"idfv\": \"\", - \"user_agent\": \"\", - \"developer_identity\": \"edsojan\", - \"country\": \"US\", - \"language\": \"en\", - \"brand\": \"Apple\", - \"randomized_device_token\": \"\", - \"sdk\": \"ios0.17.10\", - \"app_version\": \"whatever\", - \"model\": \"x86_64\", - \"screen_dpi\": 3, - \"screen_height\": 2208, - \"screen_width\": 1242 - }, - \"branch_key\": \"key_live_foo\", - \"retryNumber\": 0 -} -"; -"BUODescription" = -""; -"BNCDeviceDictionaryV2" = -"{ - \"os\": \"iOS\", - \"os_version\": 25, - \"environment\": \"FULL_APP\", - \"idfa\": \"\", - \"idfv\": \"\", - \"user_agent\": \"\", - \"developer_identity\": \"edsojan\", - \"country\": \"US\", - \"language\": \"en\", - \"brand\": \"Apple\", - \"randomized_device_token\": \"\", - \"sdk\": \"ios\", - \"sdk_version\": \"0.17.10\", - \"app_version\": \"whatever\", - \"model\": \"x86_64\", - \"screen_dpi\": 3, - \"screen_height\": 2208, - \"screen_width\": 1242 -}"; - diff --git a/Branch-TestBed/Branch-SDK-Tests/Branch-SDK-Tests-Bridging-Header.h b/Branch-TestBed/Branch-SDK-Tests/Branch-SDK-Tests-Bridging-Header.h index 1e7530a59..169bd50f3 100644 --- a/Branch-TestBed/Branch-SDK-Tests/Branch-SDK-Tests-Bridging-Header.h +++ b/Branch-TestBed/Branch-SDK-Tests/Branch-SDK-Tests-Bridging-Header.h @@ -2,5 +2,4 @@ // Module headers for Branch SDK unit testing. // -#import "BNCTestCase.h" #import "Branch.h" diff --git a/Branch-TestBed/Branch-SDK-Tests/BranchInstallRequestTests.m b/Branch-TestBed/Branch-SDK-Tests/BranchInstallRequestTests.m deleted file mode 100644 index b46ffefae..000000000 --- a/Branch-TestBed/Branch-SDK-Tests/BranchInstallRequestTests.m +++ /dev/null @@ -1,318 +0,0 @@ -// -// BranchInstallRequestTests.m -// Branch-TestBed -// -// Created by Graham Mueller on 6/24/15. -// Copyright (c) 2015 Branch Metrics. All rights reserved. -// - -#import "BNCTestCase.h" -#import "Branch.h" -#import "BNCApplication.h" -#import "BNCApplication+BNCTest.h" -#import "BranchInstallRequest.h" -#import "BNCPreferenceHelper.h" -#import "BNCSystemObserver.h" -#import "BranchConstants.h" -#import "BNCEncodingUtils.h" -//#import -// -//@interface BranchInstallRequestTests : BNCTestCase -//@end -// -//@implementation BranchInstallRequestTests -// -//- (void)setUp { -// [super setUp]; -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// preferenceHelper.installParams = nil; -// preferenceHelper.randomizedBundleToken = nil; -// [preferenceHelper saveContentAnalyticsManifest:nil]; -// [preferenceHelper synchronize]; -//} -// -//- (void)testSuccessWithAllKeysAndIsReferrable { -// NSString * const DEVICE_TOKEN = @"foo-token"; -// NSString * const USER_URL = @"http://foo"; -// NSString * const DEVELOPER_ID = @"foo"; -// NSString * const SESSION_ID = @"foo-session"; -// NSString * const SESSION_PARAMS = @"{\"+clicked_branch_link\":1,\"foo\":\"bar\"}"; -// NSString * const RANDOMIZED_BUNDLE_TOKEN = @"randomized_bundle_token"; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ -// BRANCH_RESPONSE_KEY_RANDOMIZED_DEVICE_TOKEN: DEVICE_TOKEN, -// BRANCH_RESPONSE_KEY_USER_URL: USER_URL, -// BRANCH_RESPONSE_KEY_DEVELOPER_IDENTITY: DEVELOPER_ID, -// BRANCH_RESPONSE_KEY_SESSION_ID: SESSION_ID, -// BRANCH_RESPONSE_KEY_SESSION_DATA: SESSION_PARAMS, -// BRANCH_RESPONSE_KEY_RANDOMIZED_BUNDLE_TOKEN: RANDOMIZED_BUNDLE_TOKEN -// }; -// -// XCTestExpectation *openExpectation = [self expectationWithDescription:@"OpenRequest Expectation"]; -// BranchInstallRequest *request = [[BranchInstallRequest alloc] initWithCallback:^(BOOL success, NSError *error) { -// XCTAssertNil(error); -// XCTAssertTrue(success); -// [self safelyFulfillExpectation:openExpectation]; -// }]; -// -// [Branch setBranchKey:@"key_live_foo"]; -// [request processResponse:response error:nil]; -// [self awaitExpectations]; -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// XCTAssertEqualObjects(preferenceHelper.randomizedDeviceToken, DEVICE_TOKEN); -// XCTAssertEqualObjects(preferenceHelper.userUrl, USER_URL); -// XCTAssertEqualObjects(preferenceHelper.userIdentity, DEVELOPER_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionID, SESSION_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionParams, SESSION_PARAMS); -// XCTAssertEqualObjects(preferenceHelper.installParams, SESSION_PARAMS); -// XCTAssertEqualObjects(preferenceHelper.randomizedBundleToken, RANDOMIZED_BUNDLE_TOKEN); -// XCTAssertNil(preferenceHelper.linkClickIdentifier); -//} -// -//- (void)testSuccessWithAllKeysAndIsNotReferrable { -// NSString * const DEVICE_TOKEN = @"foo-token"; -// NSString * const USER_URL = @"http://foo"; -// NSString * const DEVELOPER_ID = @"foo"; -// NSString * const SESSION_ID = @"foo-session"; -// NSString * const SESSION_PARAMS = @"{\"foo\":\"bar\"}"; -// NSString * const INSTALL_PARAMS = @"{\"bar\":\"foo\"}"; -// NSString * const RANDOMIZED_BUNDLE_TOKEN = @"randomized_bundle_token"; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ -// BRANCH_RESPONSE_KEY_RANDOMIZED_DEVICE_TOKEN: DEVICE_TOKEN, -// BRANCH_RESPONSE_KEY_USER_URL: USER_URL, -// BRANCH_RESPONSE_KEY_DEVELOPER_IDENTITY: DEVELOPER_ID, -// BRANCH_RESPONSE_KEY_SESSION_ID: SESSION_ID, -// BRANCH_RESPONSE_KEY_SESSION_DATA: SESSION_PARAMS, -// BRANCH_RESPONSE_KEY_RANDOMIZED_BUNDLE_TOKEN: RANDOMIZED_BUNDLE_TOKEN -// }; -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// preferenceHelper.installParams = INSTALL_PARAMS; -// -// XCTestExpectation *openExpectation = [self expectationWithDescription:@"OpenRequest Expectation"]; -// BranchInstallRequest *request = [[BranchInstallRequest alloc] initWithCallback:^(BOOL success, NSError *error) { -// XCTAssertNil(error); -// XCTAssertTrue(success); -// [self safelyFulfillExpectation:openExpectation]; -// }]; -// -// [Branch setBranchKey:@"key_live_foo"]; -// [request processResponse:response error:nil]; -// -// [self awaitExpectations]; -// -// XCTAssertEqualObjects(preferenceHelper.randomizedDeviceToken, DEVICE_TOKEN); -// XCTAssertEqualObjects(preferenceHelper.userUrl, USER_URL); -// XCTAssertEqualObjects(preferenceHelper.userIdentity, DEVELOPER_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionID, SESSION_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionParams, SESSION_PARAMS); -// XCTAssertEqualObjects(preferenceHelper.installParams, INSTALL_PARAMS); -// XCTAssertEqualObjects(preferenceHelper.randomizedBundleToken, RANDOMIZED_BUNDLE_TOKEN); -// XCTAssertNil(preferenceHelper.linkClickIdentifier); -//} -// -//- (void)testSuccessWithNoSessionParamsAndIsNotReferrable { -// NSString * const DEVICE_TOKEN = @"foo-token"; -// NSString * const USER_URL = @"http://foo"; -// NSString * const DEVELOPER_ID = @"foo"; -// NSString * const SESSION_ID = @"foo-session"; -// NSString * const INSTALL_PARAMS = @"{\"bar\":\"foo\"}"; -// NSString * const RANDOMIZED_BUNDLE_TOKEN = @"randomized_bundle_token"; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ -// BRANCH_RESPONSE_KEY_RANDOMIZED_DEVICE_TOKEN: DEVICE_TOKEN, -// BRANCH_RESPONSE_KEY_USER_URL: USER_URL, -// BRANCH_RESPONSE_KEY_DEVELOPER_IDENTITY: DEVELOPER_ID, -// BRANCH_RESPONSE_KEY_SESSION_ID: SESSION_ID, -// BRANCH_RESPONSE_KEY_RANDOMIZED_BUNDLE_TOKEN: RANDOMIZED_BUNDLE_TOKEN -// }; -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// preferenceHelper.installParams = INSTALL_PARAMS; -// -// XCTestExpectation *openExpectation = [self expectationWithDescription:@"OpenRequest Expectation"]; -// BranchInstallRequest *request = [[BranchInstallRequest alloc] initWithCallback:^(BOOL success, NSError *error) { -// XCTAssertNil(error); -// XCTAssertTrue(success); -// [self safelyFulfillExpectation:openExpectation]; -// }]; -// -// [Branch setBranchKey:@"key_live_foo"]; -// [request processResponse:response error:nil]; -// [self awaitExpectations]; -// -// XCTAssertEqualObjects(preferenceHelper.randomizedDeviceToken, DEVICE_TOKEN); -// XCTAssertEqualObjects(preferenceHelper.userUrl, USER_URL); -// XCTAssertEqualObjects(preferenceHelper.userIdentity, DEVELOPER_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionID, SESSION_ID); -// XCTAssertEqualObjects(preferenceHelper.installParams, INSTALL_PARAMS); -// XCTAssertEqualObjects(preferenceHelper.randomizedBundleToken, RANDOMIZED_BUNDLE_TOKEN); -// XCTAssertNil(preferenceHelper.sessionParams); -// XCTAssertNil(preferenceHelper.linkClickIdentifier); -//} -// -//- (void)testSuccessWithNoSessionParamsAndIsReferrableAndAllowToBeClearIsNotSet { -// NSString * const DEVICE_TOKEN = @"foo-token"; -// NSString * const USER_URL = @"http://foo"; -// NSString * const DEVELOPER_ID = @"foo"; -// NSString * const SESSION_ID = @"foo-session"; -// NSString * const INSTALL_PARAMS = @"{\"bar\":\"foo\"}"; -// NSString * const RANDOMIZED_BUNDLE_TOKEN = @"randomized_bundle_token"; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ -// BRANCH_RESPONSE_KEY_RANDOMIZED_DEVICE_TOKEN: DEVICE_TOKEN, -// BRANCH_RESPONSE_KEY_USER_URL: USER_URL, -// BRANCH_RESPONSE_KEY_DEVELOPER_IDENTITY: DEVELOPER_ID, -// BRANCH_RESPONSE_KEY_SESSION_ID: SESSION_ID, -// BRANCH_RESPONSE_KEY_RANDOMIZED_BUNDLE_TOKEN: RANDOMIZED_BUNDLE_TOKEN -// }; -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// preferenceHelper.installParams = INSTALL_PARAMS; -// -// XCTestExpectation *openExpectation = [self expectationWithDescription:@"OpenRequest Expectation"]; -// BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:^(BOOL success, NSError *error) { -// XCTAssertNil(error); -// XCTAssertTrue(success); -// [self safelyFulfillExpectation:openExpectation]; -// }]; -// -// [Branch setBranchKey:@"key_live_foo"]; -// [request processResponse:response error:nil]; -// [self awaitExpectations]; -// -// XCTAssertEqualObjects(preferenceHelper.randomizedDeviceToken, DEVICE_TOKEN); -// XCTAssertEqualObjects(preferenceHelper.userUrl, USER_URL); -// XCTAssertEqualObjects(preferenceHelper.userIdentity, DEVELOPER_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionID, SESSION_ID); -// XCTAssertEqualObjects(preferenceHelper.installParams, INSTALL_PARAMS); -// XCTAssertEqualObjects(preferenceHelper.randomizedBundleToken, RANDOMIZED_BUNDLE_TOKEN); -// XCTAssertNil(preferenceHelper.sessionParams); -// XCTAssertNil(preferenceHelper.linkClickIdentifier); -//} -// -//- (void)testSuccessWithNoSessionParamsAndIsReferrableAndAllowToBeClearIsSet { -// NSString * const DEVICE_TOKEN = @"foo-token"; -// NSString * const USER_URL = @"http://foo"; -// NSString * const DEVELOPER_ID = @"foo"; -// NSString * const SESSION_ID = @"foo-session"; -// NSString * const RANDOMIZED_BUNDLE_TOKEN = @"randomized_bundle_token"; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ -// BRANCH_RESPONSE_KEY_RANDOMIZED_DEVICE_TOKEN: DEVICE_TOKEN, -// BRANCH_RESPONSE_KEY_USER_URL: USER_URL, -// BRANCH_RESPONSE_KEY_DEVELOPER_IDENTITY: DEVELOPER_ID, -// BRANCH_RESPONSE_KEY_SESSION_ID: SESSION_ID, -// BRANCH_RESPONSE_KEY_RANDOMIZED_BUNDLE_TOKEN: RANDOMIZED_BUNDLE_TOKEN -// }; -// -// XCTestExpectation *openExpectation = [self expectationWithDescription:@"OpenRequest Expectation"]; -// BranchInstallRequest *request = [[BranchInstallRequest alloc] initWithCallback:^(BOOL success, NSError *error) { -// XCTAssertNil(error); -// XCTAssertTrue(success); -// [self safelyFulfillExpectation:openExpectation]; -// } isInstall:YES]; -// -// [Branch setBranchKey:@"key_live_foo"]; -// [request processResponse:response error:nil]; -// [self awaitExpectations]; -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// XCTAssertEqualObjects(preferenceHelper.randomizedDeviceToken, DEVICE_TOKEN); -// XCTAssertEqualObjects(preferenceHelper.userUrl, USER_URL); -// XCTAssertEqualObjects(preferenceHelper.userIdentity, DEVELOPER_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionID, SESSION_ID); -// XCTAssertEqualObjects(preferenceHelper.randomizedBundleToken, RANDOMIZED_BUNDLE_TOKEN); -// XCTAssertNil(preferenceHelper.sessionParams); -// XCTAssertNil(preferenceHelper.linkClickIdentifier); -// XCTAssertNil(preferenceHelper.installParams); -//} -// -//- (void)testInstallWhenReferrableAndNullData { -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// -// XCTestExpectation *expectation = [self expectationWithDescription:@"ReferrableInstall"]; -// BranchInstallRequest *request = [[BranchInstallRequest alloc] initWithCallback:^(BOOL changed, NSError *error) { -// XCTAssertNil(error); -// XCTAssertNil(preferenceHelper.installParams); -// [self safelyFulfillExpectation:expectation]; -// }]; -// -// [Branch setBranchKey:@"key_live_foo"]; -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{}; -// [request processResponse:response error:nil]; -// [self awaitExpectations]; -//} -// -//- (void)testInstallWhenReferrableAndNonNullData { -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// -// NSString * const INSTALL_PARAMS = @"{\"+clicked_branch_link\":1,\"foo\":\"bar\"}"; -// -// XCTestExpectation *expectation = [self expectationWithDescription:@"Request Expectation"]; -// BranchInstallRequest *request = [[BranchInstallRequest alloc] initWithCallback:^(BOOL changed, NSError *error) { -// XCTAssertNil(error); -// XCTAssertEqualObjects(preferenceHelper.installParams, INSTALL_PARAMS); -// -// [self safelyFulfillExpectation:expectation]; -// }]; -// -// [Branch setBranchKey:@"key_live_foo"]; -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ BRANCH_RESPONSE_KEY_SESSION_DATA: INSTALL_PARAMS }; -// [request processResponse:response error:nil]; -// [self awaitExpectations]; -//} -// -//- (void)testInstallWhenReferrableAndNoInstallParamsAndNonLinkClickData { -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// -// NSString * const OPEN_PARAMS = @"{\"+clicked_branch_link\":0}"; -// -// XCTestExpectation *expectation = [self expectationWithDescription:@"Request Expectation"]; -// BranchInstallRequest *request = [[BranchInstallRequest alloc] initWithCallback:^(BOOL changed, NSError *error) { -// XCTAssertNil(error); -// XCTAssertNil(preferenceHelper.installParams); -// -// [self safelyFulfillExpectation:expectation]; -// }]; -// -// [Branch setBranchKey:@"key_live_foo"]; -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ BRANCH_RESPONSE_KEY_SESSION_DATA: OPEN_PARAMS }; -// [request processResponse:response error:nil]; -// [self awaitExpectations]; -//} -// -//- (void)testInstallWhenNotReferrable { -// // 'isReferrable' seems to be an empty concept in iOS. -// // It is in the code but not used. -- Edward. -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// NSString * const INSTALL_PARAMS = @"{\"+clicked_branch_link\":1,\"foo\":\"bar\"}"; -// -// XCTestExpectation *expectation = [self expectationWithDescription:@"Request Expectation"]; -// BranchInstallRequest *request = -// [[BranchInstallRequest alloc] initWithCallback:^(BOOL changed, NSError *error) { -// XCTAssertNil(error); -// XCTAssert([preferenceHelper.installParams isEqualToString:INSTALL_PARAMS]); -// [self safelyFulfillExpectation:expectation]; -// }]; -// -// [Branch setBranchKey:@"key_live_foo"]; -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ BRANCH_RESPONSE_KEY_SESSION_DATA: INSTALL_PARAMS }; -// [request processResponse:response error:nil]; -// -// [self awaitExpectations]; -//} -// -//@end diff --git a/Branch-TestBed/Branch-SDK-Tests/BranchOpenRequestTests.m b/Branch-TestBed/Branch-SDK-Tests/BranchOpenRequestTests.m deleted file mode 100644 index 234084b81..000000000 --- a/Branch-TestBed/Branch-SDK-Tests/BranchOpenRequestTests.m +++ /dev/null @@ -1,390 +0,0 @@ -// -// BranchOpenRequestTests.m -// Branch-TestBed -// -// Created by Graham Mueller on 6/19/15. -// Copyright (c) 2015 Branch Metrics. All rights reserved. -// - -#import "BNCTestCase.h" -#import "Branch.h" -#import "BNCApplication+BNCTest.h" -#import "BranchOpenRequest.h" -#import "BranchConstants.h" -#import "BNCPreferenceHelper.h" -#import "BNCPreferenceHelper.h" -#import "BNCEncodingUtils.h" -#import "BNCSystemObserver.h" -//#import -// -//@interface BranchOpenRequestTests : BNCTestCase -//@end -// -//@implementation BranchOpenRequestTests -// -//- (void)setUp { -// [super setUp]; -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// preferenceHelper.installParams = nil; -// preferenceHelper.randomizedBundleToken = nil; -// [preferenceHelper saveContentAnalyticsManifest:nil]; -// [preferenceHelper synchronize]; -//} -// -//- (void)testSuccessWithAllKeysAndIsReferrable { -// NSString * const DEVICE_TOKEN = @"foo-token"; -// NSString * const USER_URL = @"http://foo"; -// NSString * const DEVELOPER_ID = @"foo"; -// NSString * const SESSION_ID = @"foo-session"; -// NSString * const SESSION_PARAMS = @"{\"+clicked_branch_link\":1,\"foo\":\"bar\"}"; -// NSString * const RANDOMIZED_BUNDLE_TOKEN = @"branch-id"; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ -// BRANCH_RESPONSE_KEY_RANDOMIZED_DEVICE_TOKEN: DEVICE_TOKEN, -// BRANCH_RESPONSE_KEY_USER_URL: USER_URL, -// BRANCH_RESPONSE_KEY_DEVELOPER_IDENTITY: DEVELOPER_ID, -// BRANCH_RESPONSE_KEY_SESSION_ID: SESSION_ID, -// BRANCH_RESPONSE_KEY_SESSION_DATA: SESSION_PARAMS, -// BRANCH_RESPONSE_KEY_RANDOMIZED_BUNDLE_TOKEN: RANDOMIZED_BUNDLE_TOKEN -// }; -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// -// XCTestExpectation *openExpectation = [self expectationWithDescription:@"OpenRequest Expectation"]; -// BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:^(BOOL success, NSError *error) { -// XCTAssertNil(error); -// XCTAssertTrue(success); -// [self safelyFulfillExpectation:openExpectation]; -// } isInstall:TRUE]; -// -// [request processResponse:response error:nil]; -// -// [self awaitExpectations]; -// -// XCTAssertEqualObjects(preferenceHelper.randomizedDeviceToken, DEVICE_TOKEN); -// XCTAssertEqualObjects(preferenceHelper.userUrl, USER_URL); -// XCTAssertEqualObjects(preferenceHelper.userIdentity, DEVELOPER_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionID, SESSION_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionParams, SESSION_PARAMS); -// XCTAssertEqualObjects(preferenceHelper.installParams, SESSION_PARAMS); -// XCTAssertEqualObjects(preferenceHelper.randomizedBundleToken, RANDOMIZED_BUNDLE_TOKEN); -// XCTAssertNil(preferenceHelper.linkClickIdentifier); -//} -// -//- (void)testSuccessWithAllKeysAndIsNotReferrable { -// NSString * const DEVICE_TOKEN = @"foo-token"; -// NSString * const USER_URL = @"http://foo"; -// NSString * const DEVELOPER_ID = @"foo"; -// NSString * const SESSION_ID = @"foo-session"; -// NSString * const SESSION_PARAMS = @"{\"foo\":\"bar\"}"; -// NSString * const INSTALL_PARAMS = @"{\"bar\":\"foo\"}"; -// NSString * const IDENTITY = @"branch-id"; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ -// BRANCH_RESPONSE_KEY_RANDOMIZED_DEVICE_TOKEN: DEVICE_TOKEN, -// BRANCH_RESPONSE_KEY_USER_URL: USER_URL, -// BRANCH_RESPONSE_KEY_DEVELOPER_IDENTITY: DEVELOPER_ID, -// BRANCH_RESPONSE_KEY_SESSION_ID: SESSION_ID, -// BRANCH_RESPONSE_KEY_SESSION_DATA: SESSION_PARAMS, -// BRANCH_RESPONSE_KEY_RANDOMIZED_BUNDLE_TOKEN: IDENTITY -// }; -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// preferenceHelper.installParams = INSTALL_PARAMS; -// -// XCTestExpectation *openExpectation = [self expectationWithDescription:@"OpenRequest Expectation"]; -// BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:^(BOOL success, NSError *error) { -// XCTAssertNil(error); -// XCTAssertTrue(success); -// [self safelyFulfillExpectation:openExpectation]; -// }]; -// -// [request processResponse:response error:nil]; -// -// [self awaitExpectations]; -// -// XCTAssertEqualObjects(preferenceHelper.randomizedDeviceToken, DEVICE_TOKEN); -// XCTAssertEqualObjects(preferenceHelper.userUrl, USER_URL); -// XCTAssertEqualObjects(preferenceHelper.userIdentity, DEVELOPER_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionID, SESSION_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionParams, SESSION_PARAMS); -// XCTAssertEqualObjects(preferenceHelper.installParams, INSTALL_PARAMS); -// XCTAssertEqualObjects(preferenceHelper.randomizedBundleToken, IDENTITY); -// XCTAssertNil(preferenceHelper.linkClickIdentifier); -//} -// -//- (void)testSuccessWithNoSessionParamsAndIsNotReferrable { -// NSString * const DEVICE_TOKEN = @"foo-token"; -// NSString * const USER_URL = @"http://foo"; -// NSString * const DEVELOPER_ID = @"foo"; -// NSString * const SESSION_ID = @"foo-session"; -// NSString * const INSTALL_PARAMS = @"{\"bar\":\"foo\"}"; -// NSString * const IDENTITY = @"branch-id"; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ -// BRANCH_RESPONSE_KEY_RANDOMIZED_DEVICE_TOKEN: DEVICE_TOKEN, -// BRANCH_RESPONSE_KEY_USER_URL: USER_URL, -// BRANCH_RESPONSE_KEY_DEVELOPER_IDENTITY: DEVELOPER_ID, -// BRANCH_RESPONSE_KEY_SESSION_ID: SESSION_ID, -// BRANCH_RESPONSE_KEY_RANDOMIZED_BUNDLE_TOKEN: IDENTITY -// }; -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// preferenceHelper.installParams = INSTALL_PARAMS; -// -// XCTestExpectation *openExpectation = [self expectationWithDescription:@"OpenRequest Expectation"]; -// BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:^(BOOL success, NSError *error) { -// XCTAssertNil(error); -// XCTAssertTrue(success); -// [self safelyFulfillExpectation:openExpectation]; -// }]; -// -// [request processResponse:response error:nil]; -// -// [self awaitExpectations]; -// -// XCTAssertEqualObjects(preferenceHelper.randomizedDeviceToken, DEVICE_TOKEN); -// XCTAssertEqualObjects(preferenceHelper.userUrl, USER_URL); -// XCTAssertEqualObjects(preferenceHelper.userIdentity, DEVELOPER_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionID, SESSION_ID); -// XCTAssertEqualObjects(preferenceHelper.installParams, INSTALL_PARAMS); -// XCTAssertEqualObjects(preferenceHelper.randomizedBundleToken, IDENTITY); -// XCTAssertNil(preferenceHelper.sessionParams); -// XCTAssertNil(preferenceHelper.linkClickIdentifier); -//} -// -//- (void)testSuccessWithNoSessionParamsAndIsReferrableAndAllowToBeClearIsNotSet { -// NSString * const DEVICE_TOKEN = @"foo-token"; -// NSString * const USER_URL = @"http://foo"; -// NSString * const DEVELOPER_ID = @"foo"; -// NSString * const SESSION_ID = @"foo-session"; -// NSString * const INSTALL_PARAMS = @"{\"bar\":\"foo\"}"; -// NSString * const IDENTITY = @"branch-id"; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ -// BRANCH_RESPONSE_KEY_RANDOMIZED_DEVICE_TOKEN: DEVICE_TOKEN, -// BRANCH_RESPONSE_KEY_USER_URL: USER_URL, -// BRANCH_RESPONSE_KEY_DEVELOPER_IDENTITY: DEVELOPER_ID, -// BRANCH_RESPONSE_KEY_SESSION_ID: SESSION_ID, -// BRANCH_RESPONSE_KEY_RANDOMIZED_BUNDLE_TOKEN: IDENTITY -// }; -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// preferenceHelper.installParams = INSTALL_PARAMS; -// -// XCTestExpectation *openExpectation = [self expectationWithDescription:@"OpenRequest Expectation"]; -// BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:^(BOOL success, NSError *error) { -// XCTAssertNil(error); -// XCTAssertTrue(success); -// [self safelyFulfillExpectation:openExpectation]; -// }]; -// -// [request processResponse:response error:nil]; -// -// [self awaitExpectations]; -// -// XCTAssertEqualObjects(preferenceHelper.randomizedDeviceToken, DEVICE_TOKEN); -// XCTAssertEqualObjects(preferenceHelper.userUrl, USER_URL); -// XCTAssertEqualObjects(preferenceHelper.userIdentity, DEVELOPER_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionID, SESSION_ID); -// XCTAssertEqualObjects(preferenceHelper.installParams, INSTALL_PARAMS); -// XCTAssertEqualObjects(preferenceHelper.randomizedBundleToken, IDENTITY); -// XCTAssertNil(preferenceHelper.sessionParams); -// XCTAssertNil(preferenceHelper.linkClickIdentifier); -//} -// -//- (void)testSuccessWithNoSessionParamsAndIsReferrableAndAllowToBeClearIsSet { -// NSString * const DEVICE_TOKEN = @"foo-token"; -// NSString * const USER_URL = @"http://foo"; -// NSString * const DEVELOPER_ID = @"foo"; -// NSString * const SESSION_ID = @"foo-session"; -// NSString * const IDENTITY = @"branch-id"; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ -// BRANCH_RESPONSE_KEY_RANDOMIZED_DEVICE_TOKEN: DEVICE_TOKEN, -// BRANCH_RESPONSE_KEY_USER_URL: USER_URL, -// BRANCH_RESPONSE_KEY_DEVELOPER_IDENTITY: DEVELOPER_ID, -// BRANCH_RESPONSE_KEY_SESSION_ID: SESSION_ID, -// BRANCH_RESPONSE_KEY_RANDOMIZED_BUNDLE_TOKEN: IDENTITY -// }; -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// -// XCTestExpectation *openExpectation = [self expectationWithDescription:@"OpenRequest Expectation"]; -// BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:^(BOOL success, NSError *error) { -// XCTAssertNil(error); -// XCTAssertTrue(success); -// [self safelyFulfillExpectation:openExpectation]; -// } isInstall:NO]; -// -// [request processResponse:response error:nil]; -// -// [self awaitExpectations]; -// -// XCTAssertEqualObjects(preferenceHelper.randomizedDeviceToken, DEVICE_TOKEN); -// XCTAssertEqualObjects(preferenceHelper.userUrl, USER_URL); -// XCTAssertEqualObjects(preferenceHelper.userIdentity, DEVELOPER_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionID, SESSION_ID); -// XCTAssertEqualObjects(preferenceHelper.randomizedBundleToken, IDENTITY); -// XCTAssertNil(preferenceHelper.sessionParams); -// XCTAssertNil(preferenceHelper.linkClickIdentifier); -// XCTAssertNil(preferenceHelper.installParams); -//} -// -//- (void)testOpenWhenReferrableAndNoInstallParamsAndNonNullData { -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// -// NSString * const OPEN_PARAMS = @"{\"+clicked_branch_link\":1,\"foo\":\"bar\"}"; -// -// XCTestExpectation *expectation = [self expectationWithDescription:@"Request Expectation"]; -// BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:^(BOOL changed, NSError *error) { -// XCTAssertNil(error); -// XCTAssertEqualObjects(preferenceHelper.installParams, OPEN_PARAMS); -// -// [self safelyFulfillExpectation:expectation]; -// } isInstall:TRUE]; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ BRANCH_RESPONSE_KEY_SESSION_DATA: OPEN_PARAMS }; -// [request processResponse:response error:nil]; -// -// [self awaitExpectations]; -//} -// -//- (void)testOpenWhenReferrableAndNoInstallParamsAndNullData { -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// -// XCTestExpectation *expectation = [self expectationWithDescription:@"Request Expectation"]; -// BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:^(BOOL changed, NSError *error) { -// XCTAssertNil(error); -// XCTAssertNil(preferenceHelper.installParams); -// -// [self safelyFulfillExpectation:expectation]; -// }]; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ }; -// [request processResponse:response error:nil]; -// -// [self awaitExpectations]; -//} -// -//- (void)testOpenWhenReferrableAndNoInstallParamsAndNonLinkClickData { -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// -// NSString * const OPEN_PARAMS = @"{\"+clicked_branch_link\":0}"; -// -// XCTestExpectation *expectation = [self expectationWithDescription:@"Request Expectation"]; -// BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:^(BOOL changed, NSError *error) { -// XCTAssertNil(error); -// XCTAssertNil(preferenceHelper.installParams); -// -// [self safelyFulfillExpectation:expectation]; -// }]; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ BRANCH_RESPONSE_KEY_SESSION_DATA: OPEN_PARAMS }; -// [request processResponse:response error:nil]; -// -// [self awaitExpectations]; -//} -// -//- (void)testOpenWhenReferrableAndInstallParams { -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// -// NSString * const INSTALL_PARAMS = @"{\"+clicked_branch_link\":1,\"foo\":\"bar\"}"; -// NSString * const OPEN_PARAMS = @"{\"+clicked_branch_link\":1,\"bar\":\"foo\"}"; -// -// preferenceHelper.installParams = INSTALL_PARAMS; -// -// XCTestExpectation *expectation = [self expectationWithDescription:@"Request Expectation"]; -// BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:^(BOOL changed, NSError *error) { -// XCTAssertNil(error); -// XCTAssertEqualObjects(preferenceHelper.installParams, INSTALL_PARAMS); -// -// [self safelyFulfillExpectation:expectation]; -// }]; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ BRANCH_RESPONSE_KEY_SESSION_DATA: OPEN_PARAMS }; -// [request processResponse:response error:nil]; -// -// [self awaitExpectations]; -//} -// -//- (void)testOpenWhenNotReferrable { -// // 'isReferrable' seems to be an empty concept in iOS. -// // It is in the code but not used. -- Edward. -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// -// NSString * const OPEN_PARAMS = @"{\"+clicked_branch_link\":1,\"foo\":\"bar\"}"; -// -// XCTestExpectation *expectation = [self expectationWithDescription:@"Request Expectation"]; -// BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:^(BOOL changed, NSError *error) { -// XCTAssertNil(error); -// XCTAssert([preferenceHelper.installParams isEqualToString:OPEN_PARAMS]); -// [self safelyFulfillExpectation:expectation]; -// } isInstall:TRUE]; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ BRANCH_RESPONSE_KEY_SESSION_DATA: OPEN_PARAMS }; -// [request processResponse:response error:nil]; -// -// [self awaitExpectations]; -//} -// -//- (void)testEmptyResponseFields { -// NSString * DEVICE_TOKEN = @"foo-token"; -// NSString * USER_URL = @"http://foo"; -// NSString * DEVELOPER_ID = @"foo"; -// NSString * SESSION_ID = @"foo-session"; -// NSString * IDENTITY = @"branch-id"; -// -// BNCServerResponse *response = [[BNCServerResponse alloc] init]; -// response.data = @{ -// BRANCH_RESPONSE_KEY_RANDOMIZED_DEVICE_TOKEN: DEVICE_TOKEN, -// BRANCH_RESPONSE_KEY_USER_URL: USER_URL, -// BRANCH_RESPONSE_KEY_DEVELOPER_IDENTITY: DEVELOPER_ID, -// BRANCH_RESPONSE_KEY_SESSION_ID: SESSION_ID, -// BRANCH_RESPONSE_KEY_RANDOMIZED_BUNDLE_TOKEN: IDENTITY -// }; -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// -// XCTestExpectation *openExpectation = [self expectationWithDescription:@"OpenRequest Expectation"]; -// BranchOpenRequest *request = [[BranchOpenRequest alloc] initWithCallback:^(BOOL success, NSError *error) { -// XCTAssertNil(error); -// XCTAssertTrue(success); -// [self safelyFulfillExpectation:openExpectation]; -// } isInstall:NO]; -// -// [request processResponse:response error:nil]; -// -// [self awaitExpectations]; -// -// XCTAssertEqualObjects(preferenceHelper.randomizedDeviceToken, DEVICE_TOKEN); -// XCTAssertEqualObjects(preferenceHelper.userUrl, USER_URL); -// XCTAssertEqualObjects(preferenceHelper.userIdentity, DEVELOPER_ID); -// XCTAssertEqualObjects(preferenceHelper.sessionID, SESSION_ID); -// XCTAssertEqualObjects(preferenceHelper.randomizedBundleToken, IDENTITY); -// XCTAssertNil(preferenceHelper.sessionParams); -// XCTAssertNil(preferenceHelper.linkClickIdentifier); -// XCTAssertNil(preferenceHelper.installParams); -// -// // Now call processResponse with empty fields again. -// response.data = @{}; -// [request processResponse:response error:nil]; -// -// XCTAssertNotNil(preferenceHelper.randomizedDeviceToken); -// XCTAssertNotNil(preferenceHelper.userUrl); -// XCTAssertNotNil(preferenceHelper.sessionID); -// XCTAssertNotNil(preferenceHelper.randomizedBundleToken); -//} -// -//@end diff --git a/Branch-TestBed/Branch-SDK-Tests/BranchSDKFunctionalityTests.m b/Branch-TestBed/Branch-SDK-Tests/BranchSDKFunctionalityTests.m deleted file mode 100644 index 889ee54a3..000000000 --- a/Branch-TestBed/Branch-SDK-Tests/BranchSDKFunctionalityTests.m +++ /dev/null @@ -1,121 +0,0 @@ -// -// Branch_SDK_test.m -// Branch-SDK test -// -// Created by Qinwei Gong on 2/19/15. -// Copyright (c) 2015 Branch Metrics. All rights reserved. -// - -#import "BNCTestCase.h" -#import "Branch.h" - -NSString * const TEST_RANDOMIZED_DEVICE_TOKEN = @"94938498586381084"; -NSString * const TEST_RANDOMIZED_BUNDLE_TOKEN = @"95765863201768032"; -NSString * const TEST_SESSION_ID = @"97141055400444225"; -NSString * const TEST_IDENTITY_LINK = @"https://bnc.lt/i/3N-xr0E-_M"; -NSString * const TEST_NEW_USER_LINK = @"https://bnc.lt/i/2kkbX6k-As"; - -@interface BranchSDKFunctionalityTests : BNCTestCase -@property (assign, nonatomic) BOOL hasExceededExpectations; -@end - -@implementation BranchSDKFunctionalityTests - -//- (void)test00OpenOrInstall { -// id serverInterfaceMock = OCMClassMock([BNCServerInterface class]); -// -// BNCPreferenceHelper *preferenceHelper = [BNCPreferenceHelper sharedInstance]; -// Branch.branchKey = @"key_live_foo"; -// -// Branch *branch = -// [[Branch alloc] -// initWithInterface:serverInterfaceMock -// queue:[[BNCServerRequestQueue alloc] init] -// cache:[[BNCLinkCache alloc] init] -// preferenceHelper:preferenceHelper -// key:@"key_live_foo"]; -// -// BNCServerResponse *openInstallResponse = [[BNCServerResponse alloc] init]; -// openInstallResponse.data = @{ -// @"randomized_device_token": TEST_RANDOMIZED_DEVICE_TOKEN, -// @"randomized_bundle_token": TEST_RANDOMIZED_BUNDLE_TOKEN, -// @"link": TEST_IDENTITY_LINK, -// @"session_id": TEST_SESSION_ID -// }; -// -// __block BNCServerCallback openOrInstallCallback; -// id openOrInstallCallbackCheckBlock = [OCMArg checkWithBlock:^BOOL(BNCServerCallback callback) { -// openOrInstallCallback = callback; -// return YES; -// }]; -// -// id openOrInstallInvocation = ^(NSInvocation *invocation) { -// openOrInstallCallback(openInstallResponse, nil); -// }; -// -// id openOrInstallUrlCheckBlock = [OCMArg checkWithBlock:^BOOL(NSString *url) { -// return [url rangeOfString:@"open"].location != NSNotFound || [url rangeOfString:@"install"].location != NSNotFound; -// }]; -// [[[serverInterfaceMock expect] -// andDo:openOrInstallInvocation] -// postRequest:[OCMArg any] -// url:openOrInstallUrlCheckBlock -// key:[OCMArg any] -// callback:openOrInstallCallbackCheckBlock]; -// -// XCTestExpectation *openExpectation = [self expectationWithDescription:@"Test open"]; -// [branch initSessionWithLaunchOptions:@{} andRegisterDeepLinkHandler:^(NSDictionary *params, NSError *error) { -// XCTAssertNil(error); -// XCTAssertEqualObjects(preferenceHelper.sessionID, TEST_SESSION_ID); -// [openExpectation fulfill]; -// }]; -// -// [self waitForExpectationsWithTimeout:2 handler:NULL]; -//} -// -//#pragma mark - Test Utility -// -//- (void)safelyFulfillExpectation:(XCTestExpectation *)expectation { -// if (!self.hasExceededExpectations) { -// [expectation fulfill]; -// } -//} -// -//- (void)awaitExpectations { -// [self waitForExpectationsWithTimeout:6.0 handler:^(NSError *error) { -// self.hasExceededExpectations = YES; -// }]; -//} -// -//- (void)setupDefaultStubsForServerInterfaceMock:(id)serverInterfaceMock { -// BNCServerResponse *openInstallResponse = [[BNCServerResponse alloc] init]; -// openInstallResponse.data = @{ -// @"session_id": TEST_SESSION_ID, -// @"randomized_bundle_token": TEST_RANDOMIZED_BUNDLE_TOKEN, -// @"randomized_device_token": TEST_RANDOMIZED_DEVICE_TOKEN, -// }; -// -// // Stub open / install -// __block BNCServerCallback openOrInstallCallback; -// id openOrInstallCallbackCheckBlock = [OCMArg checkWithBlock:^BOOL(BNCServerCallback callback) { -// openOrInstallCallback = callback; -// return YES; -// }]; -// -// id openOrInstallInvocation = ^(NSInvocation *invocation) { -// openOrInstallCallback(openInstallResponse, nil); -// }; -// -// id openOrInstallUrlCheckBlock = [OCMArg checkWithBlock:^BOOL(NSString *url) { -// return [url rangeOfString:@"open"].location != NSNotFound || -// [url rangeOfString:@"install"].location != NSNotFound; -// }]; -// [[[serverInterfaceMock expect] -// andDo:openOrInstallInvocation] -// postRequest:[OCMArg any] -// url:openOrInstallUrlCheckBlock -// key:[OCMArg any] -// callback:openOrInstallCallbackCheckBlock]; -//} - -@end diff --git a/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj b/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj index 074565a71..855bb949d 100644 --- a/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj +++ b/Branch-TestBed/Branch-TestBed.xcodeproj/project.pbxproj @@ -22,13 +22,8 @@ 4683F0761B20A73F00A432E7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 670016731940F51400A9E103 /* AppDelegate.m */; }; 46DC406E1B2A328900D2D203 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67BBCF271A69E49A009C7DAE /* AdSupport.framework */; }; 4AB16368239E3A2700D42931 /* DispatchToIsolationQueueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AB16367239E3A2700D42931 /* DispatchToIsolationQueueTests.m */; }; - 4D1683A82098C902008819E3 /* BNCServerRequestQueueOldTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D16837D2098C901008819E3 /* BNCServerRequestQueueOldTests.m */; }; - 4D1683AA2098C902008819E3 /* BranchOpenRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D16837F2098C901008819E3 /* BranchOpenRequestTests.m */; }; - 4D1683AC2098C902008819E3 /* BranchInstallRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D1683822098C901008819E3 /* BranchInstallRequestTests.m */; }; 4D1683AE2098C902008819E3 /* BNCLinkDataTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D1683842098C901008819E3 /* BNCLinkDataTests.m */; }; - 4D1683B02098C902008819E3 /* BranchSDKFunctionalityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D1683862098C901008819E3 /* BranchSDKFunctionalityTests.m */; }; 4D1683B62098C902008819E3 /* BNCURLFilterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D16838C2098C901008819E3 /* BNCURLFilterTests.m */; }; - 4D1683B72098C902008819E3 /* BNCTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D16838D2098C901008819E3 /* BNCTestCase.m */; }; 4D1683B82098C902008819E3 /* BNCEncodingUtilsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D16838E2098C901008819E3 /* BNCEncodingUtilsTests.m */; }; 4D1683B92098C902008819E3 /* BNCSystemObserverTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D16838F2098C901008819E3 /* BNCSystemObserverTests.m */; }; 4D1683C02098C902008819E3 /* BranchUniversalObjectTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D1683962098C901008819E3 /* BranchUniversalObjectTests.m */; }; @@ -38,9 +33,6 @@ 4D1683C82098C902008819E3 /* NSStringBranchTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D16839E2098C901008819E3 /* NSStringBranchTests.m */; }; 4D1683CA2098C902008819E3 /* BNCPreferenceHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D1683A02098C901008819E3 /* BNCPreferenceHelperTests.m */; }; 4D1851C120180F3300E48994 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D1851BF20180F0600E48994 /* Security.framework */; }; - 4D7881FD209CF2D4002B750F /* BNCTestCase.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4D7881F9209CF2D4002B750F /* BNCTestCase.strings */; }; - 4D7881FE209CF2D4002B750F /* BNCTestCase.Test.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D7881FA209CF2D4002B750F /* BNCTestCase.Test.m */; }; - 4D7881FF209CF2D4002B750F /* BNCApplication+BNCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D7881FC209CF2D4002B750F /* BNCApplication+BNCTest.m */; }; 4D93D8622098D43C00CFABA6 /* UITestSafari.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D93D8602098D43C00CFABA6 /* UITestSafari.m */; }; 4DBEFFF61FB114F900F7C41B /* ArrayPickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DBEFFF51FB114F900F7C41B /* ArrayPickerView.m */; }; 4DE235641FB12C2700D4E5A9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4DBEFFFB1FB12A1000F7C41B /* Main.storyboard */; }; @@ -195,7 +187,6 @@ 5F644C482B7AA811000DCD78 /* BNCCallbackMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F644BB72B7AA811000DCD78 /* BNCCallbackMap.m */; }; 5F644C492B7AA811000DCD78 /* BNCEventUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F644BB82B7AA811000DCD78 /* BNCEventUtils.m */; }; 5F67F48E228F535500067429 /* BNCEncodingUtilsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F67F48D228F535500067429 /* BNCEncodingUtilsTests.m */; }; - 5F83B9ED2433BAAA0054A022 /* BNCServerInterface.Test.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D16837E2098C901008819E3 /* BNCServerInterface.Test.m */; }; 5F86501A2B76DA3200364BDE /* NSMutableDictionaryBranchTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F8650192B76DA3200364BDE /* NSMutableDictionaryBranchTests.m */; }; 5F892EC5236116CD0023AEC1 /* NSErrorBranchTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F892EC4236116CC0023AEC1 /* NSErrorBranchTests.m */; }; 5F8B7B4021B5F5CD009CE0A6 /* libBranch.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 466B58381B17773000A69EDE /* libBranch.a */; }; @@ -309,15 +300,9 @@ 03B49EEA25F9F315000BF105 /* UITestCase0OpenNInstall.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UITestCase0OpenNInstall.m; sourceTree = ""; }; 466B58381B17773000A69EDE /* libBranch.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libBranch.a; sourceTree = BUILT_PRODUCTS_DIR; }; 4AB16367239E3A2700D42931 /* DispatchToIsolationQueueTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DispatchToIsolationQueueTests.m; sourceTree = ""; }; - 4D16837D2098C901008819E3 /* BNCServerRequestQueueOldTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCServerRequestQueueOldTests.m; sourceTree = ""; }; - 4D16837E2098C901008819E3 /* BNCServerInterface.Test.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCServerInterface.Test.m; sourceTree = ""; }; - 4D16837F2098C901008819E3 /* BranchOpenRequestTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchOpenRequestTests.m; sourceTree = ""; }; 4D1683812098C901008819E3 /* Branch-SDK-Tests-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Branch-SDK-Tests-Bridging-Header.h"; sourceTree = ""; }; - 4D1683822098C901008819E3 /* BranchInstallRequestTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchInstallRequestTests.m; sourceTree = ""; }; 4D1683842098C901008819E3 /* BNCLinkDataTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCLinkDataTests.m; sourceTree = ""; }; - 4D1683862098C901008819E3 /* BranchSDKFunctionalityTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BranchSDKFunctionalityTests.m; sourceTree = ""; }; 4D16838C2098C901008819E3 /* BNCURLFilterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCURLFilterTests.m; sourceTree = ""; }; - 4D16838D2098C901008819E3 /* BNCTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCTestCase.m; sourceTree = ""; }; 4D16838E2098C901008819E3 /* BNCEncodingUtilsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCEncodingUtilsTests.m; sourceTree = ""; }; 4D16838F2098C901008819E3 /* BNCSystemObserverTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCSystemObserverTests.m; sourceTree = ""; }; 4D1683952098C901008819E3 /* BranchEvent.Test.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BranchEvent.Test.swift; sourceTree = ""; }; @@ -328,12 +313,7 @@ 4D16839E2098C901008819E3 /* NSStringBranchTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSStringBranchTests.m; sourceTree = ""; }; 4D16839F2098C901008819E3 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4D1683A02098C901008819E3 /* BNCPreferenceHelperTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCPreferenceHelperTests.m; sourceTree = ""; }; - 4D1683A12098C901008819E3 /* BNCTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BNCTestCase.h; sourceTree = ""; }; 4D1851BF20180F0600E48994 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; - 4D7881F9209CF2D4002B750F /* BNCTestCase.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = BNCTestCase.strings; sourceTree = ""; }; - 4D7881FA209CF2D4002B750F /* BNCTestCase.Test.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BNCTestCase.Test.m; sourceTree = ""; }; - 4D7881FB209CF2D4002B750F /* BNCApplication+BNCTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "BNCApplication+BNCTest.h"; sourceTree = ""; }; - 4D7881FC209CF2D4002B750F /* BNCApplication+BNCTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "BNCApplication+BNCTest.m"; sourceTree = ""; }; 4D93D8592098CC4400CFABA6 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 4D93D85F2098D43C00CFABA6 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4D93D8602098D43C00CFABA6 /* UITestSafari.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UITestSafari.m; sourceTree = ""; }; @@ -626,8 +606,6 @@ children = ( E7A728BC2AA9A112009343B7 /* BNCAPIServerTest.m */, 5FC7326F22DD1F93006E6FBC /* BNCAppleReceiptTests.m */, - 4D7881FB209CF2D4002B750F /* BNCApplication+BNCTest.h */, - 4D7881FC209CF2D4002B750F /* BNCApplication+BNCTest.m */, 4D1683972098C901008819E3 /* BNCApplicationTests.m */, 5FE694372405FA2700E3AEE2 /* BNCCallbackMapTests.m */, 4D16839D2098C901008819E3 /* BNCCrashlyticsWrapperTests.m */, @@ -648,15 +626,9 @@ 5F92B23323835FEB00CA909B /* BNCReachabilityTests.m */, C1CC888129BAAFC000BDD2B5 /* BNCReferringURLUtilityTests.m */, 5FC20E722A93D85F00D9E1C8 /* BNCRequestFactoryTests.m */, - 4D16837E2098C901008819E3 /* BNCServerInterface.Test.m */, - 4D16837D2098C901008819E3 /* BNCServerRequestQueueOldTests.m */, 5FB6CC12264F0C7C0020E478 /* BNCServerRequestQueueTests.m */, 5FDB04F324E6156800F2F267 /* BNCSKAdNetworkTests.m */, 4D16838F2098C901008819E3 /* BNCSystemObserverTests.m */, - 4D1683A12098C901008819E3 /* BNCTestCase.h */, - 4D16838D2098C901008819E3 /* BNCTestCase.m */, - 4D7881F9209CF2D4002B750F /* BNCTestCase.strings */, - 4D7881FA209CF2D4002B750F /* BNCTestCase.Test.m */, 5FCF7EAC29DC96A7008D629E /* BNCURLFilterSkiplistUpgradeTests.m */, 4D16838C2098C901008819E3 /* BNCURLFilterTests.m */, 5F205D022318641700C776D1 /* BNCUserAgentCollectorTests.m */, @@ -665,13 +637,10 @@ C17DAF7A2AC20C2000B16B1A /* BranchClassTests.m */, 4D16839C2098C901008819E3 /* BranchEvent.Test.m */, 4D1683952098C901008819E3 /* BranchEvent.Test.swift */, - 4D1683822098C901008819E3 /* BranchInstallRequestTests.m */, 5F909B712332BEF600A774D2 /* BranchLastAttributedTouchDataTests.m */, 5F5FDA132B7DE27D00F14A43 /* BranchLoggerTests.m */, - 4D16837F2098C901008819E3 /* BranchOpenRequestTests.m */, C10F393927A0872800BF5D36 /* BranchPluginSupportTests.m */, C12320B42808DB90007771C0 /* BranchQRCodeTests.m */, - 4D1683862098C901008819E3 /* BranchSDKFunctionalityTests.m */, C10C61A9282481FB00761D7E /* BranchShareLinkTests.m */, 4D1683962098C901008819E3 /* BranchUniversalObjectTests.m */, 4AB16367239E3A2700D42931 /* DispatchToIsolationQueueTests.m */, @@ -1251,7 +1220,6 @@ 5FC4CF8C24860C440001E701 /* latd.json in Resources */, 5FC4CF9024860C440001E701 /* example.json in Resources */, 5FC4CF9224860C440001E701 /* latd_missing_data.json in Resources */, - 4D7881FD209CF2D4002B750F /* BNCTestCase.strings in Resources */, 5FC4CF8D24860C440001E701 /* latd_missing_window.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1390,13 +1358,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4D1683B72098C902008819E3 /* BNCTestCase.m in Sources */, 4D1683B82098C902008819E3 /* BNCEncodingUtilsTests.m in Sources */, 5F909B5E23314CE900A774D2 /* BNCJSONUtilityTests.m in Sources */, 5F909B722332BEF600A774D2 /* BranchLastAttributedTouchDataTests.m in Sources */, - 4D7881FE209CF2D4002B750F /* BNCTestCase.Test.m in Sources */, 5FC20E732A93D85F00D9E1C8 /* BNCRequestFactoryTests.m in Sources */, - 4D1683B02098C902008819E3 /* BranchSDKFunctionalityTests.m in Sources */, 5FA9112F29BC662000F3D35C /* BNCNetworkInterfaceTests.m in Sources */, 5FD1786E26DEE49D009696E3 /* BNCPasteboardTests.m in Sources */, 5F86501A2B76DA3200364BDE /* NSMutableDictionaryBranchTests.m in Sources */, @@ -1404,7 +1369,6 @@ 5F92B242238752A500CA909B /* BNCDeviceInfoTests.m in Sources */, 4D1683C62098C902008819E3 /* BranchEvent.Test.m in Sources */, C15CC9DE2ABCB549003CC339 /* BNCCurrencyTests.m in Sources */, - 5F83B9ED2433BAAA0054A022 /* BNCServerInterface.Test.m in Sources */, 5F205D0823186AF700C776D1 /* BNCUserAgentCollectorTests.m in Sources */, 5FCF7EAD29DC96A7008D629E /* BNCURLFilterSkiplistUpgradeTests.m in Sources */, E7A728BD2AA9A112009343B7 /* BNCAPIServerTest.m in Sources */, @@ -1419,7 +1383,6 @@ 5FDB04F424E6156800F2F267 /* BNCSKAdNetworkTests.m in Sources */, 5FB6CC13264F0C7C0020E478 /* BNCServerRequestQueueTests.m in Sources */, 4D1683AE2098C902008819E3 /* BNCLinkDataTests.m in Sources */, - 4D7881FF209CF2D4002B750F /* BNCApplication+BNCTest.m in Sources */, C15CC9E02ABCF8C8003CC339 /* BranchActivityItemTests.m in Sources */, 5F92B23423835FEB00CA909B /* BNCReachabilityTests.m in Sources */, C17DAF7B2AC20C2000B16B1A /* BranchClassTests.m in Sources */, @@ -1429,12 +1392,9 @@ 5FC7327022DD1F93006E6FBC /* BNCAppleReceiptTests.m in Sources */, 4D1683C82098C902008819E3 /* NSStringBranchTests.m in Sources */, 5F892EC5236116CD0023AEC1 /* NSErrorBranchTests.m in Sources */, - 4D1683AA2098C902008819E3 /* BranchOpenRequestTests.m in Sources */, - 4D1683A82098C902008819E3 /* BNCServerRequestQueueOldTests.m in Sources */, 4D1683B62098C902008819E3 /* BNCURLFilterTests.m in Sources */, C10C61AA282481FB00761D7E /* BranchShareLinkTests.m in Sources */, 5F437E40237E1A560052064B /* BNCDeviceSystemTests.m in Sources */, - 4D1683AC2098C902008819E3 /* BranchInstallRequestTests.m in Sources */, 4D1683C72098C902008819E3 /* BNCCrashlyticsWrapperTests.m in Sources */, 5FDF91592581CDF4009BE5A3 /* BNCPartnerParametersTests.m in Sources */, ); diff --git a/Sources/BranchSDK/BNCApplication.m b/Sources/BranchSDK/BNCApplication.m index 67c9a6f0d..17ce42a03 100644 --- a/Sources/BranchSDK/BNCApplication.m +++ b/Sources/BranchSDK/BNCApplication.m @@ -75,15 +75,18 @@ + (NSDate *)currentBuildDate { NSDictionary *info = [NSBundle mainBundle].infoDictionary; NSString *appName = info[(__bridge NSString *)kCFBundleExecutableKey]; if (appName.length > 0 && bundleURL) { + // path to the app on device. file:///private/var/containers/Bundle/Application/GUID appURL = [bundleURL URLByAppendingPathComponent:appName]; } else { + // This else block is probably no longer necessary + // path to old app location, this symlinks to the new location. file:///var/containers/Bundle/Application/GUID NSString *path = [[NSProcessInfo processInfo].arguments firstObject]; if (path) { appURL = [NSURL fileURLWithPath:path]; } } if (appURL == nil) { - [[BranchLogger shared] logWarning:@"Failed to get build date, app path is nil" error:nil]; + [[BranchLogger shared] logError:@"Failed to get build date, app path is nil" error:nil]; return nil; } @@ -91,27 +94,29 @@ + (NSDate *)currentBuildDate { NSFileManager *fileManager = [NSFileManager defaultManager]; NSDictionary *attributes = [fileManager attributesOfItemAtPath:appURL.path error:&error]; if (error) { - [[BranchLogger shared] logWarning:@"Failed to get build date" error:error]; + [[BranchLogger shared] logError:@"Failed to get build date" error:error]; return nil; } NSDate *buildDate = [attributes fileCreationDate]; if (buildDate == nil || [buildDate timeIntervalSince1970] <= 0.0) { - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Invalid build date: %@", buildDate] error:nil]; + [[BranchLogger shared] logError:[NSString stringWithFormat:@"Invalid build date: %@", buildDate] error:nil]; } return buildDate; } + (NSDate *)firstInstallBuildDate { + // check for stored build date NSError *error = nil; NSDate *firstBuildDate = [BNCKeyChain retrieveDateForService:kBranchKeychainService key:kBranchKeychainFirstBuildKey error:&error]; if (firstBuildDate) { return firstBuildDate; } + // get current build date and store it firstBuildDate = [self currentBuildDate]; error = [BNCKeyChain storeDate:firstBuildDate forService:kBranchKeychainService key:kBranchKeychainFirstBuildKey cloudAccessGroup:nil]; if (error) { - [[BranchLogger shared] logWarning:@"Error while saving build date" error:error]; + [[BranchLogger shared] logError:@"Error saving build date" error:error]; } return firstBuildDate; } @@ -123,7 +128,7 @@ + (NSDate *)currentInstallDate { // tvOS always returns a creation date of Unix epoch 0 on device installDate = [self creationDateForLibraryDirectory]; if (installDate == nil || [installDate timeIntervalSince1970] <= 0.0) { - [[BranchLogger shared] logWarning:@"Invalid install date, using [NSDate date]" error:nil]; + [[BranchLogger shared] logError:@"Invalid install date, using [NSDate date]" error:nil]; } #else [[BranchLogger shared] logWarning:@"File system creation date not supported on tvOS, using [NSDate date]" error:nil]; @@ -138,7 +143,7 @@ + (NSDate *)creationDateForLibraryDirectory { NSURL *directoryURL = [[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] firstObject]; NSDictionary *attributes = [fileManager attributesOfItemAtPath:directoryURL.path error:&error]; if (error) { - [[BranchLogger shared] logWarning:@"Failed to get creation date for Library directory" error:error]; + [[BranchLogger shared] logWarning:@"Failed to get creation date for NSLibraryDirectory" error:error]; return nil; } return [attributes fileCreationDate]; @@ -164,16 +169,3 @@ + (NSDate *)firstInstallDate { } @end - -@implementation BNCApplication (BNCTest) - -- (void) setAppOriginalInstallDate:(NSDate*)originalInstallDate - firstInstallDate:(NSDate*)firstInstallDate - lastUpdateDate:(NSDate*)lastUpdateDate { - self->_currentInstallDate = firstInstallDate; // latest_install_time - self->_firstInstallDate = originalInstallDate; // first_install_time - self->_currentBuildDate = lastUpdateDate; // lastest_update_time -} - -@end - From de3a91abb15fcec10988d456dc16f56560d82100 Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 7 Mar 2024 18:45:47 -0800 Subject: [PATCH 05/16] Clean up logs. Add braces for clarity. --- Sources/BranchSDK/BNCApplication.m | 4 +- Sources/BranchSDK/BNCEncodingUtils.m | 174 ++++++++++++--------------- 2 files changed, 81 insertions(+), 97 deletions(-) diff --git a/Sources/BranchSDK/BNCApplication.m b/Sources/BranchSDK/BNCApplication.m index 17ce42a03..a3cce47c5 100644 --- a/Sources/BranchSDK/BNCApplication.m +++ b/Sources/BranchSDK/BNCApplication.m @@ -21,7 +21,7 @@ @implementation BNCApplication // BNCApplication checks a few values in keychain -// Checking keychain from main thread early in the app lifecycle can deadlock. INTENG-7291 +// Checking keychain from main thread early in the app lifecycle can deadlock. INTENG-7291 + (void)loadCurrentApplicationWithCompletion:(void (^)(BNCApplication *application))completion { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ BNCApplication *tmp = [BNCApplication currentApplication]; @@ -78,7 +78,7 @@ + (NSDate *)currentBuildDate { // path to the app on device. file:///private/var/containers/Bundle/Application/GUID appURL = [bundleURL URLByAppendingPathComponent:appName]; } else { - // This else block is probably no longer necessary + // TODO: Why is this fallback necessary? The NSBundle approach has been available since iOS 2.0 // path to old app location, this symlinks to the new location. file:///var/containers/Bundle/Application/GUID NSString *path = [[NSProcessInfo processInfo].arguments firstObject]; if (path) { diff --git a/Sources/BranchSDK/BNCEncodingUtils.m b/Sources/BranchSDK/BNCEncodingUtils.m index 712b3d15e..ec584640d 100644 --- a/Sources/BranchSDK/BNCEncodingUtils.m +++ b/Sources/BranchSDK/BNCEncodingUtils.m @@ -165,9 +165,8 @@ + (NSString *)encodeDictionaryToJsonString:(NSDictionary *)dictionary { NSMutableString *encodedDictionary = [[NSMutableString alloc] initWithString:@"{"]; for (NSString *key in dictionary) { - // protect against non-string keys if (![key isKindOfClass:[NSString class]]) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Unexpected key type %@. Skipping key.", [key class]] error:nil]; + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Ignoring unexpected key type %@", [key class]] error:nil]; continue; } @@ -177,38 +176,30 @@ + (NSString *)encodeDictionaryToJsonString:(NSDictionary *)dictionary { id obj = dictionary[key]; if ([obj isKindOfClass:[NSString class]]) { value = [BNCEncodingUtils sanitizedStringFromString:obj]; - } - else if ([obj isKindOfClass:[NSURL class]]) { + } else if ([obj isKindOfClass:[NSURL class]]) { value = [obj absoluteString]; - } - else if ([obj isKindOfClass:[NSDate class]]) { + } else if ([obj isKindOfClass:[NSDate class]]) { value = [BNCEncodingUtils iso8601StringFromDate:obj]; - } - else if ([obj isKindOfClass:[NSArray class]]) { + } else if ([obj isKindOfClass:[NSArray class]]) { value = [BNCEncodingUtils encodeArrayToJsonString:obj]; string = NO; - } - else if ([obj isKindOfClass:[NSDictionary class]] || [obj isKindOfClass:[NSMutableDictionary class]]) { + } else if ([obj isKindOfClass:[NSDictionary class]] || [obj isKindOfClass:[NSMutableDictionary class]]) { value = [BNCEncodingUtils encodeDictionaryToJsonString:obj]; string = NO; - } - else if ([obj isKindOfClass:[NSNumber class]]) { + } else if ([obj isKindOfClass:[NSNumber class]]) { string = NO; - if (obj == (id)kCFBooleanFalse) + if (obj == (id)kCFBooleanFalse) { value = @"false"; - else - if (obj == (id)kCFBooleanTrue) + } else if (obj == (id)kCFBooleanTrue) { value = @"true"; - else + } else { value = [obj stringValue]; - } - else if ([obj isKindOfClass:[NSNull class]]) { + } + } else if ([obj isKindOfClass:[NSNull class]]) { value = @"null"; string = NO; - } - else { - // If this type is not a known type, don't attempt to encode it. - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Cannot encode value for key %@. The value is not an accepted type.", key] error:nil]; + } else { + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Ignoring unexpected value type %@", [obj class]] error:nil]; continue; } @@ -230,12 +221,11 @@ + (NSString *)encodeDictionaryToJsonString:(NSDictionary *)dictionary { [encodedDictionary appendString:@"}"]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Encoded dictionary: %@.", encodedDictionary] error:nil]; + [[BranchLogger shared] logVerbose:[NSString stringWithFormat:@"Encoded dictionary: %@.", encodedDictionary] error:nil]; return encodedDictionary; } + (NSString *)encodeArrayToJsonString:(NSArray *)array { - // Empty array if (![array count]) { return @"[]"; } @@ -247,41 +237,31 @@ + (NSString *)encodeArrayToJsonString:(NSArray *)array { if ([obj isKindOfClass:[NSString class]]) { value = [BNCEncodingUtils sanitizedStringFromString:obj]; - } - else if ([obj isKindOfClass:[NSURL class]]) { + } else if ([obj isKindOfClass:[NSURL class]]) { value = [obj absoluteString]; - } - else if ([obj isKindOfClass:[NSDate class]]) { + } else if ([obj isKindOfClass:[NSDate class]]) { value = [BNCEncodingUtils iso8601StringFromDate:obj]; - } - else if ([obj isKindOfClass:[NSArray class]]) { + } else if ([obj isKindOfClass:[NSArray class]]) { value = [BNCEncodingUtils encodeArrayToJsonString:obj]; string = NO; - } - else if ([obj isKindOfClass:[NSDictionary class]] || [obj isKindOfClass:[NSMutableDictionary class]]) { + } else if ([obj isKindOfClass:[NSDictionary class]] || [obj isKindOfClass:[NSMutableDictionary class]]) { value = [BNCEncodingUtils encodeDictionaryToJsonString:obj]; string = NO; - } - else if ([obj isKindOfClass:[NSNumber class]]) { + } else if ([obj isKindOfClass:[NSNumber class]]) { value = [obj stringValue]; string = NO; - } - else if ([obj isKindOfClass:[NSNull class]]) { + } else if ([obj isKindOfClass:[NSNull class]]) { value = @"null"; string = NO; - } - else { - // If this type is not a known type, don't attempt to encode it. - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Cannot encode value %@. The value is not an accepted type.", obj] error:nil]; + } else { + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Ignoring unexpected value type %@", [obj class]] error:nil]; continue; } - // If this is a "string" object, wrap it in quotes if (string) { + // quote strings [encodedArray appendFormat:@"\"%@\",", value]; - } - // Otherwise, just add the raw value after the colon - else { + } else { [encodedArray appendFormat:@"%@,", value]; } } @@ -290,8 +270,7 @@ + (NSString *)encodeArrayToJsonString:(NSArray *)array { [encodedArray deleteCharactersInRange:NSMakeRange([encodedArray length] - 1, 1)]; [encodedArray appendString:@"]"]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Encoded array: %@.", encodedArray] error:nil]; - + [[BranchLogger shared] logVerbose:[NSString stringWithFormat:@"Encoded array: %@.", encodedArray] error:nil]; return encodedArray; } @@ -305,26 +284,20 @@ + (NSString *)encodeDictionaryToQueryString:(NSDictionary *)dictionary { NSMutableString *queryString = [[NSMutableString alloc] initWithString:@"?"]; for (NSString *key in [dictionary allKeys]) { - // No empty keys, please. if (key.length) { id obj = dictionary[key]; NSString *value; if ([obj isKindOfClass:[NSString class]]) { value = [BNCEncodingUtils urlEncodedString:obj]; - } - else if ([obj isKindOfClass:[NSURL class]]) { + } else if ([obj isKindOfClass:[NSURL class]]) { value = [BNCEncodingUtils urlEncodedString:[obj absoluteString]]; - } - else if ([obj isKindOfClass:[NSDate class]]) { + } else if ([obj isKindOfClass:[NSDate class]]) { value = [BNCEncodingUtils iso8601StringFromDate:obj]; - } - else if ([obj isKindOfClass:[NSNumber class]]) { + } else if ([obj isKindOfClass:[NSNumber class]]) { value = [obj stringValue]; - } - else { - // If this type is not a known type, don't attempt to encode it. - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Cannot encode value %@. The value is not an accepted type.", obj] error:nil]; + } else { + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Ignoring unexpected value type %@", [obj class]] error:nil]; continue; } @@ -334,29 +307,25 @@ + (NSString *)encodeDictionaryToQueryString:(NSDictionary *)dictionary { // Delete last character (either trailing & or ? if no params present) [queryString deleteCharactersInRange:NSMakeRange(queryString.length - 1, 1)]; - return queryString; } -+ (NSString*) stringByPercentDecodingString:(NSString *)string { ++ (NSString *)stringByPercentDecodingString:(NSString *)string { return [string stringByRemovingPercentEncoding]; } -+ (NSString*) stringByPercentEncodingStringForQuery:(NSString *)string { - return [string stringByAddingPercentEncodingWithAllowedCharacters: - [NSCharacterSet URLQueryAllowedCharacterSet]]; ++ (NSString *)stringByPercentEncodingStringForQuery:(NSString *)string { + return [string stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLQueryAllowedCharacterSet]]; } #pragma mark - Param Decoding Methods + (NSDictionary *)decodeJsonDataToDictionary:(NSData *)jsonData { NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; - return [BNCEncodingUtils decodeJsonStringToDictionary:jsonString]; } + (NSDictionary *)decodeJsonStringToDictionary:(NSString *)jsonString { - // Just a basic decode, easy enough NSData *tempData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; if (!tempData) { return @{}; @@ -379,7 +348,6 @@ + (NSDictionary *)decodeJsonStringToDictionary:(NSString *)jsonString { return base64DecodedDictionary; } - // Apparently this data was not parsible into a dictionary, so we'll just return an empty one return @{}; } @@ -393,27 +361,29 @@ + (NSDictionary *)decodeQueryStringToDictionary:(NSString *)queryString { NSString *key = kv[0]; NSString *val = [kv[1] stringByRemovingPercentEncoding]; - // Don't add empty items if (val.length) { params[key] = val; } } } - return params; } #pragma mark - Hex Strings -+ (NSString *) hexStringFromData:(NSData*)data { - ++ (NSString *)hexStringFromData:(NSData*)data { NSUInteger bytesCount = data.length; - if (bytesCount <= 0) return @""; - + if (bytesCount <= 0) { + return @""; + } + const char *hexChars = "0123456789ABCDEF"; const char *dataBuffer = data.bytes; char *chars = malloc(sizeof(char) * (bytesCount * 2 + 1)); - if (!chars) return @""; + if (!chars) { + return @""; + } + char *s = chars; for (unsigned i = 0; i < bytesCount; ++i) { *s++ = hexChars[((*dataBuffer & 0xF0) >> 4)]; @@ -423,35 +393,39 @@ + (NSString *) hexStringFromData:(NSData*)data { *s = '\0'; NSString *hexString = [NSString stringWithUTF8String:chars]; - if (chars) free(chars); + if (chars) { + free(chars); + } + return hexString; } -+ (NSData *) dataFromHexString:(NSString*)string { - if (!string) return nil; - ++ (NSData *)dataFromHexString:(NSString*)string { + if (!string) { + return nil; + } + NSData *data = nil; NSData *inputData = [string dataUsingEncoding:NSUTF8StringEncoding]; size_t length = (inputData.length+1)/2; uint8_t *bytes = malloc(length); uint8_t *b = bytes; - if (!bytes) goto exit; - + if (!bytes) { + goto exit; + } + int highValue = -1; const uint8_t *p = (const uint8_t*) [inputData bytes]; for (NSUInteger i = 0; i < inputData.length; ++i) { int value; - if (*p >= '0' && *p <= '9') + if (*p >= '0' && *p <= '9') { value = *p - '0'; - else - if (*p >= 'A' && *p <= 'F') + } else if (*p >= 'A' && *p <= 'F') { value = *p - 'A' + 10; - else - if (*p >= 'a' && *p <= 'f') + } else if (*p >= 'a' && *p <= 'f') { value = *p - 'a' + 10; - else - if (isspace(*p)) { + } else if (isspace(*p)) { p++; continue; } else { @@ -468,8 +442,9 @@ + (NSData *) dataFromHexString:(NSString*)string { } // If highValue != -1 then we got an odd number of hex values, which is an error. - if (highValue == -1) + if (highValue == -1) { data = [NSData dataWithBytes:bytes length:b-bytes]; + } exit: if (bytes) { @@ -480,23 +455,27 @@ + (NSData *) dataFromHexString:(NSString*)string { #pragma mark - URL QueryItems -+ (NSArray*) queryItems:(NSURL*)URL { - NSMutableArray* keyValues = [NSMutableArray new]; - if (!URL) return keyValues; - ++ (NSArray *)queryItems:(NSURL *)URL { + NSMutableArray *keyValues = [NSMutableArray new]; + if (!URL) { + return keyValues; + } + NSArray *queryItems = [[URL query] componentsSeparatedByString:@"&"]; - for (NSString* itemPair in queryItems) { + for (NSString *itemPair in queryItems) { BNCKeyValue *keyValue = [BNCKeyValue new]; NSRange range = [itemPair rangeOfString:@"="]; if (range.location == NSNotFound) { - if (itemPair.length) + if (itemPair.length) { keyValue.key = itemPair; + } } else { keyValue.key = [itemPair substringWithRange:NSMakeRange(0, range.location)]; NSRange r = NSMakeRange(range.location+1, itemPair.length-range.location-1); - if (r.length > 0) + if (r.length > 0) { keyValue.value = [itemPair substringWithRange:r]; + } } keyValue.key = [BNCEncodingUtils stringByPercentDecodingString:keyValue.key]; @@ -506,8 +485,13 @@ + (NSData *) dataFromHexString:(NSString*)string { keyValue.value = [keyValue.value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; if (keyValue.key.length || keyValue.value.length) { - if (keyValue.key == nil) keyValue.key = @""; - if (keyValue.value == nil) keyValue.value = @""; + if (keyValue.key == nil) { + keyValue.key = @""; + } + + if (keyValue.value == nil) { + keyValue.value = @""; + } [keyValues addObject:keyValue]; } } From bd9cde76bb35949ebd7d5283d41d55fc6dbb57b0 Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 14 Mar 2024 10:27:24 -0700 Subject: [PATCH 06/16] Update log messages in BNCKeyChain --- Sources/BranchSDK/BNCKeyChain.m | 44 ++++++++++++++----------- Sources/BranchSDK/Private/BNCKeyChain.h | 6 ++-- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/Sources/BranchSDK/BNCKeyChain.m b/Sources/BranchSDK/BNCKeyChain.m index 5b75be5da..34c582c5a 100644 --- a/Sources/BranchSDK/BNCKeyChain.m +++ b/Sources/BranchSDK/BNCKeyChain.m @@ -20,11 +20,12 @@ @implementation BNCKeyChain +// Wraps OSStatus in an NSError +// Security errors are defined in Security/SecBase.h + (NSError *) errorWithKey:(NSString *)key OSStatus:(OSStatus)status { - // Security errors are defined in Security/SecBase.h if (status == errSecSuccess) return nil; NSString *reason = (__bridge_transfer NSString*) SecCopyErrorMessageString(status, NULL); - NSString *description = [NSString stringWithFormat:@"Security error with key '%@': code %ld.", key, (long) status]; + NSString *description = [NSString stringWithFormat:@"Branch Keychain error for key '%@': OSStatus %ld.", key, (long) status]; if (!reason) { reason = @"Sec OSStatus error."; @@ -37,7 +38,7 @@ + (NSError *) errorWithKey:(NSString *)key OSStatus:(OSStatus)status { return error; } -+ (NSDate *) retrieveDateForService:(NSString *)service key:(NSString *)key error:(NSError **)error { ++ (NSDate *)retrieveDateForService:(NSString *)service key:(NSString *)key error:(NSError **)error { if (error) *error = nil; if (service == nil || key == nil) { NSError *localError = [self errorWithKey:key OSStatus:errSecParam]; @@ -57,7 +58,8 @@ + (NSDate *) retrieveDateForService:(NSString *)service key:(NSString *)key erro OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)dictionary, (CFTypeRef *)&valueData); if (status != errSecSuccess) { NSError *localError = [self errorWithKey:key OSStatus:status]; - [[BranchLogger shared] logDebug:@"Can't retrieve key" error:localError]; + [[BranchLogger shared] logVerbose:@"Key not found" error:localError]; + if (error) *error = localError; if (valueData) CFRelease(valueData); return nil; @@ -82,9 +84,10 @@ + (NSError *) storeDate:(NSDate *)date key:(NSString *)key cloudAccessGroup:(NSString *)accessGroup { - if (date == nil || service == nil || key == nil) + if (date == nil || service == nil || key == nil) { return [self errorWithKey:key OSStatus:errSecParam]; - + } + NSData* valueData = nil; @try { valueData = [NSKeyedArchiver archivedDataWithRootObject:date requiringSecureCoding:YES error:NULL]; @@ -106,7 +109,7 @@ + (NSError *) storeDate:(NSDate *)date OSStatus status = SecItemDelete((__bridge CFDictionaryRef)dictionary); if (status != errSecSuccess && status != errSecItemNotFound) { NSError *error = [self errorWithKey:key OSStatus:status]; - [[BranchLogger shared] logDebug:@"Can't clear to store key" error:error]; + [[BranchLogger shared] logDebug:@"Failed to save key" error:error]; } dictionary[(__bridge id)kSecValueData] = valueData; @@ -122,7 +125,7 @@ + (NSError *) storeDate:(NSDate *)date status = SecItemAdd((__bridge CFDictionaryRef)dictionary, NULL); if (status) { NSError *error = [self errorWithKey:key OSStatus:status]; - [[BranchLogger shared] logDebug:@"Can't store key" error:error]; + [[BranchLogger shared] logDebug:@"Failed to save key" error:error]; return error; } return nil; @@ -140,24 +143,24 @@ + (NSError*) removeValuesForService:(NSString *)service key:(NSString *)key { if (status == errSecItemNotFound) status = errSecSuccess; if (status) { NSError *error = [self errorWithKey:key OSStatus:status]; - [[BranchLogger shared] logDebug:@"Can't remove key" error:error]; + [[BranchLogger shared] logDebug:@"Failed to remove key" error:[self errorWithKey:key OSStatus:status]]; return error; } return nil; } -+ (NSString * _Nullable) securityAccessGroup { - // https://stackoverflow.com/questions/11726672/access-app-identifier-prefix-programmatically +// The security access group string is prefixed with the Apple Developer Team ID ++ (NSString * _Nullable)securityAccessGroup { @synchronized(self) { - static NSString*_securityAccessGroup = nil; + static NSString *_securityAccessGroup = nil; if (_securityAccessGroup) return _securityAccessGroup; - - // First store a value: + + // The keychain cannot be empty prior to requesting the security access group string. Add a tmp variable. NSError *error = [self storeDate:[NSDate date] forService:@"BranchKeychainService" key:@"Temp" cloudAccessGroup:nil]; if (error) { - [[BranchLogger shared] logDebug:@"Error storing temp value" error:error]; + [[BranchLogger shared] logWarning:@"Failed to store temp value" error:error]; } - + NSDictionary* dictionary = @{ (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService: @"BranchKeychainService", @@ -169,12 +172,13 @@ + (NSString * _Nullable) securityAccessGroup { OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)dictionary, (CFTypeRef*)&resultDictionary); if (status == errSecItemNotFound) return nil; if (status != errSecSuccess) { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Get securityAccessGroup returned(%ld): %@.", (long) status, [self errorWithKey:nil OSStatus:status]] error:nil]; + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Failed to retrieve security access group"] error:[self errorWithKey:nil OSStatus:status]]; return nil; } - NSString*group = - [(__bridge NSDictionary *)resultDictionary objectForKey:(__bridge NSString *)kSecAttrAccessGroup]; - if (group.length > 0) _securityAccessGroup = [group copy]; + NSString *group = [(__bridge NSDictionary *)resultDictionary objectForKey:(__bridge NSString *)kSecAttrAccessGroup]; + if (group.length > 0) { + _securityAccessGroup = [group copy]; + } CFRelease(resultDictionary); return _securityAccessGroup; } diff --git a/Sources/BranchSDK/Private/BNCKeyChain.h b/Sources/BranchSDK/Private/BNCKeyChain.h index 6d7d1e03a..b898287ab 100644 --- a/Sources/BranchSDK/Private/BNCKeyChain.h +++ b/Sources/BranchSDK/Private/BNCKeyChain.h @@ -53,7 +53,9 @@ key:(NSString * _Nonnull)key cloudAccessGroup:(NSString * _Nullable)accessGroup; -/// The default security access group for the app. -+ (NSString*_Nullable) securityAccessGroup; +/** + The security access group string is prefixed with the Apple Developer Team ID + */ ++ (NSString * _Nullable) securityAccessGroup; @end From 5c6d17054c7dc6dac735d690c5f7487cc4419457 Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 14 Mar 2024 18:42:58 -0700 Subject: [PATCH 07/16] Update some log messages --- Sources/BranchSDK/BNCNetworkInterface.m | 10 +++++++--- Sources/BranchSDK/BNCReferringURLUtility.m | 8 ++++++-- Sources/BranchSDK/BNCSystemObserver.m | 10 +++++++++- Sources/BranchSDK/BNCURLFilter.m | 14 +++++--------- Sources/BranchSDK/BranchJsonConfig.m | 8 +++----- Sources/BranchSDK/BranchLastAttributedTouchData.m | 2 +- 6 files changed, 31 insertions(+), 21 deletions(-) diff --git a/Sources/BranchSDK/BNCNetworkInterface.m b/Sources/BranchSDK/BNCNetworkInterface.m index 87dffc8b2..c4d41dddc 100644 --- a/Sources/BranchSDK/BNCNetworkInterface.m +++ b/Sources/BranchSDK/BNCNetworkInterface.m @@ -41,6 +41,7 @@ - (NSString*) description { ]; } +// Reads network interface information to the device IP address + (NSArray *)currentInterfaces { struct ifaddrs *interfaces = NULL; @@ -49,8 +50,11 @@ - (NSString*) description { // Retrieve the current interfaces - returns 0 on success if (getifaddrs(&interfaces) != 0) { int e = errno; - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Can't read ip address: (%d): %s.", e, strerror(e)] error:nil]; - goto exit; + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Failed to read IP Address: (%d): %s", e, strerror(e)] error:nil]; + + // Error handling in C code is one case where goto can improve readability. + // https://www.kernel.org/doc/html/v4.19/process/coding-style.html + goto err_free_interfaces; } // Loop through linked list of interfaces -- @@ -92,7 +96,7 @@ - (NSString*) description { } } -exit: +err_free_interfaces: if (interfaces) freeifaddrs(interfaces); return currentInterfaces; } diff --git a/Sources/BranchSDK/BNCReferringURLUtility.m b/Sources/BranchSDK/BNCReferringURLUtility.m index ced3ec6e4..3d7b63aac 100644 --- a/Sources/BranchSDK/BNCReferringURLUtility.m +++ b/Sources/BranchSDK/BNCReferringURLUtility.m @@ -79,6 +79,7 @@ - (void)processQueryParameter:(NSURLQueryItem *)item { param.validityWindow = [self defaultValidityWindowForParam:name]; } + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Parsed Referring URL: %@", param] error:nil]; [self.urlQueryParameters setValue:param forKey:name]; } @@ -90,6 +91,8 @@ - (void)processMetaQueryParameter:(NSURLQueryItem *)item { param.timestamp = [NSDate date]; param.isDeepLink = YES; param.validityWindow = [self defaultValidityWindowForParam:BRANCH_REQUEST_KEY_META_CAMPAIGN_IDS]; + + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Parsed Referring URL: %@", param] error:nil]; [self.urlQueryParameters setValue:param forKey:BRANCH_REQUEST_KEY_META_CAMPAIGN_IDS]; } } @@ -112,6 +115,8 @@ - (NSDictionary *)dictionaryFromEncodedJsonString:(NSString *)encodedJsonString NSDictionary *json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; if (!error) { return json; + } else { + [[BranchLogger shared] logError:@"Failed to parse Meta AEM JSON" error:error]; } } return nil; @@ -263,7 +268,6 @@ - (NSMutableDictionary *)serializeToJson:(NSMutableDictionary)operation { if (statusCode == 404) { [[BranchLogger shared] logDebug:@"No update for URL ignore list found." error:nil]; return NO; - } else if (statusCode != 200 || error != nil || jsonString == nil) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Failed to update URL ignore list. error: %@ status: %ld", operation.error, (long)operation.response.statusCode] error:operation.error]; - [[BranchLogger shared] logDebug: [NSString stringWithFormat:@"URL ignore JSON: %@", jsonString] error:nil]; - + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Failed to update URL ignore list. error: %@ status: %ld", operation.error, (long)operation.response.statusCode] error:operation.error]; return NO; - } else { return YES; } @@ -146,19 +142,19 @@ - (nullable NSDictionary *)parseJSONFromData:(NSData *)data { NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; if (error) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Can't parse URL ignore JSON: %@.", error] error:error]; + [[BranchLogger shared] logError:@"Failed to parse uri_skip_list" error:error]; return nil; } NSArray *urls = dictionary[@"uri_skip_list"]; if (![urls isKindOfClass:NSArray.class]) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Can't parse URL ignore JSON, uri_skip_list is not a NSArray."] error:nil]; + [[BranchLogger shared] logError:@"Failed to parse uri_skip_list is not a NSArray" error:nil]; return nil; } NSNumber *version = dictionary[@"version"]; if (![version isKindOfClass:NSNumber.class]) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Can't parse URL ignore JSON, version is not a NSNumber."] error:nil]; + [[BranchLogger shared] logError:@"Failed to parse uri_skip_list, version is not a NSNumber." error:nil]; return nil; } diff --git a/Sources/BranchSDK/BranchJsonConfig.m b/Sources/BranchSDK/BranchJsonConfig.m index 9d5366e69..9ffc6f053 100644 --- a/Sources/BranchSDK/BranchJsonConfig.m +++ b/Sources/BranchSDK/BranchJsonConfig.m @@ -56,13 +56,12 @@ - (void)loadConfigFile NSError *error; id object = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; if (!object || error) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Failed to parse branch.json. Error: %@", error.localizedDescription] error:error]; + [[BranchLogger shared] logError:@"Failed to parse branch.json" error:error]; return; } if (![object isKindOfClass:NSDictionary.class]) { [[BranchLogger shared] logError:@"Contents of branch.json should be a JSON object." error:nil]; - return; } @@ -72,11 +71,10 @@ - (void)loadConfigFile - (NSData *)configFileContents { if (!self.configFileURL) return nil; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Loading %@", self.configFileURL.pathComponents.lastObject] error:nil]; NSError *error; NSData *data = [NSData dataWithContentsOfURL:self.configFileURL options:0 error:&error]; if (!data || error) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Failed to load %@. Error: %@", self.configFileURL, error.localizedDescription] error:error]; + [[BranchLogger shared] logError:@"Failed to load branch.json" error:error]; return nil; } return data; @@ -109,7 +107,7 @@ - (void)findConfigFile } if (!configFileURL) { - [[BranchLogger shared] logDebug:@"No branch.json in app bundle." error:nil]; + [[BranchLogger shared] logDebug:@"No branch.json in app bundle" error:nil]; return; } diff --git a/Sources/BranchSDK/BranchLastAttributedTouchData.m b/Sources/BranchSDK/BranchLastAttributedTouchData.m index dd7538c8e..85bc3e0ab 100644 --- a/Sources/BranchSDK/BranchLastAttributedTouchData.m +++ b/Sources/BranchSDK/BranchLastAttributedTouchData.m @@ -33,7 +33,7 @@ + (void)requestLastTouchAttributedData:(BNCServerInterface *)serverInterface key if (window > -1 && window < 365) { request.attributionWindow = window; } else { - [[BranchLogger shared] logWarning:@"Attribution window is outside the expected range, using 30 days." error:nil]; + [[BranchLogger shared] logWarning:@"Attribution window is outside the expected range, using 30 days" error:nil]; } [request makeRequest:serverInterface key:key callback:^(BNCServerResponse *response, NSError *error) { From d5f5c0e4fb77dc4157a32398c74cb075c49632fc Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 19 Mar 2024 20:15:43 -0700 Subject: [PATCH 08/16] Update log levels. Clarify network errors. --- Sources/BranchSDK/BNCEncodingUtils.m | 16 +++ Sources/BranchSDK/BNCNetworkService.m | 32 ++---- Sources/BranchSDK/BNCPreferenceHelper.m | 10 +- Sources/BranchSDK/BNCServerInterface.m | 113 ++++++++----------- Sources/BranchSDK/BNCServerRequestQueue.m | 2 +- Sources/BranchSDK/BNCSystemObserver.m | 2 +- Sources/BranchSDK/BNCURLFilter.m | 8 +- Sources/BranchSDK/Branch.m | 46 +++++--- Sources/BranchSDK/BranchJsonConfig.m | 2 +- Sources/BranchSDK/BranchLogger.m | 9 +- Sources/BranchSDK/BranchOpenRequest.m | 8 +- Sources/BranchSDK/BranchScene.m | 6 + Sources/BranchSDK/Private/BNCEncodingUtils.h | 3 + Sources/BranchSDK/Public/Branch.h | 8 +- Sources/BranchSDK/Public/BranchLogger.h | 4 + 15 files changed, 145 insertions(+), 124 deletions(-) diff --git a/Sources/BranchSDK/BNCEncodingUtils.m b/Sources/BranchSDK/BNCEncodingUtils.m index ec584640d..d8b96b3c5 100644 --- a/Sources/BranchSDK/BNCEncodingUtils.m +++ b/Sources/BranchSDK/BNCEncodingUtils.m @@ -318,6 +318,22 @@ + (NSString *)stringByPercentEncodingStringForQuery:(NSString *)string { return [string stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLQueryAllowedCharacterSet]]; } ++ (NSString *)prettyPrintJSON:(NSDictionary *)json { + if (![NSJSONSerialization isValidJSONObject:json]) { + [[BranchLogger shared] logWarning:@"Dictionary is not a valid JSON" error:nil]; + return nil; + } + + NSError *error; + NSData *data = [NSJSONSerialization dataWithJSONObject:json options:NSJSONWritingSortedKeys | NSJSONWritingPrettyPrinted error:&error]; + + if (!data || error) { + [[BranchLogger shared] logWarning:@"Failed to pretty print JSON" error:error]; + return nil; + } + return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; +} + #pragma mark - Param Decoding Methods + (NSDictionary *)decodeJsonDataToDictionary:(NSData *)jsonData { diff --git a/Sources/BranchSDK/BNCNetworkService.m b/Sources/BranchSDK/BNCNetworkService.m index 58d65035d..01c517835 100644 --- a/Sources/BranchSDK/BNCNetworkService.m +++ b/Sources/BranchSDK/BNCNetworkService.m @@ -52,7 +52,8 @@ - (void) cancel { [self.sessionTask cancel]; } -- (NSString*) stringFromResponseData { +// only used in logging? Consider removing +- (NSString *)stringFromResponseData { NSString *string = nil; if ([self.responseData isKindOfClass:[NSData class]]) { string = [[NSString alloc] initWithData:(NSData*)self.responseData encoding:NSUTF8StringEncoding]; @@ -148,12 +149,12 @@ - (BOOL) operationsAreSuspended { #pragma mark - Operations -- (BNCNetworkOperation*) networkOperationWithURLRequest:(NSMutableURLRequest*)request +- (BNCNetworkOperation *) networkOperationWithURLRequest:(NSMutableURLRequest*)request completion:(void (^)(idoperation))completion { BNCNetworkOperation *operation = [BNCNetworkOperation new]; if (![request isKindOfClass:[NSMutableURLRequest class]]) { - [[BranchLogger shared] logError:@"A `NSMutableURLRequest` request parameter was expected." error:nil]; + [[BranchLogger shared] logError:[NSString stringWithFormat:@"Expected NSMutableURLRequest, got %@", [request class]] error:nil]; return nil; } operation.request = request; @@ -162,7 +163,7 @@ - (BNCNetworkOperation*) networkOperationWithURLRequest:(NSMutableURLRequest*)re return operation; } -- (void) startOperation:(BNCNetworkOperation*)operation { +- (void)startOperation:(BNCNetworkOperation *)operation { operation.networkService = self; if (!operation.startDate) { operation.startDate = [NSDate date]; @@ -170,42 +171,29 @@ - (void) startOperation:(BNCNetworkOperation*)operation { if (!operation.timeoutDate) { NSTimeInterval timeoutInterval = operation.request.timeoutInterval; - if (timeoutInterval < 0.0) + if (timeoutInterval < 0.0) { timeoutInterval = self.defaultTimeoutInterval; - operation.timeoutDate = - [[operation startDate] dateByAddingTimeInterval:timeoutInterval]; + } + operation.timeoutDate = [[operation startDate] dateByAddingTimeInterval:timeoutInterval]; } if ([operation.request isKindOfClass:[NSMutableURLRequest class]]) { ((NSMutableURLRequest*)operation.request).timeoutInterval = [operation.timeoutDate timeIntervalSinceDate:[NSDate date]]; } else { - [[BranchLogger shared] logError:@"SDK logic error. Expected mutable request in `start` method." error:nil]; + [[BranchLogger shared] logError:[NSString stringWithFormat:@"Expected NSMutableURLRequest, got %@", [operation.request class]] error:nil]; } - operation.sessionTask = - [self.session dataTaskWithRequest:operation.request - completionHandler: - ^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + operation.sessionTask = [self.session dataTaskWithRequest:operation.request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { operation.responseData = data; operation.response = (NSHTTPURLResponse*) response; operation.error = error; - if (operation.response.statusCode != 404) { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Network finish operation %@ %1.3fs. Status %ld error %@.\n%@.", - operation.request.URL.absoluteString, - [[NSDate date] timeIntervalSinceDate:operation.startDate], - (long)operation.response.statusCode, - operation.error, - operation.stringFromResponseData] error:nil]; - } if (operation.completionBlock) { operation.completionBlock(operation); } }]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Network start operation %@.", operation.request.URL] error:nil]; - [operation.sessionTask resume]; } diff --git a/Sources/BranchSDK/BNCPreferenceHelper.m b/Sources/BranchSDK/BNCPreferenceHelper.m index 5463c98f7..dc6ecb06d 100644 --- a/Sources/BranchSDK/BNCPreferenceHelper.m +++ b/Sources/BranchSDK/BNCPreferenceHelper.m @@ -1083,9 +1083,10 @@ + (NSURL* _Nonnull) URLForPrefsFile { attributes:nil error:&error]; if (success) { + [[BranchLogger shared] logVerbose:[NSString stringWithFormat:@"Using storage URL %@", branchURL] error:error]; return branchURL; } else { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"CreateBranchURL failed: %@ URL: %@.", error, branchURL] error:error]; + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Failed to create URL %@", branchURL] error:error]; } } return nil; @@ -1123,8 +1124,11 @@ + (NSURL* _Nonnull) URLForPrefsFile { withIntermediateDirectories:YES attributes:nil error:&error]; - if (!success) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Worst case CreateBranchURL error was: %@ URL: %@.", error, branchURL] error:error]; + if (success) { + [[BranchLogger shared] logVerbose:[NSString stringWithFormat:@"Using storage URL %@", branchURL] error:error]; + } else { + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Failed to create URL %@", branchURL] error:error]; + [[BranchLogger shared] logError:@"Failed all attempts to create URLs to BNCPreferenceHelper storage." error:nil]; } return branchURL; } diff --git a/Sources/BranchSDK/BNCServerInterface.m b/Sources/BranchSDK/BNCServerInterface.m index bf6a405bd..e33ff7fcb 100644 --- a/Sources/BranchSDK/BNCServerInterface.m +++ b/Sources/BranchSDK/BNCServerInterface.m @@ -9,14 +9,13 @@ #import "BNCServerInterface.h" #import "BNCConfig.h" #import "BNCEncodingUtils.h" -#import "NSError+Branch.h" #import "BranchConstants.h" #import "NSMutableDictionary+Branch.h" #import "BranchLogger.h" #import "Branch.h" #import "BNCSKAdNetwork.h" #import "BNCReferringURLUtility.h" -#import "BranchLogger.h" +#import "NSError+Branch.h" @interface BNCServerInterface () @property (copy, nonatomic) NSString *requestEndpoint; @@ -90,17 +89,13 @@ - (void)genericHTTPRequest:(NSURLRequest *)request callback:(BNCServerCallback)c } - (void)genericHTTPRequest:(NSURLRequest *)request retryNumber:(NSInteger)retryNumber callback:(BNCServerCallback)callback retryHandler:(NSURLRequest *(^)(NSInteger))retryHandler { - + void (^completionHandler)(idoperation) = ^void (idoperation) { - BNCServerResponse *serverResponse = - [self processServerResponse:operation.response data:operation.responseData error:operation.error]; + BNCServerResponse *serverResponse = [self processServerResponse:operation.response data:operation.responseData error:operation.error]; [self collectInstrumentationMetricsWithOperation:operation]; - NSError *underlyingError = operation.error; - NSInteger status = [serverResponse.statusCode integerValue]; - // If the phone is in a poor network condition, // iOS will return statuses such as -1001, -1003, -1200, -9806 // indicating various parts of the HTTP post failed. @@ -109,68 +104,42 @@ - (void)genericHTTPRequest:(NSURLRequest *)request retryNumber:(NSInteger)retryN // Status 53 means the request was killed by the OS because we're still in the background. // This started happening in iOS 12 / Xcode 10 production when we're called from continueUserActivity: // but we're not fully out of the background yet. + + NSInteger status = [serverResponse.statusCode integerValue]; + NSError *underlyingError = operation.error; + // Retry request if appropriate BOOL isRetryableStatusCode = status >= 500 || status < 0 || status == 53; - - // Retry the request if appropriate if (retryNumber < self.preferenceHelper.retryCount && isRetryableStatusCode) { - dispatch_time_t dispatchTime = - dispatch_time(DISPATCH_TIME_NOW, self.preferenceHelper.retryInterval * NSEC_PER_SEC); + dispatch_time_t dispatchTime = dispatch_time(DISPATCH_TIME_NOW, self.preferenceHelper.retryInterval * NSEC_PER_SEC); dispatch_after(dispatchTime, dispatch_get_main_queue(), ^{ if (retryHandler) { - [[BranchLogger shared] logDebug: [NSString stringWithFormat:@"Retrying request with url %@", request.URL.relativePath] error:nil]; - // Create the next request + [[BranchLogger shared] logDebug: [NSString stringWithFormat:@"Retrying request with HTTP status code %ld", (long)status] error:underlyingError]; NSURLRequest *retryRequest = retryHandler(retryNumber); - [self genericHTTPRequest:retryRequest - retryNumber:(retryNumber + 1) - callback:callback retryHandler:retryHandler]; + [self genericHTTPRequest:retryRequest retryNumber:(retryNumber + 1) callback:callback retryHandler:retryHandler]; } }); - // Do not continue on if retrying, else the callback will be called incorrectly - return; - } - - NSError *branchError = nil; - - // Wrap up bad statuses w/ specific error messages - if (status >= 500) { - branchError = [NSError branchErrorWithCode:BNCServerProblemError error:underlyingError]; - } - else if (status == 409) { - branchError = [NSError branchErrorWithCode:BNCDuplicateResourceError error:underlyingError]; - } - else if (status >= 400) { - NSString *errorString = [serverResponse.data objectForKey:@"error"]; - if (![errorString isKindOfClass:[NSString class]]) - errorString = nil; - if (!errorString) - errorString = underlyingError.localizedDescription; - if (!errorString) - errorString = @"The request was invalid."; - branchError = [NSError branchErrorWithCode:BNCBadRequestError localizedMessage:errorString]; - } - else if (underlyingError) { - branchError = [NSError branchErrorWithCode:BNCServerProblemError error:underlyingError]; - } - - if (branchError) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"An error prevented request to %@ from completing: %@", request.URL.absoluteString, branchError] error:branchError]; + } else { + if (status != 200) { + [[BranchLogger shared] logDebug: [NSString stringWithFormat:@"Giving up on request with HTTP status code %ld", (long)status] error:underlyingError]; + } + + // Don't call on the main queue since it might be blocked. + if (callback) { + callback(serverResponse, underlyingError); + } } - - // Don't call on the main queue since it might be blocked. - if (callback) - callback(serverResponse, branchError); }; + // Drops non-linking requests when tracking is disabled if (Branch.trackingDisabled) { NSString *endpoint = request.URL.absoluteString; - - // if endpoint is not linking related, fail it. + if (![self isLinkingRelatedRequest:endpoint]) { [[BNCPreferenceHelper sharedInstance] clearTrackingInformation]; NSError *error = [NSError branchErrorWithCode:BNCTrackingDisabledError]; - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Dropping Request %@: - %@", endpoint, error] error:nil]; + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Dropping non-linking request"] error:error]; if (callback) { callback(nil, error); } @@ -178,12 +147,13 @@ - (void)genericHTTPRequest:(NSURLRequest *)request retryNumber:(NSInteger)retryN } } - id operation = - [self.networkService networkOperationWithURLRequest:request.copy completion:completionHandler]; + id operation = [self.networkService networkOperationWithURLRequest:request.copy completion:completionHandler]; [operation start]; + + // In the past we allowed clients to provide their own networking classes. NSError *error = [self verifyNetworkOperation:operation]; if (error) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Network service error: %@.", error] error:error]; + [[BranchLogger shared] logError:@"NetworkService returned an operation that failed validation" error:error]; if (callback) { callback(nil, error); } @@ -214,7 +184,6 @@ - (BOOL)isLinkingRelatedRequest:(NSString *)endpoint { } - (NSError *)verifyNetworkOperation:(id)operation { - if (!operation) { NSString *message = @"A network operation instance is expected to be returned by the" " networkOperationWithURLRequest:completion: method."; @@ -278,27 +247,23 @@ - (NSURLRequest *)prepareGetRequest:(NSDictionary *)params url:(NSString *)url k NSDictionary *tmp = [self addRetryCount:retryNumber toJSON:params]; NSString *requestUrlString = [NSString stringWithFormat:@"%@%@", url, [BNCEncodingUtils encodeDictionaryToQueryString:tmp]]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"URL: %@", requestUrlString] error:nil]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:requestUrlString] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:self.preferenceHelper.timeout]; [request setHTTPMethod:@"GET"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"%@\nHeaders %@", request, [request allHTTPHeaderFields]] error:nil]; + return request; } - (NSURLRequest *)preparePostRequest:(NSDictionary *)params url:(NSString *)url key:(NSString *)key retryNumber:(NSInteger)retryNumber { - NSDictionary *tmp = [self addRetryCount:retryNumber toJSON:params]; + NSDictionary *updatedParams = [self addRetryCount:retryNumber toJSON:params]; - NSData *postData = [BNCEncodingUtils encodeDictionaryToJsonData:tmp]; + NSData *postData = [BNCEncodingUtils encodeDictionaryToJsonData:updatedParams]; NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postData length]]; - - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"URL: %@.\n", url] error:nil]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Body: %@\nJSON: %@.", - params, - [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding]] error:nil]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] @@ -309,6 +274,10 @@ - (NSURLRequest *)preparePostRequest:(NSDictionary *)params url:(NSString *)url [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:postData]; + if ([[BranchLogger shared] shouldLog:BranchLogLevelDebug]) { + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"%@\nHeaders %@\nBody %@", request, [request allHTTPHeaderFields], [BNCEncodingUtils prettyPrintJSON:updatedParams]] error:nil]; + } + return request; } @@ -321,15 +290,21 @@ - (BNCServerResponse *)processServerResponse:(NSURLResponse *)response data:(NSD serverResponse.statusCode = @([httpResponse statusCode]); serverResponse.data = [BNCEncodingUtils decodeJsonDataToDictionary:data]; serverResponse.requestId = requestId; - } - else { + + if ([[BranchLogger shared] shouldLog:BranchLogLevelDebug]) { + [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"%@\nBody %@", response, [BNCEncodingUtils prettyPrintJSON:serverResponse.data]] error:nil]; + } + + } else { serverResponse.statusCode = @(error.code); serverResponse.data = error.userInfo; serverResponse.requestId = requestId; + + if ([[BranchLogger shared] shouldLog:BranchLogLevelDebug]) { + [[BranchLogger shared] logDebug:@"Request failed with NSError" error:error]; + } } - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Server returned: %@.", serverResponse] error:nil]; - return serverResponse; } diff --git a/Sources/BranchSDK/BNCServerRequestQueue.m b/Sources/BranchSDK/BNCServerRequestQueue.m index f90f0924b..594cdda5d 100755 --- a/Sources/BranchSDK/BNCServerRequestQueue.m +++ b/Sources/BranchSDK/BNCServerRequestQueue.m @@ -373,7 +373,7 @@ + (instancetype)getInstance { dispatch_once(&onceToken, ^ { sharedQueue = [[BNCServerRequestQueue alloc] init]; [sharedQueue retrieve]; - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"Retrieved from storage: %@.", sharedQueue] error:nil]; + [[BranchLogger shared] logVerbose:[NSString stringWithFormat:@"Retrieved from storage: %@.", sharedQueue] error:nil]; }); return sharedQueue; } diff --git a/Sources/BranchSDK/BNCSystemObserver.m b/Sources/BranchSDK/BNCSystemObserver.m index 4e8df2f6d..1864caf95 100644 --- a/Sources/BranchSDK/BNCSystemObserver.m +++ b/Sources/BranchSDK/BNCSystemObserver.m @@ -82,7 +82,7 @@ + (NSString *)advertiserIdentifier { (sharedManager, advertisingIdentifierSelector); uid = [uuid UUIDString]; if ([uid isEqualToString:@"00000000-0000-0000-0000-000000000000"]) { - [[BranchLogger shared] logDebug:[NSString stringWithFormat:@"IDFA is all 0's. Probably running on a simulator or an App Clip."] error:nil]; + [[BranchLogger shared] logVerbose:[NSString stringWithFormat:@"IDFA is all 0's. Probably running on a simulator or an App Clip."] error:nil]; uid = nil; } } diff --git a/Sources/BranchSDK/BNCURLFilter.m b/Sources/BranchSDK/BNCURLFilter.m index 5ba55b70c..b096a3b53 100644 --- a/Sources/BranchSDK/BNCURLFilter.m +++ b/Sources/BranchSDK/BNCURLFilter.m @@ -142,19 +142,21 @@ - (nullable NSDictionary *)parseJSONFromData:(NSData *)data { NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; if (error) { - [[BranchLogger shared] logError:@"Failed to parse uri_skip_list" error:error]; + [[BranchLogger shared] logWarning:@"Failed to parse uri_skip_list" error:error]; return nil; } + // Given the way this is currently designed, the server will return formats that will fail this check. + // Making this a verbose log until we have a chance to refactor this design. NSArray *urls = dictionary[@"uri_skip_list"]; if (![urls isKindOfClass:NSArray.class]) { - [[BranchLogger shared] logError:@"Failed to parse uri_skip_list is not a NSArray" error:nil]; + [[BranchLogger shared] logVerbose:@"Failed to parse uri_skip_list is not a NSArray" error:nil]; return nil; } NSNumber *version = dictionary[@"version"]; if (![version isKindOfClass:NSNumber.class]) { - [[BranchLogger shared] logError:@"Failed to parse uri_skip_list, version is not a NSNumber." error:nil]; + [[BranchLogger shared] logWarning:@"Failed to parse uri_skip_list, version is not a NSNumber." error:nil]; return nil; } diff --git a/Sources/BranchSDK/Branch.m b/Sources/BranchSDK/Branch.m index dd67ddd3b..1177b7cbb 100644 --- a/Sources/BranchSDK/Branch.m +++ b/Sources/BranchSDK/Branch.m @@ -90,6 +90,8 @@ #pragma mark - Load Categories +// Depending on linker settings, static compilation can omit ObjC categories leading to a runtime error. +// These no-op static initializers force the category to load. void ForceCategoriesToLoad(void); void ForceCategoriesToLoad(void) { BNCForceNSErrorCategoryToLoad(); @@ -236,7 +238,7 @@ - (id)initWithInterface:(BNCServerInterface *)interface self.deferInitForPluginRuntime = config.deferInitForPluginRuntime; if (config.enableLogging) { - [self enableLogging]; + [Branch enableLogging]; } if (config.checkPasteboardOnInstall) { @@ -251,7 +253,7 @@ - (id)initWithInterface:(BNCServerInterface *)interface + (void)setNetworkServiceClass:(Class)networkServiceClass { @synchronized ([Branch class]) { if (bnc_networkServiceClass) { - [[BranchLogger shared] logError:@"The Branch network service class is already set. It can be set only once." error:nil]; + [[BranchLogger shared] logError:@"The Branch network service class is already set. Ignoring attempt to set it again." error:nil]; return; } if (![networkServiceClass conformsToProtocol:@protocol(BNCNetworkServiceProtocol)]) { @@ -335,7 +337,7 @@ + (void)setBranchKey:(NSString *)branchKey { [self setBranchKey:branchKey error:&error]; if (error) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"Branch init error: %@", error.localizedDescription] error:error]; + [[BranchLogger shared] logError:@"Failed to set Branch Key" error:error]; } } @@ -419,16 +421,26 @@ + (BOOL)branchKeyIsSet { } - (void)enableLogging { + [Branch enableLogging]; +} + +- (void)enableLoggingAtLevel:(BranchLogLevel)logLevel withCallback:(nullable BranchLogCallback)callback { + [Branch enableLoggingAtLevel:logLevel withCallback:callback]; +} + ++ (void)enableLogging { BranchLogger *logger = [BranchLogger shared]; logger.loggingEnabled = YES; logger.logLevelThreshold = BranchLogLevelDebug; } -- (void)enableLoggingAtLevel:(BranchLogLevel)logLevel withCallback:(nullable BranchLogCallback)callback { ++ (void)enableLoggingAtLevel:(BranchLogLevel)logLevel withCallback:(nullable BranchLogCallback)callback { BranchLogger *logger = [BranchLogger shared]; logger.loggingEnabled = YES; logger.logLevelThreshold = logLevel; - logger.logCallback = callback; + if (callback) { + logger.logCallback = callback; + } } - (void)useEUEndpoints { @@ -566,8 +578,7 @@ - (void)initSessionWithLaunchOptions:(NSDictionary *)options automaticallyDispla #pragma mark - Actual Init Session -- (void)initSessionWithLaunchOptions:(NSDictionary *)options isReferrable:(BOOL)isReferrable explicitlyRequestedReferrable:(BOOL)explicitlyRequestedReferrable automaticallyDisplayController:(BOOL)automaticallyDisplayController registerDeepLinkHandlerUsingBranchUniversalObject:(callbackWithBranchUniversalObject)callback { - +- (void)initSessionWithLaunchOptions:(NSDictionary *)options isReferrable:(BOOL)isReferrable explicitlyRequestedReferrable:(BOOL)explicitlyRequestedReferrable automaticallyDisplayController:(BOOL)automaticallyDisplayController registerDeepLinkHandlerUsingBranchUniversalObject:(callbackWithBranchUniversalObject)callback { [self initSceneSessionWithLaunchOptions:options isReferrable:isReferrable explicitlyRequestedReferrable:explicitlyRequestedReferrable automaticallyDisplayController:automaticallyDisplayController registerDeepLinkHandler:^(BNCInitSessionResponse * _Nullable initResponse, NSError * _Nullable error) { if (callback) { @@ -581,7 +592,6 @@ - (void)initSessionWithLaunchOptions:(NSDictionary *)options isReferrable:(BOOL) } - (void)initSessionWithLaunchOptions:(NSDictionary *)options isReferrable:(BOOL)isReferrable explicitlyRequestedReferrable:(BOOL)explicitlyRequestedReferrable automaticallyDisplayController:(BOOL)automaticallyDisplayController registerDeepLinkHandler:(callbackWithParams)callback { - [self initSceneSessionWithLaunchOptions:options isReferrable:isReferrable explicitlyRequestedReferrable:explicitlyRequestedReferrable automaticallyDisplayController:automaticallyDisplayController registerDeepLinkHandler:^(BNCInitSessionResponse * _Nullable initResponse, NSError * _Nullable error) { if (callback) { @@ -633,7 +643,6 @@ - (void)initSessionWithLaunchOptions:(NSDictionary *)options } } -//these params will be added - (void)setDeepLinkDebugMode:(NSDictionary *)debugParams { self.deepLinkDebugParams = debugParams; } @@ -746,7 +755,6 @@ - (BOOL)sceneIdentifier:(NSString *)sceneIdentifier - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { - NSString *source = options[UIApplicationOpenURLOptionsSourceApplicationKey]; NSString *annotation = options[UIApplicationOpenURLOptionsAnnotationKey]; return [self application:application openURL:url sourceApplication:source annotation:annotation]; @@ -768,7 +776,6 @@ - (BOOL)continueUserActivity:(NSUserActivity *)userActivity { } - (BOOL)continueUserActivity:(NSUserActivity *)userActivity sceneIdentifier:(NSString *)sceneIdentifier { - if (userActivity.referrerURL) { self.preferenceHelper.initialReferrer = userActivity.referrerURL.absoluteString; } @@ -917,7 +924,7 @@ - (void)handleATTAuthorizationStatus:(NSUInteger)status { - (void)setSKAdNetworkCalloutMaxTimeSinceInstall:(NSTimeInterval)maxTimeInterval { if (@available(iOS 16.1, macCatalyst 16.1, *)) { - [[BranchLogger shared] logDebug:@"This is no longer supported for iOS 16.1+ - SKAN4.0" error:nil]; + [[BranchLogger shared] logDebug:@"Not supported SKAN 4.0+, iOS 16.1+" error:nil]; } else { [BNCSKAdNetwork sharedInstance].maxTimeSinceInstall = maxTimeInterval; } @@ -989,7 +996,7 @@ - (void)logoutWithCallback:(callbackWithStatus)callback { (Branch.trackingDisabled) ? [NSError branchErrorWithCode:BNCTrackingDisabledError] : [NSError branchErrorWithCode:BNCInitError]; - [[BranchLogger shared] logError:@"Branch is not initialized, cannot logout." error:error]; + [[BranchLogger shared] logWarning:@"Branch is not initialized, cannot logout." error:error]; if (callback) {callback(NO, error);} return; } @@ -1399,7 +1406,7 @@ - (void)passPasteItemProviders:(NSArray *)itemProviders { // 2. Check if URL is branch URL and if yes -> store it. [item loadItemForTypeIdentifier:UTTypeURL.identifier options:NULL completionHandler:^(NSURL *url, NSError * _Null_unspecified error) { if (error) { - [[BranchLogger shared] logError:[NSString stringWithFormat:@"%@", error] error:error]; + [[BranchLogger shared] logWarning:@"Failed to load URL from Pasteboard" error:error]; } else if ([Branch isBranchLink:url.absoluteString]) { [self.preferenceHelper setLocalUrl:[url absoluteString]]; @@ -1538,6 +1545,8 @@ - (NSString *)generateShortUrl:(NSArray *)tags // If an ignore UA string is present, we always get a new url. // Otherwise, if we've already seen this request, use the cached version. if (!ignoreUAString && [self.linkCache objectForKey:linkData]) { + [[BranchLogger shared] logVerbose:@"Returning cached Branch Link" error:nil]; + shortURL = [self.linkCache objectForKey:linkData]; } else { BranchShortUrlSyncRequest *req = @@ -1554,7 +1563,7 @@ - (NSString *)generateShortUrl:(NSArray *)tags linkData:linkData linkCache:self.linkCache]; - [[BranchLogger shared] logDebug:@"Creating a custom URL synchronously." error:nil]; + [[BranchLogger shared] logVerbose:@"Requesting Branch Link synchronously" error:nil]; BNCServerResponse *serverResponse = [req makeRequest:self.serverInterface key:self.class.branchKey]; shortURL = [req processResponse:serverResponse]; @@ -1888,11 +1897,13 @@ - (BOOL)deferInitBlock:(void (^)(void))block { BOOL deferred = NO; @synchronized (self) { if (self.deferInitForPluginRuntime) { + [[BranchLogger shared] logDebug:@"Deferring SDK init until notifyNativeToInit is called" error:nil]; self.cachedInitBlock = block; deferred = YES; } } + // handle default non-deferred state if (!deferred && block) { block(); } @@ -1902,6 +1913,7 @@ - (BOOL)deferInitBlock:(void (^)(void))block { // Releases deferred init block - (void)notifyNativeToInit { @synchronized (self) { + [[BranchLogger shared] logDebug:@"Unlocking Deferred SDK init" error:nil]; self.deferInitForPluginRuntime = NO; } @@ -1997,7 +2009,7 @@ - (void)initializeSessionAndCallCallback:(BOOL)callCallback sceneIdentifier:(NSS [self.requestQueue insert:req at:0]; - NSString *message = [NSString stringWithFormat:@"request %@ callback %@ link %@", req, req.callback, req.urlString]; + NSString *message = [NSString stringWithFormat:@"Request %@ callback %@ link %@", req, req.callback, req.urlString]; [[BranchLogger shared] logDebug:message error:nil]; } else { @@ -2012,7 +2024,7 @@ - (void)initializeSessionAndCallCallback:(BOOL)callCallback sceneIdentifier:(NSS [self.requestQueue insert:req at:1]; [[BranchLogger shared] logDebug:@"Link resolution request" error:nil]; - NSString *message = [NSString stringWithFormat:@"request %@ callback %@ link %@", req, req.callback, req.urlString]; + NSString *message = [NSString stringWithFormat:@"Request %@ callback %@ link %@", req, req.callback, req.urlString]; [[BranchLogger shared] logDebug:message error:nil]; } } diff --git a/Sources/BranchSDK/BranchJsonConfig.m b/Sources/BranchSDK/BranchJsonConfig.m index 9ffc6f053..cb913f5cf 100644 --- a/Sources/BranchSDK/BranchJsonConfig.m +++ b/Sources/BranchSDK/BranchJsonConfig.m @@ -107,7 +107,7 @@ - (void)findConfigFile } if (!configFileURL) { - [[BranchLogger shared] logDebug:@"No branch.json in app bundle" error:nil]; + [[BranchLogger shared] logVerbose:@"No branch.json in app bundle" error:nil]; return; } diff --git a/Sources/BranchSDK/BranchLogger.m b/Sources/BranchSDK/BranchLogger.m index 621272d26..3f5038b57 100644 --- a/Sources/BranchSDK/BranchLogger.m +++ b/Sources/BranchSDK/BranchLogger.m @@ -41,6 +41,13 @@ + (instancetype)shared { return sharedInstance; } +- (BOOL)shouldLog:(BranchLogLevel)level { + if (!self.loggingEnabled || level < self.logLevelThreshold) { + return NO; + } + return YES; +} + - (void)disableCallerDetails { self.includeCallerDetails = NO; } @@ -95,7 +102,7 @@ + (NSString *)formatMessage:(NSString *)message logLevel:(BranchLogLevel)logLeve NSString *logTag = [NSString stringWithFormat:@"[BranchSDK][%@]", logLevelString]; NSMutableString *fullMessage = [NSMutableString stringWithFormat:@"%@%@", logTag, message]; if (error) { - [fullMessage appendFormat:@" NSError: %@", error.localizedDescription]; + [fullMessage appendFormat:@" NSError: %@", error]; } return fullMessage; } diff --git a/Sources/BranchSDK/BranchOpenRequest.m b/Sources/BranchSDK/BranchOpenRequest.m index 104cb09d5..275595ce4 100644 --- a/Sources/BranchSDK/BranchOpenRequest.m +++ b/Sources/BranchSDK/BranchOpenRequest.m @@ -277,7 +277,7 @@ + (void) initialize { + (void) setWaitNeededForOpenResponseLock { @synchronized (self) { if (!openRequestWaitQueueIsSuspended) { - [[BranchLogger shared] logDebug:@"Suspended for openRequestWaitQueue." error:nil]; + [[BranchLogger shared] logVerbose:@"Suspended for openRequestWaitQueue." error:nil]; openRequestWaitQueueIsSuspended = YES; dispatch_suspend(openRequestWaitQueue); } @@ -285,16 +285,16 @@ + (void) setWaitNeededForOpenResponseLock { } + (void) waitForOpenResponseLock { - [[BranchLogger shared] logDebug:@"Waiting for openRequestWaitQueue." error:nil]; + [[BranchLogger shared] logVerbose:@"Waiting for openRequestWaitQueue." error:nil]; dispatch_sync(openRequestWaitQueue, ^ { - [[BranchLogger shared] logDebug:@"Finished waitForOpenResponseLock." error:nil]; + [[BranchLogger shared] logVerbose:@"Finished waitForOpenResponseLock." error:nil]; }); } + (void) releaseOpenResponseLock { @synchronized (self) { if (openRequestWaitQueueIsSuspended) { - [[BranchLogger shared] logDebug:@"Resuming openRequestWaitQueue." error:nil]; + [[BranchLogger shared] logVerbose:@"Resuming openRequestWaitQueue." error:nil]; openRequestWaitQueueIsSuspended = NO; dispatch_resume(openRequestWaitQueue); } diff --git a/Sources/BranchSDK/BranchScene.m b/Sources/BranchSDK/BranchScene.m index c436cdd4b..c4f3a2f53 100644 --- a/Sources/BranchSDK/BranchScene.m +++ b/Sources/BranchSDK/BranchScene.m @@ -22,6 +22,8 @@ + (BranchScene *)shared NS_EXTENSION_UNAVAILABLE("BranchScene does not support E } - (void)initSessionWithLaunchOptions:(nullable NSDictionary *)options registerDeepLinkHandler:(void (^ _Nonnull)(NSDictionary * _Nullable params, NSError * _Nullable error, UIScene * _Nullable scene))callback NS_EXTENSION_UNAVAILABLE("BranchScene does not support Extensions") { + [[BranchLogger shared] logVerbose:@"BranchScene initSession" error:nil]; + [[Branch getInstance] initSceneSessionWithLaunchOptions:options isReferrable:YES explicitlyRequestedReferrable:NO automaticallyDisplayController:NO registerDeepLinkHandler:^(BNCInitSessionResponse * _Nullable initResponse, NSError * _Nullable error) { if (callback) { if (initResponse) { @@ -34,11 +36,15 @@ - (void)initSessionWithLaunchOptions:(nullable NSDictionary *)options registerDe } - (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity NS_EXTENSION_UNAVAILABLE("BranchScene does not support Extensions") { + [[BranchLogger shared] logVerbose:@"BranchScene continueUserActivity" error:nil]; + NSString *identifier = scene.session.persistentIdentifier; [[Branch getInstance] continueUserActivity:userActivity sceneIdentifier:identifier]; } - (void)scene:(UIScene *)scene openURLContexts:(NSSet *)URLContexts NS_EXTENSION_UNAVAILABLE("BranchScene does not support Extensions") { + [[BranchLogger shared] logVerbose:@"BranchScene openURLContexts" error:nil]; + if (URLContexts.count != 1) { [[BranchLogger shared] logWarning:@"Branch only supports a single URLContext" error:nil]; } diff --git a/Sources/BranchSDK/Private/BNCEncodingUtils.h b/Sources/BranchSDK/Private/BNCEncodingUtils.h index 037f43caf..97879167f 100644 --- a/Sources/BranchSDK/Private/BNCEncodingUtils.h +++ b/Sources/BranchSDK/Private/BNCEncodingUtils.h @@ -64,4 +64,7 @@ extern NSString* BNCWireFormatFromString(NSString *string); + (NSArray*) queryItems:(NSURL*)URL; +// For JSON logging ++ (NSString *)prettyPrintJSON:(NSDictionary *)json; + @end diff --git a/Sources/BranchSDK/Public/Branch.h b/Sources/BranchSDK/Public/Branch.h index 7c501de08..64afdaa30 100644 --- a/Sources/BranchSDK/Public/Branch.h +++ b/Sources/BranchSDK/Public/Branch.h @@ -566,8 +566,12 @@ extern NSString * __nonnull const BNCSpotlightFeature; /** Enable debug messages to os_log. */ -- (void)enableLogging; -- (void)enableLoggingAtLevel:(BranchLogLevel)logLevel withCallback:(nullable BranchLogCallback)callback; ++ (void)enableLogging; ++ (void)enableLoggingAtLevel:(BranchLogLevel)logLevel withCallback:(nullable BranchLogCallback)callback; + +// The new logging system is independent of the Branch singleton and can be called earlier. +- (void)enableLogging __attribute__((deprecated(("This API is deprecated. Please use the static version.")))); +- (void)enableLoggingAtLevel:(BranchLogLevel)logLevel withCallback:(nullable BranchLogCallback)callback __attribute__((deprecated(("This API is deprecated. Please use the static version.")))); /** Send requests to EU endpoints. diff --git a/Sources/BranchSDK/Public/BranchLogger.h b/Sources/BranchSDK/Public/BranchLogger.h index 1b0d7b07d..c7360969d 100644 --- a/Sources/BranchSDK/Public/BranchLogger.h +++ b/Sources/BranchSDK/Public/BranchLogger.h @@ -28,6 +28,10 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype _Nonnull)shared; +// For expensive Log messages, check if it's even worth building the log message +- (BOOL)shouldLog:(BranchLogLevel)level; + +// Caller details are relatively expensive, option to disable if the cost is too high. - (void)disableCallerDetails; - (void)logError:(NSString * _Nonnull)message error:(NSError * _Nullable)error; From 1a0a5ae5c80f01baefc1003c3b65f97a9272d99d Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 26 Mar 2024 13:40:05 -0700 Subject: [PATCH 09/16] Upgrade networking failures to warning. This includes no network which is common. --- Sources/BranchSDK/BNCServerInterface.m | 4 ++-- Sources/BranchSDK/BNCServerRequestQueue.m | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/BranchSDK/BNCServerInterface.m b/Sources/BranchSDK/BNCServerInterface.m index e33ff7fcb..f770a9ac0 100644 --- a/Sources/BranchSDK/BNCServerInterface.m +++ b/Sources/BranchSDK/BNCServerInterface.m @@ -122,7 +122,7 @@ - (void)genericHTTPRequest:(NSURLRequest *)request retryNumber:(NSInteger)retryN } else { if (status != 200) { - [[BranchLogger shared] logDebug: [NSString stringWithFormat:@"Giving up on request with HTTP status code %ld", (long)status] error:underlyingError]; + [[BranchLogger shared] logWarning: [NSString stringWithFormat:@"Giving up on request with HTTP status code %ld", (long)status] error:underlyingError]; } // Don't call on the main queue since it might be blocked. @@ -301,7 +301,7 @@ - (BNCServerResponse *)processServerResponse:(NSURLResponse *)response data:(NSD serverResponse.requestId = requestId; if ([[BranchLogger shared] shouldLog:BranchLogLevelDebug]) { - [[BranchLogger shared] logDebug:@"Request failed with NSError" error:error]; + [[BranchLogger shared] logWarning:@"Request failed with NSError" error:error]; } } diff --git a/Sources/BranchSDK/BNCServerRequestQueue.m b/Sources/BranchSDK/BNCServerRequestQueue.m index 594cdda5d..58e298337 100755 --- a/Sources/BranchSDK/BNCServerRequestQueue.m +++ b/Sources/BranchSDK/BNCServerRequestQueue.m @@ -317,7 +317,7 @@ - (id)unarchiveObjectFromData:(NSData *)data { id object = [NSKeyedUnarchiver unarchivedObjectOfClasses:[BNCServerRequestQueue encodableClasses] fromData:data error:&error]; if (error) { - [[BranchLogger shared] logWarning:@"Failed to unarchive: %@" error:error]; + [[BranchLogger shared] logWarning:@"Failed to unarchive" error:error]; } return object; From 559560bff6bcc4727c8cd4926ffb844be9b908bc Mon Sep 17 00:00:00 2001 From: echo Date: Tue, 26 Mar 2024 15:56:03 -0700 Subject: [PATCH 10/16] Clarify message on expected error on first run. --- Sources/BranchSDK/BNCPreferenceHelper.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BranchSDK/BNCPreferenceHelper.m b/Sources/BranchSDK/BNCPreferenceHelper.m index dc6ecb06d..d68afa08a 100644 --- a/Sources/BranchSDK/BNCPreferenceHelper.m +++ b/Sources/BranchSDK/BNCPreferenceHelper.m @@ -969,7 +969,7 @@ - (NSData *)loadPrefData { NSError *error = nil; data = [NSData dataWithContentsOfURL:self.class.URLForPrefsFile options:0 error:&error]; if (error || !data) { - [[BranchLogger shared] logWarning:@"Failed to load preferences from storage." error:error]; + [[BranchLogger shared] logWarning:@"Failed to load preferences from storage. This is expected on first run." error:error]; } } @catch (NSException *) { [[BranchLogger shared] logWarning:@"Failed to load preferences from storage." error:nil]; From c79d5bf4045c2922072a8ca3f48d560d9eede8df Mon Sep 17 00:00:00 2001 From: echo Date: Wed, 27 Mar 2024 12:58:07 -0700 Subject: [PATCH 11/16] Add check for DNS blocking just to make logs more informative --- Sources/BranchSDK/BNCServerInterface.m | 8 ++++-- Sources/BranchSDK/BNCURLFilter.m | 7 ++++- Sources/BranchSDK/BranchQRCode.m | 8 ++++-- Sources/BranchSDK/NSError+Branch.m | 32 ++++++++++++++++++++++ Sources/BranchSDK/Private/NSError+Branch.h | 3 ++ 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/Sources/BranchSDK/BNCServerInterface.m b/Sources/BranchSDK/BNCServerInterface.m index f770a9ac0..63559c3a8 100644 --- a/Sources/BranchSDK/BNCServerInterface.m +++ b/Sources/BranchSDK/BNCServerInterface.m @@ -122,7 +122,11 @@ - (void)genericHTTPRequest:(NSURLRequest *)request retryNumber:(NSInteger)retryN } else { if (status != 200) { - [[BranchLogger shared] logWarning: [NSString stringWithFormat:@"Giving up on request with HTTP status code %ld", (long)status] error:underlyingError]; + if ([NSError branchDNSBlockingError:underlyingError]) { + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Possible DNS Ad Blocker. Giving up on request with HTTP status code %ld", (long)status] error:underlyingError]; + } else { + [[BranchLogger shared] logWarning: [NSString stringWithFormat:@"Giving up on request with HTTP status code %ld", (long)status] error:underlyingError]; + } } // Don't call on the main queue since it might be blocked. @@ -301,7 +305,7 @@ - (BNCServerResponse *)processServerResponse:(NSURLResponse *)response data:(NSD serverResponse.requestId = requestId; if ([[BranchLogger shared] shouldLog:BranchLogLevelDebug]) { - [[BranchLogger shared] logWarning:@"Request failed with NSError" error:error]; + [[BranchLogger shared] logDebug:@"Request failed with NSError" error:error]; } } diff --git a/Sources/BranchSDK/BNCURLFilter.m b/Sources/BranchSDK/BNCURLFilter.m index b096a3b53..65cf25ff5 100644 --- a/Sources/BranchSDK/BNCURLFilter.m +++ b/Sources/BranchSDK/BNCURLFilter.m @@ -11,6 +11,7 @@ #import "BNCURLFilter.h" #import "Branch.h" #import "BranchLogger.h" +#import "NSError+Branch.h" @interface BNCURLFilter () @@ -130,7 +131,11 @@ - (BOOL)foundUpdatedURLList:(id)operation { [[BranchLogger shared] logDebug:@"No update for URL ignore list found." error:nil]; return NO; } else if (statusCode != 200 || error != nil || jsonString == nil) { - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Failed to update URL ignore list. error: %@ status: %ld", operation.error, (long)operation.response.statusCode] error:operation.error]; + if ([NSError branchDNSBlockingError:error]) { + [[BranchLogger shared] logWarning:@"Possible DNS Ad Blocker" error:error]; + } else { + [[BranchLogger shared] logWarning:@"Failed to update URL ignore list" error:operation.error]; + } return NO; } else { return YES; diff --git a/Sources/BranchSDK/BranchQRCode.m b/Sources/BranchSDK/BranchQRCode.m index 43407f0e2..b88bfe068 100644 --- a/Sources/BranchSDK/BranchQRCode.m +++ b/Sources/BranchSDK/BranchQRCode.m @@ -143,8 +143,12 @@ - (void)callQRCodeAPI:(nullable NSDictionary *)params NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (error) { - [[BranchLogger shared] logError:@"QR Code request failed" error:error]; - completion(nil, error); + if ([NSError branchDNSBlockingError:error]) { + [[BranchLogger shared] logWarning:@"Possible DNS Ad Blocker" error:error]; + } else { + [[BranchLogger shared] logError:@"QR Code request failed" error:error]; + completion(nil, error); + } return; } diff --git a/Sources/BranchSDK/NSError+Branch.m b/Sources/BranchSDK/NSError+Branch.m index 524273842..1ffe8bd9d 100644 --- a/Sources/BranchSDK/NSError+Branch.m +++ b/Sources/BranchSDK/NSError+Branch.m @@ -83,4 +83,36 @@ + (NSError *) branchErrorWithCode:(BNCErrorCode)errorCode localizedMessage:(NSSt return [NSError branchErrorWithCode:errorCode error:nil localizedMessage:message]; } ++ (BOOL)branchDNSBlockingError:(NSError *)error { + if (error) { + NSError *underlyingError = error.userInfo[@"NSUnderlyingError"]; + if (underlyingError) { + + /** + Check if an NSError was likely caused by a DNS sinkhole, such as Pi-hole. + The OS level logs will show that the IP address that failed is all 0's, however App level logs will not contain that information. + + `Domain=kCFErrorDomainCFNetwork Code=-1000` - Connection failed due to a malformed URL. A bit misleading since Ad blockers DNS resolve the URL as 0.0.0.0. + https://developer.apple.com/documentation/cfnetwork/cfnetworkerrors/kcfurlerrorbadurl?language=objc + + `_kCFStreamErrorDomainKey=1` Error domain is a POSIX error. + https://opensource.apple.com/source/CF/CF-550.13/CFStream.h.auto.html + + `_kCFStreamErrorCodeKey=22` POSIX error is invalid argument. In this case the IP address is 0.0.0.0, which is invalid. + https://opensource.apple.com/source/xnu/xnu-792/bsd/sys/errno.h.auto.html + */ + BOOL isCFErrorDomainCFNetwork = [((NSString *)kCFErrorDomainCFNetwork) isEqualToString:underlyingError.domain]; + BOOL isCodeMalFormedURL = [@(-1000) isEqual:@(underlyingError.code)]; + + BOOL isErrorDomainPosix = [@(1) isEqual:error.userInfo[@"_kCFStreamErrorDomainKey"]]; + BOOL isPosixInvalidArgument = [@(22) isEqual:error.userInfo[@"_kCFStreamErrorCodeKey"]]; + + if (isCFErrorDomainCFNetwork && isCodeMalFormedURL && isErrorDomainPosix && isPosixInvalidArgument) { + return YES; + } + } + } + return NO; +} + @end diff --git a/Sources/BranchSDK/Private/NSError+Branch.h b/Sources/BranchSDK/Private/NSError+Branch.h index 610eff65e..07e36c969 100644 --- a/Sources/BranchSDK/Private/NSError+Branch.h +++ b/Sources/BranchSDK/Private/NSError+Branch.h @@ -43,6 +43,9 @@ typedef NS_ENUM(NSInteger, BNCErrorCode) { + (NSError *) branchErrorWithCode:(BNCErrorCode)errorCode error:(NSError *_Nullable)error; + (NSError *) branchErrorWithCode:(BNCErrorCode)errorCode localizedMessage:(NSString *_Nullable)message; +// Checks if an NSError looks like a DNS blocking error ++ (BOOL)branchDNSBlockingError:(NSError *)error; + @end NS_ASSUME_NONNULL_END From 983d1903a9c774b52dc391e8e5a57b97f907296c Mon Sep 17 00:00:00 2001 From: echo Date: Thu, 28 Mar 2024 19:36:09 -0700 Subject: [PATCH 12/16] fix unit test. clarify comments. --- .../Branch-SDK-Tests/BranchLoggerTests.m | 15 ++++----------- Sources/BranchSDK/BNCEncodingUtils.m | 2 ++ Sources/BranchSDK/BNCKeyChain.m | 6 ++---- Sources/BranchSDK/BNCNetworkInterface.m | 8 ++++---- Sources/BranchSDK/BNCPreferenceHelper.m | 8 ++++---- Sources/BranchSDK/BranchShareLink.m | 7 ++++--- Sources/BranchSDK/Public/BranchLogger.h | 4 ++-- 7 files changed, 22 insertions(+), 28 deletions(-) diff --git a/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m b/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m index feeeb1e22..327ca72c2 100644 --- a/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m +++ b/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m @@ -250,19 +250,12 @@ - (void)testLogFormat_includeCallerDetailsNO_NSError { } - (void)testDefaultBranchLogFormat { - __block NSError *originalError = [NSError errorWithDomain:@"com.domain.test" code:200 userInfo:@{@"Error Message": @"Test Error"}]; + NSError *error = [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 = @"[BranchSDK][Error][BranchLoggerTests testDefaultBranchLogFormat] msg NSError: The operation couldn’t be completed. (com.domain.test error 200.)"; - NSString *formattedMessage = [BranchLogger formatMessage:message logLevel:logLevel error:error]; - - XCTAssertTrue([expectedMessage isEqualToString:formattedMessage]); - }; + 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]; - [logger logError:@"msg" error:originalError]; + XCTAssertTrue([expectedMessage isEqualToString:formattedMessage]); } @end diff --git a/Sources/BranchSDK/BNCEncodingUtils.m b/Sources/BranchSDK/BNCEncodingUtils.m index d8b96b3c5..2ed69555c 100644 --- a/Sources/BranchSDK/BNCEncodingUtils.m +++ b/Sources/BranchSDK/BNCEncodingUtils.m @@ -462,6 +462,8 @@ + (NSData *)dataFromHexString:(NSString*)string { data = [NSData dataWithBytes:bytes length:b-bytes]; } + // Error handling in C code is one case where goto can improve readability. + // https://www.kernel.org/doc/html/v4.19/process/coding-style.html exit: if (bytes) { free(bytes); diff --git a/Sources/BranchSDK/BNCKeyChain.m b/Sources/BranchSDK/BNCKeyChain.m index 34c582c5a..12dfaa640 100644 --- a/Sources/BranchSDK/BNCKeyChain.m +++ b/Sources/BranchSDK/BNCKeyChain.m @@ -68,8 +68,7 @@ + (NSDate *)retrieveDateForService:(NSString *)service key:(NSString *)key error if (valueData) { @try { value = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSDate class] fromData:(__bridge NSData*)valueData error:NULL]; - } - @catch (id) { + } @catch (NSException *exception) { value = nil; NSError *localError = [self errorWithKey:key OSStatus:errSecDecode]; if (error) *error = localError; @@ -91,8 +90,7 @@ + (NSError *) storeDate:(NSDate *)date NSData* valueData = nil; @try { valueData = [NSKeyedArchiver archivedDataWithRootObject:date requiringSecureCoding:YES error:NULL]; - } - @catch(id) { + } @catch (NSException *exception) { valueData = nil; } if (!valueData) { diff --git a/Sources/BranchSDK/BNCNetworkInterface.m b/Sources/BranchSDK/BNCNetworkInterface.m index c4d41dddc..2bc9a19c4 100644 --- a/Sources/BranchSDK/BNCNetworkInterface.m +++ b/Sources/BranchSDK/BNCNetworkInterface.m @@ -52,9 +52,7 @@ - (NSString*) description { int e = errno; [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Failed to read IP Address: (%d): %s", e, strerror(e)] error:nil]; - // Error handling in C code is one case where goto can improve readability. - // https://www.kernel.org/doc/html/v4.19/process/coding-style.html - goto err_free_interfaces; + goto exit; } // Loop through linked list of interfaces -- @@ -96,7 +94,9 @@ - (NSString*) description { } } -err_free_interfaces: + // Error handling in C code is one case where goto can improve readability. + // https://www.kernel.org/doc/html/v4.19/process/coding-style.html +exit: if (interfaces) freeifaddrs(interfaces); return currentInterfaces; } diff --git a/Sources/BranchSDK/BNCPreferenceHelper.m b/Sources/BranchSDK/BNCPreferenceHelper.m index d68afa08a..730fcbe1a 100644 --- a/Sources/BranchSDK/BNCPreferenceHelper.m +++ b/Sources/BranchSDK/BNCPreferenceHelper.m @@ -937,8 +937,8 @@ - (NSData *)serializePrefDict:(NSMutableDictionary *)dict { NSData *data = nil; @try { data = [NSKeyedArchiver archivedDataWithRootObject:dict requiringSecureCoding:YES error:NULL]; - } @catch (id exception) { - [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Exception serializing preferences dict: %@.", exception] error:nil]; + } @catch (NSException *exception) { + [[BranchLogger shared] logError:[NSString stringWithFormat:@"Exception serializing preferences dict: %@.", exception] error:nil]; } return data; } @@ -971,8 +971,8 @@ - (NSData *)loadPrefData { if (error || !data) { [[BranchLogger shared] logWarning:@"Failed to load preferences from storage. This is expected on first run." error:error]; } - } @catch (NSException *) { - [[BranchLogger shared] logWarning:@"Failed to load preferences from storage." error:nil]; + } @catch (NSException *exception) { + [[BranchLogger shared] logError:[NSString stringWithFormat:@"Exception loading preferences dict: %@.", exception] error:nil]; } return data; } diff --git a/Sources/BranchSDK/BranchShareLink.m b/Sources/BranchSDK/BranchShareLink.m index 1a24fd706..c6edc50f5 100644 --- a/Sources/BranchSDK/BranchShareLink.m +++ b/Sources/BranchSDK/BranchShareLink.m @@ -197,11 +197,12 @@ - (void) presentActivityViewControllerFromViewController:(UIViewController*_Null NSString *emailSubject = self.linkProperties.controlParams[BRANCH_LINK_DATA_KEY_EMAIL_SUBJECT]; if (emailSubject.length <= 0) emailSubject = self.emailSubject; if (emailSubject.length) { + // Key value coding to set email subject + // https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueCoding/SearchImplementation.html#//apple_ref/doc/uid/20000955 @try { [shareViewController setValue:emailSubject forKey:@"subject"]; - } - @catch (NSException*) { - [[BranchLogger shared] logWarning: @"Unable to setValue 'emailSubject' forKey 'subject' on UIActivityViewController." error:nil]; + } @catch (NSException *exception) { + [[BranchLogger shared] logWarning:[NSString stringWithFormat:@"Exception to setValue 'emailSubject' forKey 'subject' on UIActivityViewController: %@.", exception] error:nil]; } } diff --git a/Sources/BranchSDK/Public/BranchLogger.h b/Sources/BranchSDK/Public/BranchLogger.h index c7360969d..d0354b387 100644 --- a/Sources/BranchSDK/Public/BranchLogger.h +++ b/Sources/BranchSDK/Public/BranchLogger.h @@ -11,8 +11,8 @@ typedef NS_ENUM(NSUInteger, BranchLogLevel) { BranchLogLevelVerbose, // development BranchLogLevelDebug, // validation and troubleshooting - BranchLogLevelWarning, // potential errors and attempts at recovery - BranchLogLevelError, // unexpected or unhandled errors + BranchLogLevelWarning, // potential errors and attempts at recovery. SDK may be in a bad state. + BranchLogLevelError, // severe errors. SDK is probably in a bad state. }; typedef void(^BranchLogCallback)(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error); From 0e1bedbc9032b893368d27947b85a09f2fdacdfe Mon Sep 17 00:00:00 2001 From: Nipun Singh <88689850+nsingh-branch@users.noreply.github.com> Date: Fri, 29 Mar 2024 11:02:05 -0700 Subject: [PATCH 13/16] Added apiUrl check for Branch.json (#1371) --- Sources/BranchSDK/Branch.m | 4 ++++ Sources/BranchSDK/BranchJsonConfig.m | 7 +++++++ Sources/BranchSDK/Private/BranchJsonConfig.h | 2 ++ 3 files changed, 13 insertions(+) diff --git a/Sources/BranchSDK/Branch.m b/Sources/BranchSDK/Branch.m index 984fbb40d..abb1770b7 100644 --- a/Sources/BranchSDK/Branch.m +++ b/Sources/BranchSDK/Branch.m @@ -235,6 +235,10 @@ - (id)initWithInterface:(BNCServerInterface *)interface BranchJsonConfig *config = BranchJsonConfig.instance; self.deferInitForPluginRuntime = config.deferInitForPluginRuntime; + if (config.apiUrl) { + [Branch setAPIUrl:config.apiUrl]; + } + if (config.enableLogging) { [self enableLogging]; } diff --git a/Sources/BranchSDK/BranchJsonConfig.m b/Sources/BranchSDK/BranchJsonConfig.m index aa3bbb077..6f004b1b6 100644 --- a/Sources/BranchSDK/BranchJsonConfig.m +++ b/Sources/BranchSDK/BranchJsonConfig.m @@ -17,6 +17,8 @@ NSString * _Nonnull const BranchJsonConfigDeferInitForPluginRuntimeOption = @"deferInitForPluginRuntime"; NSString * _Nonnull const BranchJsonConfigEnableLogging = @"enableLogging"; NSString * _Nonnull const BranchJsonConfigCheckPasteboardOnInstall = @"checkPasteboardOnInstall"; +NSString * _Nonnull const BranchJsonConfigAPIUrl = @"apiUrl"; + @interface BranchJsonConfig() @property (nonatomic, strong) NSDictionary *configuration; @@ -161,6 +163,11 @@ - (NSString *)testKey return self[BranchJsonConfigTestKeyOption]; } +- (NSString *)apiUrl +{ + return self[BranchJsonConfigAPIUrl]; +} + - (id)objectForKey:(NSString *)key { return self.configuration[key]; diff --git a/Sources/BranchSDK/Private/BranchJsonConfig.h b/Sources/BranchSDK/Private/BranchJsonConfig.h index 1a6737e32..425d589d0 100644 --- a/Sources/BranchSDK/Private/BranchJsonConfig.h +++ b/Sources/BranchSDK/Private/BranchJsonConfig.h @@ -16,6 +16,7 @@ extern NSString * _Nonnull const BranchJsonConfigUseTestInstanceOption; extern NSString * _Nonnull const BranchJsonConfigDeferInitForPluginRuntimeOption; extern NSString * _Nonnull const BranchJsonConfigEnableLogging; extern NSString * _Nonnull const BranchJsonConfigCheckPasteboardOnInstall; +extern NSString * _Nonnull const BranchJsonConfigAPIUrl; @interface BranchJsonConfig : NSObject @@ -29,6 +30,7 @@ extern NSString * _Nonnull const BranchJsonConfigCheckPasteboardOnInstall; @property (nonatomic, readonly, assign) BOOL deferInitForPluginRuntime; @property (nonatomic, readonly, assign) BOOL enableLogging; @property (nonatomic, readonly, assign) BOOL checkPasteboardOnInstall; +@property (nonatomic, readonly, nullable, copy) NSString *apiUrl; - (nullable id)objectForKey:(NSString * _Nonnull)key; - (nullable id)objectForKeyedSubscript:(NSString * _Nonnull)key; From 2293f057c2fa7f715904dc8b5e0be515b8468d2e Mon Sep 17 00:00:00 2001 From: Nipun Singh <88689850+nsingh-branch@users.noreply.github.com> Date: Mon, 1 Apr 2024 17:00:17 -0700 Subject: [PATCH 14/16] Release 3.4.0 (#1374) --- BranchSDK.podspec | 2 +- BranchSDK.xcodeproj/project.pbxproj | 12 ++++++------ ChangeLog.md | 3 +++ Sources/BranchSDK/BNCConfig.m | 2 +- scripts/version.sh | 2 +- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/BranchSDK.podspec b/BranchSDK.podspec index cf52b72d9..b7d65623c 100644 --- a/BranchSDK.podspec +++ b/BranchSDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "BranchSDK" - s.version = "3.3.0" + s.version = "3.4.0" s.summary = "Create an HTTP URL for any piece of content in your app" s.description = <<-DESC - Want the highest possible conversions on your sharing feature? diff --git a/BranchSDK.xcodeproj/project.pbxproj b/BranchSDK.xcodeproj/project.pbxproj index 3c67048f8..de8d1fda2 100644 --- a/BranchSDK.xcodeproj/project.pbxproj +++ b/BranchSDK.xcodeproj/project.pbxproj @@ -1974,7 +1974,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 3.3.0; + MARKETING_VERSION = 3.4.0; OTHER_LDFLAGS = ( "-weak_framework", LinkPresentation, @@ -2009,7 +2009,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 3.3.0; + MARKETING_VERSION = 3.4.0; OTHER_LDFLAGS = ( "-weak_framework", LinkPresentation, @@ -2215,7 +2215,7 @@ "@loader_path/Frameworks", ); MACH_O_TYPE = staticlib; - MARKETING_VERSION = 3.3.0; + MARKETING_VERSION = 3.4.0; OTHER_LDFLAGS = ( "-weak_framework", LinkPresentation, @@ -2254,7 +2254,7 @@ "@loader_path/Frameworks", ); MACH_O_TYPE = staticlib; - MARKETING_VERSION = 3.3.0; + MARKETING_VERSION = 3.4.0; OTHER_LDFLAGS = ( "-weak_framework", LinkPresentation, @@ -2291,7 +2291,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 3.3.0; + MARKETING_VERSION = 3.4.0; OTHER_LDFLAGS = ( "-weak_framework", LinkPresentation, @@ -2326,7 +2326,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 3.3.0; + MARKETING_VERSION = 3.4.0; OTHER_LDFLAGS = ( "-weak_framework", LinkPresentation, diff --git a/ChangeLog.md b/ChangeLog.md index 52323086a..8f88503ce 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,8 @@ Branch iOS SDK Change Log +v.3.4.0 +- Added support for setting the Branch API base URL through the `branch.json` file. + v.3.3.0 - SDK behavior change to fix a race condition when opening a closed app with a link. In some apps, this race condition could cause the occasional loss of link data. diff --git a/Sources/BranchSDK/BNCConfig.m b/Sources/BranchSDK/BNCConfig.m index 2e16a9c7d..7335edabc 100644 --- a/Sources/BranchSDK/BNCConfig.m +++ b/Sources/BranchSDK/BNCConfig.m @@ -8,7 +8,7 @@ #include "BNCConfig.h" -NSString * const BNC_SDK_VERSION = @"3.3.0"; +NSString * const BNC_SDK_VERSION = @"3.4.0"; NSString * const BNC_LINK_URL = @"https://bnc.lt"; NSString * const BNC_CDN_URL = @"https://cdn.branch.io"; diff --git a/scripts/version.sh b/scripts/version.sh index 56564170c..d0934f33b 100755 --- a/scripts/version.sh +++ b/scripts/version.sh @@ -30,7 +30,7 @@ Options: USAGE } -version=3.3.0 +version=3.4.0 prev_version="$version" if (( $# == 0 )); then From c1c88279a786a35d589021ebd93abf050056aca1 Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 1 Apr 2024 19:27:02 -0700 Subject: [PATCH 15/16] make increment the same across tests. --- Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m b/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m index 327ca72c2..94badb12d 100644 --- a/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m +++ b/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m @@ -27,7 +27,7 @@ - (void)testLoggingEnabled_NOByDefault { __block int count = 0; logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - count++; + count = count + 1; }; [logger logError:@"msg" error:nil]; @@ -40,7 +40,7 @@ - (void)testLoggingEnabled_Yes { __block int count = 0; logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - count++; + count = count + 1; }; [logger logError:@"msg" error:nil]; @@ -56,7 +56,7 @@ - (void)testLoggingIgnoresNil { __block int count = 0; logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - count++; + count = count + 1; }; [logger logError:nil error:nil]; @@ -69,7 +69,7 @@ - (void)testLoggingIgnoresEmptyString { __block int count = 0; logger.logCallback = ^(NSString * _Nonnull message, BranchLogLevel logLevel, NSError * _Nullable error) { - count++; + count = count + 1; }; [logger logError:@"" error:nil]; From 4152af5af2ed5c694e72628b750159b556effeef Mon Sep 17 00:00:00 2001 From: echo Date: Mon, 1 Apr 2024 19:28:46 -0700 Subject: [PATCH 16/16] clarify comment --- Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m b/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m index 94badb12d..1a4be3490 100644 --- a/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m +++ b/Branch-TestBed/Branch-SDK-Tests/BranchLoggerTests.m @@ -111,7 +111,7 @@ - (void)testLogLevel_DebugByDefault { [logger logDebug:@"msg" error:nil]; XCTAssertTrue(count == 3); - // this should be ignored + // this should be ignored and the counter not incremented [logger logVerbose:@"msg" error:nil]; XCTAssertTrue(count == 3); } @@ -130,7 +130,7 @@ - (void)testLogLevel_Error { [logger logError:@"msg" error:nil]; XCTAssertTrue(count == 1); - // this should be ignored + // these should be ignored and the counter not incremented [logger logWarning:@"msg" error:nil]; XCTAssertTrue(count == 1); [logger logDebug:@"msg" error:nil]; @@ -155,7 +155,7 @@ - (void)testLogLevel_Warning { [logger logWarning:@"msg" error:nil]; XCTAssertTrue(count == 2); - // this should be ignored + // this should be ignored and the counter not incremented [logger logDebug:@"msg" error:nil]; XCTAssertTrue(count == 2); [logger logVerbose:@"msg" error:nil];