From 649cf7b5d31d3a39ef98baebd191e93d0dab50bc Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 1 Apr 2020 11:01:49 +0200 Subject: [PATCH 01/27] filePath nil check --- Adjust/ADJUtil.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 523ab3450..97c3d7274 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -384,7 +384,9 @@ + (void)writeObject:(id)object NSError *errorArchiving = nil; NSError *errorWriting = nil; NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object requiringSecureCoding:NO error:&errorArchiving]; - [data writeToFile:filePath options:NSDataWritingAtomic error:&errorWriting]; + if (filePath != nil) { + [data writeToFile:filePath options:NSDataWritingAtomic error:&errorWriting]; + } result = (filePath != nil) && (errorArchiving == nil) && (errorWriting == nil); } else { result = (filePath != nil) && [NSKeyedArchiver archiveRootObject:object toFile:filePath]; From 46ab49a07b0185af6e59407332a54a09fc521f78 Mon Sep 17 00:00:00 2001 From: nonelse Date: Wed, 1 Apr 2020 14:25:03 +0200 Subject: [PATCH 02/27] refac style to avoid IDE unclosed parentisis --- Adjust/ADJUtil.m | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 97c3d7274..4b3f4d058 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -293,10 +293,11 @@ + (id)readObject:(NSString *)fileName @try { id appSupportObject; #if !TARGET_OS_TV - if (@available(iOS 11.0, *)) { + if (@available(iOS 11.0, *)) #else - if (@available(tvOS 11.0, *)) { + if (@available(tvOS 11.0, *)) #endif + { NSData *data = [NSData dataWithContentsOfFile:appSupportFilePath]; NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; [unarchiver setRequiresSecureCoding:NO]; @@ -333,10 +334,11 @@ + (id)readObject:(NSString *)fileName @try { id documentsObject; #if !TARGET_OS_TV - if (@available(iOS 11.0, *)) { + if (@available(iOS 11.0, *)) #else - if (@available(tvOS 11.0, *)) { + if (@available(tvOS 11.0, *)) #endif + { NSData *data = [NSData dataWithContentsOfFile:documentsFilePath]; NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; [unarchiver setRequiresSecureCoding:NO]; @@ -377,10 +379,11 @@ + (void)writeObject:(id)object NSString *filePath = [ADJUtil getFilePathInAppSupportDir:fileName]; #if !TARGET_OS_TV - if (@available(iOS 11.0, *)) { + if (@available(iOS 11.0, *)) #else - if (@available(tvOS 11.0, *)) { + if (@available(tvOS 11.0, *)) #endif + { NSError *errorArchiving = nil; NSError *errorWriting = nil; NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object requiringSecureCoding:NO error:&errorArchiving]; @@ -391,7 +394,6 @@ + (void)writeObject:(id)object } else { result = (filePath != nil) && [NSKeyedArchiver archiveRootObject:object toFile:filePath]; } - if (result == YES) { [ADJUtil excludeFromBackup:filePath]; if ([object isKindOfClass:[NSArray class]]) { From e9afd744a69d74d51cecd6d05fc8ea26345ff54e Mon Sep 17 00:00:00 2001 From: nonelse Date: Wed, 1 Apr 2020 14:25:40 +0200 Subject: [PATCH 03/27] refac write object valid path --- Adjust/ADJUtil.m | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 4b3f4d058..45dc5adec 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -378,6 +378,11 @@ + (void)writeObject:(id)object BOOL result; NSString *filePath = [ADJUtil getFilePathInAppSupportDir:fileName]; + if (!filePath) { + [[ADJAdjustFactory logger] error:@"Cannot get filepath from filename: %@, to write %@ file", fileName, objectName]; + return; + } + #if !TARGET_OS_TV if (@available(iOS 11.0, *)) #else @@ -385,14 +390,16 @@ + (void)writeObject:(id)object #endif { NSError *errorArchiving = nil; - NSError *errorWriting = nil; NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object requiringSecureCoding:NO error:&errorArchiving]; - if (filePath != nil) { - [data writeToFile:filePath options:NSDataWritingAtomic error:&errorWriting]; + if (data && errorArchiving == nil) { + NSError *errorWriting = nil; + result = [data writeToFile:filePath options:NSDataWritingAtomic error:&errorWriting]; + result = result && (errorWriting == nil); + } else { + result = NO; } - result = (filePath != nil) && (errorArchiving == nil) && (errorWriting == nil); } else { - result = (filePath != nil) && [NSKeyedArchiver archiveRootObject:object toFile:filePath]; + result = [NSKeyedArchiver archiveRootObject:object toFile:filePath]; } if (result == YES) { [ADJUtil excludeFromBackup:filePath]; From 089f22b61519f725692764a068648c29d988c66a Mon Sep 17 00:00:00 2001 From: nonelse Date: Wed, 1 Apr 2020 16:33:26 +0200 Subject: [PATCH 04/27] Refac extract keys --- Adjust/ADJUtil.m | 52 ++++++++++++++---------------------------------- 1 file changed, 15 insertions(+), 37 deletions(-) diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 45dc5adec..04dd86ccf 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -615,57 +615,35 @@ + (void)sendRequest:(NSMutableURLRequest *)request + (NSString *)buildAuthorizationHeader:(NSMutableDictionary *)parameters activityKind:(ADJActivityKind)activityKind { - NSString * secretId = [ADJUtil extractSecretId:parameters]; - NSString * signature = [ADJUtil extractSignature:parameters]; - NSString * headersId = [ADJUtil extractHeadersId:parameters]; - NSString * authorizationHeader = [ADJUtil buildAuthorizationHeaderV2:signature + NSString *secretId = [ADJUtil extractEntry:parameters + key:@"secret_id"]; + NSString *signature = [ADJUtil extractEntry:parameters + key:@"signature"]; + NSString *headersId = [ADJUtil extractEntry:parameters + key:@"headers_id"]; + NSString *authorizationHeader = [ADJUtil buildAuthorizationHeaderV2:signature secretId:secretId headersId:headersId]; if (authorizationHeader != nil) { return authorizationHeader; } - NSString * appSecret = [ADJUtil extractAppSecret:parameters]; + NSString * appSecret = [ADJUtil extractEntry:parameters key:@"app_secret"]; return [ADJUtil buildAuthorizationHeaderV1:appSecret secretId:secretId parameters:parameters activityKind:activityKind]; } -+ (NSString *)extractSecretId:(NSMutableDictionary *)parameters { - NSString *appSecret = [parameters objectForKey:@"secret_id"]; - if (appSecret == nil) { - return nil; - } - [parameters removeObjectForKey:@"secret_id"]; - return appSecret; -} - -+ (NSString *)extractSignature:(NSMutableDictionary *)parameters { - NSString *appSecret = [parameters objectForKey:@"signature"]; - if (appSecret == nil) { - return nil; - } - [parameters removeObjectForKey:@"signature"]; - return appSecret; -} - -+ (NSString *)extractHeadersId:(NSMutableDictionary *)parameters { - NSString *appSecret = [parameters objectForKey:@"headers_id"]; - if (appSecret == nil) { - return nil; - } - [parameters removeObjectForKey:@"headers_id"]; - return appSecret; -} - -+ (NSString *)extractAppSecret:(NSMutableDictionary *)parameters { - NSString *appSecret = [parameters objectForKey:@"app_secret"]; - if (appSecret == nil) { ++ (NSString *)extractEntry:(NSMutableDictionary *)parameters + key:(NSString *)key +{ + NSString *stringValue = [parameters objectForKey:key]; + if (stringValue == nil) { return nil; } - [parameters removeObjectForKey:@"app_secret"]; - return appSecret; + [parameters removeObjectForKey:key]; + return stringValue; } + (NSString *)buildAuthorizationHeaderV2:(NSString *)signature From ec6d048ae8d02028ef3d4a550dbfde140f3778d7 Mon Sep 17 00:00:00 2001 From: nonelse Date: Wed, 1 Apr 2020 16:33:48 +0200 Subject: [PATCH 05/27] Add native version of signature lib --- Adjust/ADJActivityPackage.m | 2 +- Adjust/ADJPackageBuilder.m | 26 ++++++++++++++++++++++++++ Adjust/ADJUtil.m | 15 +++++++++++---- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/Adjust/ADJActivityPackage.m b/Adjust/ADJActivityPackage.m index 6231e28ab..69667aca1 100644 --- a/Adjust/ADJActivityPackage.m +++ b/Adjust/ADJActivityPackage.m @@ -15,7 +15,7 @@ @implementation ADJActivityPackage - (NSString *)extendedString { NSMutableString *builder = [NSMutableString string]; - NSArray *excludedKeys = @[@"secret_id", @"app_secret", @"event_callback_id"]; + NSArray *excludedKeys = @[@"secret_id", @"app_secret", @"signature", @"headers_id", @"native_version", @"event_callback_id"]; [builder appendFormat:@"Path: %@\n", self.path]; [builder appendFormat:@"ClientSdk: %@\n", self.clientSdk]; diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index bd961883b..b6f311cf4 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -216,6 +216,32 @@ - (void)signWithSigV2Plugin:(ADJActivityPackage *)activityPackage { [signInvocation setArgument:&sdkVersionChar atIndex: 4]; [signInvocation invoke]; + + SEL getVersionSEL = NSSelectorFromString(@"getVersion"); + if (![signerClass respondsToSelector:getVersionSEL]) { + return; + } + /* + NSString *signerVersion = [ADJSigner getVersion]; + */ + IMP getVersionIMP = [signerClass methodForSelector:getVersionSEL]; + if (!getVersionIMP) { + return; + } + + id (*getVersionFunc)(id, SEL) = (void *)getVersionIMP; + + id signerVersion = getVersionFunc(signerClass, getVersionSEL); + + if (![signerVersion isKindOfClass:[NSString class]]) { + return; + } + + NSString *signerVersionString = (NSString *)signerVersion; + [ADJPackageBuilder parameters:parameters + setString:signerVersionString + forKey:@"native_version"]; + } - (NSMutableDictionary *)getSessionParameters:(BOOL)isInDelay { diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 04dd86ccf..3aa691761 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -621,9 +621,12 @@ + (NSString *)buildAuthorizationHeader:(NSMutableDictionary *)parameters key:@"signature"]; NSString *headersId = [ADJUtil extractEntry:parameters key:@"headers_id"]; + NSString *nativeVersion = [ADJUtil extractEntry:parameters + key:@"native_version"]; NSString *authorizationHeader = [ADJUtil buildAuthorizationHeaderV2:signature secretId:secretId - headersId:headersId]; + headersId:headersId + nativeVersion:nativeVersion]; if (authorizationHeader != nil) { return authorizationHeader; } @@ -647,8 +650,9 @@ + (NSString *)extractEntry:(NSMutableDictionary *)parameters } + (NSString *)buildAuthorizationHeaderV2:(NSString *)signature - secretId:(NSString*)secretId - headersId:(NSString*)headersId + secretId:(NSString *)secretId + headersId:(NSString *)headersId + nativeVersion:(NSString *)nativeVersion { if (secretId == nil || signature == nil || headersId == nil) { return nil; @@ -662,7 +666,10 @@ + (NSString *)buildAuthorizationHeaderV2:(NSString *)signature NSString * authorizationHeader = [NSString stringWithFormat:@"Signature %@,%@,%@,%@", signatureHeader, secretIdHeader, algorithmHeader, idHeader]; - return authorizationHeader; + if (nativeVersion == nil) { + return authorizationHeader; + } + return [authorizationHeader stringByAppendingFormat:@",native_version=\"%@\"", nativeVersion]; } + (void)extractEventCallbackId:(NSMutableDictionary *)parameters { From 575e7ca38928f9f3dc89e9031cdffeb74b01442c Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 1 Apr 2020 23:30:07 +0200 Subject: [PATCH 06/27] @available replace proposal --- Adjust/ADJUtil.m | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 3aa691761..61ba08548 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -24,6 +24,8 @@ #import #endif +#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) + static const double kRequestTimeout = 60; // 60 seconds static NSString *userAgent = nil; @@ -292,12 +294,7 @@ + (id)readObject:(NSString *)fileName // Try to read from Application Support directory first. @try { id appSupportObject; -#if !TARGET_OS_TV - if (@available(iOS 11.0, *)) -#else - if (@available(tvOS 11.0, *)) -#endif - { + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { NSData *data = [NSData dataWithContentsOfFile:appSupportFilePath]; NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; [unarchiver setRequiresSecureCoding:NO]; @@ -333,12 +330,7 @@ + (id)readObject:(NSString *)fileName // Let's check the Documents folder. @try { id documentsObject; -#if !TARGET_OS_TV - if (@available(iOS 11.0, *)) -#else - if (@available(tvOS 11.0, *)) -#endif - { + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { NSData *data = [NSData dataWithContentsOfFile:documentsFilePath]; NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; [unarchiver setRequiresSecureCoding:NO]; @@ -383,14 +375,12 @@ + (void)writeObject:(id)object return; } -#if !TARGET_OS_TV - if (@available(iOS 11.0, *)) -#else - if (@available(tvOS 11.0, *)) -#endif - { + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { NSError *errorArchiving = nil; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object requiringSecureCoding:NO error:&errorArchiving]; +#pragma clang diagnostic pop if (data && errorArchiving == nil) { NSError *errorWriting = nil; result = [data writeToFile:filePath options:NSDataWritingAtomic error:&errorWriting]; From 2be163ea3a326a55a6fa4b0a731621902d44a241 Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 1 Apr 2020 23:30:19 +0200 Subject: [PATCH 07/27] Xcode 11.4 --- Adjust.xcodeproj/project.pbxproj | 2 +- Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdk.xcscheme | 2 +- Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdkIm.xcscheme | 2 +- Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdkTv.xcscheme | 2 +- .../xcshareddata/xcschemes/AdjustSdkWebBridge.xcscheme | 2 +- .../xcshareddata/xcschemes/AdjustWebBridgeTestApp.xcscheme | 2 +- .../xcshareddata/xcschemes/PocketSocket-Mac.xcscheme | 2 +- .../xcshareddata/xcschemes/PocketSocket.xcscheme | 2 +- .../xcschemes/AdjustExample-iMessage MessagesExtension.xcscheme | 2 +- .../xcshareddata/xcschemes/AdjustExample-iMessage.xcscheme | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Adjust.xcodeproj/project.pbxproj b/Adjust.xcodeproj/project.pbxproj index 4ebae30f3..5faf90ca2 100644 --- a/Adjust.xcodeproj/project.pbxproj +++ b/Adjust.xcodeproj/project.pbxproj @@ -2197,7 +2197,7 @@ 9679920518BBAE2800394606 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1130; + LastUpgradeCheck = 1140; ORGANIZATIONNAME = "adjust GmbH"; TargetAttributes = { 9615158E1CD2CB2C0022D336 = { diff --git a/Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdk.xcscheme b/Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdk.xcscheme index 40aed6fbe..1f5e13c3a 100644 --- a/Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdk.xcscheme +++ b/Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdk.xcscheme @@ -1,6 +1,6 @@ Date: Wed, 1 Apr 2020 23:31:03 +0200 Subject: [PATCH 08/27] Fix for different data types comparison warning --- Adjust/ADJUtil.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 61ba08548..a6d2695a3 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -1313,7 +1313,7 @@ + (NSString *)convertDeviceToken:(NSData *)deviceToken { NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)]; - for (int i = 0; i < dataLength; ++i) { + for (NSUInteger i = 0; i < dataLength; ++i) { [hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]]; } From 54b37abdb957d12c700daea3601cbd53d840d379 Mon Sep 17 00:00:00 2001 From: Rob Chatfield Date: Thu, 2 Apr 2020 21:49:25 +1100 Subject: [PATCH 09/27] Xcode 11.4 support --- Adjust/ADJDeviceInfo.m | 2 +- Adjust/ADJUtil.m | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Adjust/ADJDeviceInfo.m b/Adjust/ADJDeviceInfo.m index c8c386e71..3a283a6ea 100644 --- a/Adjust/ADJDeviceInfo.m +++ b/Adjust/ADJDeviceInfo.m @@ -14,7 +14,7 @@ #import "NSData+ADJAdditions.h" #import "ADJReachability.h" -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST #import #import #endif diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index a6d2695a3..0ffc3bdaf 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -19,7 +19,7 @@ #import "UIDevice+ADJAdditions.h" #import "NSString+ADJAdditions.h" -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST #import #import #endif @@ -37,7 +37,7 @@ static NSRegularExpression *excludedDeeplinkRegex = nil; static NSURLSessionConfiguration *urlSessionConfiguration = nil; -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST static CTCarrier *carrier = nil; static CTTelephonyNetworkInfo *networkInfo = nil; #endif @@ -66,7 +66,7 @@ + (void)initialize { [self initializeExcludedDeeplinkRegex]; [self initializeUrlSessionConfiguration]; [self initializeReachability]; -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST [self initializeNetworkInfoAndCarrier]; #endif } @@ -78,7 +78,7 @@ + (void)teardown { optionalRedirectRegex = nil; shortUniversalLinkRegex = nil; urlSessionConfiguration = nil; -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST networkInfo = nil; carrier = nil; #endif @@ -150,7 +150,7 @@ + (void)initializeUrlSessionConfiguration { urlSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; } -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST + (void)initializeNetworkInfoAndCarrier { networkInfo = [[CTTelephonyNetworkInfo alloc] init]; carrier = [networkInfo subscriberCellularProvider]; @@ -1401,7 +1401,7 @@ + (NSString *)sdkVersion { return kClientSdk; } -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST + (NSString *)readMCC { if (carrier == nil) { return nil; From 8454d6d181b4f505118f8f75431204315e9266c0 Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 2 Apr 2020 13:59:03 +0200 Subject: [PATCH 10/27] Add Mac Catalyst support to ObjC example app --- .../AdjustExample-ObjC.xcodeproj/project.pbxproj | 2 ++ .../AdjustExample-ObjC/AdjustExample-ObjC.entitlements | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/examples/AdjustExample-ObjC/AdjustExample-ObjC.xcodeproj/project.pbxproj b/examples/AdjustExample-ObjC/AdjustExample-ObjC.xcodeproj/project.pbxproj index d9f6ccff2..0543794db 100644 --- a/examples/AdjustExample-ObjC/AdjustExample-ObjC.xcodeproj/project.pbxproj +++ b/examples/AdjustExample-ObjC/AdjustExample-ObjC.xcodeproj/project.pbxproj @@ -545,6 +545,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.adjust.examples; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTS_MACCATALYST = YES; }; name = Debug; }; @@ -566,6 +567,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.adjust.examples; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTS_MACCATALYST = YES; }; name = Release; }; diff --git a/examples/AdjustExample-ObjC/AdjustExample-ObjC/AdjustExample-ObjC.entitlements b/examples/AdjustExample-ObjC/AdjustExample-ObjC/AdjustExample-ObjC.entitlements index c7476a337..3cd2fd0dc 100644 --- a/examples/AdjustExample-ObjC/AdjustExample-ObjC/AdjustExample-ObjC.entitlements +++ b/examples/AdjustExample-ObjC/AdjustExample-ObjC/AdjustExample-ObjC.entitlements @@ -6,5 +6,9 @@ applinks:f6wc.adj.st + com.apple.security.app-sandbox + + com.apple.security.network.client + From 82a26020ac9166a84e308c12fd9ac1082fd7ac39 Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 2 Apr 2020 14:03:51 +0200 Subject: [PATCH 11/27] Add missing TARGET_OS_MACCATALYST macros --- Adjust/ADJPackageBuilder.m | 10 +++++----- Adjust/ADJUtil.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index b6f311cf4..c3f927521 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -303,7 +303,7 @@ - (NSMutableDictionary *)getSessionParameters:(BOOL)isInDelay { [ADJPackageBuilder parameters:parameters setDictionary:self.sessionParameters.partnerParameters forKey:@"partner_params"]; } -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST [ADJPackageBuilder parameters:parameters setString:[ADJUtil readMCC] forKey:@"mcc"]; [ADJPackageBuilder parameters:parameters setString:[ADJUtil readMNC] forKey:@"mnc"]; [ADJPackageBuilder parameters:parameters setString:[ADJUtil readCurrentRadioAccessTechnology] forKey:@"network_type"]; @@ -389,7 +389,7 @@ - (NSMutableDictionary *)getEventParameters:(BOOL)isInDelay forEventPackage:(ADJ [ADJPackageBuilder parameters:parameters setString:event.transactionId forKey:@"transaction_id"]; } -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST [ADJPackageBuilder parameters:parameters setString:[ADJUtil readMCC] forKey:@"mcc"]; [ADJPackageBuilder parameters:parameters setString:[ADJUtil readMNC] forKey:@"mnc"]; [ADJPackageBuilder parameters:parameters setString:[ADJUtil readCurrentRadioAccessTechnology] forKey:@"network_type"]; @@ -487,7 +487,7 @@ - (NSMutableDictionary *)getAdRevenueParameters:(NSString *)source payload:(NSDa } } -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST [ADJPackageBuilder parameters:parameters setString:[ADJUtil readMCC] forKey:@"mcc"]; [ADJPackageBuilder parameters:parameters setString:[ADJUtil readMNC] forKey:@"mnc"]; [ADJPackageBuilder parameters:parameters setString:[ADJUtil readCurrentRadioAccessTechnology] forKey:@"network_type"]; @@ -566,7 +566,7 @@ - (NSMutableDictionary *)getClickParameters:(NSString *)source { [ADJPackageBuilder parameters:parameters setString:self.attribution.trackerName forKey:@"tracker"]; } -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST [ADJPackageBuilder parameters:parameters setString:[ADJUtil readMCC] forKey:@"mcc"]; [ADJPackageBuilder parameters:parameters setString:[ADJUtil readMNC] forKey:@"mnc"]; [ADJPackageBuilder parameters:parameters setString:[ADJUtil readCurrentRadioAccessTechnology] forKey:@"network_type"]; @@ -717,7 +717,7 @@ - (NSMutableDictionary *)getDisableThirdPartySharingParameters { } } -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST [ADJPackageBuilder parameters:parameters setString:[ADJUtil readMCC] forKey:@"mcc"]; [ADJPackageBuilder parameters:parameters setString:[ADJUtil readMNC] forKey:@"mnc"]; [ADJPackageBuilder parameters:parameters setString:[ADJUtil readCurrentRadioAccessTechnology] forKey:@"network_type"]; diff --git a/Adjust/ADJUtil.h b/Adjust/ADJUtil.h index dc5082c09..dff12afca 100644 --- a/Adjust/ADJUtil.h +++ b/Adjust/ADJUtil.h @@ -116,7 +116,7 @@ typedef void (^isInactiveInjected)(BOOL); + (NSString *)sdkVersion; -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST + (NSString *)readMCC; + (NSString *)readMNC; From 3f83c1dd87ec3254820b46993d3cad17c173dbfd Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 2 Apr 2020 16:08:31 +0200 Subject: [PATCH 12/27] Adding source for the macro --- Adjust/ADJUtil.m | 1 + 1 file changed, 1 insertion(+) diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 0ffc3bdaf..358cc1175 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -24,6 +24,7 @@ #import #endif +// https://stackoverflow.com/a/5337804/1498352 #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) static const double kRequestTimeout = 60; // 60 seconds From 5003a824f42a53de0b07f127a9e25742f4da92e5 Mon Sep 17 00:00:00 2001 From: nonelse Date: Fri, 3 Apr 2020 15:18:02 +0200 Subject: [PATCH 13/27] Sync object read/write --- Adjust/ADJUtil.m | 183 ++++++++++++++++++++++++----------------------- 1 file changed, 95 insertions(+), 88 deletions(-) diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 358cc1175..98baa9204 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -288,119 +288,126 @@ + (NSDictionary *)buildJsonDict:(NSData *)jsonData + (id)readObject:(NSString *)fileName objectName:(NSString *)objectName - class:(Class)classToRead { - NSString *documentsFilePath = [ADJUtil getFilePathInDocumentsDir:fileName]; - NSString *appSupportFilePath = [ADJUtil getFilePathInAppSupportDir:fileName]; + class:(Class)classToRead +{ + @synchronized([ADJUtil class]) { + NSString *documentsFilePath = [ADJUtil getFilePathInDocumentsDir:fileName]; + NSString *appSupportFilePath = [ADJUtil getFilePathInAppSupportDir:fileName]; + + // Try to read from Application Support directory first. + @try { + id appSupportObject; + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { + NSData *data = [NSData dataWithContentsOfFile:appSupportFilePath]; + NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; + [unarchiver setRequiresSecureCoding:NO]; + appSupportObject = [unarchiver decodeObjectOfClass:classToRead forKey:NSKeyedArchiveRootObjectKey]; + } else { + appSupportObject = [NSKeyedUnarchiver unarchiveObjectWithFile:appSupportFilePath]; + } - // Try to read from Application Support directory first. - @try { - id appSupportObject; - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { - NSData *data = [NSData dataWithContentsOfFile:appSupportFilePath]; - NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; - [unarchiver setRequiresSecureCoding:NO]; - appSupportObject = [unarchiver decodeObjectOfClass:classToRead forKey:NSKeyedArchiveRootObjectKey]; - } else { - appSupportObject = [NSKeyedUnarchiver unarchiveObjectWithFile:appSupportFilePath]; - } - - if (appSupportObject != nil) { - if ([appSupportObject isKindOfClass:classToRead]) { - // Successfully read object from Application Support folder, return it. - if ([appSupportObject isKindOfClass:[NSArray class]]) { - [[ADJAdjustFactory logger] debug:@"Package handler read %d packages", [appSupportObject count]]; - } else { - [[ADJAdjustFactory logger] debug:@"Read %@: %@", objectName, appSupportObject]; - } + if (appSupportObject != nil) { + if ([appSupportObject isKindOfClass:classToRead]) { + // Successfully read object from Application Support folder, return it. + if ([appSupportObject isKindOfClass:[NSArray class]]) { + [[ADJAdjustFactory logger] debug:@"Package handler read %d packages", [appSupportObject count]]; + } else { + [[ADJAdjustFactory logger] debug:@"Read %@: %@", objectName, appSupportObject]; + } - // Just in case check if old file exists in Documents folder and if yes, remove it. - [ADJUtil deleteFileInPath:documentsFilePath]; + // Just in case check if old file exists in Documents folder and if yes, remove it. + [ADJUtil deleteFileInPath:documentsFilePath]; - return appSupportObject; + return appSupportObject; + } + } else { + // [[ADJAdjustFactory logger] error:@"Failed to read %@ file", appSupportFilePath]; + [[ADJAdjustFactory logger] debug:@"File %@ not found in \"Application Support/Adjust\" folder", fileName]; } - } else { - // [[ADJAdjustFactory logger] error:@"Failed to read %@ file", appSupportFilePath]; - [[ADJAdjustFactory logger] debug:@"File %@ not found in \"Application Support/Adjust\" folder", fileName]; + } @catch (NSException *ex) { + // [[ADJAdjustFactory logger] error:@"Failed to read %@ file (%@)", appSupportFilePath, ex]; + [[ADJAdjustFactory logger] error:@"Failed to read %@ file from \"Application Support/Adjust\" folder (%@)", fileName, ex]; } - } @catch (NSException *ex) { - // [[ADJAdjustFactory logger] error:@"Failed to read %@ file (%@)", appSupportFilePath, ex]; - [[ADJAdjustFactory logger] error:@"Failed to read %@ file from \"Application Support/Adjust\" folder (%@)", fileName, ex]; - } - // If in here, for some reason, reading of file from Application Support folder failed. - // Let's check the Documents folder. - @try { - id documentsObject; - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { - NSData *data = [NSData dataWithContentsOfFile:documentsFilePath]; - NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; - [unarchiver setRequiresSecureCoding:NO]; - documentsObject = [unarchiver decodeObjectOfClass:classToRead forKey:NSKeyedArchiveRootObjectKey]; - } else { - documentsObject = [NSKeyedUnarchiver unarchiveObjectWithFile:documentsFilePath]; - } - - if (documentsObject != nil) { - // Successfully read object from Documents folder. - if ([documentsObject isKindOfClass:[NSArray class]]) { - [[ADJAdjustFactory logger] debug:@"Package handler read %d packages", [documentsObject count]]; + // If in here, for some reason, reading of file from Application Support folder failed. + // Let's check the Documents folder. + @try { + id documentsObject; + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { + NSData *data = [NSData dataWithContentsOfFile:documentsFilePath]; + NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; + [unarchiver setRequiresSecureCoding:NO]; + documentsObject = [unarchiver decodeObjectOfClass:classToRead forKey:NSKeyedArchiveRootObjectKey]; } else { - [[ADJAdjustFactory logger] debug:@"Read %@: %@", objectName, documentsObject]; + documentsObject = [NSKeyedUnarchiver unarchiveObjectWithFile:documentsFilePath]; } - // Do the file migration. - [[ADJAdjustFactory logger] verbose:@"Migrating %@ file from Documents to \"Application Support/Adjust\" folder", fileName]; - [ADJUtil migrateFileFromPath:documentsFilePath toPath:appSupportFilePath]; + if (documentsObject != nil) { + // Successfully read object from Documents folder. + if ([documentsObject isKindOfClass:[NSArray class]]) { + [[ADJAdjustFactory logger] debug:@"Package handler read %d packages", [documentsObject count]]; + } else { + [[ADJAdjustFactory logger] debug:@"Read %@: %@", objectName, documentsObject]; + } + + // Do the file migration. + [[ADJAdjustFactory logger] verbose:@"Migrating %@ file from Documents to \"Application Support/Adjust\" folder", fileName]; + [ADJUtil migrateFileFromPath:documentsFilePath toPath:appSupportFilePath]; - return documentsObject; - } else { - // [[ADJAdjustFactory logger] error:@"Failed to read %@ file", documentsFilePath]; - [[ADJAdjustFactory logger] debug:@"File %@ not found in Documents folder", fileName]; + return documentsObject; + } else { + // [[ADJAdjustFactory logger] error:@"Failed to read %@ file", documentsFilePath]; + [[ADJAdjustFactory logger] debug:@"File %@ not found in Documents folder", fileName]; + } + } @catch (NSException *ex) { + // [[ADJAdjustFactory logger] error:@"Failed to read %@ file (%@)", documentsFilePath, ex]; + [[ADJAdjustFactory logger] error:@"Failed to read %@ file from Documents folder (%@)", fileName, ex]; } - } @catch (NSException *ex) { - // [[ADJAdjustFactory logger] error:@"Failed to read %@ file (%@)", documentsFilePath, ex]; - [[ADJAdjustFactory logger] error:@"Failed to read %@ file from Documents folder (%@)", fileName, ex]; - } - return nil; + return nil; + } } + (void)writeObject:(id)object fileName:(NSString *)fileName - objectName:(NSString *)objectName { - BOOL result; - NSString *filePath = [ADJUtil getFilePathInAppSupportDir:fileName]; + objectName:(NSString *)objectName +{ + @synchronized([ADJUtil class]) { + BOOL result; + NSString *filePath = [ADJUtil getFilePathInAppSupportDir:fileName]; - if (!filePath) { - [[ADJAdjustFactory logger] error:@"Cannot get filepath from filename: %@, to write %@ file", fileName, objectName]; - return; - } + if (!filePath) { + [[ADJAdjustFactory logger] error:@"Cannot get filepath from filename: %@, to write %@ file", fileName, objectName]; + return; + } - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { - NSError *errorArchiving = nil; + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { + NSError *errorArchiving = nil; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunguarded-availability" - NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object requiringSecureCoding:NO error:&errorArchiving]; + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object requiringSecureCoding:NO error:&errorArchiving]; #pragma clang diagnostic pop - if (data && errorArchiving == nil) { - NSError *errorWriting = nil; - result = [data writeToFile:filePath options:NSDataWritingAtomic error:&errorWriting]; - result = result && (errorWriting == nil); + if (data && errorArchiving == nil) { + NSError *errorWriting = nil; + result = [data writeToFile:filePath options:NSDataWritingAtomic error:&errorWriting]; + result = result && (errorWriting == nil); + } else { + result = NO; + } } else { - result = NO; + result = [NSKeyedArchiver archiveRootObject:object toFile:filePath]; } - } else { - result = [NSKeyedArchiver archiveRootObject:object toFile:filePath]; - } - if (result == YES) { - [ADJUtil excludeFromBackup:filePath]; - if ([object isKindOfClass:[NSArray class]]) { - [[ADJAdjustFactory logger] debug:@"Package handler wrote %d packages", [object count]]; + if (result == YES) { + [ADJUtil excludeFromBackup:filePath]; + if ([object isKindOfClass:[NSArray class]]) { + [[ADJAdjustFactory logger] debug:@"Package handler wrote %d packages", [object count]]; + } else { + [[ADJAdjustFactory logger] debug:@"Wrote %@: %@", objectName, object]; + } } else { - [[ADJAdjustFactory logger] debug:@"Wrote %@: %@", objectName, object]; + [[ADJAdjustFactory logger] error:@"Failed to write %@ file", objectName]; } - } else { - [[ADJAdjustFactory logger] error:@"Failed to write %@ file", objectName]; + } } From 9b2a5874e44e4a70b4d4e628c0154746b691fc4e Mon Sep 17 00:00:00 2001 From: nonelse Date: Fri, 3 Apr 2020 15:35:56 +0200 Subject: [PATCH 14/27] Replace retry count from package to handler --- Adjust/ADJActivityPackage.h | 6 ------ Adjust/ADJActivityPackage.m | 10 ---------- Adjust/ADJPackageHandler.m | 16 +++++++++++----- Adjust/ADJSdkClickHandler.m | 16 ++++++++++------ 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/Adjust/ADJActivityPackage.h b/Adjust/ADJActivityPackage.h index 668d9e5a9..3db72b530 100644 --- a/Adjust/ADJActivityPackage.h +++ b/Adjust/ADJActivityPackage.h @@ -16,8 +16,6 @@ @property (nonatomic, copy) NSString *clientSdk; -@property (nonatomic, assign) NSInteger retries; - @property (nonatomic, strong) NSMutableDictionary *parameters; @property (nonatomic, strong) NSDictionary *partnerParameters; @@ -36,8 +34,4 @@ - (NSString *)failureMessage; -- (NSInteger)getRetries; - -- (NSInteger)increaseRetries; - @end diff --git a/Adjust/ADJActivityPackage.m b/Adjust/ADJActivityPackage.m index 69667aca1..a92954361 100644 --- a/Adjust/ADJActivityPackage.m +++ b/Adjust/ADJActivityPackage.m @@ -42,16 +42,6 @@ - (NSString *)extendedString { return builder; } -- (NSInteger)getRetries { - return self.retries; -} - -- (NSInteger)increaseRetries { - self.retries = self.retries + 1; - - return self.retries; -} - - (NSString *)description { return [NSString stringWithFormat:@"%@%@", [ADJActivityKindUtil activityKindToString:self.activityKind], self.suffix]; } diff --git a/Adjust/ADJPackageHandler.m b/Adjust/ADJPackageHandler.m index 38122469b..6bf96692b 100644 --- a/Adjust/ADJPackageHandler.m +++ b/Adjust/ADJPackageHandler.m @@ -33,6 +33,7 @@ @interface ADJPackageHandler() @property (nonatomic, weak) id logger; @property (nonatomic, copy) NSString *basePath; @property (nonatomic, copy) NSString *gdprPath; +@property (nonatomic, assign) NSInteger lastPackageRetriesCount; @end @@ -56,6 +57,7 @@ - (id)initWithActivityHandler:(id)activityHandler self.backoffStrategyForInstallSession = [ADJAdjustFactory installSessionBackoffStrategy]; self.basePath = [activityHandler getBasePath]; self.gdprPath = [activityHandler getGdprPath]; + self.lastPackageRetriesCount = 0; [ADJUtil launchInQueue:self.internalQueue selfInject:self @@ -84,7 +86,9 @@ - (void)sendFirstPackage { }]; } -- (void)sendNextPackage:(ADJResponseData *)responseData{ +- (void)sendNextPackage:(ADJResponseData *)responseData { + self.lastPackageRetriesCount = 0; + [ADJUtil launchInQueue:self.internalQueue selfInject:self block:^(ADJPackageHandler* selfI) { @@ -108,20 +112,22 @@ - (void)closeFirstPackage:(ADJResponseData *)responseData }; if (activityPackage == nil) { + self.lastPackageRetriesCount = 0; work(); return; } - NSInteger retries = [activityPackage increaseRetries]; + self.lastPackageRetriesCount++; + NSTimeInterval waitTime; if ([activityPackage activityKind] == ADJActivityKindSession && [ADJUserDefaults getInstallTracked] == NO) { - waitTime = [ADJUtil waitingTime:retries backoffStrategy:self.backoffStrategyForInstallSession]; + waitTime = [ADJUtil waitingTime:self.lastPackageRetriesCount backoffStrategy:self.backoffStrategyForInstallSession]; } else { - waitTime = [ADJUtil waitingTime:retries backoffStrategy:self.backoffStrategy]; + waitTime = [ADJUtil waitingTime:self.lastPackageRetriesCount backoffStrategy:self.backoffStrategy]; } NSString *waitTimeFormatted = [ADJUtil secondsNumberFormat:waitTime]; - [self.logger verbose:@"Waiting for %@ seconds before retrying the %d time", waitTimeFormatted, retries]; + [self.logger verbose:@"Waiting for %@ seconds before retrying the %d time", waitTimeFormatted, self.lastPackageRetriesCount]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(waitTime * NSEC_PER_SEC)), self.internalQueue, work); } diff --git a/Adjust/ADJSdkClickHandler.m b/Adjust/ADJSdkClickHandler.m index fe8da9019..73ff01e7e 100644 --- a/Adjust/ADJSdkClickHandler.m +++ b/Adjust/ADJSdkClickHandler.m @@ -26,6 +26,8 @@ @interface ADJSdkClickHandler() @property (nonatomic, weak) id logger; @property (nonatomic, weak) id activityHandler; +@property (nonatomic, assign) NSInteger lastPackageRetriesCount; + @end @implementation ADJSdkClickHandler @@ -50,6 +52,7 @@ - (id)initWithActivityHandler:(id)activityHandler self.internalQueue = dispatch_queue_create(kInternalQueueName, DISPATCH_QUEUE_SERIAL); self.logger = ADJAdjustFactory.logger; self.basePath = [activityHandler getBasePath]; + self.lastPackageRetriesCount = 0; [ADJUtil launchInQueue:self.internalQueue selfInject:self @@ -159,15 +162,17 @@ - (void)sendNextSdkClickI:(ADJSdkClickHandler *)selfI { // Check if any package response contains information that user has opted out. // If yes, disable SDK and flush any potentially stored packages that happened afterwards. if (responseData.trackingState == ADJTrackingStateOptedOut) { + selfI.lastPackageRetriesCount = 0; [selfI.activityHandler setTrackingStateOptedOut]; return; } if (responseData.jsonResponse == nil) { - NSInteger retries = [sdkClickPackage increaseRetries]; - [selfI.logger error:@"Retrying sdk_click package for the %d time", retries]; + selfI.lastPackageRetriesCount++; + [selfI.logger error:@"Retrying sdk_click package for the %d time", selfI.lastPackageRetriesCount]; [selfI sendSdkClick:sdkClickPackage]; return; } + selfI.lastPackageRetriesCount = 0; [selfI.activityHandler finishedTracking:responseData]; }]; @@ -175,16 +180,15 @@ - (void)sendNextSdkClickI:(ADJSdkClickHandler *)selfI { [selfI sendNextSdkClick]; }; - NSInteger retries = [sdkClickPackage retries]; - if (retries <= 0) { + if (selfI.lastPackageRetriesCount <= 0) { work(); return; } - NSTimeInterval waitTime = [ADJUtil waitingTime:retries backoffStrategy:self.backoffStrategy]; + NSTimeInterval waitTime = [ADJUtil waitingTime:selfI.lastPackageRetriesCount backoffStrategy:self.backoffStrategy]; NSString *waitTimeFormatted = [ADJUtil secondsNumberFormat:waitTime]; - [self.logger verbose:@"Waiting for %@ seconds before retrying sdk_click for the %d time", waitTimeFormatted, retries]; + [self.logger verbose:@"Waiting for %@ seconds before retrying sdk_click for the %d time", waitTimeFormatted, selfI.lastPackageRetriesCount]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(waitTime * NSEC_PER_SEC)), self.internalQueue, work); } From 2bcf3e11fd5b192b5f47c6e62665a19ab72ab4f1 Mon Sep 17 00:00:00 2001 From: uerceg Date: Fri, 3 Apr 2020 16:38:05 +0200 Subject: [PATCH 15/27] iAd information reading update --- Adjust/ADJActivityHandler.m | 53 +++++++++++++++------ Adjust/ADJAdditions/UIDevice+ADJAdditions.h | 4 +- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 38 +++++++-------- 3 files changed, 59 insertions(+), 36 deletions(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 7c46373d6..4b4de33f8 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -38,10 +38,7 @@ static NSTimeInterval kBackgroundTimerInterval; static double kSessionInterval; static double kSubSessionInterval; - -// number of tries -static const int kTryIadV3 = 2; -static const uint64_t kDelayRetryIad = 2 * NSEC_PER_SEC; // 1 second +static const int kiAdRetriesCount = 3; @implementation ADJInternalState @@ -108,6 +105,8 @@ @interface ADJActivityHandler() typedef NS_ENUM(NSInteger, AdjADClientError) { AdjADClientErrorUnknown = 0, AdjADClientErrorLimitAdTracking = 1, + AdjADClientErrorMissingData = 2, + AdjADClientErrorCorruptResponse = 3, }; #pragma mark - @@ -394,23 +393,47 @@ - (void)setTrackingStateOptedOut { - (void)setAttributionDetails:(NSDictionary *)attributionDetails error:(NSError *)error - retriesLeft:(int)retriesLeft -{ + retriesLeft:(int)retriesLeft { if (![ADJUtil isNull:error]) { [self.logger warn:@"Unable to read iAd details"]; if (retriesLeft < 0) { - [self.logger warn:@"Limit number of retry for iAd v3 surpassed"]; + [self.logger warn:@"Number of retries to get iAd information surpassed"]; return; } - if (error.code == AdjADClientErrorUnknown) { - dispatch_time_t retryTime = dispatch_time(DISPATCH_TIME_NOW, kDelayRetryIad); - dispatch_after(retryTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [[UIDevice currentDevice] adjSetIad:self triesV3Left:retriesLeft]; - }); + // if first request was unsuccessful and ended up with one of the following error codes: + // - AdjADClientErrorUnknown + // - AdjADClientErrorMissingData + // - AdjADClientErrorCorruptResponse + // apply following retry logic: + // - 1st retry after 5 seconds + // - 2nd retry after 2 seconds + // - 3rd retry after 2 seconds + switch (error.code) { + case AdjADClientErrorUnknown: + case AdjADClientErrorMissingData: + case AdjADClientErrorCorruptResponse: { + int64_t iAdRetryDelay = 0; + switch (retriesLeft) { + case 2: + iAdRetryDelay = 5 * NSEC_PER_SEC; + break; + default: + iAdRetryDelay = 2 * NSEC_PER_SEC; + break; + } + dispatch_time_t retryTime = dispatch_time(DISPATCH_TIME_NOW, iAdRetryDelay); + dispatch_after(retryTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [[UIDevice currentDevice] adjCheckForiAd:self retriesLeft:retriesLeft]; + }); + return; + } + case AdjADClientErrorLimitAdTracking: + return; + default: + return; } - return; } // check if it's a valid attribution details @@ -757,7 +780,7 @@ - (void)initI:(ADJActivityHandler *)selfI sdkClickHandlerOnly:YES]]; if (self.adjustConfig.allowiAdInfoReading == YES) { - [[UIDevice currentDevice] adjSetIad:selfI triesV3Left:kTryIadV3]; + [[UIDevice currentDevice] adjCheckForiAd:selfI retriesLeft:kiAdRetriesCount]; } [selfI preLaunchActionsI:selfI preLaunchActionsArray:preLaunchActionsArray]; @@ -1261,7 +1284,7 @@ - (void)setEnabledI:(ADJActivityHandler *)selfI enabled:(BOOL)enabled { [selfI disableThirdPartySharing]; } if (self.adjustConfig.allowiAdInfoReading == YES) { - [[UIDevice currentDevice] adjSetIad:selfI triesV3Left:kTryIadV3]; + [[UIDevice currentDevice] adjCheckForiAd:selfI retriesLeft:kiAdRetriesCount]; } } diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h index a506ac0eb..809d481f7 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h @@ -19,6 +19,6 @@ - (NSString *)adjDeviceName; - (NSString *)adjCreateUuid; - (NSString *)adjVendorId; -- (void)adjSetIad:(ADJActivityHandler *)activityHandler - triesV3Left:(int)triesV3Left; +- (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler + retriesLeft:(int)retriesLeft; @end diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index ca185e7e4..7f964e867 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -144,9 +144,14 @@ - (NSString *)adjVendorId { return @""; } -- (void)adjSetIad:(ADJActivityHandler *)activityHandler - triesV3Left:(int)triesV3Left { +- (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler + retriesLeft:(int)retriesLeft { + // if no tries for iad v3 left, stop trying id logger = [ADJAdjustFactory logger]; + if (retriesLeft == 0) { + [logger warn:@"Reached maximum number of retries for getting iAd information"]; + return; + } #if ADJUST_NO_IAD || TARGET_OS_TV [logger debug:@"ADJUST_NO_IAD or TARGET_OS_TV set"]; @@ -174,30 +179,23 @@ - (void)adjSetIad:(ADJActivityHandler *)activityHandler } [logger debug:@"iAd framework successfully found in user's app"]; - [logger debug:@"iAd with %d tries to read v3", triesV3Left]; - - // if no tries for iad v3 left, stop trying - if (triesV3Left == 0) { - [logger warn:@"Reached limit number of retry for iAd v3"]; - return; - } + [logger debug:@"Retries left to read iAd information: %d", retriesLeft]; - BOOL isIadV3Avaliable = [self adjSetIadWithDetails:activityHandler - ADClientSharedClientInstance:ADClientSharedClientInstance - retriesLeft:(triesV3Left - 1)]; + BOOL iAdInformationAvailable = [self setiAdWithDetails:activityHandler + adcClientSharedInstance:ADClientSharedClientInstance + retriesLeft:(retriesLeft - 1)]; - // if iad v3 not available - if (!isIadV3Avaliable) { - [logger warn:@"iAd v3 not available"]; + if (!iAdInformationAvailable) { + [logger warn:@"iAd information not available"]; return; } #pragma clang diagnostic pop #endif } -- (BOOL)adjSetIadWithDetails:(ADJActivityHandler *)activityHandler -ADClientSharedClientInstance:(id)ADClientSharedClientInstance - retriesLeft:(int)retriesLeft { +- (BOOL)setiAdWithDetails:(ADJActivityHandler *)activityHandler + adcClientSharedInstance:(id)ADClientSharedClientInstance + retriesLeft:(int)retriesLeft { SEL iadDetailsSelector = NSSelectorFromString(@"requestAttributionDetailsWithBlock:"); if (![ADClientSharedClientInstance respondsToSelector:iadDetailsSelector]) { return NO; @@ -207,7 +205,9 @@ - (BOOL)adjSetIadWithDetails:(ADJActivityHandler *)activityHandler #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [ADClientSharedClientInstance performSelector:iadDetailsSelector withObject:^(NSDictionary *attributionDetails, NSError *error) { - [activityHandler setAttributionDetails:attributionDetails error:error retriesLeft:retriesLeft]; + [activityHandler setAttributionDetails:attributionDetails + error:error + retriesLeft:retriesLeft]; }]; #pragma clang diagnostic pop From dae121362da48e0b4a6c5f2b1fa77e8723600a07 Mon Sep 17 00:00:00 2001 From: uerceg Date: Mon, 6 Apr 2020 15:11:21 +0200 Subject: [PATCH 16/27] iAd request timeout handling --- Adjust/ADJActivityHandler.m | 5 ++++- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 4b4de33f8..7d27434bc 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -107,6 +107,7 @@ typedef NS_ENUM(NSInteger, AdjADClientError) { AdjADClientErrorLimitAdTracking = 1, AdjADClientErrorMissingData = 2, AdjADClientErrorCorruptResponse = 3, + AdjCustomErrorTimeout = 100, }; #pragma mark - @@ -406,6 +407,7 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails // - AdjADClientErrorUnknown // - AdjADClientErrorMissingData // - AdjADClientErrorCorruptResponse + // - AdjCustomErrorTimeout // apply following retry logic: // - 1st retry after 5 seconds // - 2nd retry after 2 seconds @@ -413,7 +415,8 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails switch (error.code) { case AdjADClientErrorUnknown: case AdjADClientErrorMissingData: - case AdjADClientErrorCorruptResponse: { + case AdjADClientErrorCorruptResponse: + case AdjCustomErrorTimeout: { int64_t iAdRetryDelay = 0; switch (retriesLeft) { case 2: diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index 7f964e867..530323ae8 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -19,6 +19,7 @@ #import #endif +#import "ADJTimerOnce.h" #import "ADJAdjustFactory.h" @implementation UIDevice(ADJAdditions) @@ -201,6 +202,16 @@ - (BOOL)setiAdWithDetails:(ADJActivityHandler *)activityHandler return NO; } + ADJTimerOnce *iAdTimer = [ADJTimerOnce timerWithBlock:^{ + NSError *iAdTimeoutError = [NSError errorWithDomain:@"com.adjust.sdk.iAd" + code:100 + userInfo:@{@"Error reason": @"iAd request timed out"}]; + [activityHandler setAttributionDetails:nil + error:iAdTimeoutError + retriesLeft:retriesLeft]; + } + queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) + name:@"iAdTimer"]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [ADClientSharedClientInstance performSelector:iadDetailsSelector @@ -208,8 +219,10 @@ - (BOOL)setiAdWithDetails:(ADJActivityHandler *)activityHandler [activityHandler setAttributionDetails:attributionDetails error:error retriesLeft:retriesLeft]; + [iAdTimer cancel]; }]; #pragma clang diagnostic pop + [iAdTimer startIn:5.0]; return YES; } From 436583e5458700c5a5c07e08af628131eba98ab9 Mon Sep 17 00:00:00 2001 From: uerceg Date: Mon, 6 Apr 2020 17:32:51 +0200 Subject: [PATCH 17/27] Handling of native_version nil string --- Adjust/ADJUtil.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 98baa9204..f4cc543f7 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -665,7 +665,7 @@ + (NSString *)buildAuthorizationHeaderV2:(NSString *)signature signatureHeader, secretIdHeader, algorithmHeader, idHeader]; if (nativeVersion == nil) { - return authorizationHeader; + return [authorizationHeader stringByAppendingFormat:@",native_version=\"\""]; } return [authorizationHeader stringByAppendingFormat:@",native_version=\"%@\"", nativeVersion]; } From 47865c8b47bf83b528f4498f0588e192d1fd02d2 Mon Sep 17 00:00:00 2001 From: uerceg Date: Mon, 6 Apr 2020 18:25:32 +0200 Subject: [PATCH 18/27] Use updated FB API --- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index 530323ae8..086d767b3 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -97,8 +97,15 @@ - (NSString *)adjFbAnonymousId { #if TARGET_OS_TV return @""; #else + // pre FB SDK v6.0.0 // return [FBSDKAppEventsUtility retrievePersistedAnonymousID]; - Class class = NSClassFromString(@"FBSDKAppEventsUtility"); + // post FB SDK v6.0.0 + // return [FBSDKBasicUtility retrievePersistedAnonymousID]; + Class class = nil; + class = NSClassFromString(@"FBSDKBasicUtility"); + if (class == nil) { + class = NSClassFromString(@"FBSDKAppEventsUtility"); + } if (class == nil) { return @""; } From 69b3c1f29bf4ce1a635487b1c22f8e5a06500dd2 Mon Sep 17 00:00:00 2001 From: uerceg Date: Mon, 6 Apr 2020 18:35:24 +0200 Subject: [PATCH 19/27] Minor logic refac --- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 28 +++++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index 086d767b3..f8a08f58e 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -102,22 +102,28 @@ - (NSString *)adjFbAnonymousId { // post FB SDK v6.0.0 // return [FBSDKBasicUtility retrievePersistedAnonymousID]; Class class = nil; - class = NSClassFromString(@"FBSDKBasicUtility"); - if (class == nil) { - class = NSClassFromString(@"FBSDKAppEventsUtility"); - } - if (class == nil) { - return @""; - } SEL selGetId = NSSelectorFromString(@"retrievePersistedAnonymousID"); - if (![class respondsToSelector:selGetId]) { - return @""; + class = NSClassFromString(@"FBSDKBasicUtility"); + if (class != nil) { + if ([class respondsToSelector:selGetId]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + NSString *fbAnonymousId = (NSString *)[class performSelector:selGetId]; + return fbAnonymousId; +#pragma clang diagnostic pop + } } + class = NSClassFromString(@"FBSDKAppEventsUtility"); + if (class != nil) { + if ([class respondsToSelector:selGetId]) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" - NSString *fbAnonymousId = (NSString *)[class performSelector:selGetId]; + NSString *fbAnonymousId = (NSString *)[class performSelector:selGetId]; + return fbAnonymousId; #pragma clang diagnostic pop - return fbAnonymousId; + } + } + return @""; #endif } From cb848ef3d4bce79e6f339e7edc4870e5c3a317e7 Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 7 Apr 2020 15:54:58 +0200 Subject: [PATCH 20/27] Read algorithm field from package payload --- Adjust/ADJUtil.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index f4cc543f7..841ebe582 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -621,10 +621,13 @@ + (NSString *)buildAuthorizationHeader:(NSMutableDictionary *)parameters key:@"headers_id"]; NSString *nativeVersion = [ADJUtil extractEntry:parameters key:@"native_version"]; + NSString *algorithm = [ADJUtil extractEntry:parameters + key:@"algorithm"]; NSString *authorizationHeader = [ADJUtil buildAuthorizationHeaderV2:signature secretId:secretId headersId:headersId - nativeVersion:nativeVersion]; + nativeVersion:nativeVersion + algorithm:algorithm]; if (authorizationHeader != nil) { return authorizationHeader; } @@ -651,6 +654,7 @@ + (NSString *)buildAuthorizationHeaderV2:(NSString *)signature secretId:(NSString *)secretId headersId:(NSString *)headersId nativeVersion:(NSString *)nativeVersion + algorithm:(NSString *)algorithm { if (secretId == nil || signature == nil || headersId == nil) { return nil; @@ -659,7 +663,7 @@ + (NSString *)buildAuthorizationHeaderV2:(NSString *)signature NSString * signatureHeader = [NSString stringWithFormat:@"signature=\"%@\"", signature]; NSString * secretIdHeader = [NSString stringWithFormat:@"secret_id=\"%@\"", secretId]; NSString * idHeader = [NSString stringWithFormat:@"headers_id=\"%@\"", headersId]; - NSString * algorithmHeader = [NSString stringWithFormat:@"algorithm=\"adj1\""]; + NSString * algorithmHeader = [NSString stringWithFormat:@"algorithm=\"%@\"", algorithm != nil ? algorithm : @"adj1"]; NSString * authorizationHeader = [NSString stringWithFormat:@"Signature %@,%@,%@,%@", signatureHeader, secretIdHeader, algorithmHeader, idHeader]; From 934894b90c0fae771486d55be45b80e10ed3cd79 Mon Sep 17 00:00:00 2001 From: nonelse Date: Wed, 8 Apr 2020 18:47:24 +0200 Subject: [PATCH 21/27] Refac iad timeout --- Adjust/ADJActivityHandler.h | 3 +- Adjust/ADJActivityHandler.m | 42 ++++++++++++++++++--- Adjust/ADJAdditions/UIDevice+ADJAdditions.h | 3 +- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 29 ++++---------- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/Adjust/ADJActivityHandler.h b/Adjust/ADJActivityHandler.h index c3fd4b80d..da2787fb7 100644 --- a/Adjust/ADJActivityHandler.h +++ b/Adjust/ADJActivityHandler.h @@ -82,8 +82,7 @@ - (BOOL)updateAttributionI:(id)selfI attribution:(ADJAttribution *)attribution; - (void)setAttributionDetails:(NSDictionary *)attributionDetails - error:(NSError *)error - retriesLeft:(int)retriesLeft; + error:(NSError *)error; - (void)setOfflineMode:(BOOL)offline; - (void)sendFirstPackages; diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 7d27434bc..960dbdb69 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -86,6 +86,8 @@ @interface ADJActivityHandler() @property (nonatomic, strong) ADJActivityState *activityState; @property (nonatomic, strong) ADJTimerCycle *foregroundTimer; @property (nonatomic, strong) ADJTimerOnce *backgroundTimer; +@property (nonatomic, strong) ADJTimerOnce *iAdTimeoutTimer; +@property (nonatomic, assign) NSInteger iadRetriesLeft; @property (nonatomic, strong) ADJInternalState *internalState; @property (nonatomic, strong) ADJDeviceInfo *deviceInfo; @property (nonatomic, strong) ADJTimerOnce *delayStartTimer; @@ -202,6 +204,8 @@ - (id)initWithConfig:(ADJConfig *)adjustConfig self.gdprPath = savedPreLaunch.gdprPath; } + self.iadRetriesLeft = kiAdRetriesCount; + self.internalQueue = dispatch_queue_create(kInternalQueueName, DISPATCH_QUEUE_SERIAL); [ADJUtil launchInQueue:self.internalQueue selfInject:self @@ -394,11 +398,13 @@ - (void)setTrackingStateOptedOut { - (void)setAttributionDetails:(NSDictionary *)attributionDetails error:(NSError *)error - retriesLeft:(int)retriesLeft { +{ + [self.iAdTimeoutTimer cancel]; + if (![ADJUtil isNull:error]) { [self.logger warn:@"Unable to read iAd details"]; - if (retriesLeft < 0) { + if (self.iadRetriesLeft < 0) { [self.logger warn:@"Number of retries to get iAd information surpassed"]; return; } @@ -418,7 +424,7 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails case AdjADClientErrorCorruptResponse: case AdjCustomErrorTimeout: { int64_t iAdRetryDelay = 0; - switch (retriesLeft) { + switch (self.iadRetriesLeft) { case 2: iAdRetryDelay = 5 * NSEC_PER_SEC; break; @@ -426,9 +432,10 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails iAdRetryDelay = 2 * NSEC_PER_SEC; break; } + self.iadRetriesLeft = self.iadRetriesLeft - 1; dispatch_time_t retryTime = dispatch_time(DISPATCH_TIME_NOW, iAdRetryDelay); dispatch_after(retryTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [[UIDevice currentDevice] adjCheckForiAd:self retriesLeft:retriesLeft]; + [[UIDevice currentDevice] adjCheckForiAd:self iAdTimeoutTimer:self.iAdTimeoutTimer]; }); return; } @@ -629,6 +636,9 @@ - (void)teardown if (self.backgroundTimer != nil) { [self.backgroundTimer cancel]; } + if (self.iAdTimeoutTimer != nil) { + [self.iAdTimeoutTimer cancel]; + } if (self.foregroundTimer != nil) { [self.foregroundTimer cancel]; } @@ -656,6 +666,7 @@ - (void)teardown self.sdkClickHandler = nil; self.foregroundTimer = nil; self.backgroundTimer = nil; + self.iAdTimeoutTimer = nil; self.adjustDelegate = nil; self.adjustConfig = nil; self.internalState = nil; @@ -783,7 +794,7 @@ - (void)initI:(ADJActivityHandler *)selfI sdkClickHandlerOnly:YES]]; if (self.adjustConfig.allowiAdInfoReading == YES) { - [[UIDevice currentDevice] adjCheckForiAd:selfI retriesLeft:kiAdRetriesCount]; + [self checkForIad]; } [selfI preLaunchActionsI:selfI preLaunchActionsArray:preLaunchActionsArray]; @@ -1287,7 +1298,7 @@ - (void)setEnabledI:(ADJActivityHandler *)selfI enabled:(BOOL)enabled { [selfI disableThirdPartySharing]; } if (self.adjustConfig.allowiAdInfoReading == YES) { - [[UIDevice currentDevice] adjCheckForiAd:selfI retriesLeft:kiAdRetriesCount]; + [self checkForIad]; } } @@ -1298,6 +1309,25 @@ - (void)setEnabledI:(ADJActivityHandler *)selfI enabled:(BOOL)enabled { unPausingMessage:@"Resuming handlers due to SDK being enabled"]; } +- (void)checkForIad { + if (self.iAdTimeoutTimer != nil) { + self.iAdTimeoutTimer = + [ADJTimerOnce + timerWithBlock:^{ + [self + setAttributionDetails:nil + error:[NSError errorWithDomain:@"com.adjust.sdk.iAd" + code:100 + userInfo:@{@"Error reason": @"iAd request timed out"}]]; + + } + queue:self.internalQueue + name:@"iAdTimeoutTimer"]; + } + + [[UIDevice currentDevice] adjCheckForiAd:self iAdTimeoutTimer:self.iAdTimeoutTimer]; +} + - (void)setOfflineModeI:(ADJActivityHandler *)selfI offline:(BOOL)offline { // compare with the internal state diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h index 809d481f7..4bba1d86e 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h @@ -9,6 +9,7 @@ #import #import #import "ADJActivityHandler.h" +#import "ADJTimerOnce.h" @interface UIDevice(ADJAdditions) @@ -20,5 +21,5 @@ - (NSString *)adjCreateUuid; - (NSString *)adjVendorId; - (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler - retriesLeft:(int)retriesLeft; + iAdTimeoutTimer:(ADJTimerOnce *)iAdTimeoutTimer; @end diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index f8a08f58e..e8c39bcc4 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -159,13 +159,10 @@ - (NSString *)adjVendorId { } - (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler - retriesLeft:(int)retriesLeft { + iAdTimeoutTimer:(ADJTimerOnce *)iAdTimeoutTimer +{ // if no tries for iad v3 left, stop trying id logger = [ADJAdjustFactory logger]; - if (retriesLeft == 0) { - [logger warn:@"Reached maximum number of retries for getting iAd information"]; - return; - } #if ADJUST_NO_IAD || TARGET_OS_TV [logger debug:@"ADJUST_NO_IAD or TARGET_OS_TV set"]; @@ -193,11 +190,10 @@ - (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler } [logger debug:@"iAd framework successfully found in user's app"]; - [logger debug:@"Retries left to read iAd information: %d", retriesLeft]; BOOL iAdInformationAvailable = [self setiAdWithDetails:activityHandler adcClientSharedInstance:ADClientSharedClientInstance - retriesLeft:(retriesLeft - 1)]; + iAdTimeoutTimer:iAdTimeoutTimer]; if (!iAdInformationAvailable) { [logger warn:@"iAd information not available"]; @@ -209,33 +205,22 @@ - (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler - (BOOL)setiAdWithDetails:(ADJActivityHandler *)activityHandler adcClientSharedInstance:(id)ADClientSharedClientInstance - retriesLeft:(int)retriesLeft { + iAdTimeoutTimer:(ADJTimerOnce *)iAdTimeoutTimer +{ SEL iadDetailsSelector = NSSelectorFromString(@"requestAttributionDetailsWithBlock:"); if (![ADClientSharedClientInstance respondsToSelector:iadDetailsSelector]) { return NO; } - ADJTimerOnce *iAdTimer = [ADJTimerOnce timerWithBlock:^{ - NSError *iAdTimeoutError = [NSError errorWithDomain:@"com.adjust.sdk.iAd" - code:100 - userInfo:@{@"Error reason": @"iAd request timed out"}]; - [activityHandler setAttributionDetails:nil - error:iAdTimeoutError - retriesLeft:retriesLeft]; - } - queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) - name:@"iAdTimer"]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [ADClientSharedClientInstance performSelector:iadDetailsSelector withObject:^(NSDictionary *attributionDetails, NSError *error) { [activityHandler setAttributionDetails:attributionDetails - error:error - retriesLeft:retriesLeft]; - [iAdTimer cancel]; + error:error]; }]; #pragma clang diagnostic pop - [iAdTimer startIn:5.0]; + [iAdTimeoutTimer startIn:5.0]; return YES; } From 9814186abc39cd3271eacbdf765f76891543a51d Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 9 Apr 2020 09:47:01 +0200 Subject: [PATCH 22/27] Fix for iAd timeout timer initialisation --- Adjust/ADJActivityHandler.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 960dbdb69..7bbb19381 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -435,7 +435,7 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails self.iadRetriesLeft = self.iadRetriesLeft - 1; dispatch_time_t retryTime = dispatch_time(DISPATCH_TIME_NOW, iAdRetryDelay); dispatch_after(retryTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [[UIDevice currentDevice] adjCheckForiAd:self iAdTimeoutTimer:self.iAdTimeoutTimer]; + [self checkForIad]; }); return; } @@ -1310,7 +1310,7 @@ - (void)setEnabledI:(ADJActivityHandler *)selfI enabled:(BOOL)enabled { } - (void)checkForIad { - if (self.iAdTimeoutTimer != nil) { + if (self.iAdTimeoutTimer == nil) { self.iAdTimeoutTimer = [ADJTimerOnce timerWithBlock:^{ From 972137309da6b02a65be677224a3d7f22cd26009 Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 9 Apr 2020 09:50:14 +0200 Subject: [PATCH 23/27] Minor iAd naming unification --- Adjust/ADJActivityHandler.m | 10 +++++----- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 7bbb19381..bf0fc9335 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -87,7 +87,7 @@ @interface ADJActivityHandler() @property (nonatomic, strong) ADJTimerCycle *foregroundTimer; @property (nonatomic, strong) ADJTimerOnce *backgroundTimer; @property (nonatomic, strong) ADJTimerOnce *iAdTimeoutTimer; -@property (nonatomic, assign) NSInteger iadRetriesLeft; +@property (nonatomic, assign) NSInteger iAdRetriesLeft; @property (nonatomic, strong) ADJInternalState *internalState; @property (nonatomic, strong) ADJDeviceInfo *deviceInfo; @property (nonatomic, strong) ADJTimerOnce *delayStartTimer; @@ -204,7 +204,7 @@ - (id)initWithConfig:(ADJConfig *)adjustConfig self.gdprPath = savedPreLaunch.gdprPath; } - self.iadRetriesLeft = kiAdRetriesCount; + self.iAdRetriesLeft = kiAdRetriesCount; self.internalQueue = dispatch_queue_create(kInternalQueueName, DISPATCH_QUEUE_SERIAL); [ADJUtil launchInQueue:self.internalQueue @@ -404,7 +404,7 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails if (![ADJUtil isNull:error]) { [self.logger warn:@"Unable to read iAd details"]; - if (self.iadRetriesLeft < 0) { + if (self.iAdRetriesLeft < 0) { [self.logger warn:@"Number of retries to get iAd information surpassed"]; return; } @@ -424,7 +424,7 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails case AdjADClientErrorCorruptResponse: case AdjCustomErrorTimeout: { int64_t iAdRetryDelay = 0; - switch (self.iadRetriesLeft) { + switch (self.iAdRetriesLeft) { case 2: iAdRetryDelay = 5 * NSEC_PER_SEC; break; @@ -432,7 +432,7 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails iAdRetryDelay = 2 * NSEC_PER_SEC; break; } - self.iadRetriesLeft = self.iadRetriesLeft - 1; + self.iAdRetriesLeft = self.iAdRetriesLeft - 1; dispatch_time_t retryTime = dispatch_time(DISPATCH_TIME_NOW, iAdRetryDelay); dispatch_after(retryTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self checkForIad]; diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index e8c39bcc4..b6b081e0e 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -207,14 +207,14 @@ - (BOOL)setiAdWithDetails:(ADJActivityHandler *)activityHandler adcClientSharedInstance:(id)ADClientSharedClientInstance iAdTimeoutTimer:(ADJTimerOnce *)iAdTimeoutTimer { - SEL iadDetailsSelector = NSSelectorFromString(@"requestAttributionDetailsWithBlock:"); - if (![ADClientSharedClientInstance respondsToSelector:iadDetailsSelector]) { + SEL iAdDetailsSelector = NSSelectorFromString(@"requestAttributionDetailsWithBlock:"); + if (![ADClientSharedClientInstance respondsToSelector:iAdDetailsSelector]) { return NO; } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" - [ADClientSharedClientInstance performSelector:iadDetailsSelector + [ADClientSharedClientInstance performSelector:iAdDetailsSelector withObject:^(NSDictionary *attributionDetails, NSError *error) { [activityHandler setAttributionDetails:attributionDetails error:error]; From 509e3eca2af61b985eb738191d03992a12092a60 Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 9 Apr 2020 10:03:08 +0200 Subject: [PATCH 24/27] Add missing stuff to web bridge --- AdjustBridge/AdjustBridge.m | 8 +++++ AdjustBridge/AdjustBridgeRegister.m | 8 +++++ .../TestLibraryBridge.js | 32 +++++++++++++------ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/AdjustBridge/AdjustBridge.m b/AdjustBridge/AdjustBridge.m index fa25baf88..29d79d6b6 100644 --- a/AdjustBridge/AdjustBridge.m +++ b/AdjustBridge/AdjustBridge.m @@ -191,6 +191,8 @@ - (void)loadWKWebViewBridge:(WKWebView *)wkWebView NSNumber *delayStart = [data objectForKey:@"delayStart"]; NSString *userAgent = [data objectForKey:@"userAgent"]; NSNumber *isDeviceKnown = [data objectForKey:@"isDeviceKnown"]; + NSNumber *allowiAdInfoReading = [data objectForKey:@"allowiAdInfoReading"]; + NSNumber *allowIdfaReading = [data objectForKey:@"allowIdfaReading"]; NSNumber *secretId = [data objectForKey:@"secretId"]; NSString *info1 = [data objectForKey:@"info1"]; NSString *info2 = [data objectForKey:@"info2"]; @@ -245,6 +247,12 @@ - (void)loadWKWebViewBridge:(WKWebView *)wkWebView if ([self isFieldValid:isDeviceKnown]) { [adjustConfig setIsDeviceKnown:[isDeviceKnown boolValue]]; } + if ([self isFieldValid:allowiAdInfoReading]) { + [adjustConfig setAllowiAdInfoReading:[allowiAdInfoReading boolValue]]; + } + if ([self isFieldValid:allowIdfaReading]) { + [adjustConfig setAllowIdfaReading:[allowIdfaReading boolValue]]; + } BOOL isAppSecretDefined = [self isFieldValid:secretId] && [self isFieldValid:info1] && [self isFieldValid:info2] diff --git a/AdjustBridge/AdjustBridgeRegister.m b/AdjustBridge/AdjustBridgeRegister.m index 95f43cb68..6d263c1c8 100644 --- a/AdjustBridge/AdjustBridgeRegister.m +++ b/AdjustBridge/AdjustBridgeRegister.m @@ -290,6 +290,8 @@ + (NSString *)adjust_js { this.delayStart = null; this.userAgent = null; this.isDeviceKnown = null; + this.allowiAdInfoReading = null; + this.allowIdfaReading = null; this.secretId = null; this.info1 = null; this.info2 = null; @@ -364,6 +366,12 @@ + (NSString *)adjust_js { AdjustConfig.prototype.setIsDeviceKnown = function(isDeviceKnown) { this.isDeviceKnown = isDeviceKnown; }; + AdjustConfig.prototype.setAllowiAdInfoReading = function(allowiAdInfoReading) { + this.allowiAdInfoReading = allowiAdInfoReading; + }; + AdjustConfig.prototype.setAllowIdfaReading = function(allowIdfaReading) { + this.allowIdfaReading = allowIdfaReading; + }; AdjustConfig.prototype.setAppSecret = function(secretId, info1, info2, info3, info4) { this.secretId = secretId; this.info1 = info1; diff --git a/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.js b/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.js index d0671e779..4888ce4a7 100644 --- a/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.js +++ b/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.js @@ -33,13 +33,13 @@ var TestLibraryBridge = { }; var AdjustCommandExecutor = function(baseUrl, gdprUrl) { - this.baseUrl = baseUrl; - this.gdprUrl = gdprUrl; - this.basePath = null; - this.gdprPath = null; - this.savedEvents = {}; - this.savedConfigs = {}; - this.savedCommands = []; + this.baseUrl = baseUrl; + this.gdprUrl = gdprUrl; + this.basePath = null; + this.gdprPath = null; + this.savedEvents = {}; + this.savedConfigs = {}; + this.savedCommands = []; this.nextToSendCounter = 0; }; @@ -85,12 +85,14 @@ AdjustCommandExecutor.prototype.testOptions = function(params) { testOptions.subsessionIntervalInMilliseconds = getFirstValue(params, 'subsessionInterval'); } if ('noBackoffWait' in params) { - testOptions.noBackoffWait = getFirstValue(params, 'noBackoffWait'); + var noBackoffWait = getFirstValue(params, 'noBackoffWait'); + testOptions.noBackoffWait = noBackoffWait == 'true'; } // iAd will not be used in test app by default testOptions.iAdFrameworkEnabled = false; if ('iAdFrameworkEnabled' in params) { - testOptions.iAdFrameworkEnabled = getFirstValue(params, 'iAdFrameworkEnabled'); + var iAdFrameworkEnabled = getFirstValue(params, 'iAdFrameworkEnabled'); + testOptions.iAdFrameworkEnabled = iAdFrameworkEnabled == 'true'; } if ('teardown' in params) { console.log('TestLibraryBridge hasOwnProperty teardown: ' + params['teardown']); @@ -226,6 +228,18 @@ AdjustCommandExecutor.prototype.config = function(params) { var deviceKnown = deviceKnownS == 'true'; adjustConfig.setIsDeviceKnown(deviceKnown); } + + if ('allowiAdInfoReading' in params) { + var allowiAdInfoReadingS = getFirstValue(params, 'allowiAdInfoReading'); + var allowiAdInfoReading = allowiAdInfoReadingS == 'true'; + adjustConfig.setAllowiAdInfoReading(allowiAdInfoReading); + } + + if ('allowIdfaReading' in params) { + var allowIdfaReadingS = getFirstValue(params, 'allowIdfaReading'); + var allowIdfaReading = allowIdfaReadingS == 'true'; + adjustConfig.setAllowIdfaReading(allowIdfaReading); + } if ('eventBufferingEnabled' in params) { var eventBufferingEnabledS = getFirstValue(params, 'eventBufferingEnabled'); From c943f8a2e5de4def01d533487effe85b0ca7a32f Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 9 Apr 2020 10:06:52 +0200 Subject: [PATCH 25/27] New version 4.21.1 --- Adjust.podspec | 4 ++-- Adjust/ADJUtil.m | 2 +- Adjust/Adjust.h | 2 +- AdjustBridge/AdjustBridgeRegister.m | 2 +- AdjustTests/AdjustUnitTests/ADJPackageFields.m | 2 +- README.md | 4 ++-- VERSION | 2 +- doc/chinese/README.md | 4 ++-- doc/english/migrate.md | 2 +- doc/english/web_views.md | 2 +- doc/japanese/README.md | 4 ++-- doc/korean/README.md | 4 ++-- doc/korean/web_views.md | 2 +- doc/migrate.md | 2 +- 14 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Adjust.podspec b/Adjust.podspec index af71cca67..995a1fedf 100644 --- a/Adjust.podspec +++ b/Adjust.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = "Adjust" - s.version = "4.21.0" + s.version = "4.21.1" s.summary = "This is the iOS SDK of adjust. You can read more about it at http://adjust.com." s.homepage = "https://github.com/adjust/ios_sdk" s.license = { :type => 'MIT', :file => 'MIT-LICENSE' } s.author = { "Christian Wellenbrock" => "welle@adjust.com" } - s.source = { :git => "https://github.com/adjust/ios_sdk.git", :tag => "v4.21.0" } + s.source = { :git => "https://github.com/adjust/ios_sdk.git", :tag => "v4.21.1" } s.ios.deployment_target = '6.0' s.tvos.deployment_target = '9.0' s.framework = 'SystemConfiguration' diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 841ebe582..96d1058f8 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -43,7 +43,7 @@ static CTTelephonyNetworkInfo *networkInfo = nil; #endif -static NSString * const kClientSdk = @"ios4.21.0"; +static NSString * const kClientSdk = @"ios4.21.1"; static NSString * const kDeeplinkParam = @"deep_link="; static NSString * const kSchemeDelimiter = @"://"; static NSString * const kDefaultScheme = @"AdjustUniversalScheme"; diff --git a/Adjust/Adjust.h b/Adjust/Adjust.h index bf1d1163d..e2658ad89 100644 --- a/Adjust/Adjust.h +++ b/Adjust/Adjust.h @@ -2,7 +2,7 @@ // Adjust.h // Adjust // -// V4.21.0 +// V4.21.1 // Created by Christian Wellenbrock (wellle) on 23rd July 2013. // Copyright © 2012-2017 Adjust GmbH. All rights reserved. // diff --git a/AdjustBridge/AdjustBridgeRegister.m b/AdjustBridge/AdjustBridgeRegister.m index 6d263c1c8..9b12a52be 100644 --- a/AdjustBridge/AdjustBridgeRegister.m +++ b/AdjustBridge/AdjustBridgeRegister.m @@ -221,7 +221,7 @@ + (NSString *)adjust_js { if (this.sdkPrefix) { return this.sdkPrefix; } else { - return 'web-bridge4.21.0'; + return 'web-bridge4.21.1'; } }, setTestOptions: function(testOptions) { diff --git a/AdjustTests/AdjustUnitTests/ADJPackageFields.m b/AdjustTests/AdjustUnitTests/ADJPackageFields.m index e134d5353..d21e55a6e 100644 --- a/AdjustTests/AdjustUnitTests/ADJPackageFields.m +++ b/AdjustTests/AdjustUnitTests/ADJPackageFields.m @@ -16,7 +16,7 @@ - (id) init { // default values self.appToken = @"qwerty123456"; - self.clientSdk = @"ios4.21.0"; + self.clientSdk = @"ios4.21.1"; self.suffix = @""; self.environment = @"sandbox"; diff --git a/README.md b/README.md index e66c39f63..a4de3ec0d 100644 --- a/README.md +++ b/README.md @@ -74,13 +74,13 @@ We will describe the steps to integrate the Adjust SDK into your iOS project. We If you're using [CocoaPods][cocoapods], you can add the following line to your `Podfile` and continue from [this step](#sdk-integrate): ```ruby -pod 'Adjust', '~> 4.21.0' +pod 'Adjust', '~> 4.21.1' ``` or: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.0' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.1' ``` --- diff --git a/VERSION b/VERSION index 7c6be3171..79b1bb629 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.21.0 +4.21.1 diff --git a/doc/chinese/README.md b/doc/chinese/README.md index 2d2ae8d36..2cd831e03 100644 --- a/doc/chinese/README.md +++ b/doc/chinese/README.md @@ -73,13 +73,13 @@ Read this in other languages: [English][en-readme], [中文][zh-readme], [日本 如果您正在使用[CocoaPods][cocoapods],您可以将以下代码行添加至 `Podfile`,然后继续进行[此步骤](#sdk-integrate): ```ruby -pod 'Adjust', '~> 4.21.0' +pod 'Adjust', '~> 4.21.1' ``` 或: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.0' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.1' ``` --- diff --git a/doc/english/migrate.md b/doc/english/migrate.md index 34307476d..0c4373eeb 100644 --- a/doc/english/migrate.md +++ b/doc/english/migrate.md @@ -1,4 +1,4 @@ -## Migrate your adjust SDK for iOS to v4.21.0 from v3.4.0 +## Migrate your adjust SDK for iOS to v4.21.1 from v3.4.0 ### Initial setup diff --git a/doc/english/web_views.md b/doc/english/web_views.md index 933b9aab1..9f2ac0f45 100644 --- a/doc/english/web_views.md +++ b/doc/english/web_views.md @@ -64,7 +64,7 @@ We will describe the steps to integrate the Adjust SDK into your iOS project. We If you're using [CocoaPods][cocoapods], you can add the following line to your `Podfile` and continue from [this step](#sdk-integrate): ```ruby -pod 'Adjust/WebBridge', '~> 4.21.0' +pod 'Adjust/WebBridge', '~> 4.21.1' ``` --- diff --git a/doc/japanese/README.md b/doc/japanese/README.md index 93711ca11..b0cf6c936 100644 --- a/doc/japanese/README.md +++ b/doc/japanese/README.md @@ -25,13 +25,13 @@ adjust SDKをiOSプロジェクトに連携する手順を説明します。 [こちらの手順](#sdk-integrate)に進んでください。 ```ruby -pod 'Adjust', '~> 4.21.0' +pod 'Adjust', '~> 4.21.1' ``` または ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.0' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.1' ``` --- diff --git a/doc/korean/README.md b/doc/korean/README.md index e68cdc7a8..f20bb7b14 100644 --- a/doc/korean/README.md +++ b/doc/korean/README.md @@ -73,13 +73,13 @@ iOS 개발용 Xcode를 사용한다는 가정하에 iOS 프로젝트에 Adjust S [CocoaPods][cocoapods]를 사용하는 경우, 다음 내용을 `Podfile`에 추가한 후 [해당 단계](#sdk-integrate)를 완료하세요. ```ruby -pod 'Adjust', '~> 4.21.0' +pod 'Adjust', '~> 4.21.1' ``` 또는: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.0' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.1' ``` --- diff --git a/doc/korean/web_views.md b/doc/korean/web_views.md index e6654672d..7c1c848a3 100644 --- a/doc/korean/web_views.md +++ b/doc/korean/web_views.md @@ -64,7 +64,7 @@ iOS 개발용 Xcode를 사용한다는 가정하에 iOS 프로젝트에 Adjust S [CocoaPods][cocoapods]를 사용하는 경우, 다음 내용을 'Podfile'에 추가한 후 [해당 단계](#sdk-integrate)를 완료하세요. ```ruby -pod 'Adjust/WebBridge', '~> 4.21.0' +pod 'Adjust/WebBridge', '~> 4.21.1' ``` --- diff --git a/doc/migrate.md b/doc/migrate.md index fc3809a80..8eaed6623 100644 --- a/doc/migrate.md +++ b/doc/migrate.md @@ -1,4 +1,4 @@ -## Migrate your Adjust SDK for iOS to v4.21.0 from v3.4.0 +## Migrate your Adjust SDK for iOS to v4.21.1 from v3.4.0 ### Initial setup From 075f2c7846760655c55def99124d1c5677d75e13 Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 9 Apr 2020 10:29:21 +0200 Subject: [PATCH 26/27] Fix for web bridge command executor --- .../AdjustWebBridgeTestApp/TestLibraryBridge.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.js b/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.js index 4888ce4a7..e787699e8 100644 --- a/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.js +++ b/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.js @@ -203,7 +203,7 @@ AdjustCommandExecutor.prototype.config = function(params) { } if ('externalDeviceId' in params) { - var defaultTracker = getFirstValue(params, 'externalDeviceId'); + var externalDeviceId = getFirstValue(params, 'externalDeviceId'); adjustConfig.setExternalDeviceId(externalDeviceId); } From 36f83523fadd81bcf6417673abae5014c8921e92 Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 9 Apr 2020 11:53:01 +0200 Subject: [PATCH 27/27] CHANGELOG.md update --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ca8bb7b4..923e5dbe1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +### Version 4.21.1 (9th April 2020) +#### Added +- Added support for Mac Catalyst (thanks to @rjchatfield). + +#### Changed +- Replaced `available` attribute with a macro for non native SDKs compatibility. +- Synchronised writing to package queue. +- Updated communication flow with `iAd.framework`. + +#### Fixed +- Added nullability check for path being written onto (thanks to @sidepelican). + +--- + ### Version 4.21.0 (19th March 2020) #### Added - Added support for signature library as a plugin.