From a22200c2bf2c40ce2c06581f98365d928561a973 Mon Sep 17 00:00:00 2001 From: Kevin Farst Date: Fri, 20 Mar 2020 11:28:52 -0700 Subject: [PATCH 001/173] Remove unused MD5 and SHA-1 implementations --- Adjust/ADJActivityState.m | 14 ----------- Adjust/ADJAdditions/NSString+ADJAdditions.h | 2 -- Adjust/ADJAdditions/NSString+ADJAdditions.m | 27 --------------------- 3 files changed, 43 deletions(-) diff --git a/Adjust/ADJActivityState.m b/Adjust/ADJActivityState.m index 528981d80..3a3b9c14e 100644 --- a/Adjust/ADJActivityState.m +++ b/Adjust/ADJActivityState.m @@ -105,20 +105,6 @@ - (void)assignUuid:(NSString *)uuid { self.isPersisted = [ADJKeychain setValue:self.uuid forKeychainKey:@"adjust_uuid" inService:@"deviceInfo"]; } -- (NSString *)generateUniqueKey { - if (appToken == nil) { - return nil; - } - - NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; - if (bundleIdentifier == nil) { - return nil; - } - - NSString *joinedKey = [NSString stringWithFormat:@"%@%@", bundleIdentifier, appToken]; - return [joinedKey adjSha1]; -} - - (NSString *)description { return [NSString stringWithFormat:@"ec:%d sc:%d ssc:%d ask:%d sl:%.1f ts:%.1f la:%.1f dt:%@ gdprf:%d dtps:%d", self.eventCount, self.sessionCount, diff --git a/Adjust/ADJAdditions/NSString+ADJAdditions.h b/Adjust/ADJAdditions/NSString+ADJAdditions.h index f3a14dfa3..d76550fce 100644 --- a/Adjust/ADJAdditions/NSString+ADJAdditions.h +++ b/Adjust/ADJAdditions/NSString+ADJAdditions.h @@ -9,8 +9,6 @@ @interface NSString(ADJAdditions) -- (NSString *)adjMd5; -- (NSString *)adjSha1; - (NSString *)adjSha256; - (NSString *)adjTrim; - (NSString *)adjUrlEncode; diff --git a/Adjust/ADJAdditions/NSString+ADJAdditions.m b/Adjust/ADJAdditions/NSString+ADJAdditions.m index b14e6938d..94e2b6c3a 100644 --- a/Adjust/ADJAdditions/NSString+ADJAdditions.m +++ b/Adjust/ADJAdditions/NSString+ADJAdditions.m @@ -43,33 +43,6 @@ - (NSString *)adjRemoveColons { return [self stringByReplacingOccurrencesOfString:@":" withString:@""]; } -- (NSString *)adjMd5 { - const char *cStr = [self UTF8String]; - unsigned char digest[CC_MD5_DIGEST_LENGTH]; - CC_MD5(cStr, (CC_LONG)strlen(cStr), digest); - - NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; - for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { - [output appendFormat:@"%02x", digest[i]]; - } - return output; -} - -- (NSString *)adjSha1 { - NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding]; - uint8_t digest[CC_SHA1_DIGEST_LENGTH]; - - CC_SHA1(data.bytes, (CC_LONG)data.length, digest); - - NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2]; - - for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) { - [output appendFormat:@"%02x", digest[i]]; - } - - return output; -} - - (NSString *)adjSha256 { const char* str = [self UTF8String]; unsigned char result[CC_SHA256_DIGEST_LENGTH]; From 6a6db777bbe8bfdff21527cdc3e2da07d2d49dfc Mon Sep 17 00:00:00 2001 From: Kevin Farst Date: Mon, 23 Mar 2020 10:35:27 -0700 Subject: [PATCH 002/173] Update ADJKeychain accessibility to kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly --- Adjust/ADJKeychain.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Adjust/ADJKeychain.m b/Adjust/ADJKeychain.m index 8b2283b5c..d60dec446 100644 --- a/Adjust/ADJKeychain.m +++ b/Adjust/ADJKeychain.m @@ -76,10 +76,10 @@ - (BOOL)setValue:(NSString *)value forKeychainKey:(NSString *)key inService:(NSS - (OSStatus)setValueWithStatus:(NSString *)value forKeychainKey:(NSString *)key inService:(NSString *)service { NSMutableDictionary *keychainItem; - + keychainItem = [self keychainItemForKey:key service:service]; keychainItem[(__bridge id)kSecValueData] = [value dataUsingEncoding:NSUTF8StringEncoding]; - + return SecItemAdd((__bridge CFDictionaryRef)keychainItem, NULL); } @@ -118,7 +118,7 @@ - (NSString *)valueForKeychainItem:(NSMutableDictionary *)keychainItem key:(NSSt - (NSMutableDictionary *)keychainItemForKey:(NSString *)key service:(NSString *)service { NSMutableDictionary *keychainItem = [[NSMutableDictionary alloc] init]; - keychainItem[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAfterFirstUnlock; + keychainItem[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly; [self keychainItemForKey:keychainItem key:key service:service]; return keychainItem; From 649cf7b5d31d3a39ef98baebd191e93d0dab50bc Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 1 Apr 2020 11:01:49 +0200 Subject: [PATCH 003/173] 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 004/173] 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 005/173] 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 006/173] 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 007/173] 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 008/173] @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 009/173] 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 010/173] 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 011/173] 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 012/173] 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 013/173] 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 014/173] 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 015/173] 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 016/173] 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 017/173] 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 018/173] 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 019/173] 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 020/173] 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 021/173] 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 022/173] 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 023/173] 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 024/173] 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 025/173] 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 026/173] 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 027/173] 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 028/173] 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 029/173] 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. From 5d82fe9d7b765157f93eb35ba6630350c08bd225 Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 14 Apr 2020 13:48:05 +0200 Subject: [PATCH 030/173] Surround object writing with try-catch --- Adjust/ADJUtil.m | 57 ++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 96d1058f8..6f1970a16 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -370,44 +370,45 @@ + (id)readObject:(NSString *)fileName + (void)writeObject:(id)object fileName:(NSString *)fileName - objectName:(NSString *)objectName -{ + 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; - } + @try { + BOOL result; + NSString *filePath = [ADJUtil getFilePathInAppSupportDir:fileName]; + 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]; + } @catch (NSException *exception) { + [[ADJAdjustFactory logger] error:@"Failed to write %@ file (%@)", objectName, exception]; } - } } From f8188b6452f20860bdceb9543174861577a6ef05 Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 14 Apr 2020 23:57:23 +0200 Subject: [PATCH 031/173] self reference fix when working with iAd timeout timer --- Adjust/ADJActivityHandler.m | 40 ++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index bf0fc9335..762c109ce 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -32,6 +32,7 @@ static NSString * const kForegroundTimerName = @"Foreground timer"; static NSString * const kBackgroundTimerName = @"Background timer"; static NSString * const kDelayStartTimerName = @"Delay Start timer"; +static NSString * const kiAdTimeoutTimerName = @"iAd Timeout timer"; static NSTimeInterval kForegroundTimerInterval; static NSTimeInterval kForegroundTimerStart; @@ -435,7 +436,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), ^{ - [self checkForIad]; + [self checkForiAd]; }); return; } @@ -793,8 +794,8 @@ - (void)initI:(ADJActivityHandler *)selfI startsSending:[selfI toSendI:selfI sdkClickHandlerOnly:YES]]; - if (self.adjustConfig.allowiAdInfoReading == YES) { - [self checkForIad]; + if (selfI.adjustConfig.allowiAdInfoReading == YES) { + [selfI checkForiAdI:selfI]; } [selfI preLaunchActionsI:selfI preLaunchActionsArray:preLaunchActionsArray]; @@ -1297,8 +1298,8 @@ - (void)setEnabledI:(ADJActivityHandler *)selfI enabled:(BOOL)enabled { } else if ([ADJUserDefaults getDisableThirdPartySharing]) { [selfI disableThirdPartySharing]; } - if (self.adjustConfig.allowiAdInfoReading == YES) { - [self checkForIad]; + if (selfI.adjustConfig.allowiAdInfoReading == YES) { + [selfI checkForiAdI:selfI]; } } @@ -1309,23 +1310,30 @@ - (void)setEnabledI:(ADJActivityHandler *)selfI enabled:(BOOL)enabled { unPausingMessage:@"Resuming handlers due to SDK being enabled"]; } -- (void)checkForIad { - if (self.iAdTimeoutTimer == nil) { - self.iAdTimeoutTimer = +- (void)checkForiAd { + [ADJUtil launchInQueue:self.internalQueue + selfInject:self + block:^(ADJActivityHandler *selfI) { + [selfI checkForiAdI:selfI]; + }]; +} + +- (void)checkForiAdI:(ADJActivityHandler *)selfI { + if (selfI.iAdTimeoutTimer == nil) { + selfI.iAdTimeoutTimer = [ADJTimerOnce timerWithBlock:^{ - [self - setAttributionDetails:nil - error:[NSError errorWithDomain:@"com.adjust.sdk.iAd" - code:100 - userInfo:@{@"Error reason": @"iAd request timed out"}]]; + [selfI setAttributionDetails:nil + error:[NSError errorWithDomain:@"com.adjust.sdk.iAd" + code:100 + userInfo:@{@"Error reason": @"iAd request timed out"}]]; } - queue:self.internalQueue - name:@"iAdTimeoutTimer"]; + queue:selfI.internalQueue + name:kiAdTimeoutTimerName]; } - [[UIDevice currentDevice] adjCheckForiAd:self iAdTimeoutTimer:self.iAdTimeoutTimer]; + [[UIDevice currentDevice] adjCheckForiAd:selfI iAdTimeoutTimer:selfI.iAdTimeoutTimer]; } - (void)setOfflineModeI:(ADJActivityHandler *)selfI From dbe58f38587e8fe2b865642810e74511f008c7d9 Mon Sep 17 00:00:00 2001 From: nonelse Date: Wed, 15 Apr 2020 08:33:36 +0200 Subject: [PATCH 032/173] Check if timer is valid --- Adjust/ADJActivityHandler.m | 5 +++-- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 762c109ce..d6f1c4697 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -400,8 +400,9 @@ - (void)setTrackingStateOptedOut { - (void)setAttributionDetails:(NSDictionary *)attributionDetails error:(NSError *)error { - [self.iAdTimeoutTimer cancel]; - + if (self.iAdTimeoutTimer) { + [self.iAdTimeoutTimer cancel]; + } if (![ADJUtil isNull:error]) { [self.logger warn:@"Unable to read iAd details"]; diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index b6b081e0e..7f10cc173 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -220,8 +220,9 @@ - (BOOL)setiAdWithDetails:(ADJActivityHandler *)activityHandler error:error]; }]; #pragma clang diagnostic pop - [iAdTimeoutTimer startIn:5.0]; - + if (iAdTimeoutTimer) { + [iAdTimeoutTimer startIn:5.0]; + } return YES; } From b015c25bb1598531dafd7986b57f32da1f0de1fe Mon Sep 17 00:00:00 2001 From: nonelse Date: Wed, 15 Apr 2020 08:34:43 +0200 Subject: [PATCH 033/173] Check for source and block in timer once --- Adjust/ADJTimerOnce.m | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Adjust/ADJTimerOnce.m b/Adjust/ADJTimerOnce.m index bfa4d8545..e6ea63e78 100644 --- a/Adjust/ADJTimerOnce.m +++ b/Adjust/ADJTimerOnce.m @@ -72,6 +72,15 @@ - (void)startIn:(NSTimeInterval)startIn { self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.internalQueue); + if (!self.source) { + [self.logger error:@"%@ could not start witouth source", self.name]; + return; + } + if (!self.block) { + [self.logger error:@"%@ could not start witouth block", self.name]; + return; + } + dispatch_source_set_timer(self.source, dispatch_walltime(NULL, startIn * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, From e2192344090b08329a798ce30ee4a2bf01a76e88 Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 15 Apr 2020 11:55:54 +0200 Subject: [PATCH 034/173] 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 995a1fedf..9b0fa6970 100644 --- a/Adjust.podspec +++ b/Adjust.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = "Adjust" - s.version = "4.21.1" + s.version = "4.21.2" 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.1" } + s.source = { :git => "https://github.com/adjust/ios_sdk.git", :tag => "v4.21.2" } 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 6f1970a16..6f103c499 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -43,7 +43,7 @@ static CTTelephonyNetworkInfo *networkInfo = nil; #endif -static NSString * const kClientSdk = @"ios4.21.1"; +static NSString * const kClientSdk = @"ios4.21.2"; 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 e2658ad89..f33bbc0eb 100644 --- a/Adjust/Adjust.h +++ b/Adjust/Adjust.h @@ -2,7 +2,7 @@ // Adjust.h // Adjust // -// V4.21.1 +// V4.21.2 // 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 9b12a52be..8ae4c40cf 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.1'; + return 'web-bridge4.21.2'; } }, setTestOptions: function(testOptions) { diff --git a/AdjustTests/AdjustUnitTests/ADJPackageFields.m b/AdjustTests/AdjustUnitTests/ADJPackageFields.m index d21e55a6e..13606d9e9 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.1"; + self.clientSdk = @"ios4.21.2"; self.suffix = @""; self.environment = @"sandbox"; diff --git a/README.md b/README.md index a4de3ec0d..30bff553e 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.1' +pod 'Adjust', '~> 4.21.2' ``` or: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.1' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.2' ``` --- diff --git a/VERSION b/VERSION index 79b1bb629..c93e58ee0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.21.1 +4.21.2 diff --git a/doc/chinese/README.md b/doc/chinese/README.md index 2cd831e03..1acf5ab24 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.1' +pod 'Adjust', '~> 4.21.2' ``` 或: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.1' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.2' ``` --- diff --git a/doc/english/migrate.md b/doc/english/migrate.md index 0c4373eeb..e74db1313 100644 --- a/doc/english/migrate.md +++ b/doc/english/migrate.md @@ -1,4 +1,4 @@ -## Migrate your adjust SDK for iOS to v4.21.1 from v3.4.0 +## Migrate your Adjust SDK for iOS to v4.21.2 from v3.4.0 ### Initial setup diff --git a/doc/english/web_views.md b/doc/english/web_views.md index 9f2ac0f45..30ea2d10a 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.1' +pod 'Adjust/WebBridge', '~> 4.21.2' ``` --- diff --git a/doc/japanese/README.md b/doc/japanese/README.md index b0cf6c936..783d31f04 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.1' +pod 'Adjust', '~> 4.21.2' ``` または ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.1' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.2' ``` --- diff --git a/doc/korean/README.md b/doc/korean/README.md index f20bb7b14..c4d1678aa 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.1' +pod 'Adjust', '~> 4.21.2' ``` 또는: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.1' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.2' ``` --- diff --git a/doc/korean/web_views.md b/doc/korean/web_views.md index 7c1c848a3..1f3a32e69 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.1' +pod 'Adjust/WebBridge', '~> 4.21.2' ``` --- diff --git a/doc/migrate.md b/doc/migrate.md index 8eaed6623..e74db1313 100644 --- a/doc/migrate.md +++ b/doc/migrate.md @@ -1,4 +1,4 @@ -## Migrate your Adjust SDK for iOS to v4.21.1 from v3.4.0 +## Migrate your Adjust SDK for iOS to v4.21.2 from v3.4.0 ### Initial setup From f616d9ec91d30c07b6ae5bddb83be9330008b4be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uglje=C5=A1a=20Erceg?= Date: Wed, 15 Apr 2020 12:30:06 +0200 Subject: [PATCH 035/173] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 923e5dbe1..cd92d282e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### Version 4.21.2 (15th April 2020) +#### Fixed +- Added check for timer source and block existence prior to starting it. + +--- + ### Version 4.21.1 (9th April 2020) #### Added - Added support for Mac Catalyst (thanks to @rjchatfield). From 33919dfcb7ca731290f0569bb92d4ca9cc27f319 Mon Sep 17 00:00:00 2001 From: uerceg Date: Mon, 20 Apr 2020 15:40:25 +0200 Subject: [PATCH 036/173] Synchronise access to callback/partner parameters in ADJEvent instance --- Adjust/ADJEvent.m | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/Adjust/ADJEvent.m b/Adjust/ADJEvent.m index 87132abb1..db525f211 100644 --- a/Adjust/ADJEvent.m +++ b/Adjust/ADJEvent.m @@ -47,15 +47,17 @@ - (void) addCallbackParameter:(NSString *)key attributeType:@"value" parameterName:@"Callback"]) return; - if (self.callbackMutableParameters == nil) { - self.callbackMutableParameters = [[NSMutableDictionary alloc] init]; - } + @synchronized (self) { + if (self.callbackMutableParameters == nil) { + self.callbackMutableParameters = [[NSMutableDictionary alloc] init]; + } - if ([self.callbackMutableParameters objectForKey:key]) { - [self.logger warn:@"key %@ was overwritten", key]; - } + if ([self.callbackMutableParameters objectForKey:key]) { + [self.logger warn:@"key %@ was overwritten", key]; + } - [self.callbackMutableParameters setObject:value forKey:key]; + [self.callbackMutableParameters setObject:value forKey:key]; + } } - (void) addPartnerParameter:(NSString *)key @@ -69,15 +71,17 @@ - (void) addPartnerParameter:(NSString *)key attributeType:@"value" parameterName:@"Partner"]) return; - if (self.partnerMutableParameters == nil) { - self.partnerMutableParameters = [[NSMutableDictionary alloc] init]; - } + @synchronized (self) { + if (self.partnerMutableParameters == nil) { + self.partnerMutableParameters = [[NSMutableDictionary alloc] init]; + } - if ([self.partnerMutableParameters objectForKey:key]) { - [self.logger warn:@"key %@ was overwritten", key]; - } + if ([self.partnerMutableParameters objectForKey:key]) { + [self.logger warn:@"key %@ was overwritten", key]; + } - [self.partnerMutableParameters setObject:value forKey:key]; + [self.partnerMutableParameters setObject:value forKey:key]; + } } - (void) setRevenue:(double) amount currency:(NSString *)currency{ @@ -98,11 +102,15 @@ - (void)setCallbackId:(NSString *)callbackId { } - (NSDictionary *) callbackParameters { - return (NSDictionary *) self.callbackMutableParameters; + @synchronized (self) { + return (NSDictionary *) self.callbackMutableParameters; + } } - (NSDictionary *) partnerParameters { - return (NSDictionary *) self.partnerMutableParameters; + @synchronized (self) { + return (NSDictionary *) self.partnerMutableParameters; + } } - (BOOL)checkEventToken:(NSString *)eventToken { From 58e9a650aade47d7c3154c92d6462fe166551abb Mon Sep 17 00:00:00 2001 From: uerceg Date: Mon, 20 Apr 2020 16:13:29 +0200 Subject: [PATCH 037/173] Copying user's input in ADJEvent and minor cleanup --- Adjust/ADJEvent.m | 117 +++++++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 54 deletions(-) diff --git a/Adjust/ADJEvent.m b/Adjust/ADJEvent.m index db525f211..117b0cce6 100644 --- a/Adjust/ADJEvent.m +++ b/Adjust/ADJEvent.m @@ -10,11 +10,12 @@ #import "ADJAdjustFactory.h" #import "ADJUtil.h" -#pragma mark - @interface ADJEvent() + @property (nonatomic, weak) id logger; -@property (nonatomic, strong) NSMutableDictionary* callbackMutableParameters; -@property (nonatomic, strong) NSMutableDictionary* partnerMutableParameters; +@property (nonatomic, strong) NSMutableDictionary *callbackMutableParameters; +@property (nonatomic, strong) NSMutableDictionary *partnerMutableParameters; + @end @implementation ADJEvent @@ -25,91 +26,100 @@ + (ADJEvent *)eventWithEventToken:(NSString *)eventToken { - (id) initWithEventToken:(NSString *)eventToken { self = [super init]; - if (self == nil) return nil; + if (self == nil) { + return nil; + } self.logger = ADJAdjustFactory.logger; - if (![self checkEventToken:eventToken]) return self; + if (![self checkEventToken:eventToken]) { + return self; + } - _eventToken = eventToken; + _eventToken = [[NSString alloc] initWithString:eventToken]; return self; } -- (void) addCallbackParameter:(NSString *)key - value:(NSString *)value -{ - if (![ADJUtil isValidParameter:key - attributeType:@"key" - parameterName:@"Callback"]) return; +- (void)addCallbackParameter:(NSString *)key value:(NSString *)value { + NSString *immutableKey = [NSString stringWithString:key]; + NSString *immutableValue = [NSString stringWithString:value]; - if (![ADJUtil isValidParameter:value + if (![ADJUtil isValidParameter:immutableKey + attributeType:@"key" + parameterName:@"Callback"]) { + return; + } + if (![ADJUtil isValidParameter:immutableValue attributeType:@"value" - parameterName:@"Callback"]) return; + parameterName:@"Callback"]) { + return; + } @synchronized (self) { if (self.callbackMutableParameters == nil) { self.callbackMutableParameters = [[NSMutableDictionary alloc] init]; } - - if ([self.callbackMutableParameters objectForKey:key]) { - [self.logger warn:@"key %@ was overwritten", key]; + if ([self.callbackMutableParameters objectForKey:immutableKey]) { + [self.logger warn:@"Callback parameter key %@ was overwritten", immutableKey]; } - - [self.callbackMutableParameters setObject:value forKey:key]; + [self.callbackMutableParameters setObject:immutableValue forKey:immutableKey]; } } -- (void) addPartnerParameter:(NSString *)key - value:(NSString *)value { +- (void)addPartnerParameter:(NSString *)key value:(NSString *)value { + NSString *immutableKey = [NSString stringWithString:key]; + NSString *immutableValue = [NSString stringWithString:value]; - if (![ADJUtil isValidParameter:key + if (![ADJUtil isValidParameter:immutableKey attributeType:@"key" - parameterName:@"Partner"]) return; - + parameterName:@"Partner"]) { + return; + } if (![ADJUtil isValidParameter:value attributeType:@"value" - parameterName:@"Partner"]) return; + parameterName:@"Partner"]) { + return; + } @synchronized (self) { if (self.partnerMutableParameters == nil) { self.partnerMutableParameters = [[NSMutableDictionary alloc] init]; } - - if ([self.partnerMutableParameters objectForKey:key]) { - [self.logger warn:@"key %@ was overwritten", key]; + if ([self.partnerMutableParameters objectForKey:immutableKey]) { + [self.logger warn:@"Partner parameter key %@ was overwritten", immutableKey]; } - - [self.partnerMutableParameters setObject:value forKey:key]; + [self.partnerMutableParameters setObject:immutableValue forKey:immutableKey]; } } -- (void) setRevenue:(double) amount currency:(NSString *)currency{ - NSNumber * revenue = [NSNumber numberWithDouble:amount]; - - if (![self checkRevenue:revenue currency:currency]) return; +- (void)setRevenue:(double)amount currency:(NSString *)currency { + NSNumber *revenue = [NSNumber numberWithDouble:amount]; + if (![self checkRevenue:revenue currency:currency]) { + return; + } _revenue = revenue; - _currency = currency; + _currency = [NSString stringWithString:currency]; } -- (void) setTransactionId:(NSString *)transactionId { - _transactionId = transactionId; +- (void)setTransactionId:(NSString *)transactionId { + _transactionId = [NSString stringWithString:transactionId]; } - (void)setCallbackId:(NSString *)callbackId { - _callbackId = callbackId; + _callbackId = [NSString stringWithString:callbackId]; } -- (NSDictionary *) callbackParameters { +- (NSDictionary *)callbackParameters { @synchronized (self) { - return (NSDictionary *) self.callbackMutableParameters; + return (NSDictionary *)self.callbackMutableParameters; } } -- (NSDictionary *) partnerParameters { +- (NSDictionary *)partnerParameters { @synchronized (self) { - return (NSDictionary *) self.partnerMutableParameters; + return (NSDictionary *)self.partnerMutableParameters; } } @@ -125,21 +135,17 @@ - (BOOL)checkEventToken:(NSString *)eventToken { return YES; } -- (BOOL) checkRevenue:(NSNumber*) revenue - currency:(NSString*) currency -{ +- (BOOL)checkRevenue:(NSNumber *)revenue currency:(NSString *)currency { if (![ADJUtil isNull:revenue]) { double amount = [revenue doubleValue]; if (amount < 0.0) { [self.logger error:@"Invalid amount %.5f", amount]; return NO; } - if ([ADJUtil isNull:currency]) { [self.logger error:@"Currency must be set with revenue"]; return NO; } - if ([currency isEqualToString:@""]) { [self.logger error:@"Currency is empty"]; return NO; @@ -154,12 +160,14 @@ - (BOOL) checkRevenue:(NSNumber*) revenue return YES; } -- (BOOL) isValid { +- (BOOL)isValid { return self.eventToken != nil; } -- (void) setReceipt:(NSData *)receipt transactionId:(NSString *)transactionId { - if (![self checkReceipt:receipt transactionId:transactionId]) return; +- (void)setReceipt:(NSData *)receipt transactionId:(NSString *)transactionId { + if (![self checkReceipt:receipt transactionId:transactionId]) { + return; + } if ([ADJUtil isNull:receipt] || [receipt length] == 0) { _emptyReceipt = YES; @@ -168,7 +176,7 @@ - (void) setReceipt:(NSData *)receipt transactionId:(NSString *)transactionId { _transactionId = transactionId; } -- (BOOL) checkReceipt:(NSData *)receipt transactionId:(NSString *)transactionId { +- (BOOL)checkReceipt:(NSData *)receipt transactionId:(NSString *)transactionId { if ([ADJUtil isNotNull:receipt] && [ADJUtil isNull:transactionId]) { [self.logger error:@"Missing transactionId"]; return NO; @@ -176,9 +184,9 @@ - (BOOL) checkReceipt:(NSData *)receipt transactionId:(NSString *)transactionId return YES; } --(id)copyWithZone:(NSZone *)zone -{ - ADJEvent* copy = [[[self class] allocWithZone:zone] init]; +- (id)copyWithZone:(NSZone *)zone { + ADJEvent *copy = [[[self class] allocWithZone:zone] init]; + if (copy) { copy->_eventToken = [self.eventToken copyWithZone:zone]; copy->_revenue = [self.revenue copyWithZone:zone]; @@ -189,6 +197,7 @@ -(id)copyWithZone:(NSZone *)zone copy->_receipt = [self.receipt copyWithZone:zone]; copy->_emptyReceipt = self.emptyReceipt; } + return copy; } From d7f1434382befdca698df1d82c237ccbf6121130 Mon Sep 17 00:00:00 2001 From: uerceg Date: Mon, 20 Apr 2020 16:15:58 +0200 Subject: [PATCH 038/173] Fix to use immutable value --- Adjust/ADJEvent.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Adjust/ADJEvent.m b/Adjust/ADJEvent.m index 117b0cce6..52a66db78 100644 --- a/Adjust/ADJEvent.m +++ b/Adjust/ADJEvent.m @@ -24,7 +24,7 @@ + (ADJEvent *)eventWithEventToken:(NSString *)eventToken { return [[ADJEvent alloc] initWithEventToken:eventToken]; } -- (id) initWithEventToken:(NSString *)eventToken { +- (id)initWithEventToken:(NSString *)eventToken { self = [super init]; if (self == nil) { return nil; @@ -76,7 +76,7 @@ - (void)addPartnerParameter:(NSString *)key value:(NSString *)value { parameterName:@"Partner"]) { return; } - if (![ADJUtil isValidParameter:value + if (![ADJUtil isValidParameter:immutableValue attributeType:@"value" parameterName:@"Partner"]) { return; From c3f760b0ec336c98f7ce310640069737558e0ae6 Mon Sep 17 00:00:00 2001 From: uerceg Date: Mon, 20 Apr 2020 23:43:17 +0200 Subject: [PATCH 039/173] Always use callback and partner parameters copies in package builder --- Adjust/ADJPackageBuilder.m | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index c3f927521..6d67f92dc 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -299,8 +299,8 @@ - (NSMutableDictionary *)getSessionParameters:(BOOL)isInDelay { } if (!isInDelay) { - [ADJPackageBuilder parameters:parameters setDictionary:self.sessionParameters.callbackParameters forKey:@"callback_params"]; - [ADJPackageBuilder parameters:parameters setDictionary:self.sessionParameters.partnerParameters forKey:@"partner_params"]; + [ADJPackageBuilder parameters:parameters setDictionary:[self.sessionParameters.callbackParameters copy] forKey:@"callback_params"]; + [ADJPackageBuilder parameters:parameters setDictionary:[self.sessionParameters.partnerParameters copy] forKey:@"partner_params"]; } #if !TARGET_OS_TV && !TARGET_OS_MACCATALYST @@ -368,11 +368,11 @@ - (NSMutableDictionary *)getEventParameters:(BOOL)isInDelay forEventPackage:(ADJ } if (!isInDelay) { - NSDictionary *mergedCallbackParameters = [ADJUtil mergeParameters:self.sessionParameters.callbackParameters - source:event.callbackParameters + NSDictionary *mergedCallbackParameters = [ADJUtil mergeParameters:[self.sessionParameters.callbackParameters copy] + source:[event.callbackParameters copy] parameterName:@"Callback"]; - NSDictionary *mergedPartnerParameters = [ADJUtil mergeParameters:self.sessionParameters.partnerParameters - source:event.partnerParameters + NSDictionary *mergedPartnerParameters = [ADJUtil mergeParameters:[self.sessionParameters.partnerParameters copy] + source:[event.partnerParameters copy] parameterName:@"Partner"]; [ADJPackageBuilder parameters:parameters setDictionary:mergedCallbackParameters forKey:@"callback_params"]; @@ -507,7 +507,7 @@ - (NSMutableDictionary *)getClickParameters:(NSString *)source { [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.bundleShortVersion forKey:@"app_version_short"]; [ADJPackageBuilder parameters:parameters setBool:YES forKey:@"attribution_deeplink"]; [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.bundeIdentifier forKey:@"bundle_id"]; - [ADJPackageBuilder parameters:parameters setDictionary:self.sessionParameters.callbackParameters forKey:@"callback_params"]; + [ADJPackageBuilder parameters:parameters setDictionary:[self.sessionParameters.callbackParameters copy] forKey:@"callback_params"]; [ADJPackageBuilder parameters:parameters setDate:self.clickTime forKey:@"click_time"]; [ADJPackageBuilder parameters:parameters setNumberInt:[ADJUtil readReachabilityFlags] forKey:@"connectivity_type"]; [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.countryCode forKey:@"country"]; @@ -535,7 +535,7 @@ - (NSMutableDictionary *)getClickParameters:(NSString *)source { [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.osName forKey:@"os_name"]; [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.systemVersion forKey:@"os_version"]; [ADJPackageBuilder parameters:parameters setDictionary:self.deeplinkParameters forKey:@"params"]; - [ADJPackageBuilder parameters:parameters setDictionary:self.sessionParameters.partnerParameters forKey:@"partner_params"]; + [ADJPackageBuilder parameters:parameters setDictionary:[self.sessionParameters.partnerParameters copy] forKey:@"partner_params"]; [ADJPackageBuilder parameters:parameters setDate:self.purchaseTime forKey:@"purchase_time"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; [ADJPackageBuilder parameters:parameters setString:source forKey:@"source"]; @@ -666,7 +666,7 @@ - (NSMutableDictionary *)getDisableThirdPartySharingParameters { [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.bundleShortVersion forKey:@"app_version_short"]; [ADJPackageBuilder parameters:parameters setBool:YES forKey:@"attribution_deeplink"]; [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.bundeIdentifier forKey:@"bundle_id"]; - [ADJPackageBuilder parameters:parameters setDictionary:self.sessionParameters.callbackParameters forKey:@"callback_params"]; + [ADJPackageBuilder parameters:parameters setDictionary:[self.sessionParameters.callbackParameters copy] forKey:@"callback_params"]; [ADJPackageBuilder parameters:parameters setDate:self.clickTime forKey:@"click_time"]; [ADJPackageBuilder parameters:parameters setNumberInt:[ADJUtil readReachabilityFlags] forKey:@"connectivity_type"]; [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.countryCode forKey:@"country"]; @@ -694,7 +694,7 @@ - (NSMutableDictionary *)getDisableThirdPartySharingParameters { [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.osName forKey:@"os_name"]; [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.systemVersion forKey:@"os_version"]; [ADJPackageBuilder parameters:parameters setDictionary:self.deeplinkParameters forKey:@"params"]; - [ADJPackageBuilder parameters:parameters setDictionary:self.sessionParameters.partnerParameters forKey:@"partner_params"]; + [ADJPackageBuilder parameters:parameters setDictionary:[self.sessionParameters.partnerParameters copy] forKey:@"partner_params"]; [ADJPackageBuilder parameters:parameters setDate:self.purchaseTime forKey:@"purchase_time"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; From 8555d5845b9e37941b55f046a81ab643500f3c82 Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 21 Apr 2020 01:01:56 +0200 Subject: [PATCH 040/173] Copy deeplinkParameters dictionary just in case --- Adjust/ADJActivityHandler.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index d6f1c4697..d3356ced1 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -1446,7 +1446,7 @@ - (void)appWillOpenUrlI:(ADJActivityHandler *)selfI config:selfI.adjustConfig sessionParameters:selfI.sessionParameters createdAt:now]; - clickBuilder.deeplinkParameters = adjustDeepLinks; + clickBuilder.deeplinkParameters = [adjustDeepLinks copy]; clickBuilder.attribution = deeplinkAttribution; clickBuilder.clickTime = clickTime; clickBuilder.deeplink = [url absoluteString]; From 85821d39230f7f17950c1c21106d14c4f73203a2 Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 21 Apr 2020 02:52:01 +0200 Subject: [PATCH 041/173] Remove iAd timer (for now) --- Adjust/ADJActivityHandler.m | 30 ++------------------- Adjust/ADJAdditions/UIDevice+ADJAdditions.h | 3 +-- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 14 +++------- 3 files changed, 6 insertions(+), 41 deletions(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index d3356ced1..6f8311c21 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -32,7 +32,6 @@ static NSString * const kForegroundTimerName = @"Foreground timer"; static NSString * const kBackgroundTimerName = @"Background timer"; static NSString * const kDelayStartTimerName = @"Delay Start timer"; -static NSString * const kiAdTimeoutTimerName = @"iAd Timeout timer"; static NSTimeInterval kForegroundTimerInterval; static NSTimeInterval kForegroundTimerStart; @@ -87,7 +86,6 @@ @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; @@ -110,7 +108,6 @@ typedef NS_ENUM(NSInteger, AdjADClientError) { AdjADClientErrorLimitAdTracking = 1, AdjADClientErrorMissingData = 2, AdjADClientErrorCorruptResponse = 3, - AdjCustomErrorTimeout = 100, }; #pragma mark - @@ -400,9 +397,6 @@ - (void)setTrackingStateOptedOut { - (void)setAttributionDetails:(NSDictionary *)attributionDetails error:(NSError *)error { - if (self.iAdTimeoutTimer) { - [self.iAdTimeoutTimer cancel]; - } if (![ADJUtil isNull:error]) { [self.logger warn:@"Unable to read iAd details"]; @@ -415,7 +409,6 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails // - AdjADClientErrorUnknown // - AdjADClientErrorMissingData // - AdjADClientErrorCorruptResponse - // - AdjCustomErrorTimeout // apply following retry logic: // - 1st retry after 5 seconds // - 2nd retry after 2 seconds @@ -423,8 +416,7 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails switch (error.code) { case AdjADClientErrorUnknown: case AdjADClientErrorMissingData: - case AdjADClientErrorCorruptResponse: - case AdjCustomErrorTimeout: { + case AdjADClientErrorCorruptResponse: { int64_t iAdRetryDelay = 0; switch (self.iAdRetriesLeft) { case 2: @@ -638,9 +630,6 @@ - (void)teardown if (self.backgroundTimer != nil) { [self.backgroundTimer cancel]; } - if (self.iAdTimeoutTimer != nil) { - [self.iAdTimeoutTimer cancel]; - } if (self.foregroundTimer != nil) { [self.foregroundTimer cancel]; } @@ -668,7 +657,6 @@ - (void)teardown self.sdkClickHandler = nil; self.foregroundTimer = nil; self.backgroundTimer = nil; - self.iAdTimeoutTimer = nil; self.adjustDelegate = nil; self.adjustConfig = nil; self.internalState = nil; @@ -1320,21 +1308,7 @@ - (void)checkForiAd { } - (void)checkForiAdI:(ADJActivityHandler *)selfI { - if (selfI.iAdTimeoutTimer == nil) { - selfI.iAdTimeoutTimer = - [ADJTimerOnce - timerWithBlock:^{ - [selfI setAttributionDetails:nil - error:[NSError errorWithDomain:@"com.adjust.sdk.iAd" - code:100 - userInfo:@{@"Error reason": @"iAd request timed out"}]]; - - } - queue:selfI.internalQueue - name:kiAdTimeoutTimerName]; - } - - [[UIDevice currentDevice] adjCheckForiAd:selfI iAdTimeoutTimer:selfI.iAdTimeoutTimer]; + [[UIDevice currentDevice] adjCheckForiAd:selfI]; } - (void)setOfflineModeI:(ADJActivityHandler *)selfI diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h index 4bba1d86e..b1778204d 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h @@ -20,6 +20,5 @@ - (NSString *)adjDeviceName; - (NSString *)adjCreateUuid; - (NSString *)adjVendorId; -- (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler - iAdTimeoutTimer:(ADJTimerOnce *)iAdTimeoutTimer; +- (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler; @end diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index 7f10cc173..b62da6d2f 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -158,9 +158,7 @@ - (NSString *)adjVendorId { return @""; } -- (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler - iAdTimeoutTimer:(ADJTimerOnce *)iAdTimeoutTimer -{ +- (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler { // if no tries for iad v3 left, stop trying id logger = [ADJAdjustFactory logger]; @@ -192,8 +190,7 @@ - (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler [logger debug:@"iAd framework successfully found in user's app"]; BOOL iAdInformationAvailable = [self setiAdWithDetails:activityHandler - adcClientSharedInstance:ADClientSharedClientInstance - iAdTimeoutTimer:iAdTimeoutTimer]; + adcClientSharedInstance:ADClientSharedClientInstance]; if (!iAdInformationAvailable) { [logger warn:@"iAd information not available"]; @@ -204,9 +201,7 @@ - (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler } - (BOOL)setiAdWithDetails:(ADJActivityHandler *)activityHandler - adcClientSharedInstance:(id)ADClientSharedClientInstance - iAdTimeoutTimer:(ADJTimerOnce *)iAdTimeoutTimer -{ + adcClientSharedInstance:(id)ADClientSharedClientInstance { SEL iAdDetailsSelector = NSSelectorFromString(@"requestAttributionDetailsWithBlock:"); if (![ADClientSharedClientInstance respondsToSelector:iAdDetailsSelector]) { return NO; @@ -220,9 +215,6 @@ - (BOOL)setiAdWithDetails:(ADJActivityHandler *)activityHandler error:error]; }]; #pragma clang diagnostic pop - if (iAdTimeoutTimer) { - [iAdTimeoutTimer startIn:5.0]; - } return YES; } From cad90dfdb4f7d9eb7f2da545ea7ac8fd2d8d1507 Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 21 Apr 2020 02:55:23 +0200 Subject: [PATCH 042/173] New version 4.21.3 --- 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 9b0fa6970..316a436b0 100644 --- a/Adjust.podspec +++ b/Adjust.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = "Adjust" - s.version = "4.21.2" + s.version = "4.21.3" 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.2" } + s.source = { :git => "https://github.com/adjust/ios_sdk.git", :tag => "v4.21.3" } 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 6f103c499..c5e46ce64 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -43,7 +43,7 @@ static CTTelephonyNetworkInfo *networkInfo = nil; #endif -static NSString * const kClientSdk = @"ios4.21.2"; +static NSString * const kClientSdk = @"ios4.21.3"; 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 f33bbc0eb..6e9c5ad79 100644 --- a/Adjust/Adjust.h +++ b/Adjust/Adjust.h @@ -2,7 +2,7 @@ // Adjust.h // Adjust // -// V4.21.2 +// V4.21.3 // 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 8ae4c40cf..b87799a2d 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.2'; + return 'web-bridge4.21.3'; } }, setTestOptions: function(testOptions) { diff --git a/AdjustTests/AdjustUnitTests/ADJPackageFields.m b/AdjustTests/AdjustUnitTests/ADJPackageFields.m index 13606d9e9..ab7a0b56e 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.2"; + self.clientSdk = @"ios4.21.3"; self.suffix = @""; self.environment = @"sandbox"; diff --git a/README.md b/README.md index 30bff553e..e2ade75b1 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.2' +pod 'Adjust', '~> 4.21.3' ``` or: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.2' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.3' ``` --- diff --git a/VERSION b/VERSION index c93e58ee0..fedb11348 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.21.2 +4.21.3 diff --git a/doc/chinese/README.md b/doc/chinese/README.md index 1acf5ab24..4d497188b 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.2' +pod 'Adjust', '~> 4.21.3' ``` 或: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.2' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.3' ``` --- diff --git a/doc/english/migrate.md b/doc/english/migrate.md index e74db1313..754f75536 100644 --- a/doc/english/migrate.md +++ b/doc/english/migrate.md @@ -1,4 +1,4 @@ -## Migrate your Adjust SDK for iOS to v4.21.2 from v3.4.0 +## Migrate your Adjust SDK for iOS to v4.21.3 from v3.4.0 ### Initial setup diff --git a/doc/english/web_views.md b/doc/english/web_views.md index 30ea2d10a..3758dc7f3 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.2' +pod 'Adjust/WebBridge', '~> 4.21.3' ``` --- diff --git a/doc/japanese/README.md b/doc/japanese/README.md index 783d31f04..068d4cc50 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.2' +pod 'Adjust', '~> 4.21.3' ``` または ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.2' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.3' ``` --- diff --git a/doc/korean/README.md b/doc/korean/README.md index c4d1678aa..98586b073 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.2' +pod 'Adjust', '~> 4.21.3' ``` 또는: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.2' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.3' ``` --- diff --git a/doc/korean/web_views.md b/doc/korean/web_views.md index 1f3a32e69..e191eb289 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.2' +pod 'Adjust/WebBridge', '~> 4.21.3' ``` --- diff --git a/doc/migrate.md b/doc/migrate.md index e74db1313..754f75536 100644 --- a/doc/migrate.md +++ b/doc/migrate.md @@ -1,4 +1,4 @@ -## Migrate your Adjust SDK for iOS to v4.21.2 from v3.4.0 +## Migrate your Adjust SDK for iOS to v4.21.3 from v3.4.0 ### Initial setup From 03b073db66339d4504f14af29b8f993ddaab16c5 Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 21 Apr 2020 02:59:20 +0200 Subject: [PATCH 043/173] CHANGELOG.md update --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd92d282e..a7e602778 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +### Version 4.21.3 (21st April 2020) +#### Changed +- Added copying of each injected mutable property of `ADJEvent` class. +- Sychronised access to callback/partner parameters in `ADJEvent` class. + +#### Fixed +- Removed iAd timer. +- Removed activity package mutation scenarios after package has been created. + +--- + ### Version 4.21.2 (15th April 2020) #### Fixed - Added check for timer source and block existence prior to starting it. From f66ee7e3dcbb320b039287bb63afc69829709691 Mon Sep 17 00:00:00 2001 From: nonelse Date: Tue, 21 Apr 2020 15:22:54 +0200 Subject: [PATCH 044/173] Make NSString copys safe --- Adjust/ADJEvent.m | 16 ++++++++-------- Adjust/ADJUtil.m | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Adjust/ADJEvent.m b/Adjust/ADJEvent.m index 52a66db78..168dd70e1 100644 --- a/Adjust/ADJEvent.m +++ b/Adjust/ADJEvent.m @@ -36,14 +36,14 @@ - (id)initWithEventToken:(NSString *)eventToken { return self; } - _eventToken = [[NSString alloc] initWithString:eventToken]; + _eventToken = [eventToken copy]; return self; } - (void)addCallbackParameter:(NSString *)key value:(NSString *)value { - NSString *immutableKey = [NSString stringWithString:key]; - NSString *immutableValue = [NSString stringWithString:value]; + NSString *immutableKey = [key copy]; + NSString *immutableValue = [value copy]; if (![ADJUtil isValidParameter:immutableKey attributeType:@"key" @@ -68,8 +68,8 @@ - (void)addCallbackParameter:(NSString *)key value:(NSString *)value { } - (void)addPartnerParameter:(NSString *)key value:(NSString *)value { - NSString *immutableKey = [NSString stringWithString:key]; - NSString *immutableValue = [NSString stringWithString:value]; + NSString *immutableKey = [key copy]; + NSString *immutableValue = [value copy]; if (![ADJUtil isValidParameter:immutableKey attributeType:@"key" @@ -100,15 +100,15 @@ - (void)setRevenue:(double)amount currency:(NSString *)currency { } _revenue = revenue; - _currency = [NSString stringWithString:currency]; + _currency = [currency copy]; } - (void)setTransactionId:(NSString *)transactionId { - _transactionId = [NSString stringWithString:transactionId]; + _transactionId = [transactionId copy]; } - (void)setCallbackId:(NSString *)callbackId { - _callbackId = [NSString stringWithString:callbackId]; + _callbackId = [callbackId copy]; } - (NSDictionary *)callbackParameters { diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index c5e46ce64..ef867f2ed 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -1330,7 +1330,7 @@ + (NSString *)convertDeviceToken:(NSData *)deviceToken { [hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]]; } - return [NSString stringWithString:hexString]; + return [hexString copy]; } + (BOOL)checkAttributionDetails:(NSDictionary *)attributionDetails { From ee9afb9d62dba32191d5c85e20a71c8ecd417566 Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 22 Apr 2020 11:42:03 +0200 Subject: [PATCH 045/173] CHANGELOG.md update --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7e602778..3993dfd71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### Version 4.21.3 (21st April 2020) +### Version 4.21.3 (22nd April 2020) #### Changed - Added copying of each injected mutable property of `ADJEvent` class. - Sychronised access to callback/partner parameters in `ADJEvent` class. From 82c2910a40c0930a24c51da294f8c69a662f7dba Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 22 Apr 2020 13:09:53 +0200 Subject: [PATCH 046/173] Synchronise remaining ADJEvent setters --- Adjust/ADJEvent.m | 64 ++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/Adjust/ADJEvent.m b/Adjust/ADJEvent.m index 168dd70e1..ecb6b1cd8 100644 --- a/Adjust/ADJEvent.m +++ b/Adjust/ADJEvent.m @@ -42,21 +42,21 @@ - (id)initWithEventToken:(NSString *)eventToken { } - (void)addCallbackParameter:(NSString *)key value:(NSString *)value { - NSString *immutableKey = [key copy]; - NSString *immutableValue = [value copy]; + @synchronized (self) { + NSString *immutableKey = [key copy]; + NSString *immutableValue = [value copy]; - if (![ADJUtil isValidParameter:immutableKey - attributeType:@"key" - parameterName:@"Callback"]) { - return; - } - if (![ADJUtil isValidParameter:immutableValue - attributeType:@"value" - parameterName:@"Callback"]) { - return; - } + if (![ADJUtil isValidParameter:immutableKey + attributeType:@"key" + parameterName:@"Callback"]) { + return; + } + if (![ADJUtil isValidParameter:immutableValue + attributeType:@"value" + parameterName:@"Callback"]) { + return; + } - @synchronized (self) { if (self.callbackMutableParameters == nil) { self.callbackMutableParameters = [[NSMutableDictionary alloc] init]; } @@ -68,21 +68,21 @@ - (void)addCallbackParameter:(NSString *)key value:(NSString *)value { } - (void)addPartnerParameter:(NSString *)key value:(NSString *)value { - NSString *immutableKey = [key copy]; - NSString *immutableValue = [value copy]; + @synchronized (self) { + NSString *immutableKey = [key copy]; + NSString *immutableValue = [value copy]; - if (![ADJUtil isValidParameter:immutableKey - attributeType:@"key" - parameterName:@"Partner"]) { - return; - } - if (![ADJUtil isValidParameter:immutableValue - attributeType:@"value" - parameterName:@"Partner"]) { - return; - } + if (![ADJUtil isValidParameter:immutableKey + attributeType:@"key" + parameterName:@"Partner"]) { + return; + } + if (![ADJUtil isValidParameter:immutableValue + attributeType:@"value" + parameterName:@"Partner"]) { + return; + } - @synchronized (self) { if (self.partnerMutableParameters == nil) { self.partnerMutableParameters = [[NSMutableDictionary alloc] init]; } @@ -100,15 +100,21 @@ - (void)setRevenue:(double)amount currency:(NSString *)currency { } _revenue = revenue; - _currency = [currency copy]; + @synchronized (self) { + _currency = [currency copy]; + } } - (void)setTransactionId:(NSString *)transactionId { - _transactionId = [transactionId copy]; + @synchronized (self) { + _transactionId = [transactionId copy]; + } } - (void)setCallbackId:(NSString *)callbackId { - _callbackId = [callbackId copy]; + @synchronized (self) { + _callbackId = [callbackId copy]; + } } - (NSDictionary *)callbackParameters { From 11af2cc9fec9f4571625bf1c25f90845ae25b26c Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 22 Apr 2020 15:55:57 +0200 Subject: [PATCH 047/173] Synchronise public API methods access --- Adjust/Adjust.m | 120 +++++++++++++----- .../AdjustExample-ObjC/ViewControllerObjC.m | 27 +++- 2 files changed, 106 insertions(+), 41 deletions(-) diff --git a/Adjust/Adjust.m b/Adjust/Adjust.m index 0e0d01042..228d5615f 100644 --- a/Adjust/Adjust.m +++ b/Adjust/Adjust.m @@ -85,44 +85,64 @@ - (id)init { #pragma mark - Public static methods + (void)appDidLaunch:(ADJConfig *)adjustConfig { - [[Adjust getInstance] appDidLaunch:adjustConfig]; + @synchronized (self) { + [[Adjust getInstance] appDidLaunch:adjustConfig]; + } } + (void)trackEvent:(ADJEvent *)event { - [[Adjust getInstance] trackEvent:event]; + @synchronized (self) { + [[Adjust getInstance] trackEvent:event]; + } } + (void)trackSubsessionStart { - [[Adjust getInstance] trackSubsessionStart]; + @synchronized (self) { + [[Adjust getInstance] trackSubsessionStart]; + } } + (void)trackSubsessionEnd { - [[Adjust getInstance] trackSubsessionEnd]; + @synchronized (self) { + [[Adjust getInstance] trackSubsessionEnd]; + } } + (void)setEnabled:(BOOL)enabled { - Adjust *instance = [Adjust getInstance]; - [instance setEnabled:enabled]; + @synchronized (self) { + Adjust *instance = [Adjust getInstance]; + [instance setEnabled:enabled]; + } } + (BOOL)isEnabled { - return [[Adjust getInstance] isEnabled]; + @synchronized (self) { + return [[Adjust getInstance] isEnabled]; + } } + (void)appWillOpenUrl:(NSURL *)url { - [[Adjust getInstance] appWillOpenUrl:url]; + @synchronized (self) { + [[Adjust getInstance] appWillOpenUrl:[url copy]]; + } } + (void)setDeviceToken:(NSData *)deviceToken { - [[Adjust getInstance] setDeviceToken:deviceToken]; + @synchronized (self) { + [[Adjust getInstance] setDeviceToken:[deviceToken copy]]; + } } + (void)setPushToken:(NSString *)pushToken { - [[Adjust getInstance] setPushToken:pushToken]; + @synchronized (self) { + [[Adjust getInstance] setPushToken:[pushToken copy]]; + } } + (void)setOfflineMode:(BOOL)enabled { - [[Adjust getInstance] setOfflineMode:enabled]; + @synchronized (self) { + [[Adjust getInstance] setOfflineMode:enabled]; + } } + (void)sendAdWordsRequest { @@ -130,77 +150,107 @@ + (void)sendAdWordsRequest { } + (NSString *)idfa { - return [[Adjust getInstance] idfa]; + @synchronized (self) { + return [[Adjust getInstance] idfa]; + } } + (NSString *)sdkVersion { - return [[Adjust getInstance] sdkVersion]; + @synchronized (self) { + return [[Adjust getInstance] sdkVersion]; + } } + (NSURL *)convertUniversalLink:(NSURL *)url scheme:(NSString *)scheme { - return [[Adjust getInstance] convertUniversalLink:url scheme:scheme]; + @synchronized (self) { + return [[Adjust getInstance] convertUniversalLink:[url copy] scheme:[scheme copy]]; + } } + (void)sendFirstPackages { - [[Adjust getInstance] sendFirstPackages]; + @synchronized (self) { + [[Adjust getInstance] sendFirstPackages]; + } } + (void)addSessionCallbackParameter:(NSString *)key value:(NSString *)value { - [[Adjust getInstance] addSessionCallbackParameter:key value:value]; - + @synchronized (self) { + [[Adjust getInstance] addSessionCallbackParameter:[key copy] value:[value copy]]; + } } + (void)addSessionPartnerParameter:(NSString *)key value:(NSString *)value { - [[Adjust getInstance] addSessionPartnerParameter:key value:value]; + @synchronized (self) { + [[Adjust getInstance] addSessionPartnerParameter:[key copy] value:[value copy]]; + } } - + (void)removeSessionCallbackParameter:(NSString *)key { - [[Adjust getInstance] removeSessionCallbackParameter:key]; + @synchronized (self) { + [[Adjust getInstance] removeSessionCallbackParameter:[key copy]]; + } } + (void)removeSessionPartnerParameter:(NSString *)key { - [[Adjust getInstance] removeSessionPartnerParameter:key]; + @synchronized (self) { + [[Adjust getInstance] removeSessionPartnerParameter:[key copy]]; + } } + (void)resetSessionCallbackParameters { - [[Adjust getInstance] resetSessionCallbackParameters]; + @synchronized (self) { + [[Adjust getInstance] resetSessionCallbackParameters]; + } } + (void)resetSessionPartnerParameters { - [[Adjust getInstance] resetSessionPartnerParameters]; + @synchronized (self) { + [[Adjust getInstance] resetSessionPartnerParameters]; + } } + (void)gdprForgetMe { - [[Adjust getInstance] gdprForgetMe]; + @synchronized (self) { + [[Adjust getInstance] gdprForgetMe]; + } } + (void)trackAdRevenue:(nonnull NSString *)source payload:(nonnull NSData *)payload { - [[Adjust getInstance] trackAdRevenue:source payload:payload]; + @synchronized (self) { + [[Adjust getInstance] trackAdRevenue:[source copy] payload:[payload copy]]; + } } + (void)disableThirdPartySharing { - [[Adjust getInstance] disableThirdPartySharing]; + @synchronized (self) { + [[Adjust getInstance] disableThirdPartySharing]; + } } + (ADJAttribution *)attribution { - return [[Adjust getInstance] attribution]; + @synchronized (self) { + return [[Adjust getInstance] attribution]; + } } + (NSString *)adid { - return [[Adjust getInstance] adid]; + @synchronized (self) { + return [[Adjust getInstance] adid]; + } } + (void)setTestOptions:(AdjustTestOptions *)testOptions { - if (testOptions.teardown) { - if (defaultInstance != nil) { - [defaultInstance teardown]; + @synchronized (self) { + if (testOptions.teardown) { + if (defaultInstance != nil) { + [defaultInstance teardown]; + } + defaultInstance = nil; + onceToken = 0; + [ADJAdjustFactory teardown:testOptions.deleteState]; } - defaultInstance = nil; - onceToken = 0; - [ADJAdjustFactory teardown:testOptions.deleteState]; + [[Adjust getInstance] setTestOptions:(AdjustTestOptions *)testOptions]; } - [[Adjust getInstance] setTestOptions:(AdjustTestOptions *)testOptions]; } #pragma mark - Public instance methods diff --git a/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m b/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m index 938f4778f..083cf57ff 100644 --- a/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m +++ b/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m @@ -44,12 +44,27 @@ - (IBAction)clickTrackSimpleEvent:(UIButton *)sender { } - (IBAction)clickTrackRevenueEvent:(UIButton *)sender { - ADJEvent *event = [ADJEvent eventWithEventToken:kEventToken2]; - - // Add revenue 1 cent of an EURO. - [event setRevenue:0.01 currency:@"EUR"]; - - [Adjust trackEvent:event]; + NSURL __block *url = [NSURL URLWithString:@"random-url"]; +// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ +// // Add revenue 1 cent of an EURO. +// for (int i = 0; i < 30000; i += 1) { +// [event setRevenue:i currency:@"EUR"]; +// [event setCallbackId:[NSString stringWithFormat:@"%@%d", @"random-id", i]]; +// [event addCallbackParameter:@"foo" value:[NSString stringWithFormat:@"%@%d", @"bar", i]]; +// [event addCallbackParameter:@"key" value:[NSString stringWithFormat:@"%@%d", @"value", i]]; +// } +// }); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + for (int i = 0; i < 300; i += 1) { + [Adjust appWillOpenUrl:[NSURL URLWithString:[NSString stringWithFormat:@"random-url-%d", i]]]; + } + }); +// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ +// // Add revenue 1 cent of an EURO. +// for (int i = 30000; i < 60000; i += 1) { +// url = [NSURL URLWithString:[NSString stringWithFormat:@"random-url-%d", i]]; +// } +// }); } - (IBAction)clickTrackCallbackEvent:(UIButton *)sender { From a7f064f79b29f62d376a52b921b6785c8e44904c Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 22 Apr 2020 16:01:37 +0200 Subject: [PATCH 048/173] CHANGELOG.md update --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3993dfd71..3251a15ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ ### Version 4.21.3 (22nd April 2020) #### Changed - Added copying of each injected mutable property of `ADJEvent` class. -- Sychronised access to callback/partner parameters in `ADJEvent` class. +- Synchronised access to callback/partner parameters in `ADJEvent` class. +- Synchronised access to public API methods in `Adjust` class. #### Fixed - Removed iAd timer. From 608de43725c01db5f203111c5ec8d4fc0c960f6a Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 22 Apr 2020 16:04:20 +0200 Subject: [PATCH 049/173] Put revenue tracking back in AdjustExample-ObjC app --- .../AdjustExample-ObjC/ViewControllerObjC.m | 27 +++++-------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m b/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m index 083cf57ff..938f4778f 100644 --- a/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m +++ b/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m @@ -44,27 +44,12 @@ - (IBAction)clickTrackSimpleEvent:(UIButton *)sender { } - (IBAction)clickTrackRevenueEvent:(UIButton *)sender { - NSURL __block *url = [NSURL URLWithString:@"random-url"]; -// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ -// // Add revenue 1 cent of an EURO. -// for (int i = 0; i < 30000; i += 1) { -// [event setRevenue:i currency:@"EUR"]; -// [event setCallbackId:[NSString stringWithFormat:@"%@%d", @"random-id", i]]; -// [event addCallbackParameter:@"foo" value:[NSString stringWithFormat:@"%@%d", @"bar", i]]; -// [event addCallbackParameter:@"key" value:[NSString stringWithFormat:@"%@%d", @"value", i]]; -// } -// }); - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - for (int i = 0; i < 300; i += 1) { - [Adjust appWillOpenUrl:[NSURL URLWithString:[NSString stringWithFormat:@"random-url-%d", i]]]; - } - }); -// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ -// // Add revenue 1 cent of an EURO. -// for (int i = 30000; i < 60000; i += 1) { -// url = [NSURL URLWithString:[NSString stringWithFormat:@"random-url-%d", i]]; -// } -// }); + ADJEvent *event = [ADJEvent eventWithEventToken:kEventToken2]; + + // Add revenue 1 cent of an EURO. + [event setRevenue:0.01 currency:@"EUR"]; + + [Adjust trackEvent:event]; } - (IBAction)clickTrackCallbackEvent:(UIButton *)sender { From d0cc98f16abd88d866b9d2015d1fed8da14efd0f Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 16 Apr 2020 02:56:13 +0200 Subject: [PATCH 050/173] Initial subscription tracking implementation --- Adjust.xcodeproj/project.pbxproj | 40 ++++++ Adjust/ADJActivityHandler.h | 3 + Adjust/ADJActivityHandler.m | 42 ++++++ Adjust/ADJActivityKind.h | 21 +-- Adjust/ADJActivityKind.m | 4 + Adjust/ADJAdjustFactory.h | 2 + Adjust/ADJAdjustFactory.m | 10 ++ Adjust/ADJPackageBuilder.h | 3 + Adjust/ADJPackageBuilder.m | 97 +++++++++++++ Adjust/ADJPackageHandler.h | 1 + Adjust/ADJPackageHandler.m | 6 + Adjust/ADJRequestHandler.m | 10 ++ Adjust/ADJSubscription.h | 43 ++++++ Adjust/ADJSubscription.m | 135 ++++++++++++++++++ Adjust/Adjust.h | 12 ++ Adjust/Adjust.m | 18 +++ AdjustSdk/AdjustSdk.h | 1 + AdjustSdkIm/AdjustSdkIm.h | 1 + AdjustSdkTv/AdjustSdkTv.h | 1 + AdjustSdkWebBridge/AdjustSdkWebBridge.h | 1 + .../AdjustTestApp.xcodeproj/project.pbxproj | 6 + .../AdjustTestApp/ATAAdjustCommandExecutor.m | 7 + .../AdjustTestApp/ViewController.h | 1 + .../project.pbxproj | 6 + .../project.pbxproj | 6 + .../project.pbxproj | 6 + .../project.pbxproj | 6 + .../project.pbxproj | 6 + .../project.pbxproj | 6 + .../project.pbxproj | 6 + 30 files changed, 497 insertions(+), 10 deletions(-) create mode 100644 Adjust/ADJSubscription.h create mode 100644 Adjust/ADJSubscription.m diff --git a/Adjust.xcodeproj/project.pbxproj b/Adjust.xcodeproj/project.pbxproj index 5faf90ca2..84695aeec 100644 --- a/Adjust.xcodeproj/project.pbxproj +++ b/Adjust.xcodeproj/project.pbxproj @@ -216,6 +216,16 @@ 9D0E2EB9210B575600133B4F /* WKWebViewJavascriptBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D0E2E68210B575600133B4F /* WKWebViewJavascriptBridge.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D0E2EBA210B575600133B4F /* AdjustBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D0E2E69210B575600133B4F /* AdjustBridge.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D0E2EBB210B575600133B4F /* AdjustBridgeRegister.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D0E2E6A210B575600133B4F /* AdjustBridgeRegister.m */; }; + 9D2F23E22447CE5C00B7CA90 /* ADJSubscription.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D2F23E02447CE5C00B7CA90 /* ADJSubscription.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9D2F23E32447CE5C00B7CA90 /* ADJSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D2F23E12447CE5C00B7CA90 /* ADJSubscription.m */; }; + 9D2F23F82447DCE800B7CA90 /* ADJSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D2F23F62447DCE800B7CA90 /* ADJSubscription.m */; }; + 9D2F23F92447DCE800B7CA90 /* ADJSubscription.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D2F23F72447DCE800B7CA90 /* ADJSubscription.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9D2F23FC2447DD2500B7CA90 /* ADJSubscription.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D2F23FA2447DD2500B7CA90 /* ADJSubscription.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9D2F23FD2447DD2500B7CA90 /* ADJSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D2F23FB2447DD2500B7CA90 /* ADJSubscription.m */; }; + 9D2F24002447DD3700B7CA90 /* ADJSubscription.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D2F23FE2447DD3600B7CA90 /* ADJSubscription.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9D2F24012447DD3700B7CA90 /* ADJSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D2F23FF2447DD3700B7CA90 /* ADJSubscription.m */; }; + 9D2F24042447DD6000B7CA90 /* ADJSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D2F24022447DD6000B7CA90 /* ADJSubscription.m */; }; + 9D2F24052447DD6000B7CA90 /* ADJSubscription.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D2F24032447DD6000B7CA90 /* ADJSubscription.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D363AC31BDA50FA00B47FE9 /* ADJLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 96E5E37318BBB48A008E7B30 /* ADJLogger.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9D7431EA1EB9F9B700969F14 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D7431E91EB9F9B700969F14 /* main.m */; }; 9D7431ED1EB9F9B700969F14 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D7431EC1EB9F9B700969F14 /* AppDelegate.m */; }; @@ -806,6 +816,16 @@ 9D0E2E68210B575600133B4F /* WKWebViewJavascriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKWebViewJavascriptBridge.h; sourceTree = ""; }; 9D0E2E69210B575600133B4F /* AdjustBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdjustBridge.h; sourceTree = ""; }; 9D0E2E6A210B575600133B4F /* AdjustBridgeRegister.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AdjustBridgeRegister.m; sourceTree = ""; }; + 9D2F23E02447CE5C00B7CA90 /* ADJSubscription.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ADJSubscription.h; sourceTree = ""; }; + 9D2F23E12447CE5C00B7CA90 /* ADJSubscription.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ADJSubscription.m; sourceTree = ""; }; + 9D2F23F62447DCE800B7CA90 /* ADJSubscription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJSubscription.m; sourceTree = ""; }; + 9D2F23F72447DCE800B7CA90 /* ADJSubscription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJSubscription.h; sourceTree = ""; }; + 9D2F23FA2447DD2500B7CA90 /* ADJSubscription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJSubscription.h; sourceTree = ""; }; + 9D2F23FB2447DD2500B7CA90 /* ADJSubscription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJSubscription.m; sourceTree = ""; }; + 9D2F23FE2447DD3600B7CA90 /* ADJSubscription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJSubscription.h; sourceTree = ""; }; + 9D2F23FF2447DD3700B7CA90 /* ADJSubscription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJSubscription.m; sourceTree = ""; }; + 9D2F24022447DD6000B7CA90 /* ADJSubscription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJSubscription.m; sourceTree = ""; }; + 9D2F24032447DD6000B7CA90 /* ADJSubscription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJSubscription.h; sourceTree = ""; }; 9D449DB31E6ED23400E7E80B /* AdjustExample-iWatch.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "AdjustExample-iWatch.xcodeproj"; path = "examples/AdjustExample-iWatch/AdjustExample-iWatch.xcodeproj"; sourceTree = ""; }; 9D449DBF1E6ED23900E7E80B /* AdjustExample-Swift.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "AdjustExample-Swift.xcodeproj"; path = "examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj"; sourceTree = ""; }; 9D449DC51E6ED24000E7E80B /* AdjustExample-tvOS.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "AdjustExample-tvOS.xcodeproj"; path = "examples/AdjustExample-tvOS/AdjustExample-tvOS.xcodeproj"; sourceTree = ""; }; @@ -1334,6 +1354,8 @@ 6FCC84F71F278CF300D6A0ED /* ADJReachability.m */, 9DD0E9AC1F44690B00B2A759 /* ADJUserDefaults.h */, 9DD0E9AD1F44690B00B2A759 /* ADJUserDefaults.m */, + 9D2F23E02447CE5C00B7CA90 /* ADJSubscription.h */, + 9D2F23E12447CE5C00B7CA90 /* ADJSubscription.m */, ); path = Adjust; sourceTree = ""; @@ -1434,6 +1456,8 @@ 9D0E2E58210B575600133B4F /* ADJTimerCycle.h */, 9D0E2E59210B575600133B4F /* ADJActivityHandler.m */, 9D0E2E5A210B575600133B4F /* ADJReachability.m */, + 9D2F24032447DD6000B7CA90 /* ADJSubscription.h */, + 9D2F24022447DD6000B7CA90 /* ADJSubscription.m */, ); path = Adjust; sourceTree = SOURCE_ROOT; @@ -1638,6 +1662,8 @@ 9DEAF0F2210072BC005CAEDB /* ADJTimerCycle.h */, 9DEAF0F3210072BC005CAEDB /* ADJActivityHandler.m */, 9DEAF0F4210072BC005CAEDB /* ADJReachability.m */, + 9D2F23FA2447DD2500B7CA90 /* ADJSubscription.h */, + 9D2F23FB2447DD2500B7CA90 /* ADJSubscription.m */, ); path = Adjust; sourceTree = SOURCE_ROOT; @@ -1717,6 +1743,8 @@ 96B671131D788F4A0090A023 /* ADJSessionParameters.m */, 6FCC85021F27944600D6A0ED /* ADJReachability.h */, 6FCC85031F27944600D6A0ED /* ADJReachability.m */, + 9D2F23F72447DCE800B7CA90 /* ADJSubscription.h */, + 9D2F23F62447DCE800B7CA90 /* ADJSubscription.m */, ); path = Adjust; sourceTree = SOURCE_ROOT; @@ -1816,6 +1844,8 @@ 96B671171D788F7A0090A023 /* ADJSessionParameters.m */, 6FCC85071F27948700D6A0ED /* ADJReachability.h */, 6FCC85061F27948700D6A0ED /* ADJReachability.m */, + 9D2F23FE2447DD3600B7CA90 /* ADJSubscription.h */, + 9D2F23FF2447DD3700B7CA90 /* ADJSubscription.m */, ); path = Adjust; sourceTree = SOURCE_ROOT; @@ -1845,6 +1875,7 @@ 96BCFBD01AC9923F005A65C5 /* ADJConfig.h in Headers */, 9D363AC31BDA50FA00B47FE9 /* ADJLogger.h in Headers */, 96BCFBD11AC99246005A65C5 /* ADJAttribution.h in Headers */, + 9D2F23E22447CE5C00B7CA90 /* ADJSubscription.h in Headers */, 9601CAE81C74BAAE00670879 /* ADJEventFailure.h in Headers */, 9601CAE41C74B70600670879 /* ADJEventSuccess.h in Headers */, 6FCC85011F278CF300D6A0ED /* ADJReachability.h in Headers */, @@ -1890,6 +1921,7 @@ 9D0E2E6B210B575600133B4F /* ADJConfig.h in Headers */, 9D0E2E8F210B575600133B4F /* ADJEvent.h in Headers */, 9D0E2E73210B575600133B4F /* ADJAttribution.h in Headers */, + 9D2F24052447DD6000B7CA90 /* ADJSubscription.h in Headers */, 9D0E2EA2210B575600133B4F /* ADJEventFailure.h in Headers */, 9D0E2EA1210B575600133B4F /* ADJEventSuccess.h in Headers */, 9D0E2E9E210B575600133B4F /* ADJSessionFailure.h in Headers */, @@ -1931,6 +1963,7 @@ 9DEAF0F9210072BC005CAEDB /* Adjust.h in Headers */, 9DEAF0F5210072BC005CAEDB /* ADJConfig.h in Headers */, 9DEAF119210072BC005CAEDB /* ADJEvent.h in Headers */, + 9D2F23FC2447DD2500B7CA90 /* ADJSubscription.h in Headers */, 9DEAF0FD210072BC005CAEDB /* ADJAttribution.h in Headers */, 9DEAF12E210072BC005CAEDB /* ADJSessionSuccess.h in Headers */, 9DEAF128210072BC005CAEDB /* ADJSessionFailure.h in Headers */, @@ -1973,6 +2006,7 @@ 9DF9C91F1D6F3CA5008E362F /* ADJConfig.h in Headers */, 9DF9C92B1D6F3CA5008E362F /* ADJLogger.h in Headers */, 9DF9C9191D6F3CA5008E362F /* ADJAttribution.h in Headers */, + 9D2F23F92447DCE800B7CA90 /* ADJSubscription.h in Headers */, 9DF9C9251D6F3CA5008E362F /* ADJEventFailure.h in Headers */, 9DF9C9271D6F3CA5008E362F /* ADJEventSuccess.h in Headers */, 9DF9C9371D6F3CA5008E362F /* ADJSessionFailure.h in Headers */, @@ -2014,6 +2048,7 @@ 9DFB06701D7470C0006D48FC /* ADJConfig.h in Headers */, 9DFB067C1D7470C0006D48FC /* ADJLogger.h in Headers */, 9DFB066A1D7470C0006D48FC /* ADJAttribution.h in Headers */, + 9D2F24002447DD3700B7CA90 /* ADJSubscription.h in Headers */, 9DFB06761D7470C0006D48FC /* ADJEventFailure.h in Headers */, 9DFB06781D7470C0006D48FC /* ADJEventSuccess.h in Headers */, 9DFB06881D7470C0006D48FC /* ADJSessionFailure.h in Headers */, @@ -2528,6 +2563,7 @@ 96E5E39418BBB48A008E7B30 /* ADJPackageBuilder.m in Sources */, 6FCC85001F278CF300D6A0ED /* ADJReachability.m in Sources */, 96E5E39618BBB48A008E7B30 /* ADJRequestHandler.m in Sources */, + 9D2F23E32447CE5C00B7CA90 /* ADJSubscription.m in Sources */, 96E5E39918BBB48A008E7B30 /* ADJUtil.m in Sources */, 9609BC6A19EEA55800E02303 /* ADJEvent.m in Sources */, 965307F61A000DA400107FF9 /* ADJDeviceInfo.m in Sources */, @@ -2614,6 +2650,7 @@ 9D0E2E6D210B575600133B4F /* ADJTimerOnce.m in Sources */, 9D0E2E77210B575600133B4F /* ADJEvent.m in Sources */, 9D0E2E8D210B575600133B4F /* ADJConfig.m in Sources */, + 9D2F24042447DD6000B7CA90 /* ADJSubscription.m in Sources */, 9D0E2E6E210B575600133B4F /* ADJAttributionHandler.m in Sources */, 9D0E2E87210B575600133B4F /* ADJBackoffStrategy.m in Sources */, 9D0E2EBB210B575600133B4F /* AdjustBridgeRegister.m in Sources */, @@ -2657,6 +2694,7 @@ 9DEAF10A210072BC005CAEDB /* ADJSessionFailure.m in Sources */, 9DEAF121210072BC005CAEDB /* UIDevice+ADJAdditions.m in Sources */, 9DEAF105210072BC005CAEDB /* ADJSessionSuccess.m in Sources */, + 9D2F23FD2447DD2500B7CA90 /* ADJSubscription.m in Sources */, 9DEAF124210072BC005CAEDB /* ADJSystemProfile.m in Sources */, 9DEAF0FB210072BC005CAEDB /* ADJRequestHandler.m in Sources */, 9DEAF11B210072BC005CAEDB /* ADJActivityKind.m in Sources */, @@ -2697,6 +2735,7 @@ 9DF9C92E1D6F3CA5008E362F /* ADJPackageBuilder.m in Sources */, 9DF9C9301D6F3CA5008E362F /* ADJPackageHandler.m in Sources */, 6FCC85051F27946100D6A0ED /* ADJReachability.m in Sources */, + 9D2F23F82447DCE800B7CA90 /* ADJSubscription.m in Sources */, 9DF9C9321D6F3CA5008E362F /* ADJRequestHandler.m in Sources */, 9DF9C9461D6F3CA5008E362F /* ADJUtil.m in Sources */, 9DF9C9241D6F3CA5008E362F /* ADJEvent.m in Sources */, @@ -2737,6 +2776,7 @@ 9DFB067F1D7470C0006D48FC /* ADJPackageBuilder.m in Sources */, 9DFB06811D7470C0006D48FC /* ADJPackageHandler.m in Sources */, 6FCC85091F27949000D6A0ED /* ADJReachability.m in Sources */, + 9D2F24012447DD3700B7CA90 /* ADJSubscription.m in Sources */, 9DFB06831D7470C0006D48FC /* ADJRequestHandler.m in Sources */, 9DFB06971D7470C0006D48FC /* ADJUtil.m in Sources */, 9DFB06751D7470C0006D48FC /* ADJEvent.m in Sources */, diff --git a/Adjust/ADJActivityHandler.h b/Adjust/ADJActivityHandler.h index da2787fb7..9a96dd4fa 100644 --- a/Adjust/ADJActivityHandler.h +++ b/Adjust/ADJActivityHandler.h @@ -46,6 +46,7 @@ @property (nonatomic, assign) BOOL offline; @property (nonatomic, copy) NSString *basePath; @property (nonatomic, copy) NSString *gdprPath; +@property (nonatomic, copy) NSString *subscriptionPath; - (id)init; @@ -97,8 +98,10 @@ - (void)resetSessionPartnerParameters; - (void)trackAdRevenue:(NSString *)soruce payload:(NSData *)payload; - (void)disableThirdPartySharing; +- (void)trackSubscription:(ADJSubscription *)subscription; - (NSString *)getBasePath; - (NSString *)getGdprPath; +- (NSString *)getSubscriptionPath; - (ADJDeviceInfo *)deviceInfo; - (ADJActivityState *)activityState; diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 6f8311c21..009e74916 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -99,6 +99,7 @@ @interface ADJActivityHandler() @property (nonatomic, copy) NSData* deviceTokenData; @property (nonatomic, copy) NSString* basePath; @property (nonatomic, copy) NSString* gdprPath; +@property (nonatomic, copy) NSString* subscriptionPath; @end @@ -201,6 +202,9 @@ - (id)initWithConfig:(ADJConfig *)adjustConfig if (savedPreLaunch.gdprPath != nil) { self.gdprPath = savedPreLaunch.gdprPath; } + if (savedPreLaunch.subscriptionPath != nil) { + self.subscriptionPath = savedPreLaunch.subscriptionPath; + } self.iAdRetriesLeft = kiAdRetriesCount; @@ -607,6 +611,14 @@ - (void)trackAdRevenue:(NSString *)source payload:(NSData *)payload { }]; } +- (void)trackSubscription:(ADJSubscription *)subscription { + [ADJUtil launchInQueue:self.internalQueue + selfInject:self + block:^(ADJActivityHandler * selfI) { + [selfI trackSubscriptionI:selfI subscription:subscription]; + }]; +} + - (void)disableThirdPartySharing { [ADJUtil launchInQueue:self.internalQueue selfInject:self @@ -623,6 +635,10 @@ - (NSString *)getGdprPath { return _gdprPath; } +- (NSString *)getSubscriptionPath { + return _subscriptionPath; +} + - (void)teardown { [ADJAdjustFactory.logger verbose:@"ADJActivityHandler teardown"]; @@ -1022,6 +1038,32 @@ - (void)adRevenueI:(ADJActivityHandler *)selfI [selfI.packageHandler sendFirstPackage]; } +- (void)trackSubscriptionI:(ADJActivityHandler *)selfI + subscription:(ADJSubscription *)subscription { + if (!selfI.activityState) { + return; + } + if (![selfI isEnabledI:selfI]) { + return; + } + if (selfI.activityState.isGdprForgotten) { + return; + } + + double now = [NSDate.date timeIntervalSince1970]; + + // Create and submit ad revenue package. + ADJPackageBuilder *subscriptionBuilder = [[ADJPackageBuilder alloc] initWithDeviceInfo:selfI.deviceInfo + activityState:selfI.activityState + config:selfI.adjustConfig + sessionParameters:selfI.sessionParameters + createdAt:now]; + ADJActivityPackage *subscriptionPackage = [subscriptionBuilder buildSubscriptionPackage:subscription + isInDelay:[selfI.internalState isInDelayedStart]]; + [selfI.packageHandler addPackage:subscriptionPackage]; + [selfI.packageHandler sendFirstPackage]; +} + - (void)disableThirdPartySharingI:(ADJActivityHandler *)selfI { // cache the disable third party sharing request, so that the request order maintains // even this call returns before making server request diff --git a/Adjust/ADJActivityKind.h b/Adjust/ADJActivityKind.h index 6a13128c0..1f83c99d0 100644 --- a/Adjust/ADJActivityKind.h +++ b/Adjust/ADJActivityKind.h @@ -13,16 +13,17 @@ #endif typedef NS_ENUM(int, ADJActivityKind) { - ADJActivityKindUnknown = 0, - ADJActivityKindSession = 1, - ADJActivityKindEvent = 2, -// ADJActivityKindRevenue = 3, - ADJActivityKindClick = 4, - ADJActivityKindAttribution = 5, - ADJActivityKindInfo = 6, - ADJActivityKindGdpr = 7, - ADJActivityKindAdRevenue = 8, - ADJActivityKindDisableThirdPartySharing = 9 + ADJActivityKindUnknown = 0, + ADJActivityKindSession = 1, + ADJActivityKindEvent = 2, + // ADJActivityKindRevenue = 3, + ADJActivityKindClick = 4, + ADJActivityKindAttribution = 5, + ADJActivityKindInfo = 6, + ADJActivityKindGdpr = 7, + ADJActivityKindAdRevenue = 8, + ADJActivityKindDisableThirdPartySharing = 9, + ADJActivityKindSubscription = 10 }; @interface ADJActivityKindUtil : NSObject diff --git a/Adjust/ADJActivityKind.m b/Adjust/ADJActivityKind.m index 694ff623f..7c8cb862d 100644 --- a/Adjust/ADJActivityKind.m +++ b/Adjust/ADJActivityKind.m @@ -29,6 +29,8 @@ + (ADJActivityKind)activityKindFromString:(NSString *)activityKindString { return ADJActivityKindAdRevenue; } else if ([@"disable_third_party_sharing" isEqualToString:activityKindString]) { return ADJActivityKindDisableThirdPartySharing; + } else if ([@"subscription" isEqualToString:activityKindString]) { + return ADJActivityKindSubscription; } else { return ADJActivityKindUnknown; } @@ -52,6 +54,8 @@ + (NSString *)activityKindToString:(ADJActivityKind)activityKind { return @"ad_revenue"; case ADJActivityKindDisableThirdPartySharing: return @"disable_third_party_sharing"; + case ADJActivityKindSubscription: + return @"subscription"; default: return @"unknown"; } diff --git a/Adjust/ADJAdjustFactory.h b/Adjust/ADJAdjustFactory.h index fab71f48f..fce9560b3 100644 --- a/Adjust/ADJAdjustFactory.h +++ b/Adjust/ADJAdjustFactory.h @@ -42,6 +42,7 @@ + (NSTimeInterval)maxDelayStart; + (NSString *)baseUrl; + (NSString *)gdprUrl; ++ (NSString *)subscriptionUrl; + (BOOL)iAdFrameworkEnabled; + (void)setPackageHandler:(id)packageHandler; @@ -61,6 +62,7 @@ + (void)setMaxDelayStart:(NSTimeInterval)maxDelayStart; + (void)setBaseUrl:(NSString *)baseUrl; + (void)setGdprUrl:(NSString *)gdprUrl; ++ (void)setSubscriptionUrl:(NSString *)subscriptionUrl; + (void)enableSigning; + (void)disableSigning; diff --git a/Adjust/ADJAdjustFactory.m b/Adjust/ADJAdjustFactory.m index 2c59c67bd..e58e0f0f2 100644 --- a/Adjust/ADJAdjustFactory.m +++ b/Adjust/ADJAdjustFactory.m @@ -30,6 +30,8 @@ static NSString * internalBaseUrl = @"https://app.adjust.com"; static NSString * const kGdprUrl = @"https://gdpr.adjust.com"; static NSString * internalGdprUrl = @"https://gdpr.adjust.com"; +static NSString * const kSubscriptionUrl = @"https://staging-api-sub.adjust.com"; +static NSString * internalSubscriptionUrl = @"https://staging-api-sub.adjust.com"; @implementation ADJAdjustFactory @@ -166,6 +168,10 @@ + (NSString *)gdprUrl { return internalGdprUrl; } ++ (NSString *)subscriptionUrl { + return internalSubscriptionUrl; +} + + (void)setPackageHandler:(id)packageHandler { internalPackageHandler = packageHandler; } @@ -234,6 +240,10 @@ + (void)setGdprUrl:(NSString *)gdprUrl { internalGdprUrl = gdprUrl; } ++ (void)setSubscriptionUrl:(NSString *)subscriptionUrl { + internalSubscriptionUrl = subscriptionUrl; +} + + (void)enableSigning { Class signerClass = NSClassFromString(@"ADJSigner"); if (signerClass == nil) { diff --git a/Adjust/ADJPackageBuilder.h b/Adjust/ADJPackageBuilder.h index 026079dc9..3b1349dd1 100644 --- a/Adjust/ADJPackageBuilder.h +++ b/Adjust/ADJPackageBuilder.h @@ -51,6 +51,9 @@ - (ADJActivityPackage *)buildDisableThirdPartySharingPackage; +- (ADJActivityPackage *)buildSubscriptionPackage:(ADJSubscription *)subscription + isInDelay:(BOOL)isInDelay; + + (void)parameters:(NSMutableDictionary *)parameters setDictionary:(NSDictionary *)dictionary forKey:(NSString *)key; diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index 6d67f92dc..6c67236be 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -163,6 +163,25 @@ - (ADJActivityPackage *)buildDisableThirdPartySharingPackage { return dtpsPackage; } +- (ADJActivityPackage *)buildSubscriptionPackage:(ADJSubscription *)subscription + isInDelay:(BOOL)isInDelay { + NSMutableDictionary *parameters = [self getSubscriptionParameters:isInDelay forSubscriptionPackage:subscription]; + ADJActivityPackage *subscriptionPackage = [self defaultActivityPackage]; + subscriptionPackage.path = @"/v2/purchase"; + subscriptionPackage.activityKind = ADJActivityKindEvent; + subscriptionPackage.suffix = @""; + subscriptionPackage.parameters = parameters; + + if (isInDelay) { + subscriptionPackage.callbackParameters = subscriptionPackage.callbackParameters; + subscriptionPackage.partnerParameters = subscriptionPackage.partnerParameters; + } + + [self signWithSigV2Plugin:subscriptionPackage]; + + return subscriptionPackage; +} + + (void)parameters:(NSMutableDictionary *)parameters setDictionary:(NSDictionary *)dictionary forKey:(NSString *)key { if (dictionary == nil) { return; @@ -726,6 +745,84 @@ - (NSMutableDictionary *)getDisableThirdPartySharingParameters { return parameters; } +- (NSMutableDictionary *)getSubscriptionParameters:(BOOL)isInDelay forSubscriptionPackage:(ADJSubscription *)subscription { + NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; + + [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.appSecret forKey:@"app_secret"]; + [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.appToken forKey:@"app_token"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.bundleVersion forKey:@"app_version"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.bundleShortVersion forKey:@"app_version_short"]; + [ADJPackageBuilder parameters:parameters setBool:YES forKey:@"attribution_deeplink"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.bundeIdentifier forKey:@"bundle_id"]; + [ADJPackageBuilder parameters:parameters setNumberInt:[ADJUtil readReachabilityFlags] forKey:@"connectivity_type"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.countryCode forKey:@"country"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.cpuSubtype forKey:@"cpu_type"]; + [ADJPackageBuilder parameters:parameters setDate1970:self.createdAt forKey:@"created_at"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.deviceName forKey:@"device_name"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.deviceType forKey:@"device_type"]; + [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.environment forKey:@"environment"]; + [ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.eventBufferingEnabled forKey:@"event_buffering_enabled"]; + [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.fbAnonymousId forKey:@"fb_anon_id"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.machineModel forKey:@"hardware_name"]; + if (self.adjustConfig.allowIdfaReading == YES) { + [ADJPackageBuilder parameters:parameters setString:UIDevice.currentDevice.adjIdForAdvertisers forKey:@"idfa"]; + } + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.vendorId forKey:@"idfv"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.installReceiptBase64 forKey:@"install_receipt"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.languageCode forKey:@"language"]; + [ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.osBuild forKey:@"os_build"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.osName forKey:@"os_name"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.systemVersion forKey:@"os_version"]; + [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; + [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + + if (self.adjustConfig.isDeviceKnown) { + [ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.isDeviceKnown forKey:@"device_known"]; + } + + if (self.activityState != nil) { + [ADJPackageBuilder parameters:parameters setInt:self.activityState.eventCount forKey:@"event_count"]; + [ADJPackageBuilder parameters:parameters setString:self.activityState.deviceToken forKey:@"push_token"]; + [ADJPackageBuilder parameters:parameters setInt:self.activityState.sessionCount forKey:@"session_count"]; + [ADJPackageBuilder parameters:parameters setDuration:self.activityState.sessionLength forKey:@"session_length"]; + [ADJPackageBuilder parameters:parameters setInt:self.activityState.subsessionCount forKey:@"subsession_count"]; + [ADJPackageBuilder parameters:parameters setDuration:self.activityState.timeSpent forKey:@"time_spent"]; + if (self.activityState.isPersisted) { + [ADJPackageBuilder parameters:parameters setString:self.activityState.uuid forKey:@"persistent_ios_uuid"]; + } else { + [ADJPackageBuilder parameters:parameters setString:self.activityState.uuid forKey:@"ios_uuid"]; + } + } + + if (!isInDelay) { + NSDictionary *mergedCallbackParameters = [ADJUtil mergeParameters:self.sessionParameters.callbackParameters + source:subscription.callbackParameters + parameterName:@"Callback"]; + NSDictionary *mergedPartnerParameters = [ADJUtil mergeParameters:self.sessionParameters.partnerParameters + source:subscription.partnerParameters + parameterName:@"Partner"]; + + [ADJPackageBuilder parameters:parameters setDictionary:mergedCallbackParameters forKey:@"callback_params"]; + [ADJPackageBuilder parameters:parameters setDictionary:mergedPartnerParameters forKey:@"partner_params"]; + } + + [ADJPackageBuilder parameters:parameters setNumber:subscription.revenue forKey:@"revenue"]; + [ADJPackageBuilder parameters:parameters setString:subscription.currency forKey:@"currency"]; + [ADJPackageBuilder parameters:parameters setDate1970:[subscription.transactionDate doubleValue] forKey:@"transaction_date"]; + [ADJPackageBuilder parameters:parameters setString:subscription.transactionId forKey:@"transaction_id"]; + [ADJPackageBuilder parameters:parameters setString:[subscription.receipt adjEncodeBase64] forKey:@"receipt"]; + [ADJPackageBuilder parameters:parameters setString:subscription.billingStore forKey:@"billing_store"]; + +#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"]; +#endif + + return parameters; +} - (ADJActivityPackage *)defaultActivityPackage { ADJActivityPackage *activityPackage = [[ADJActivityPackage alloc] init]; diff --git a/Adjust/ADJPackageHandler.h b/Adjust/ADJPackageHandler.h index a69a2df97..12d4f3a01 100644 --- a/Adjust/ADJPackageHandler.h +++ b/Adjust/ADJPackageHandler.h @@ -29,6 +29,7 @@ - (void)flush; - (NSString *)getBasePath; - (NSString *)getGdprPath; +- (NSString *)getSubscriptionPath; - (void)teardown; + (void)deleteState; diff --git a/Adjust/ADJPackageHandler.m b/Adjust/ADJPackageHandler.m index 6bf96692b..c918f4dce 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, copy) NSString *subscriptionPath; @property (nonatomic, assign) NSInteger lastPackageRetriesCount; @end @@ -57,6 +58,7 @@ - (id)initWithActivityHandler:(id)activityHandler self.backoffStrategyForInstallSession = [ADJAdjustFactory installSessionBackoffStrategy]; self.basePath = [activityHandler getBasePath]; self.gdprPath = [activityHandler getGdprPath]; + self.subscriptionPath = [activityHandler getSubscriptionPath]; self.lastPackageRetriesCount = 0; [ADJUtil launchInQueue:self.internalQueue @@ -165,6 +167,10 @@ - (NSString *)getGdprPath { return _gdprPath; } +- (NSString *)getSubscriptionPath { + return _subscriptionPath; +} + - (void)teardown { [ADJAdjustFactory.logger verbose:@"ADJPackageHandler teardown"]; if (self.sendingSemaphore != nil) { diff --git a/Adjust/ADJRequestHandler.m b/Adjust/ADJRequestHandler.m index 5e8e1bc90..260c7b466 100644 --- a/Adjust/ADJRequestHandler.m +++ b/Adjust/ADJRequestHandler.m @@ -30,6 +30,8 @@ @interface ADJRequestHandler() @property (nonatomic, copy) NSString *gdprPath; +@property (nonatomic, copy) NSString *subscriptionPath; + @end @implementation ADJRequestHandler @@ -56,6 +58,7 @@ - (id)initWithPackageHandler:(id)packageHandler self.logger = ADJAdjustFactory.logger; self.basePath = [packageHandler getBasePath]; self.gdprPath = [packageHandler getGdprPath]; + self.gdprPath = [packageHandler getSubscriptionPath]; return self; } @@ -89,6 +92,13 @@ - (void)sendI:(ADJRequestHandler *)selfI activityPackage:(ADJActivityPackage *)a } else { url = [NSURL URLWithString:gdprUrl]; } + } else if (activityPackage.activityKind == ADJActivityKindGdpr) { + NSString *subscriptionUrl = [ADJAdjustFactory subscriptionUrl]; + if (selfI.subscriptionPath != nil) { + url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", subscriptionUrl, selfI.subscriptionPath]]; + } else { + url = [NSURL URLWithString:subscriptionUrl]; + } } else { NSString *baseUrl = [ADJAdjustFactory baseUrl]; if (selfI.basePath != nil) { diff --git a/Adjust/ADJSubscription.h b/Adjust/ADJSubscription.h new file mode 100644 index 000000000..0e7eea10d --- /dev/null +++ b/Adjust/ADJSubscription.h @@ -0,0 +1,43 @@ +// +// ADJSubscription.h +// Adjust +// +// Created by Uglješa Erceg on 16.04.20. +// Copyright © 2020 adjust GmbH. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ADJSubscription : NSObject + +@property (nonatomic, copy, readonly, nonnull) NSNumber *revenue; + +@property (nonatomic, copy, readonly, nonnull) NSString *currency; + +@property (nonatomic, copy, readonly, nonnull) NSNumber *transactionDate; + +@property (nonatomic, copy, readonly, nonnull) NSString *transactionId; + +@property (nonatomic, copy, readonly, nonnull) NSData *receipt; + +@property (nonatomic, copy, readonly, nonnull) NSString *billingStore; + +@property (nonatomic, readonly, nonnull) NSDictionary *partnerParameters; + +@property (nonatomic, readonly, nonnull) NSDictionary *callbackParameters; + +- (nullable id)initWithRevenue:(double)revenue + currency:(nonnull NSString *)currency + transactionDate:(double)transactionDate + transactionId:(nonnull NSString *)transactionId + andReceipt:(nonnull NSData *)receipt; + +- (void)addCallbackParameter:(nonnull NSString *)key value:(nonnull NSString *)value; + +- (void)addPartnerParameter:(nonnull NSString *)key value:(nonnull NSString *)value; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Adjust/ADJSubscription.m b/Adjust/ADJSubscription.m new file mode 100644 index 000000000..42e01f754 --- /dev/null +++ b/Adjust/ADJSubscription.m @@ -0,0 +1,135 @@ +// +// ADJSubscription.m +// Adjust +// +// Created by Uglješa Erceg on 16.04.20. +// Copyright © 2020 adjust GmbH. All rights reserved. +// + +#import "ADJUtil.h" +#import "ADJSubscription.h" +#import "ADJAdjustFactory.h" + +@interface ADJSubscription() + +@property (nonatomic, weak) id logger; + +@property (nonatomic, strong) NSMutableDictionary *mutableCallbackParameters; + +@property (nonatomic, strong) NSMutableDictionary *mutablePartnerParameters; + +@end + +@implementation ADJSubscription + +- (nullable id)initWithRevenue:(double)revenue + currency:(nonnull NSString *)currency + transactionDate:(double)transactionDate + transactionId:(nonnull NSString *)transactionId + andReceipt:(nonnull NSData *)receipt { + self = [super init]; + if (self == nil) { + return nil; + } + + _revenue = [NSNumber numberWithDouble:revenue]; + _currency = currency; + _transactionDate = [NSNumber numberWithDouble:transactionDate]; + _transactionId = transactionId; + _receipt = receipt; + _billingStore = @"iOS"; + + self.logger = ADJAdjustFactory.logger; + + if (![self isValid]) { + return nil; + } + + return self; +} + +- (void)addCallbackParameter:(NSString *)key value:(NSString *)value { + if (![ADJUtil isValidParameter:key + attributeType:@"key" + parameterName:@"Callback"]) { + return; + } + if (![ADJUtil isValidParameter:value + attributeType:@"value" + parameterName:@"Callback"]) { + return; + } + + if (self.mutableCallbackParameters == nil) { + self.mutableCallbackParameters = [[NSMutableDictionary alloc] init]; + } + + if ([self.mutableCallbackParameters objectForKey:key]) { + [self.logger warn:@"key %@ was overwritten", key]; + } + + [self.mutableCallbackParameters setObject:value forKey:key]; +} + +- (void)addPartnerParameter:(NSString *)key value:(NSString *)value { + if (![ADJUtil isValidParameter:key + attributeType:@"key" + parameterName:@"Partner"]) { + return; + } + if (![ADJUtil isValidParameter:value + attributeType:@"value" + parameterName:@"Partner"]) { + return; + } + + if (self.mutablePartnerParameters == nil) { + self.mutablePartnerParameters = [[NSMutableDictionary alloc] init]; + } + + if ([self.mutablePartnerParameters objectForKey:key]) { + [self.logger warn:@"key %@ was overwritten", key]; + } + + [self.mutablePartnerParameters setObject:value forKey:key]; +} + +- (BOOL)isValid { + if (_revenue == nil) { + return NO; + } + if (_currency == nil) { + return NO; + } + if (_transactionDate == nil) { + return NO; + } + if (_transactionId == nil) { + return NO; + } + if (_receipt == nil) { + return NO; + } + if (_billingStore == nil) { + return NO; + } + + return YES; +} + +- (id)copyWithZone:(NSZone *)zone { + ADJSubscription *copy = [[[self class] allocWithZone:zone] init]; + if (copy) { + copy->_revenue = [self.revenue copyWithZone:zone]; + copy->_currency = [self.currency copyWithZone:zone]; + copy->_transactionDate = [self.receipt copyWithZone:zone]; + copy->_transactionId = [self.transactionId copyWithZone:zone]; + copy->_receipt = [self.receipt copyWithZone:zone]; + copy->_billingStore = [self.receipt copyWithZone:zone]; + copy.mutableCallbackParameters = [self.mutableCallbackParameters copyWithZone:zone]; + copy.mutablePartnerParameters = [self.mutablePartnerParameters copyWithZone:zone]; + } + return copy; +} + +@end diff --git a/Adjust/Adjust.h b/Adjust/Adjust.h index 6e9c5ad79..c6c55a5f6 100644 --- a/Adjust/Adjust.h +++ b/Adjust/Adjust.h @@ -10,13 +10,16 @@ #import "ADJEvent.h" #import "ADJConfig.h" #import "ADJAttribution.h" +#import "ADJSubscription.h" @interface AdjustTestOptions : NSObject @property (nonatomic, copy, nullable) NSString *baseUrl; @property (nonatomic, copy, nullable) NSString *gdprUrl; +@property (nonatomic, copy, nullable) NSString *subscriptionUrl; @property (nonatomic, copy, nullable) NSString *basePath; @property (nonatomic, copy, nullable) NSString *gdprPath; +@property (nonatomic, copy, nullable) NSString *subscriptionPath; @property (nonatomic, copy, nullable) NSNumber *timerIntervalInMilliseconds; @property (nonatomic, copy, nullable) NSNumber *timerStartInMilliseconds; @property (nonatomic, copy, nullable) NSNumber *sessionIntervalInMilliseconds; @@ -266,6 +269,13 @@ extern NSString * __nonnull const ADJAdRevenueSourceTapdaq; */ + (void)disableThirdPartySharing; +/** + * @brief Track subscription. + * + * @param subscription Subscription object. + */ ++ (void)trackSubscription:(nonnull ADJSubscription *)subscription; + /** * Obtain singleton Adjust object. */ @@ -311,6 +321,8 @@ extern NSString * __nonnull const ADJAdRevenueSourceTapdaq; - (void)trackAdRevenue:(nonnull NSString *)source payload:(nonnull NSData *)payload; +- (void)trackSubscription:(nonnull ADJSubscription *)subscription; + - (BOOL)isEnabled; - (nullable NSString *)adid; diff --git a/Adjust/Adjust.m b/Adjust/Adjust.m index 228d5615f..836836f96 100644 --- a/Adjust/Adjust.m +++ b/Adjust/Adjust.m @@ -227,6 +227,10 @@ + (void)disableThirdPartySharing { } } ++ (void)trackSubscription:(nonnull ADJSubscription *)subscription { + [[Adjust getInstance] trackSubscription:subscription]; +} + + (ADJAttribution *)attribution { @synchronized (self) { return [[Adjust getInstance] attribution]; @@ -480,6 +484,14 @@ - (void)disableThirdPartySharing { [self.activityHandler disableThirdPartySharing]; } +- (void)trackSubscription:(ADJSubscription *)subscription { + if (![self checkActivityHandler]) { + return; + } + + [self.activityHandler trackSubscription:subscription]; +} + - (ADJAttribution *)attribution { if (![self checkActivityHandler]) { return nil; @@ -517,12 +529,18 @@ - (void)setTestOptions:(AdjustTestOptions *)testOptions { if (testOptions.gdprPath != nil) { self.savedPreLaunch.gdprPath = testOptions.gdprPath; } + if (testOptions.subscriptionPath != nil) { + self.savedPreLaunch.subscriptionPath = testOptions.subscriptionPath; + } if (testOptions.baseUrl != nil) { [ADJAdjustFactory setBaseUrl:testOptions.baseUrl]; } if (testOptions.gdprUrl != nil) { [ADJAdjustFactory setGdprUrl:testOptions.gdprUrl]; } + if (testOptions.subscriptionUrl != nil) { + [ADJAdjustFactory setSubscriptionUrl:testOptions.subscriptionUrl]; + } if (testOptions.timerIntervalInMilliseconds != nil) { NSTimeInterval timerIntervalInSeconds = [testOptions.timerIntervalInMilliseconds intValue] / 1000.0; [ADJAdjustFactory setTimerInterval:timerIntervalInSeconds]; diff --git a/AdjustSdk/AdjustSdk.h b/AdjustSdk/AdjustSdk.h index 405e288ec..7004b4f6a 100644 --- a/AdjustSdk/AdjustSdk.h +++ b/AdjustSdk/AdjustSdk.h @@ -21,6 +21,7 @@ FOUNDATION_EXPORT const unsigned char AdjustSdkVersionString[]; #import #import #import +#import #import #import #import diff --git a/AdjustSdkIm/AdjustSdkIm.h b/AdjustSdkIm/AdjustSdkIm.h index c0d84c2a3..38b59b571 100644 --- a/AdjustSdkIm/AdjustSdkIm.h +++ b/AdjustSdkIm/AdjustSdkIm.h @@ -21,6 +21,7 @@ FOUNDATION_EXPORT const unsigned char AdjustSdkImVersionString[]; #import #import #import +#import #import #import #import diff --git a/AdjustSdkTv/AdjustSdkTv.h b/AdjustSdkTv/AdjustSdkTv.h index bf083fa5a..31947ac54 100644 --- a/AdjustSdkTv/AdjustSdkTv.h +++ b/AdjustSdkTv/AdjustSdkTv.h @@ -21,6 +21,7 @@ FOUNDATION_EXPORT const unsigned char AdjustSdkTvVersionString[]; #import #import #import +#import #import #import #import diff --git a/AdjustSdkWebBridge/AdjustSdkWebBridge.h b/AdjustSdkWebBridge/AdjustSdkWebBridge.h index ccebc3f81..123b03d18 100644 --- a/AdjustSdkWebBridge/AdjustSdkWebBridge.h +++ b/AdjustSdkWebBridge/AdjustSdkWebBridge.h @@ -22,6 +22,7 @@ FOUNDATION_EXPORT const unsigned char AdjustSdkWebBridgeVersionString[]; #import #import #import +#import #import #import #import diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp.xcodeproj/project.pbxproj b/AdjustTests/AdjustTestApp/AdjustTestApp.xcodeproj/project.pbxproj index fff02e305..dc20b90fb 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp.xcodeproj/project.pbxproj +++ b/AdjustTests/AdjustTestApp/AdjustTestApp.xcodeproj/project.pbxproj @@ -71,6 +71,7 @@ 9D1D8E9E219246E50088E3CF /* iAd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D1D8E9D219246E50088E3CF /* iAd.framework */; }; 9D1D8EA0219246EA0088E3CF /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D1D8E9F219246EA0088E3CF /* AdSupport.framework */; }; 9D1D8EA2219246EF0088E3CF /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D1D8EA1219246EF0088E3CF /* CoreTelephony.framework */; }; + 9D2F24082447DDCB00B7CA90 /* ADJSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D2F24072447DDCA00B7CA90 /* ADJSubscription.m */; }; 9D75AFDB210217FF0079A36C /* ATAAdjustDelegateDeferredDeeplink.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D75AFDA210217FF0079A36C /* ATAAdjustDelegateDeferredDeeplink.m */; }; /* End PBXBuildFile section */ @@ -203,6 +204,8 @@ 9D1D8E9D219246E50088E3CF /* iAd.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = iAd.framework; path = System/Library/Frameworks/iAd.framework; sourceTree = SDKROOT; }; 9D1D8E9F219246EA0088E3CF /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; 9D1D8EA1219246EF0088E3CF /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; }; + 9D2F24062447DDCA00B7CA90 /* ADJSubscription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJSubscription.h; sourceTree = ""; }; + 9D2F24072447DDCA00B7CA90 /* ADJSubscription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJSubscription.m; sourceTree = ""; }; 9D75AFD9210217FF0079A36C /* ATAAdjustDelegateDeferredDeeplink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ATAAdjustDelegateDeferredDeeplink.h; sourceTree = ""; }; 9D75AFDA210217FF0079A36C /* ATAAdjustDelegateDeferredDeeplink.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ATAAdjustDelegateDeferredDeeplink.m; sourceTree = ""; }; /* End PBXFileReference section */ @@ -324,6 +327,8 @@ 6F3A5E6B2018CE14000AACD0 /* ADJTimerCycle.h */, 6F3A5E6C2018CE14000AACD0 /* ADJActivityHandler.m */, 6F3A5E6D2018CE14000AACD0 /* ADJReachability.m */, + 9D2F24062447DDCA00B7CA90 /* ADJSubscription.h */, + 9D2F24072447DDCA00B7CA90 /* ADJSubscription.m */, ); name = Adjust; path = ../../../Adjust; @@ -542,6 +547,7 @@ 6F3A5E872018CE14000AACD0 /* ADJActivityPackage.m in Sources */, 6FFCFE71200797D100467F01 /* ATAAdjustDelegateEventSuccess.m in Sources */, 6F3A5E6F2018CE14000AACD0 /* ADJTimerOnce.m in Sources */, + 9D2F24082447DDCB00B7CA90 /* ADJSubscription.m in Sources */, 6FFCFE6F200797D100467F01 /* ATAAdjustDelegateSessionFailure.m in Sources */, 6F3A5E7D2018CE14000AACD0 /* ADJBackoffStrategy.m in Sources */, 6F3A5E8F2018CE14000AACD0 /* ADJReachability.m in Sources */, diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m b/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m index 3fb6de374..c43b14b45 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m @@ -22,6 +22,7 @@ @interface ATAAdjustCommandExecutor () @property (nonatomic, copy) NSString *basePath; @property (nonatomic, copy) NSString *gdprPath; +@property (nonatomic, copy) NSString *subscriptionPath; @property (nonatomic, strong) NSMutableDictionary *savedConfigs; @property (nonatomic, strong) NSMutableDictionary *savedEvents; @property (nonatomic, strong) NSObject *adjustDelegate; @@ -42,6 +43,7 @@ - (id)init { self.adjustDelegate = nil; self.basePath = nil; self.gdprPath = nil; + self.subscriptionPath = nil; return self; } @@ -100,10 +102,12 @@ - (void)testOptions:(NSDictionary *)parameters { AdjustTestOptions *testOptions = [[AdjustTestOptions alloc] init]; testOptions.baseUrl = baseUrl; testOptions.gdprUrl = gdprUrl; + testOptions.subscriptionUrl = subscriptionUrl; if ([parameters objectForKey:@"basePath"]) { self.basePath = [parameters objectForKey:@"basePath"][0]; self.gdprPath = [parameters objectForKey:@"basePath"][0]; + self.subscriptionPath = [parameters objectForKey:@"basePath"][0]; } if ([parameters objectForKey:@"timerInterval"]) { NSString *timerIntervalMilliS = [parameters objectForKey:@"timerInterval"][0]; @@ -157,6 +161,7 @@ - (void)testOptions:(NSDictionary *)parameters { testOptions.teardown = YES; testOptions.basePath = self.basePath; testOptions.gdprPath = self.gdprPath; + testOptions.subscriptionPath = self.subscriptionPath; } if ([teardownOption isEqualToString:@"deleteState"]) { testOptions.deleteState = YES; @@ -174,6 +179,7 @@ - (void)testOptions:(NSDictionary *)parameters { testOptions.teardown = YES; testOptions.basePath = nil; testOptions.gdprPath = nil; + testOptions.subscriptionPath = nil; } if ([teardownOption isEqualToString:@"test"]) { self.savedConfigs = nil; @@ -181,6 +187,7 @@ - (void)testOptions:(NSDictionary *)parameters { self.adjustDelegate = nil; self.basePath = nil; self.gdprPath = nil; + self.subscriptionPath = nil; testOptions.timerIntervalInMilliseconds = [NSNumber numberWithInt:-1000]; testOptions.timerStartInMilliseconds = [NSNumber numberWithInt:-1000]; testOptions.sessionIntervalInMilliseconds = [NSNumber numberWithInt:-1000]; diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/ViewController.h b/AdjustTests/AdjustTestApp/AdjustTestApp/ViewController.h index 08e568f54..8dcedac10 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/ViewController.h +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/ViewController.h @@ -10,6 +10,7 @@ static NSString * baseUrl = @"http://127.0.0.1:8080"; static NSString * gdprUrl = @"http://127.0.0.1:8080"; +static NSString * subscriptionUrl = @"http://127.0.0.1:8080"; static NSString * controlUrl = @"ws://127.0.0.1:1987"; @interface ViewController : UIViewController diff --git a/examples/AdjustExample-FbPixel/AdjustExample-FbPixel.xcodeproj/project.pbxproj b/examples/AdjustExample-FbPixel/AdjustExample-FbPixel.xcodeproj/project.pbxproj index 18beec1e0..d3e84d6ae 100644 --- a/examples/AdjustExample-FbPixel/AdjustExample-FbPixel.xcodeproj/project.pbxproj +++ b/examples/AdjustExample-FbPixel/AdjustExample-FbPixel.xcodeproj/project.pbxproj @@ -46,6 +46,7 @@ 9D0F16CA2193F96F00F5140E /* ADJUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D0F169E2193F96F00F5140E /* ADJUserDefaults.m */; }; 9D0F16CC2193F96F00F5140E /* ADJActivityHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D0F16A42193F96F00F5140E /* ADJActivityHandler.m */; }; 9D0F16CD2193F96F00F5140E /* ADJReachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D0F16A52193F96F00F5140E /* ADJReachability.m */; }; + 9D2F241D2447DE5A00B7CA90 /* ADJSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D2F241B2447DE5A00B7CA90 /* ADJSubscription.m */; }; 9D9D1533212EB3920081445E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D9D1532212EB3920081445E /* AppDelegate.m */; }; 9D9D1539212EB3920081445E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9D9D1537212EB3920081445E /* Main.storyboard */; }; 9D9D153B212EB3940081445E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9D9D153A212EB3940081445E /* Assets.xcassets */; }; @@ -139,6 +140,8 @@ 9D0F16A32193F96F00F5140E /* ADJTimerCycle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJTimerCycle.h; sourceTree = ""; }; 9D0F16A42193F96F00F5140E /* ADJActivityHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJActivityHandler.m; sourceTree = ""; }; 9D0F16A52193F96F00F5140E /* ADJReachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJReachability.m; sourceTree = ""; }; + 9D2F241B2447DE5A00B7CA90 /* ADJSubscription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJSubscription.m; sourceTree = ""; }; + 9D2F241C2447DE5A00B7CA90 /* ADJSubscription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJSubscription.h; sourceTree = ""; }; 9D9D152E212EB3920081445E /* AdjustExample-FbPixel.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "AdjustExample-FbPixel.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 9D9D1531212EB3920081445E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 9D9D1532212EB3920081445E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -273,6 +276,8 @@ 9D0F16A32193F96F00F5140E /* ADJTimerCycle.h */, 9D0F16A42193F96F00F5140E /* ADJActivityHandler.m */, 9D0F16A52193F96F00F5140E /* ADJReachability.m */, + 9D2F241C2447DE5A00B7CA90 /* ADJSubscription.h */, + 9D2F241B2447DE5A00B7CA90 /* ADJSubscription.m */, ); name = Adjust; path = ../../../../Adjust; @@ -441,6 +446,7 @@ 9D0F16BE2193F96F00F5140E /* ADJPackageHandler.m in Sources */, 9D0F16B72193F96F00F5140E /* ADJSessionFailure.m in Sources */, 9D0F16C22193F96F00F5140E /* UIDevice+ADJAdditions.m in Sources */, + 9D2F241D2447DE5A00B7CA90 /* ADJSubscription.m in Sources */, 9D0F16B62193F96F00F5140E /* ADJActivityState.m in Sources */, 9D0F16CC2193F96F00F5140E /* ADJActivityHandler.m in Sources */, 9D0F16A72193F96F00F5140E /* WebViewJavascriptBridgeBase.m in Sources */, diff --git a/examples/AdjustExample-ObjC/AdjustExample-ObjC.xcodeproj/project.pbxproj b/examples/AdjustExample-ObjC/AdjustExample-ObjC.xcodeproj/project.pbxproj index 0543794db..1477a31bc 100644 --- a/examples/AdjustExample-ObjC/AdjustExample-ObjC.xcodeproj/project.pbxproj +++ b/examples/AdjustExample-ObjC/AdjustExample-ObjC.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 9639094F1BCBFCF300A2E8A4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9639094D1BCBFCF300A2E8A4 /* LaunchScreen.storyboard */; }; 9639095F1BCBFD3B00A2E8A4 /* iAd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9639095E1BCBFD3B00A2E8A4 /* iAd.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 963909611BCBFD4200A2E8A4 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 963909601BCBFD4200A2E8A4 /* AdSupport.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 9D2F240B2447DDE100B7CA90 /* ADJSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D2F240A2447DDE100B7CA90 /* ADJSubscription.m */; }; 9D449E131E6ED88F00E7E80B /* NSString+ADJAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449DD21E6ED88F00E7E80B /* NSString+ADJAdditions.m */; }; 9D449E141E6ED88F00E7E80B /* UIDevice+ADJAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449DD41E6ED88F00E7E80B /* UIDevice+ADJAdditions.m */; }; 9D449E151E6ED88F00E7E80B /* NSData+ADJAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449DD61E6ED88F00E7E80B /* NSData+ADJAdditions.m */; }; @@ -65,6 +66,8 @@ 9639095E1BCBFD3B00A2E8A4 /* iAd.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = iAd.framework; path = System/Library/Frameworks/iAd.framework; sourceTree = SDKROOT; }; 963909601BCBFD4200A2E8A4 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; 964E17FC1D50C6250097770B /* SafariServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SafariServices.framework; path = System/Library/Frameworks/SafariServices.framework; sourceTree = SDKROOT; }; + 9D2F24092447DDE100B7CA90 /* ADJSubscription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJSubscription.h; sourceTree = ""; }; + 9D2F240A2447DDE100B7CA90 /* ADJSubscription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJSubscription.m; sourceTree = ""; }; 9D449DD11E6ED88F00E7E80B /* NSString+ADJAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+ADJAdditions.h"; sourceTree = ""; }; 9D449DD21E6ED88F00E7E80B /* NSString+ADJAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+ADJAdditions.m"; sourceTree = ""; }; 9D449DD31E6ED88F00E7E80B /* UIDevice+ADJAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIDevice+ADJAdditions.h"; sourceTree = ""; }; @@ -271,6 +274,8 @@ 6FCC850A1F2794A300D6A0ED /* ADJReachability.m */, 9DD0E9BC1F457EF800B2A759 /* ADJUserDefaults.h */, 9DD0E9BD1F457EF800B2A759 /* ADJUserDefaults.m */, + 9D2F24092447DDE100B7CA90 /* ADJSubscription.h */, + 9D2F240A2447DDE100B7CA90 /* ADJSubscription.m */, ); name = Adjust; path = ../../../Adjust; @@ -369,6 +374,7 @@ 9D449E201E6ED88F00E7E80B /* ADJUtil.m in Sources */, 9D449E241E6ED88F00E7E80B /* ADJAttribution.m in Sources */, 9DC95F2A1C10515300138E4B /* Constants.m in Sources */, + 9D2F240B2447DDE100B7CA90 /* ADJSubscription.m in Sources */, 963909441BCBFCF300A2E8A4 /* AppDelegate.m in Sources */, 9D449E311E6ED88F00E7E80B /* ADJSessionParameters.m in Sources */, 9D449E171E6ED88F00E7E80B /* ADJActivityHandler.m in Sources */, diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/project.pbxproj b/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/project.pbxproj index 72daadca3..f7791b4e5 100644 --- a/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/project.pbxproj +++ b/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 6FCC850F1F2794C600D6A0ED /* ADJReachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FCC850E1F2794BE00D6A0ED /* ADJReachability.m */; }; + 9D2F240E2447DDF600B7CA90 /* ADJSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D2F240C2447DDF600B7CA90 /* ADJSubscription.m */; }; 9D449E761E6EDC3D00E7E80B /* ADJActivityHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449E351E6EDC3D00E7E80B /* ADJActivityHandler.m */; }; 9D449E771E6EDC3D00E7E80B /* ADJActivityKind.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449E371E6EDC3D00E7E80B /* ADJActivityKind.m */; }; 9D449E781E6EDC3D00E7E80B /* ADJActivityPackage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449E391E6EDC3D00E7E80B /* ADJActivityPackage.m */; }; @@ -52,6 +53,8 @@ /* Begin PBXFileReference section */ 6FCC850D1F2794BE00D6A0ED /* ADJReachability.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ADJReachability.h; sourceTree = ""; }; 6FCC850E1F2794BE00D6A0ED /* ADJReachability.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ADJReachability.m; sourceTree = ""; }; + 9D2F240C2447DDF600B7CA90 /* ADJSubscription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJSubscription.m; sourceTree = ""; }; + 9D2F240D2447DDF600B7CA90 /* ADJSubscription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJSubscription.h; sourceTree = ""; }; 9D319B9823054502000E28A6 /* AdjustExample-Swift.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "AdjustExample-Swift.entitlements"; sourceTree = ""; }; 9D449E341E6EDC3D00E7E80B /* ADJActivityHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJActivityHandler.h; sourceTree = ""; }; 9D449E351E6EDC3D00E7E80B /* ADJActivityHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJActivityHandler.m; sourceTree = ""; }; @@ -206,6 +209,8 @@ 6FCC850E1F2794BE00D6A0ED /* ADJReachability.m */, 9DD0E9BF1F45879A00B2A759 /* ADJUserDefaults.h */, 9DD0E9C01F45879A00B2A759 /* ADJUserDefaults.m */, + 9D2F240D2447DDF600B7CA90 /* ADJSubscription.h */, + 9D2F240C2447DDF600B7CA90 /* ADJSubscription.m */, ); name = Adjust; path = ../../../Adjust; @@ -365,6 +370,7 @@ 9D449E841E6EDC3D00E7E80B /* ADJEvent.m in Sources */, 9D449E951E6EDC3D00E7E80B /* ADJUtil.m in Sources */, 9D449E7C1E6EDC3D00E7E80B /* UIDevice+ADJAdditions.m in Sources */, + 9D2F240E2447DDF600B7CA90 /* ADJSubscription.m in Sources */, 9D449E851E6EDC3D00E7E80B /* ADJEventFailure.m in Sources */, 9D449E7B1E6EDC3D00E7E80B /* NSString+ADJAdditions.m in Sources */, 9D449E7D1E6EDC3D00E7E80B /* ADJAdjustFactory.m in Sources */, diff --git a/examples/AdjustExample-WebView/AdjustExample-WebView.xcodeproj/project.pbxproj b/examples/AdjustExample-WebView/AdjustExample-WebView.xcodeproj/project.pbxproj index ccd8d6ae0..09f61ce42 100644 --- a/examples/AdjustExample-WebView/AdjustExample-WebView.xcodeproj/project.pbxproj +++ b/examples/AdjustExample-WebView/AdjustExample-WebView.xcodeproj/project.pbxproj @@ -20,6 +20,7 @@ 9D10833F1CFDDBF50050568B /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9D10833E1CFDDBF50050568B /* Default-568h@2x.png */; }; 9D1083411CFDE2470050568B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D1083401CFDE2470050568B /* UIKit.framework */; }; 9D1083431CFDE29A0050568B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D1083421CFDE29A0050568B /* Foundation.framework */; }; + 9D2F24112447DE0A00B7CA90 /* ADJSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D2F24102447DE0A00B7CA90 /* ADJSubscription.m */; }; 9D449EDA1E6EDD4100E7E80B /* ADJActivityHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449E991E6EDD4100E7E80B /* ADJActivityHandler.m */; }; 9D449EDB1E6EDD4100E7E80B /* ADJActivityKind.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449E9B1E6EDD4100E7E80B /* ADJActivityKind.m */; }; 9D449EDC1E6EDD4100E7E80B /* ADJActivityPackage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449E9D1E6EDD4100E7E80B /* ADJActivityPackage.m */; }; @@ -78,6 +79,8 @@ 9D10833E1CFDDBF50050568B /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 9D1083401CFDE2470050568B /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 9D1083421CFDE29A0050568B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 9D2F240F2447DE0A00B7CA90 /* ADJSubscription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJSubscription.h; sourceTree = ""; }; + 9D2F24102447DE0A00B7CA90 /* ADJSubscription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJSubscription.m; sourceTree = ""; }; 9D449E981E6EDD4100E7E80B /* ADJActivityHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJActivityHandler.h; sourceTree = ""; }; 9D449E991E6EDD4100E7E80B /* ADJActivityHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJActivityHandler.m; sourceTree = ""; }; 9D449E9A1E6EDD4100E7E80B /* ADJActivityKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJActivityKind.h; sourceTree = ""; }; @@ -293,6 +296,8 @@ 6FCC85111F2794D600D6A0ED /* ADJReachability.m */, 9DD0E9C21F4587C600B2A759 /* ADJUserDefaults.h */, 9DD0E9C31F4587C600B2A759 /* ADJUserDefaults.m */, + 9D2F240F2447DE0A00B7CA90 /* ADJSubscription.h */, + 9D2F24102447DE0A00B7CA90 /* ADJSubscription.m */, ); name = Adjust; path = ../../../Adjust; @@ -448,6 +453,7 @@ 9D449EF01E6EDD4100E7E80B /* ADJResponseData.m in Sources */, 9D1082A91CFDAF8E0050568B /* main.m in Sources */, 9D449EF91E6EDD4100E7E80B /* ADJUtil.m in Sources */, + 9D2F24112447DE0A00B7CA90 /* ADJSubscription.m in Sources */, 9D449EEE1E6EDD4100E7E80B /* ADJPackageHandler.m in Sources */, 9D449EE91E6EDD4100E7E80B /* ADJEventFailure.m in Sources */, 9D449EF41E6EDD4100E7E80B /* ADJSessionSuccess.m in Sources */, diff --git a/examples/AdjustExample-iMessage/AdjustExample-iMessage.xcodeproj/project.pbxproj b/examples/AdjustExample-iMessage/AdjustExample-iMessage.xcodeproj/project.pbxproj index 6c88f2ed5..14d923840 100644 --- a/examples/AdjustExample-iMessage/AdjustExample-iMessage.xcodeproj/project.pbxproj +++ b/examples/AdjustExample-iMessage/AdjustExample-iMessage.xcodeproj/project.pbxproj @@ -46,6 +46,7 @@ 9D01687420FF88F60029CFFF /* ADJUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D01684E20FF88F60029CFFF /* ADJUserDefaults.m */; }; 9D01687620FF88F60029CFFF /* ADJActivityHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D01685420FF88F60029CFFF /* ADJActivityHandler.m */; }; 9D01687720FF88F60029CFFF /* ADJReachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D01685520FF88F60029CFFF /* ADJReachability.m */; }; + 9D2F241A2447DE4700B7CA90 /* ADJSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D2F24192447DE4700B7CA90 /* ADJSubscription.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -149,6 +150,8 @@ 9D01685320FF88F60029CFFF /* ADJTimerCycle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJTimerCycle.h; sourceTree = ""; }; 9D01685420FF88F60029CFFF /* ADJActivityHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJActivityHandler.m; sourceTree = ""; }; 9D01685520FF88F60029CFFF /* ADJReachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJReachability.m; sourceTree = ""; }; + 9D2F24182447DE4700B7CA90 /* ADJSubscription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJSubscription.h; sourceTree = ""; }; + 9D2F24192447DE4700B7CA90 /* ADJSubscription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJSubscription.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -276,6 +279,8 @@ 9D01685320FF88F60029CFFF /* ADJTimerCycle.h */, 9D01685420FF88F60029CFFF /* ADJActivityHandler.m */, 9D01685520FF88F60029CFFF /* ADJReachability.m */, + 9D2F24182447DE4700B7CA90 /* ADJSubscription.h */, + 9D2F24192447DE4700B7CA90 /* ADJSubscription.m */, ); name = Adjust; path = ../../../Adjust; @@ -423,6 +428,7 @@ 9D01686B20FF88F60029CFFF /* NSData+ADJAdditions.m in Sources */, 9D01685C20FF88F60029CFFF /* ADJEvent.m in Sources */, 9D01687320FF88F60029CFFF /* ADJPackageBuilder.m in Sources */, + 9D2F241A2447DE4700B7CA90 /* ADJSubscription.m in Sources */, 9D01685620FF88F60029CFFF /* ADJDeviceInfo.m in Sources */, 9D01686620FF88F60029CFFF /* Adjust.m in Sources */, 9D01685D20FF88F60029CFFF /* ADJSessionSuccess.m in Sources */, diff --git a/examples/AdjustExample-iWatch/AdjustExample-iWatch.xcodeproj/project.pbxproj b/examples/AdjustExample-iWatch/AdjustExample-iWatch.xcodeproj/project.pbxproj index c09d332ec..9a61fa748 100644 --- a/examples/AdjustExample-iWatch/AdjustExample-iWatch.xcodeproj/project.pbxproj +++ b/examples/AdjustExample-iWatch/AdjustExample-iWatch.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 6FCC85181F27950000D6A0ED /* ADJReachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FCC85171F2794F800D6A0ED /* ADJReachability.m */; }; + 9D2F24172447DE3400B7CA90 /* ADJSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D2F24152447DE3400B7CA90 /* ADJSubscription.m */; }; 9D449FA31E6EE72000E7E80B /* ADJActivityHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449F621E6EE72000E7E80B /* ADJActivityHandler.m */; }; 9D449FA41E6EE72000E7E80B /* ADJActivityKind.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449F641E6EE72000E7E80B /* ADJActivityKind.m */; }; 9D449FA51E6EE72000E7E80B /* ADJActivityPackage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449F661E6EE72000E7E80B /* ADJActivityPackage.m */; }; @@ -107,6 +108,8 @@ /* Begin PBXFileReference section */ 6FCC85161F2794F800D6A0ED /* ADJReachability.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ADJReachability.h; sourceTree = ""; }; 6FCC85171F2794F800D6A0ED /* ADJReachability.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ADJReachability.m; sourceTree = ""; }; + 9D2F24152447DE3400B7CA90 /* ADJSubscription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJSubscription.m; sourceTree = ""; }; + 9D2F24162447DE3400B7CA90 /* ADJSubscription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJSubscription.h; sourceTree = ""; }; 9D449F611E6EE72000E7E80B /* ADJActivityHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJActivityHandler.h; sourceTree = ""; }; 9D449F621E6EE72000E7E80B /* ADJActivityHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJActivityHandler.m; sourceTree = ""; }; 9D449F631E6EE72000E7E80B /* ADJActivityKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJActivityKind.h; sourceTree = ""; }; @@ -290,6 +293,8 @@ 6FCC85171F2794F800D6A0ED /* ADJReachability.m */, 9DD0E9C51F45949600B2A759 /* ADJUserDefaults.h */, 9DD0E9C61F45949600B2A759 /* ADJUserDefaults.m */, + 9D2F24162447DE3400B7CA90 /* ADJSubscription.h */, + 9D2F24152447DE3400B7CA90 /* ADJSubscription.m */, ); name = Adjust; path = ../../../Adjust; @@ -555,6 +560,7 @@ 9DF7AC191CB4FEDB00D3591F /* main.m in Sources */, 9D449FB41E6EE72000E7E80B /* ADJKeychain.m in Sources */, 9D449FA91E6EE72000E7E80B /* UIDevice+ADJAdditions.m in Sources */, + 9D2F24172447DE3400B7CA90 /* ADJSubscription.m in Sources */, 9D449FBE1E6EE72000E7E80B /* ADJSystemProfile.m in Sources */, 9D449FAD1E6EE72000E7E80B /* ADJBackoffStrategy.m in Sources */, 9D449FBC1E6EE72000E7E80B /* ADJSessionParameters.m in Sources */, diff --git a/examples/AdjustExample-tvOS/AdjustExample-tvOS.xcodeproj/project.pbxproj b/examples/AdjustExample-tvOS/AdjustExample-tvOS.xcodeproj/project.pbxproj index 007a76f48..6972902d0 100644 --- a/examples/AdjustExample-tvOS/AdjustExample-tvOS.xcodeproj/project.pbxproj +++ b/examples/AdjustExample-tvOS/AdjustExample-tvOS.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ 963909C01BCC0D8300A2E8A4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 963909BE1BCC0D8300A2E8A4 /* Main.storyboard */; }; 963909C21BCC0D8300A2E8A4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 963909C11BCC0D8300A2E8A4 /* Assets.xcassets */; }; 963909D01BCC0DA600A2E8A4 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 963909CF1BCC0DA600A2E8A4 /* AdSupport.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 9D2F24142447DE1F00B7CA90 /* ADJSubscription.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D2F24122447DE1E00B7CA90 /* ADJSubscription.m */; }; 9D449F3F1E6EE6C500E7E80B /* ADJActivityHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449EFE1E6EE6C500E7E80B /* ADJActivityHandler.m */; }; 9D449F401E6EE6C500E7E80B /* ADJActivityKind.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449F001E6EE6C500E7E80B /* ADJActivityKind.m */; }; 9D449F411E6EE6C500E7E80B /* ADJActivityPackage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D449F021E6EE6C500E7E80B /* ADJActivityPackage.m */; }; @@ -75,6 +76,8 @@ 963909C11BCC0D8300A2E8A4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 963909C31BCC0D8300A2E8A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 963909CF1BCC0DA600A2E8A4 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; + 9D2F24122447DE1E00B7CA90 /* ADJSubscription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJSubscription.m; sourceTree = ""; }; + 9D2F24132447DE1F00B7CA90 /* ADJSubscription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJSubscription.h; sourceTree = ""; }; 9D449EFD1E6EE6C400E7E80B /* ADJActivityHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJActivityHandler.h; sourceTree = ""; }; 9D449EFE1E6EE6C500E7E80B /* ADJActivityHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJActivityHandler.m; sourceTree = ""; }; 9D449EFF1E6EE6C500E7E80B /* ADJActivityKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJActivityKind.h; sourceTree = ""; }; @@ -262,6 +265,8 @@ 6FCC85131F2794E800D6A0ED /* ADJReachability.m */, 9DD0E9CD1F459ECE00B2A759 /* ADJUserDefaults.h */, 9DD0E9CE1F459ECE00B2A759 /* ADJUserDefaults.m */, + 9D2F24132447DE1F00B7CA90 /* ADJSubscription.h */, + 9D2F24122447DE1E00B7CA90 /* ADJSubscription.m */, ); name = Adjust; path = ../../../Adjust; @@ -371,6 +376,7 @@ 9D449F4F1E6EE6C500E7E80B /* ADJEventSuccess.m in Sources */, 9D449F5B1E6EE6C500E7E80B /* ADJTimerCycle.m in Sources */, 9D449F471E6EE6C500E7E80B /* ADJAttribution.m in Sources */, + 9D2F24142447DE1F00B7CA90 /* ADJSubscription.m in Sources */, 9D449F421E6EE6C500E7E80B /* ADJActivityState.m in Sources */, 9DC95F2F1C10596500138E4B /* Constants.m in Sources */, 963909BD1BCC0D8300A2E8A4 /* ViewControllertvOS.m in Sources */, From 8ec63c72171f1d5f7acb3bfe841470857d80bc0b Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 16 Apr 2020 03:02:12 +0200 Subject: [PATCH 051/173] Use subscription activity kind for package --- Adjust/ADJPackageBuilder.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index 6c67236be..cb96619b8 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -168,7 +168,7 @@ - (ADJActivityPackage *)buildSubscriptionPackage:(ADJSubscription *)subscription NSMutableDictionary *parameters = [self getSubscriptionParameters:isInDelay forSubscriptionPackage:subscription]; ADJActivityPackage *subscriptionPackage = [self defaultActivityPackage]; subscriptionPackage.path = @"/v2/purchase"; - subscriptionPackage.activityKind = ADJActivityKindEvent; + subscriptionPackage.activityKind = ADJActivityKindSubscription; subscriptionPackage.suffix = @""; subscriptionPackage.parameters = parameters; From 43c8f2ae6ad282864c27d970979b03bd2ff7c5de Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 16 Apr 2020 03:03:29 +0200 Subject: [PATCH 052/173] Fix activity kind for subscription package in request handler --- Adjust/ADJRequestHandler.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adjust/ADJRequestHandler.m b/Adjust/ADJRequestHandler.m index 260c7b466..dfa56fa5a 100644 --- a/Adjust/ADJRequestHandler.m +++ b/Adjust/ADJRequestHandler.m @@ -92,7 +92,7 @@ - (void)sendI:(ADJRequestHandler *)selfI activityPackage:(ADJActivityPackage *)a } else { url = [NSURL URLWithString:gdprUrl]; } - } else if (activityPackage.activityKind == ADJActivityKindGdpr) { + } else if (activityPackage.activityKind == ADJActivityKindSubscription) { NSString *subscriptionUrl = [ADJAdjustFactory subscriptionUrl]; if (selfI.subscriptionPath != nil) { url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", subscriptionUrl, selfI.subscriptionPath]]; From 464c993079429fa647c02821b45e635e2a29e19e Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 16 Apr 2020 03:09:16 +0200 Subject: [PATCH 053/173] Track subscription in example app --- .../AdjustExample-ObjC/ViewControllerObjC.m | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m b/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m index 938f4778f..57e1d6a74 100644 --- a/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m +++ b/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m @@ -35,12 +35,18 @@ - (void)didReceiveMemoryWarning { } - (IBAction)clickTrackSimpleEvent:(UIButton *)sender { - ADJEvent *event = [ADJEvent eventWithEventToken:kEventToken1]; - - // Attach callback ID to event. - [event setCallbackId:@"RandomCallbackId"]; - - [Adjust trackEvent:event]; + ADJSubscription *subscription = [[ADJSubscription alloc] + initWithRevenue:6.66 + currency:@"CAD" + transactionDate:1234567890 + transactionId:@"random-transaction-id" + andReceipt:[@"random-receipt" dataUsingEncoding:NSUTF8StringEncoding]]; + [subscription addCallbackParameter:@"foo" value:@"bar"]; + [subscription addCallbackParameter:@"key" value:@"value"]; + [subscription addPartnerParameter:@"foo" value:@"bar"]; + [subscription addPartnerParameter:@"key" value:@"value"]; + + [Adjust trackSubscription:subscription]; } - (IBAction)clickTrackRevenueEvent:(UIButton *)sender { From 2049e13da921e12f8270edb3d58b949c5ad87a3b Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 21 Apr 2020 11:10:07 +0200 Subject: [PATCH 054/173] Set subscription endpoint URL --- Adjust/ADJAdjustFactory.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Adjust/ADJAdjustFactory.m b/Adjust/ADJAdjustFactory.m index e58e0f0f2..c14c248c7 100644 --- a/Adjust/ADJAdjustFactory.m +++ b/Adjust/ADJAdjustFactory.m @@ -30,8 +30,8 @@ static NSString * internalBaseUrl = @"https://app.adjust.com"; static NSString * const kGdprUrl = @"https://gdpr.adjust.com"; static NSString * internalGdprUrl = @"https://gdpr.adjust.com"; -static NSString * const kSubscriptionUrl = @"https://staging-api-sub.adjust.com"; -static NSString * internalSubscriptionUrl = @"https://staging-api-sub.adjust.com"; +static NSString * const kSubscriptionUrl = @"https://subscription.adjust.com"; +static NSString * internalSubscriptionUrl = @"https://subscription.adjust.com"; @implementation ADJAdjustFactory From 84a93ae8cbab99f7623f6758ecf6273e3f4b0aaf Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 22 Apr 2020 15:55:57 +0200 Subject: [PATCH 055/173] Synchronise public API methods access --- .../AdjustExample-ObjC/ViewControllerObjC.m | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m b/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m index 57e1d6a74..ac3a27650 100644 --- a/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m +++ b/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m @@ -50,12 +50,27 @@ - (IBAction)clickTrackSimpleEvent:(UIButton *)sender { } - (IBAction)clickTrackRevenueEvent:(UIButton *)sender { - ADJEvent *event = [ADJEvent eventWithEventToken:kEventToken2]; - - // Add revenue 1 cent of an EURO. - [event setRevenue:0.01 currency:@"EUR"]; - - [Adjust trackEvent:event]; + NSURL __block *url = [NSURL URLWithString:@"random-url"]; +// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ +// // Add revenue 1 cent of an EURO. +// for (int i = 0; i < 30000; i += 1) { +// [event setRevenue:i currency:@"EUR"]; +// [event setCallbackId:[NSString stringWithFormat:@"%@%d", @"random-id", i]]; +// [event addCallbackParameter:@"foo" value:[NSString stringWithFormat:@"%@%d", @"bar", i]]; +// [event addCallbackParameter:@"key" value:[NSString stringWithFormat:@"%@%d", @"value", i]]; +// } +// }); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + for (int i = 0; i < 300; i += 1) { + [Adjust appWillOpenUrl:[NSURL URLWithString:[NSString stringWithFormat:@"random-url-%d", i]]]; + } + }); +// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ +// // Add revenue 1 cent of an EURO. +// for (int i = 30000; i < 60000; i += 1) { +// url = [NSURL URLWithString:[NSString stringWithFormat:@"random-url-%d", i]]; +// } +// }); } - (IBAction)clickTrackCallbackEvent:(UIButton *)sender { From d3ea191b5897af81b336683b5a727691e365090e Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 23 Apr 2020 02:38:15 +0200 Subject: [PATCH 056/173] Synchronise trackSubscription: method --- Adjust/Adjust.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Adjust/Adjust.m b/Adjust/Adjust.m index 836836f96..873afa13d 100644 --- a/Adjust/Adjust.m +++ b/Adjust/Adjust.m @@ -228,7 +228,9 @@ + (void)disableThirdPartySharing { } + (void)trackSubscription:(nonnull ADJSubscription *)subscription { - [[Adjust getInstance] trackSubscription:subscription]; + @synchronized (self) { + [[Adjust getInstance] trackSubscription:subscription]; + } } + (ADJAttribution *)attribution { From 8fd4ea8ef97f4526016d49bc8c7f6d26157f01c7 Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 23 Apr 2020 11:55:41 +0200 Subject: [PATCH 057/173] Reinitialise internalSubscriptionUrl in teardown method --- Adjust/ADJAdjustFactory.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Adjust/ADJAdjustFactory.m b/Adjust/ADJAdjustFactory.m index c14c248c7..70ad0b4d2 100644 --- a/Adjust/ADJAdjustFactory.m +++ b/Adjust/ADJAdjustFactory.m @@ -298,7 +298,7 @@ + (void)teardown:(BOOL)deleteState { internalAttributionHandler = nil; internalSdkClickHandler = nil; - internalSessionInterval = -1; + internalSessionInterval = -1; intervalSubsessionInterval = -1; internalTimerInterval = -1; intervalTimerStart = -1; @@ -308,6 +308,7 @@ + (void)teardown:(BOOL)deleteState { internalMaxDelayStart = -1; internalBaseUrl = kBaseUrl; internalGdprUrl = kGdprUrl; + internalSubscriptionUrl = kSubscriptionUrl; internaliAdFrameworkEnabled = YES; } @end From 8921382855fff32f576f6d7f9542d2d7a7c0e2d6 Mon Sep 17 00:00:00 2001 From: nonelse Date: Thu, 23 Apr 2020 14:50:30 +0200 Subject: [PATCH 058/173] Refac subscription --- Adjust/ADJSubscription.h | 4 ---- Adjust/ADJSubscription.m | 28 ++++++++++++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Adjust/ADJSubscription.h b/Adjust/ADJSubscription.h index 0e7eea10d..2725f6225 100644 --- a/Adjust/ADJSubscription.h +++ b/Adjust/ADJSubscription.h @@ -8,8 +8,6 @@ #import -NS_ASSUME_NONNULL_BEGIN - @interface ADJSubscription : NSObject @property (nonatomic, copy, readonly, nonnull) NSNumber *revenue; @@ -39,5 +37,3 @@ NS_ASSUME_NONNULL_BEGIN - (void)addPartnerParameter:(nonnull NSString *)key value:(nonnull NSString *)value; @end - -NS_ASSUME_NONNULL_END diff --git a/Adjust/ADJSubscription.m b/Adjust/ADJSubscription.m index 42e01f754..1b57da5b8 100644 --- a/Adjust/ADJSubscription.m +++ b/Adjust/ADJSubscription.m @@ -33,13 +33,13 @@ - (nullable id)initWithRevenue:(double)revenue } _revenue = [NSNumber numberWithDouble:revenue]; - _currency = currency; + _currency = [currency copy]; _transactionDate = [NSNumber numberWithDouble:transactionDate]; - _transactionId = transactionId; - _receipt = receipt; + _transactionId = [transactionId copy]; + _receipt = [receipt copy]; _billingStore = @"iOS"; - self.logger = ADJAdjustFactory.logger; + _logger = ADJAdjustFactory.logger; if (![self isValid]) { return nil; @@ -48,7 +48,9 @@ - (nullable id)initWithRevenue:(double)revenue return self; } -- (void)addCallbackParameter:(NSString *)key value:(NSString *)value { +- (void)addCallbackParameter:(nonnull NSString *)key + value:(nonnull NSString *)value +{ if (![ADJUtil isValidParameter:key attributeType:@"key" parameterName:@"Callback"]) { @@ -71,7 +73,9 @@ - (void)addCallbackParameter:(NSString *)key value:(NSString *)value { [self.mutableCallbackParameters setObject:value forKey:key]; } -- (void)addPartnerParameter:(NSString *)key value:(NSString *)value { +- (void)addPartnerParameter:(nonnull NSString *)key + value:(nonnull NSString *)value +{ if (![ADJUtil isValidParameter:key attributeType:@"key" parameterName:@"Partner"]) { @@ -95,22 +99,22 @@ - (void)addPartnerParameter:(NSString *)key value:(NSString *)value { } - (BOOL)isValid { - if (_revenue == nil) { + if (self.revenue == nil) { return NO; } - if (_currency == nil) { + if (self.currency == nil) { return NO; } - if (_transactionDate == nil) { + if (self.transactionDate == nil) { return NO; } - if (_transactionId == nil) { + if (self.transactionId == nil) { return NO; } - if (_receipt == nil) { + if (self.receipt == nil) { return NO; } - if (_billingStore == nil) { + if (self.billingStore == nil) { return NO; } From 8c6ecff470ed6aa67af0d12921a3872308fb6de8 Mon Sep 17 00:00:00 2001 From: nonelse Date: Thu, 23 Apr 2020 14:50:57 +0200 Subject: [PATCH 059/173] Link read-only subscription parameters with mutable --- Adjust/ADJSubscription.h | 4 ++-- Adjust/ADJSubscription.m | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Adjust/ADJSubscription.h b/Adjust/ADJSubscription.h index 2725f6225..7ff580ac9 100644 --- a/Adjust/ADJSubscription.h +++ b/Adjust/ADJSubscription.h @@ -22,9 +22,9 @@ @property (nonatomic, copy, readonly, nonnull) NSString *billingStore; -@property (nonatomic, readonly, nonnull) NSDictionary *partnerParameters; +@property (nonatomic, copy, readonly, nonnull) NSDictionary *partnerParameters; -@property (nonatomic, readonly, nonnull) NSDictionary *callbackParameters; +@property (nonatomic, copy, readonly, nonnull) NSDictionary *callbackParameters; - (nullable id)initWithRevenue:(double)revenue currency:(nonnull NSString *)currency diff --git a/Adjust/ADJSubscription.m b/Adjust/ADJSubscription.m index 1b57da5b8..59fb160e8 100644 --- a/Adjust/ADJSubscription.m +++ b/Adjust/ADJSubscription.m @@ -121,6 +121,14 @@ - (BOOL)isValid { return YES; } +- (nonnull NSDictionary *)callbackParameters { + return [self.mutableCallbackParameters copy]; +} + +- (nonnull NSDictionary *)partnerParameters { + return [self.mutablePartnerParameters copy]; +} + - (id)copyWithZone:(NSZone *)zone { ADJSubscription *copy = [[[self class] allocWithZone:zone] init]; if (copy) { From d3d3ea3a5c04865ae04f18656500c4129e962146 Mon Sep 17 00:00:00 2001 From: nonelse Date: Thu, 23 Apr 2020 14:51:40 +0200 Subject: [PATCH 060/173] Add syncronized to subscription parameters --- Adjust/ADJSubscription.m | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/Adjust/ADJSubscription.m b/Adjust/ADJSubscription.m index 59fb160e8..fe5820dfb 100644 --- a/Adjust/ADJSubscription.m +++ b/Adjust/ADJSubscription.m @@ -62,15 +62,17 @@ - (void)addCallbackParameter:(nonnull NSString *)key return; } - if (self.mutableCallbackParameters == nil) { - self.mutableCallbackParameters = [[NSMutableDictionary alloc] init]; - } + @synchronized (self) { + if (self.mutableCallbackParameters == nil) { + self.mutableCallbackParameters = [[NSMutableDictionary alloc] init]; + } - if ([self.mutableCallbackParameters objectForKey:key]) { - [self.logger warn:@"key %@ was overwritten", key]; - } + if ([self.mutableCallbackParameters objectForKey:key]) { + [self.logger warn:@"key %@ was overwritten", key]; + } - [self.mutableCallbackParameters setObject:value forKey:key]; + [self.mutableCallbackParameters setObject:value forKey:key]; + } } - (void)addPartnerParameter:(nonnull NSString *)key @@ -87,15 +89,17 @@ - (void)addPartnerParameter:(nonnull NSString *)key return; } - if (self.mutablePartnerParameters == nil) { - self.mutablePartnerParameters = [[NSMutableDictionary alloc] init]; - } + @synchronized (self) { + if (self.mutablePartnerParameters == nil) { + self.mutablePartnerParameters = [[NSMutableDictionary alloc] init]; + } - if ([self.mutablePartnerParameters objectForKey:key]) { - [self.logger warn:@"key %@ was overwritten", key]; - } + if ([self.mutablePartnerParameters objectForKey:key]) { + [self.logger warn:@"key %@ was overwritten", key]; + } - [self.mutablePartnerParameters setObject:value forKey:key]; + [self.mutablePartnerParameters setObject:value forKey:key]; + } } - (BOOL)isValid { From 95877842e01aab175951c2c37a2c19daf9f7153a Mon Sep 17 00:00:00 2001 From: nonelse Date: Thu, 23 Apr 2020 17:11:14 +0200 Subject: [PATCH 061/173] Fix typo --- Adjust/ADJRequestHandler.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adjust/ADJRequestHandler.m b/Adjust/ADJRequestHandler.m index dfa56fa5a..ec2fb6eb1 100644 --- a/Adjust/ADJRequestHandler.m +++ b/Adjust/ADJRequestHandler.m @@ -58,7 +58,7 @@ - (id)initWithPackageHandler:(id)packageHandler self.logger = ADJAdjustFactory.logger; self.basePath = [packageHandler getBasePath]; self.gdprPath = [packageHandler getGdprPath]; - self.gdprPath = [packageHandler getSubscriptionPath]; + self.subscriptionPath = [packageHandler getSubscriptionPath]; return self; } From cc7ea43485fdbdc7fd11250dda600c856c560367 Mon Sep 17 00:00:00 2001 From: nonelse Date: Thu, 23 Apr 2020 17:11:41 +0200 Subject: [PATCH 062/173] Add subscription test handling --- .../AdjustTestApp/ATAAdjustCommandExecutor.m | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m b/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m index c43b14b45..40a7d531f 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m @@ -95,7 +95,9 @@ - (void)executeCommand:(NSString *)className [self trackAdRevenue:parameters]; } else if ([methodName isEqualToString:@"disableThirdPartySharing"]) { [self disableThirdPartySharing:parameters]; - } + } else if ([methodName isEqualToString:@"trackSubscription"]) { + [self trackSubscription:parameters]; + } } - (void)testOptions:(NSDictionary *)parameters { @@ -548,4 +550,57 @@ - (void)disableThirdPartySharing:(NSDictionary *)parameters { [Adjust disableThirdPartySharing]; } +- (void)trackSubscription:(NSDictionary *)parameters { + double revenue = 0; + NSString *currency; + double transactionDate = 0; + NSString *transactionId; + NSData *receipt; + + if ([parameters objectForKey:@"revenue"]) { + revenue = [[parameters objectForKey:@"revenue"][0] doubleValue]; + } + if ([parameters objectForKey:@"currency"]) { + currency = [parameters objectForKey:@"currency"][0]; + } + if ([parameters objectForKey:@"transactionDate"]) { + transactionDate = [[parameters objectForKey:@"transactionDate"][0] doubleValue]; + } + if ([parameters objectForKey:@"transactionId"]) { + transactionId = [parameters objectForKey:@"transactionId"][0]; + } + if ([parameters objectForKey:@"receipt"]) { + NSString *receiptString = [parameters objectForKey:@"receipt"][0]; + receipt = [receiptString dataUsingEncoding:NSUTF8StringEncoding]; + } + + ADJSubscription *subscription = + [[ADJSubscription alloc] + initWithRevenue:revenue + currency:currency + transactionDate:transactionDate + transactionId:transactionId + andReceipt:receipt]; + + if ([parameters objectForKey:@"callbackParams"]) { + NSArray *callbackParams = [parameters objectForKey:@"callbackParams"]; + for (int i = 0; i < callbackParams.count; i = i + 2) { + NSString *key = callbackParams[i]; + NSString *value = callbackParams[i + 1]; + [subscription addCallbackParameter:key value:value]; + } + } + + if ([parameters objectForKey:@"partnerParams"]) { + NSArray *partnerParams = [parameters objectForKey:@"partnerParams"]; + for (int i = 0; i < partnerParams.count; i = i + 2) { + NSString *key = partnerParams[i]; + NSString *value = partnerParams[i + 1]; + [subscription addPartnerParameter:key value:value]; + } + } + + [Adjust trackSubscription:subscription]; +} + @end From 08fd2d5670970584d07fe09b8d48fb6b2b5d8146 Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 28 Apr 2020 01:39:51 +0200 Subject: [PATCH 063/173] Clean up examlple Obj-C app --- .../AdjustExample-ObjC/ViewControllerObjC.m | 42 ++++--------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m b/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m index ac3a27650..80d0025ff 100644 --- a/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m +++ b/examples/AdjustExample-ObjC/AdjustExample-ObjC/ViewControllerObjC.m @@ -35,42 +35,18 @@ - (void)didReceiveMemoryWarning { } - (IBAction)clickTrackSimpleEvent:(UIButton *)sender { - ADJSubscription *subscription = [[ADJSubscription alloc] - initWithRevenue:6.66 - currency:@"CAD" - transactionDate:1234567890 - transactionId:@"random-transaction-id" - andReceipt:[@"random-receipt" dataUsingEncoding:NSUTF8StringEncoding]]; - [subscription addCallbackParameter:@"foo" value:@"bar"]; - [subscription addCallbackParameter:@"key" value:@"value"]; - [subscription addPartnerParameter:@"foo" value:@"bar"]; - [subscription addPartnerParameter:@"key" value:@"value"]; - - [Adjust trackSubscription:subscription]; + ADJEvent *event = [ADJEvent eventWithEventToken:kEventToken1]; + + [Adjust trackEvent:event]; } - (IBAction)clickTrackRevenueEvent:(UIButton *)sender { - NSURL __block *url = [NSURL URLWithString:@"random-url"]; -// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ -// // Add revenue 1 cent of an EURO. -// for (int i = 0; i < 30000; i += 1) { -// [event setRevenue:i currency:@"EUR"]; -// [event setCallbackId:[NSString stringWithFormat:@"%@%d", @"random-id", i]]; -// [event addCallbackParameter:@"foo" value:[NSString stringWithFormat:@"%@%d", @"bar", i]]; -// [event addCallbackParameter:@"key" value:[NSString stringWithFormat:@"%@%d", @"value", i]]; -// } -// }); - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - for (int i = 0; i < 300; i += 1) { - [Adjust appWillOpenUrl:[NSURL URLWithString:[NSString stringWithFormat:@"random-url-%d", i]]]; - } - }); -// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ -// // Add revenue 1 cent of an EURO. -// for (int i = 30000; i < 60000; i += 1) { -// url = [NSURL URLWithString:[NSString stringWithFormat:@"random-url-%d", i]]; -// } -// }); + ADJEvent *event = [ADJEvent eventWithEventToken:kEventToken2]; + + // Add revenue 1 cent of an EURO. + [event setRevenue:0.01 currency:@"EUR"]; + + [Adjust trackEvent:event]; } - (IBAction)clickTrackCallbackEvent:(UIButton *)sender { From 0d32df2ee1ed1f604b8ecc2ddbb1e83ab842c2d0 Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 28 Apr 2020 01:41:34 +0200 Subject: [PATCH 064/173] Change price (double->NSDecimalNumber) and transactionDate (double->NSDate) type --- Adjust/ADJPackageBuilder.m | 4 +- Adjust/ADJSubscription.h | 14 ++--- Adjust/ADJSubscription.m | 62 +++++++++---------- .../AdjustTestApp/ATAAdjustCommandExecutor.m | 20 +++--- .../AdjustTestApp/ViewController.m | 2 +- 5 files changed, 50 insertions(+), 52 deletions(-) diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index cb96619b8..2a40b3644 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -808,9 +808,9 @@ - (NSMutableDictionary *)getSubscriptionParameters:(BOOL)isInDelay forSubscripti [ADJPackageBuilder parameters:parameters setDictionary:mergedPartnerParameters forKey:@"partner_params"]; } - [ADJPackageBuilder parameters:parameters setNumber:subscription.revenue forKey:@"revenue"]; + [ADJPackageBuilder parameters:parameters setNumber:subscription.price forKey:@"revenue"]; [ADJPackageBuilder parameters:parameters setString:subscription.currency forKey:@"currency"]; - [ADJPackageBuilder parameters:parameters setDate1970:[subscription.transactionDate doubleValue] forKey:@"transaction_date"]; + [ADJPackageBuilder parameters:parameters setDate:subscription.transactionDate forKey:@"transaction_date"]; [ADJPackageBuilder parameters:parameters setString:subscription.transactionId forKey:@"transaction_id"]; [ADJPackageBuilder parameters:parameters setString:[subscription.receipt adjEncodeBase64] forKey:@"receipt"]; [ADJPackageBuilder parameters:parameters setString:subscription.billingStore forKey:@"billing_store"]; diff --git a/Adjust/ADJSubscription.h b/Adjust/ADJSubscription.h index 7ff580ac9..0409cb508 100644 --- a/Adjust/ADJSubscription.h +++ b/Adjust/ADJSubscription.h @@ -10,11 +10,11 @@ @interface ADJSubscription : NSObject -@property (nonatomic, copy, readonly, nonnull) NSNumber *revenue; +@property (nonatomic, copy, readonly, nonnull) NSDecimalNumber *price; @property (nonatomic, copy, readonly, nonnull) NSString *currency; -@property (nonatomic, copy, readonly, nonnull) NSNumber *transactionDate; +@property (nonatomic, copy, readonly, nonnull) NSDate *transactionDate; @property (nonatomic, copy, readonly, nonnull) NSString *transactionId; @@ -26,11 +26,11 @@ @property (nonatomic, copy, readonly, nonnull) NSDictionary *callbackParameters; -- (nullable id)initWithRevenue:(double)revenue - currency:(nonnull NSString *)currency - transactionDate:(double)transactionDate - transactionId:(nonnull NSString *)transactionId - andReceipt:(nonnull NSData *)receipt; +- (nullable id)initWithPrice:(nonnull NSDecimalNumber *)price + currency:(nonnull NSString *)currency + transactionDate:(nonnull NSDate *)transactionDate + transactionId:(nonnull NSString *)transactionId + andReceipt:(nonnull NSData *)receipt; - (void)addCallbackParameter:(nonnull NSString *)key value:(nonnull NSString *)value; diff --git a/Adjust/ADJSubscription.m b/Adjust/ADJSubscription.m index fe5820dfb..eaf3aa898 100644 --- a/Adjust/ADJSubscription.m +++ b/Adjust/ADJSubscription.m @@ -22,19 +22,19 @@ @interface ADJSubscription() @implementation ADJSubscription -- (nullable id)initWithRevenue:(double)revenue - currency:(nonnull NSString *)currency - transactionDate:(double)transactionDate - transactionId:(nonnull NSString *)transactionId - andReceipt:(nonnull NSData *)receipt { +- (nullable id)initWithPrice:(nonnull NSDecimalNumber *)price + currency:(nonnull NSString *)currency + transactionDate:(nonnull NSDate *)transactionDate + transactionId:(nonnull NSString *)transactionId + andReceipt:(nonnull NSData *)receipt { self = [super init]; if (self == nil) { return nil; } - _revenue = [NSNumber numberWithDouble:revenue]; + _price = [price copy]; _currency = [currency copy]; - _transactionDate = [NSNumber numberWithDouble:transactionDate]; + _transactionDate = [transactionDate copy]; _transactionId = [transactionId copy]; _receipt = [receipt copy]; _billingStore = @"iOS"; @@ -51,18 +51,18 @@ - (nullable id)initWithRevenue:(double)revenue - (void)addCallbackParameter:(nonnull NSString *)key value:(nonnull NSString *)value { - if (![ADJUtil isValidParameter:key - attributeType:@"key" - parameterName:@"Callback"]) { - return; - } - if (![ADJUtil isValidParameter:value - attributeType:@"value" - parameterName:@"Callback"]) { - return; - } - @synchronized (self) { + if (![ADJUtil isValidParameter:key + attributeType:@"key" + parameterName:@"Callback"]) { + return; + } + if (![ADJUtil isValidParameter:value + attributeType:@"value" + parameterName:@"Callback"]) { + return; + } + if (self.mutableCallbackParameters == nil) { self.mutableCallbackParameters = [[NSMutableDictionary alloc] init]; } @@ -78,18 +78,18 @@ - (void)addCallbackParameter:(nonnull NSString *)key - (void)addPartnerParameter:(nonnull NSString *)key value:(nonnull NSString *)value { - if (![ADJUtil isValidParameter:key - attributeType:@"key" - parameterName:@"Partner"]) { - return; - } - if (![ADJUtil isValidParameter:value - attributeType:@"value" - parameterName:@"Partner"]) { - return; - } - @synchronized (self) { + if (![ADJUtil isValidParameter:key + attributeType:@"key" + parameterName:@"Partner"]) { + return; + } + if (![ADJUtil isValidParameter:value + attributeType:@"value" + parameterName:@"Partner"]) { + return; + } + if (self.mutablePartnerParameters == nil) { self.mutablePartnerParameters = [[NSMutableDictionary alloc] init]; } @@ -103,7 +103,7 @@ - (void)addPartnerParameter:(nonnull NSString *)key } - (BOOL)isValid { - if (self.revenue == nil) { + if (self.price == nil) { return NO; } if (self.currency == nil) { @@ -136,7 +136,7 @@ - (nonnull NSDictionary *)partnerParameters { - (id)copyWithZone:(NSZone *)zone { ADJSubscription *copy = [[[self class] allocWithZone:zone] init]; if (copy) { - copy->_revenue = [self.revenue copyWithZone:zone]; + copy->_price = [self.price copyWithZone:zone]; copy->_currency = [self.currency copyWithZone:zone]; copy->_transactionDate = [self.receipt copyWithZone:zone]; copy->_transactionId = [self.transactionId copyWithZone:zone]; diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m b/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m index 40a7d531f..7387a3155 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m @@ -551,20 +551,20 @@ - (void)disableThirdPartySharing:(NSDictionary *)parameters { } - (void)trackSubscription:(NSDictionary *)parameters { - double revenue = 0; + NSDecimalNumber *price; NSString *currency; - double transactionDate = 0; + NSDate *transactionDate; NSString *transactionId; NSData *receipt; if ([parameters objectForKey:@"revenue"]) { - revenue = [[parameters objectForKey:@"revenue"][0] doubleValue]; + price = [[NSDecimalNumber alloc] initWithDouble:[[parameters objectForKey:@"revenue"][0] doubleValue]]; } if ([parameters objectForKey:@"currency"]) { currency = [parameters objectForKey:@"currency"][0]; } if ([parameters objectForKey:@"transactionDate"]) { - transactionDate = [[parameters objectForKey:@"transactionDate"][0] doubleValue]; + transactionDate = [NSDate dateWithTimeIntervalSince1970:[[parameters objectForKey:@"transactionDate"][0] doubleValue]]; } if ([parameters objectForKey:@"transactionId"]) { transactionId = [parameters objectForKey:@"transactionId"][0]; @@ -574,13 +574,11 @@ - (void)trackSubscription:(NSDictionary *)parameters { receipt = [receiptString dataUsingEncoding:NSUTF8StringEncoding]; } - ADJSubscription *subscription = - [[ADJSubscription alloc] - initWithRevenue:revenue - currency:currency - transactionDate:transactionDate - transactionId:transactionId - andReceipt:receipt]; + ADJSubscription *subscription = [[ADJSubscription alloc] initWithPrice:price + currency:currency + transactionDate:transactionDate + transactionId:transactionId + andReceipt:receipt]; if ([parameters objectForKey:@"callbackParams"]) { NSArray *callbackParams = [parameters objectForKey:@"callbackParams"]; diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/ViewController.m b/AdjustTests/AdjustTestApp/AdjustTestApp/ViewController.m index f42dc99cc..9eb837814 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/ViewController.m +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/ViewController.m @@ -31,7 +31,7 @@ - (void)viewDidLoad { [self.adjustCommandExecutor setTestLibrary:self.testLibrary]; // [self.testLibrary addTestDirectory:@"current/third-party-sharing"]; - // [self.testLibrary addTest:@"Test_GdprForgetMe_after_install_kill_before_install"]; + [self.testLibrary addTest:@"Test_iOs_Subscription_subscription"]; // [self.testLibrary doNotExitAfterEnd]; [self startTestSession]; From f644c71c4df44dff9c3d00371b2b2f6176e59f25 Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 29 Apr 2020 02:13:28 +0200 Subject: [PATCH 065/173] No need for event_count in subscription package --- Adjust/ADJPackageBuilder.m | 1 - 1 file changed, 1 deletion(-) diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index 2a40b3644..139fa4042 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -783,7 +783,6 @@ - (NSMutableDictionary *)getSubscriptionParameters:(BOOL)isInDelay forSubscripti } if (self.activityState != nil) { - [ADJPackageBuilder parameters:parameters setInt:self.activityState.eventCount forKey:@"event_count"]; [ADJPackageBuilder parameters:parameters setString:self.activityState.deviceToken forKey:@"push_token"]; [ADJPackageBuilder parameters:parameters setInt:self.activityState.sessionCount forKey:@"session_count"]; [ADJPackageBuilder parameters:parameters setDuration:self.activityState.sessionLength forKey:@"session_length"]; From 313681c1066c9893e81130dba28b24ff56c80938 Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 29 Apr 2020 02:14:13 +0200 Subject: [PATCH 066/173] Make mandatory fields to be softly mandatory --- Adjust/ADJSubscription.m | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/Adjust/ADJSubscription.m b/Adjust/ADJSubscription.m index eaf3aa898..86f4a8f03 100644 --- a/Adjust/ADJSubscription.m +++ b/Adjust/ADJSubscription.m @@ -41,10 +41,6 @@ - (nullable id)initWithPrice:(nonnull NSDecimalNumber *)price _logger = ADJAdjustFactory.logger; - if (![self isValid]) { - return nil; - } - return self; } @@ -102,29 +98,6 @@ - (void)addPartnerParameter:(nonnull NSString *)key } } -- (BOOL)isValid { - if (self.price == nil) { - return NO; - } - if (self.currency == nil) { - return NO; - } - if (self.transactionDate == nil) { - return NO; - } - if (self.transactionId == nil) { - return NO; - } - if (self.receipt == nil) { - return NO; - } - if (self.billingStore == nil) { - return NO; - } - - return YES; -} - - (nonnull NSDictionary *)callbackParameters { return [self.mutableCallbackParameters copy]; } @@ -135,6 +108,7 @@ - (nonnull NSDictionary *)partnerParameters { - (id)copyWithZone:(NSZone *)zone { ADJSubscription *copy = [[[self class] allocWithZone:zone] init]; + if (copy) { copy->_price = [self.price copyWithZone:zone]; copy->_currency = [self.currency copyWithZone:zone]; @@ -145,6 +119,7 @@ - (id)copyWithZone:(NSZone *)zone { copy.mutableCallbackParameters = [self.mutableCallbackParameters copyWithZone:zone]; copy.mutablePartnerParameters = [self.mutablePartnerParameters copyWithZone:zone]; } + return copy; } From 0328aef5482b0705b089aa1c3dea009fa74c34bb Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 5 May 2020 02:04:12 +0200 Subject: [PATCH 067/173] Remove install_receipt from subscription payload --- Adjust/ADJPackageBuilder.m | 1 - 1 file changed, 1 deletion(-) diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index 139fa4042..b3e04a6ee 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -769,7 +769,6 @@ - (NSMutableDictionary *)getSubscriptionParameters:(BOOL)isInDelay forSubscripti [ADJPackageBuilder parameters:parameters setString:UIDevice.currentDevice.adjIdForAdvertisers forKey:@"idfa"]; } [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.vendorId forKey:@"idfv"]; - [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.installReceiptBase64 forKey:@"install_receipt"]; [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.languageCode forKey:@"language"]; [ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"]; [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.osBuild forKey:@"os_build"]; From 1fdf4aff5508b39ddc5e64dca23960c4d083b3ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uglje=C5=A1a=20Erceg?= Date: Tue, 12 May 2020 23:04:17 +0200 Subject: [PATCH 068/173] Update README.md --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index e2ade75b1..f3678992b 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ Read this in other languages: [English][en-readme], [中文][zh-readme], [日本 * [Delay start](#delay-start) * [Attribution callback](#attribution-callback) * [Ad revenue tracking](#ad-revenue) + * [Subscriptions tracking](#subscriptions) * [Event and session callbacks](#event-session-callbacks) * [Disable tracking](#disable-tracking) * [Offline mode](#offline-mode) @@ -518,6 +519,29 @@ Currently we support the below `source` parameter values: - `ADJAdRevenueSourceMopub` - representing MoPub mediation platform (for more information, check [integration guide][sdk2sdk-mopub]) +### Subscriptions tracking + +**Note**: This feature is available only in the native SDK v4.22.0 and above. + +You can track App Store subscriptions and verify their validity with Adjust SDK. After subscription has been successfully purchased, you need to make following call to Adjust SDK: + +```objc +ADJSubscription *subscription = [[ADJSubscription alloc] initWithPrice:price + currency:currency + transactionDate:transactionDate + transactionId:transactionId + andReceipt:receipt]; +[Adjust trackSubscription:subscription]; +``` + +Subscription parameters you need to pass to the method are: + +- [price](https://developer.apple.com/documentation/storekit/skproduct/1506094-price?language=objc) +- currency (you need to pass [currencyCode](https://developer.apple.com/documentation/foundation/nslocale/1642836-currencycode?language=objc) of the [priceLocale](https://developer.apple.com/documentation/storekit/skproduct/1506145-pricelocale?language=objc) object) +- [transactionDate](https://developer.apple.com/documentation/storekit/skpaymenttransaction/1411273-transactiondate?language=objc) +- [transactionId](https://developer.apple.com/documentation/storekit/skpaymenttransaction/1411288-transactionidentifier?language=objc) +- [receipt](https://developer.apple.com/documentation/foundation/nsbundle/1407276-appstorereceipturl) + ### Event and session callbacks You can register a delegate callback to be notified of successful and failed tracked events and/or sessions. The same optional protocol `AdjustDelegate` used for the [attribution callback](#attribution-callback) is used. From 6def8c3b5dcb97135f572032f23cb582fe1a8b28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uglje=C5=A1a=20Erceg?= Date: Tue, 12 May 2020 23:09:15 +0200 Subject: [PATCH 069/173] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f3678992b..1ae7eb18f 100644 --- a/README.md +++ b/README.md @@ -519,7 +519,7 @@ Currently we support the below `source` parameter values: - `ADJAdRevenueSourceMopub` - representing MoPub mediation platform (for more information, check [integration guide][sdk2sdk-mopub]) -### Subscriptions tracking +### Subscriptions tracking **Note**: This feature is available only in the native SDK v4.22.0 and above. @@ -534,6 +534,9 @@ ADJSubscription *subscription = [[ADJSubscription alloc] initWithPrice:price [Adjust trackSubscription:subscription]; ``` + +Make sure to do this before making a call to `finishTransaction` in `paymentQueue:updatedTransaction` only if the state changed to `SKPaymentTransactionStatePurchased` or `SKPaymentTransactionStateRestored`. + Subscription parameters you need to pass to the method are: - [price](https://developer.apple.com/documentation/storekit/skproduct/1506094-price?language=objc) From 1c2caaf03348d313f1ee0070d4cbf21bff66cc50 Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 14 May 2020 02:00:26 +0200 Subject: [PATCH 070/173] Add sales_region parameter and make transaction_date optional --- Adjust/ADJPackageBuilder.m | 3 +- Adjust/ADJSubscription.h | 23 ++++++----- Adjust/ADJSubscription.m | 40 +++++++++++++------ .../AdjustTestApp/ATAAdjustCommandExecutor.m | 15 ++++--- 4 files changed, 54 insertions(+), 27 deletions(-) diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index b3e04a6ee..e66e83753 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -808,10 +808,11 @@ - (NSMutableDictionary *)getSubscriptionParameters:(BOOL)isInDelay forSubscripti [ADJPackageBuilder parameters:parameters setNumber:subscription.price forKey:@"revenue"]; [ADJPackageBuilder parameters:parameters setString:subscription.currency forKey:@"currency"]; - [ADJPackageBuilder parameters:parameters setDate:subscription.transactionDate forKey:@"transaction_date"]; [ADJPackageBuilder parameters:parameters setString:subscription.transactionId forKey:@"transaction_id"]; [ADJPackageBuilder parameters:parameters setString:[subscription.receipt adjEncodeBase64] forKey:@"receipt"]; [ADJPackageBuilder parameters:parameters setString:subscription.billingStore forKey:@"billing_store"]; + [ADJPackageBuilder parameters:parameters setDate:subscription.transactionDate forKey:@"transaction_date"]; + [ADJPackageBuilder parameters:parameters setString:subscription.salesRegion forKey:@"sales_region"]; #if !TARGET_OS_TV && !TARGET_OS_MACCATALYST [ADJPackageBuilder parameters:parameters setString:[ADJUtil readMCC] forKey:@"mcc"]; diff --git a/Adjust/ADJSubscription.h b/Adjust/ADJSubscription.h index 0409cb508..92f5395ed 100644 --- a/Adjust/ADJSubscription.h +++ b/Adjust/ADJSubscription.h @@ -10,28 +10,33 @@ @interface ADJSubscription : NSObject -@property (nonatomic, copy, readonly, nonnull) NSDecimalNumber *price; +@property (nonatomic, copy, readonly, nonnull) NSDecimalNumber *price; // [M] revenue -@property (nonatomic, copy, readonly, nonnull) NSString *currency; +@property (nonatomic, copy, readonly, nonnull) NSString *currency; // [M] currency -@property (nonatomic, copy, readonly, nonnull) NSDate *transactionDate; +@property (nonatomic, copy, readonly, nonnull) NSString *transactionId; // [M] transaction_id -@property (nonatomic, copy, readonly, nonnull) NSString *transactionId; +@property (nonatomic, copy, readonly, nonnull) NSData *receipt; // [M] receipt -@property (nonatomic, copy, readonly, nonnull) NSData *receipt; +@property (nonatomic, copy, readonly, nonnull) NSString *billingStore; // [M] billing_store -@property (nonatomic, copy, readonly, nonnull) NSString *billingStore; +@property (nonatomic, copy, readonly, nonnull) NSDate *transactionDate; // [O] transaction_date -@property (nonatomic, copy, readonly, nonnull) NSDictionary *partnerParameters; +@property (nonatomic, copy, readonly, nonnull) NSString *salesRegion; // [O] sales_region -@property (nonatomic, copy, readonly, nonnull) NSDictionary *callbackParameters; +@property (nonatomic, copy, readonly, nonnull) NSDictionary *callbackParameters; // [O] callback_params + +@property (nonatomic, copy, readonly, nonnull) NSDictionary *partnerParameters; // [O] partner_params - (nullable id)initWithPrice:(nonnull NSDecimalNumber *)price currency:(nonnull NSString *)currency - transactionDate:(nonnull NSDate *)transactionDate transactionId:(nonnull NSString *)transactionId andReceipt:(nonnull NSData *)receipt; +- (void)setTransactionDate:(nonnull NSDate *)transactionDate; + +- (void)setSalesRegion:(nonnull NSString *)salesRegion; + - (void)addCallbackParameter:(nonnull NSString *)key value:(nonnull NSString *)value; - (void)addPartnerParameter:(nonnull NSString *)key value:(nonnull NSString *)value; diff --git a/Adjust/ADJSubscription.m b/Adjust/ADJSubscription.m index 86f4a8f03..304c37b6d 100644 --- a/Adjust/ADJSubscription.m +++ b/Adjust/ADJSubscription.m @@ -24,7 +24,6 @@ @implementation ADJSubscription - (nullable id)initWithPrice:(nonnull NSDecimalNumber *)price currency:(nonnull NSString *)currency - transactionDate:(nonnull NSDate *)transactionDate transactionId:(nonnull NSString *)transactionId andReceipt:(nonnull NSData *)receipt { self = [super init]; @@ -34,7 +33,6 @@ - (nullable id)initWithPrice:(nonnull NSDecimalNumber *)price _price = [price copy]; _currency = [currency copy]; - _transactionDate = [transactionDate copy]; _transactionId = [transactionId copy]; _receipt = [receipt copy]; _billingStore = @"iOS"; @@ -44,16 +42,31 @@ - (nullable id)initWithPrice:(nonnull NSDecimalNumber *)price return self; } +- (void)setTransactionDate:(NSDate *)transactionDate { + @synchronized (self) { + _transactionDate = [transactionDate copy]; + } +} + +- (void)setSalesRegion:(NSString *)salesRegion { + @synchronized (self) { + _salesRegion = [salesRegion copy]; + } +} + - (void)addCallbackParameter:(nonnull NSString *)key value:(nonnull NSString *)value { @synchronized (self) { - if (![ADJUtil isValidParameter:key + NSString *immutableKey = [key copy]; + NSString *immutableValue = [value copy]; + + if (![ADJUtil isValidParameter:immutableKey attributeType:@"key" parameterName:@"Callback"]) { return; } - if (![ADJUtil isValidParameter:value + if (![ADJUtil isValidParameter:immutableValue attributeType:@"value" parameterName:@"Callback"]) { return; @@ -63,11 +76,11 @@ - (void)addCallbackParameter:(nonnull NSString *)key self.mutableCallbackParameters = [[NSMutableDictionary alloc] init]; } - if ([self.mutableCallbackParameters objectForKey:key]) { - [self.logger warn:@"key %@ was overwritten", key]; + if ([self.mutableCallbackParameters objectForKey:immutableKey]) { + [self.logger warn:@"key %@ was overwritten", immutableKey]; } - [self.mutableCallbackParameters setObject:value forKey:key]; + [self.mutableCallbackParameters setObject:immutableValue forKey:immutableKey]; } } @@ -75,12 +88,15 @@ - (void)addPartnerParameter:(nonnull NSString *)key value:(nonnull NSString *)value { @synchronized (self) { - if (![ADJUtil isValidParameter:key + NSString *immutableKey = [key copy]; + NSString *immutableValue = [value copy]; + + if (![ADJUtil isValidParameter:immutableKey attributeType:@"key" parameterName:@"Partner"]) { return; } - if (![ADJUtil isValidParameter:value + if (![ADJUtil isValidParameter:immutableValue attributeType:@"value" parameterName:@"Partner"]) { return; @@ -90,11 +106,11 @@ - (void)addPartnerParameter:(nonnull NSString *)key self.mutablePartnerParameters = [[NSMutableDictionary alloc] init]; } - if ([self.mutablePartnerParameters objectForKey:key]) { - [self.logger warn:@"key %@ was overwritten", key]; + if ([self.mutablePartnerParameters objectForKey:immutableKey]) { + [self.logger warn:@"key %@ was overwritten", immutableKey]; } - [self.mutablePartnerParameters setObject:value forKey:key]; + [self.mutablePartnerParameters setObject:immutableValue forKey:immutableKey]; } } diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m b/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m index 7387a3155..f8a24d4cc 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m @@ -553,9 +553,10 @@ - (void)disableThirdPartySharing:(NSDictionary *)parameters { - (void)trackSubscription:(NSDictionary *)parameters { NSDecimalNumber *price; NSString *currency; - NSDate *transactionDate; NSString *transactionId; NSData *receipt; + NSDate *transactionDate; + NSString *salesRegion; if ([parameters objectForKey:@"revenue"]) { price = [[NSDecimalNumber alloc] initWithDouble:[[parameters objectForKey:@"revenue"][0] doubleValue]]; @@ -563,9 +564,6 @@ - (void)trackSubscription:(NSDictionary *)parameters { if ([parameters objectForKey:@"currency"]) { currency = [parameters objectForKey:@"currency"][0]; } - if ([parameters objectForKey:@"transactionDate"]) { - transactionDate = [NSDate dateWithTimeIntervalSince1970:[[parameters objectForKey:@"transactionDate"][0] doubleValue]]; - } if ([parameters objectForKey:@"transactionId"]) { transactionId = [parameters objectForKey:@"transactionId"][0]; } @@ -573,12 +571,19 @@ - (void)trackSubscription:(NSDictionary *)parameters { NSString *receiptString = [parameters objectForKey:@"receipt"][0]; receipt = [receiptString dataUsingEncoding:NSUTF8StringEncoding]; } + if ([parameters objectForKey:@"transactionDate"]) { + transactionDate = [NSDate dateWithTimeIntervalSince1970:[[parameters objectForKey:@"transactionDate"][0] doubleValue]]; + } + if ([parameters objectForKey:@"salesRegion"]) { + salesRegion = [parameters objectForKey:@"salesRegion"][0]; + } ADJSubscription *subscription = [[ADJSubscription alloc] initWithPrice:price currency:currency - transactionDate:transactionDate transactionId:transactionId andReceipt:receipt]; + [subscription setTransactionDate:transactionDate]; + [subscription setSalesRegion:salesRegion]; if ([parameters objectForKey:@"callbackParams"]) { NSArray *callbackParams = [parameters objectForKey:@"callbackParams"]; From 027f10115a13b91206a1b18815a37a789d8c4a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uglje=C5=A1a=20Erceg?= Date: Thu, 14 May 2020 02:04:45 +0200 Subject: [PATCH 071/173] Update README.md --- README.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1ae7eb18f..b65b65a3d 100644 --- a/README.md +++ b/README.md @@ -528,22 +528,46 @@ You can track App Store subscriptions and verify their validity with Adjust SDK. ```objc ADJSubscription *subscription = [[ADJSubscription alloc] initWithPrice:price currency:currency - transactionDate:transactionDate transactionId:transactionId andReceipt:receipt]; +[subscription setTransactionDate:transactionDate]; +[subscription setSalesRegion:salesRegion]; + [Adjust trackSubscription:subscription]; ``` Make sure to do this before making a call to `finishTransaction` in `paymentQueue:updatedTransaction` only if the state changed to `SKPaymentTransactionStatePurchased` or `SKPaymentTransactionStateRestored`. -Subscription parameters you need to pass to the method are: +Subscription tracking parameters: - [price](https://developer.apple.com/documentation/storekit/skproduct/1506094-price?language=objc) - currency (you need to pass [currencyCode](https://developer.apple.com/documentation/foundation/nslocale/1642836-currencycode?language=objc) of the [priceLocale](https://developer.apple.com/documentation/storekit/skproduct/1506145-pricelocale?language=objc) object) -- [transactionDate](https://developer.apple.com/documentation/storekit/skpaymenttransaction/1411273-transactiondate?language=objc) - [transactionId](https://developer.apple.com/documentation/storekit/skpaymenttransaction/1411288-transactionidentifier?language=objc) - [receipt](https://developer.apple.com/documentation/foundation/nsbundle/1407276-appstorereceipturl) +- [transactionDate](https://developer.apple.com/documentation/storekit/skpaymenttransaction/1411273-transactiondate?language=objc) +- salesRegion (you need to pass [countryCode](https://developer.apple.com/documentation/foundation/nslocale/1643060-countrycode?language=objc) of the [priceLocale](https://developer.apple.com/documentation/storekit/skproduct/1506145-pricelocale?language=objc) object) + +In same fashion like with event tracking, you can attach callback and partner parameters to subscription object as well: + +```objc +ADJSubscription *subscription = [[ADJSubscription alloc] initWithPrice:price + currency:currency + transactionId:transactionId + andReceipt:receipt]; +[subscription setTransactionDate:transactionDate]; +[subscription setSalesRegion:salesRegion]; + +// add callback parameters +[subscription addCallbackParameter:@"key" value:@"value"]; +[subscription addCallbackParameter:@"foo" value:@"bar"]; + +// add partner parameters +[subscription addPartnerParameter:@"key" value:@"value"]; +[subscription addPartnerParameter:@"foo" value:@"bar"]; + +[Adjust trackSubscription:subscription]; +``` ### Event and session callbacks From aeb32bf1f9195ff5dc737b5386b822090223571c Mon Sep 17 00:00:00 2001 From: nonelse Date: Tue, 19 May 2020 18:06:31 +0200 Subject: [PATCH 072/173] Extract networking into request handler --- Adjust/ADJActivityHandler.h | 11 +- Adjust/ADJActivityHandler.m | 59 +- Adjust/ADJAdjustFactory.h | 22 +- Adjust/ADJAdjustFactory.m | 98 +-- Adjust/ADJAttributionHandler.h | 14 +- Adjust/ADJAttributionHandler.m | 71 ++- Adjust/ADJPackageBuilder.h | 4 + Adjust/ADJPackageHandler.h | 19 +- Adjust/ADJPackageHandler.m | 109 ++-- Adjust/ADJRequestHandler.h | 29 +- Adjust/ADJRequestHandler.m | 558 +++++++++++++++--- Adjust/ADJResponseData.h | 9 +- Adjust/ADJResponseData.m | 47 +- Adjust/ADJSdkClickHandler.h | 14 +- Adjust/ADJSdkClickHandler.m | 88 +-- Adjust/ADJUtil.h | 20 +- Adjust/ADJUtil.m | 458 -------------- Adjust/Adjust.h | 4 +- Adjust/Adjust.m | 15 +- AdjustBridge/AdjustBridge.m | 10 +- .../AdjustTestApp/ATAAdjustCommandExecutor.m | 57 +- .../Delegates/ATAAdjustDelegateAttribution.h | 2 +- .../Delegates/ATAAdjustDelegateAttribution.m | 8 +- .../ATAAdjustDelegateDeferredDeeplink.h | 2 +- .../ATAAdjustDelegateDeferredDeeplink.m | 8 +- .../Delegates/ATAAdjustDelegateEventFailure.h | 2 +- .../Delegates/ATAAdjustDelegateEventFailure.m | 8 +- .../Delegates/ATAAdjustDelegateEventSuccess.h | 2 +- .../Delegates/ATAAdjustDelegateEventSuccess.m | 8 +- .../ATAAdjustDelegateSessionFailure.h | 2 +- .../ATAAdjustDelegateSessionFailure.m | 8 +- .../ATAAdjustDelegateSessionSuccess.h | 2 +- .../ATAAdjustDelegateSessionSuccess.m | 8 +- .../AdjustTestApp/ViewController.m | 4 +- 34 files changed, 796 insertions(+), 984 deletions(-) diff --git a/Adjust/ADJActivityHandler.h b/Adjust/ADJActivityHandler.h index 9a96dd4fa..360699ced 100644 --- a/Adjust/ADJActivityHandler.h +++ b/Adjust/ADJActivityHandler.h @@ -44,9 +44,7 @@ @property (nonatomic, copy) NSData *deviceTokenData; @property (nonatomic, copy) NSNumber *enabled; @property (nonatomic, assign) BOOL offline; -@property (nonatomic, copy) NSString *basePath; -@property (nonatomic, copy) NSString *gdprPath; -@property (nonatomic, copy) NSString *subscriptionPath; +@property (nonatomic, copy) NSString *extraPath; - (id)init; @@ -99,9 +97,6 @@ - (void)trackAdRevenue:(NSString *)soruce payload:(NSData *)payload; - (void)disableThirdPartySharing; - (void)trackSubscription:(ADJSubscription *)subscription; -- (NSString *)getBasePath; -- (NSString *)getGdprPath; -- (NSString *)getSubscriptionPath; - (ADJDeviceInfo *)deviceInfo; - (ADJActivityState *)activityState; @@ -114,8 +109,8 @@ @interface ADJActivityHandler : NSObject -+ (id)handlerWithConfig:(ADJConfig *)adjustConfig - savedPreLaunch:(ADJSavedPreLaunch *)savedPreLaunch; +- (id)initWithConfig:(ADJConfig *)adjustConfig + savedPreLaunch:(ADJSavedPreLaunch *)savedPreLaunch; - (void)addSessionCallbackParameterI:(ADJActivityHandler *)selfI key:(NSString *)key diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 009e74916..d119c9d9f 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -80,9 +80,9 @@ - (id)init { @interface ADJActivityHandler() @property (nonatomic, strong) dispatch_queue_t internalQueue; -@property (nonatomic, strong) id packageHandler; -@property (nonatomic, strong) id attributionHandler; -@property (nonatomic, strong) id sdkClickHandler; +@property (nonatomic, strong) ADJPackageHandler *packageHandler; +@property (nonatomic, strong) ADJAttributionHandler *attributionHandler; +@property (nonatomic, strong) ADJSdkClickHandler *sdkClickHandler; @property (nonatomic, strong) ADJActivityState *activityState; @property (nonatomic, strong) ADJTimerCycle *foregroundTimer; @property (nonatomic, strong) ADJTimerOnce *backgroundTimer; @@ -116,15 +116,9 @@ @implementation ADJActivityHandler @synthesize attribution = _attribution; -+ (id)handlerWithConfig:(ADJConfig *)adjustConfig - savedPreLaunch:(ADJSavedPreLaunch *)savedPreLaunch -{ - return [[ADJActivityHandler alloc] initWithConfig:adjustConfig - savedPreLaunch:savedPreLaunch]; -} - - (id)initWithConfig:(ADJConfig *)adjustConfig - savedPreLaunch:(ADJSavedPreLaunch *)savedPreLaunch { + savedPreLaunch:(ADJSavedPreLaunch *)savedPreLaunch +{ self = [super init]; if (self == nil) return nil; @@ -196,16 +190,6 @@ - (id)initWithConfig:(ADJConfig *)adjustConfig // does not have the session response by default self.internalState.sessionResponseProcessed = NO; - if (savedPreLaunch.basePath != nil) { - self.basePath = savedPreLaunch.basePath; - } - if (savedPreLaunch.gdprPath != nil) { - self.gdprPath = savedPreLaunch.gdprPath; - } - if (savedPreLaunch.subscriptionPath != nil) { - self.subscriptionPath = savedPreLaunch.subscriptionPath; - } - self.iAdRetriesLeft = kiAdRetriesCount; self.internalQueue = dispatch_queue_create(kInternalQueueName, DISPATCH_QUEUE_SERIAL); @@ -213,7 +197,7 @@ - (id)initWithConfig:(ADJConfig *)adjustConfig selfInject:self block:^(ADJActivityHandler * selfI) { [selfI initI:selfI - preLaunchActionsArray:savedPreLaunch.preLaunchActionsArray]; + preLaunchActions:savedPreLaunch]; }]; /* Not needed, done already in initI:preLaunchActionsArray: method. @@ -709,7 +693,7 @@ + (void)deleteSessionPartnerParameter { #pragma mark - internal - (void)initI:(ADJActivityHandler *)selfI -preLaunchActionsArray:(NSArray*)preLaunchActionsArray +preLaunchActions:(ADJSavedPreLaunch*)preLaunchActions { // get session values kSessionInterval = ADJAdjustFactory.sessionInterval; @@ -782,28 +766,37 @@ - (void)initI:(ADJActivityHandler *)selfI [ADJUtil updateUrlSessionConfiguration:selfI.adjustConfig]; - selfI.packageHandler = [ADJAdjustFactory packageHandlerForActivityHandler:selfI - startsSending:[selfI toSendI:selfI - sdkClickHandlerOnly:NO]]; + selfI.packageHandler = [[ADJPackageHandler alloc] + initWithActivityHandler:selfI + startsSending: + [selfI toSendI:selfI sdkClickHandlerOnly:NO] + userAgent:selfI.adjustConfig.userAgent + extraPath:preLaunchActions.extraPath]; // update session parameters in package queue if ([selfI itHasToUpdatePackagesI:selfI]) { [selfI updatePackagesI:selfI]; } - selfI.attributionHandler = [ADJAdjustFactory attributionHandlerForActivityHandler:selfI - startsSending:[selfI toSendI:selfI - sdkClickHandlerOnly:NO]]; + selfI.attributionHandler = [[ADJAttributionHandler alloc] + initWithActivityHandler:selfI + startsSending: + [selfI toSendI:selfI sdkClickHandlerOnly:NO] + userAgent:selfI.adjustConfig.userAgent + extraPath:preLaunchActions.extraPath]; - selfI.sdkClickHandler = [ADJAdjustFactory sdkClickHandlerForActivityHandler:selfI - startsSending:[selfI toSendI:selfI - sdkClickHandlerOnly:YES]]; + selfI.sdkClickHandler = [[ADJSdkClickHandler alloc] + initWithActivityHandler:selfI + startsSending:[selfI toSendI:selfI sdkClickHandlerOnly:YES] + userAgent:selfI.adjustConfig.userAgent + extraPath:preLaunchActions.extraPath]; if (selfI.adjustConfig.allowiAdInfoReading == YES) { [selfI checkForiAdI:selfI]; } - [selfI preLaunchActionsI:selfI preLaunchActionsArray:preLaunchActionsArray]; + [selfI preLaunchActionsI:selfI + preLaunchActionsArray:preLaunchActions.preLaunchActionsArray]; [ADJUtil launchInMainThreadWithInactive:^(BOOL isInactive) { [ADJUtil launchInQueue:self.internalQueue selfInject:self block:^(ADJActivityHandler * selfI) { diff --git a/Adjust/ADJAdjustFactory.h b/Adjust/ADJAdjustFactory.h index fce9560b3..cef20d7e3 100644 --- a/Adjust/ADJAdjustFactory.h +++ b/Adjust/ADJAdjustFactory.h @@ -7,37 +7,23 @@ // #import -#import "ADJActivityHandler.h" -#import "ADJPackageHandler.h" -#import "ADJRequestHandler.h" #import "ADJLogger.h" -#import "ADJAttributionHandler.h" #import "ADJActivityPackage.h" #import "ADJBackoffStrategy.h" #import "ADJSdkClickHandler.h" @interface ADJAdjustFactory : NSObject -+ (id)packageHandlerForActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending; -+ (id)requestHandlerForPackageHandler:(id)packageHandler - andActivityHandler:(id)activityHandler; -+ (id)activityHandlerWithConfig:(ADJConfig *)adjustConfig - savedPreLaunch:(ADJSavedPreLaunch *)savedPreLaunch; -+ (id)sdkClickHandlerForActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending; - + (id)logger; + (double)sessionInterval; + (double)subsessionInterval; ++ (double)requestTimeout; + (NSTimeInterval)timerInterval; + (NSTimeInterval)timerStart; + (ADJBackoffStrategy *)packageHandlerBackoffStrategy; + (ADJBackoffStrategy *)sdkClickHandlerBackoffStrategy; + (ADJBackoffStrategy *)installSessionBackoffStrategy; -+ (id)attributionHandlerForActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending; + (BOOL)testing; + (NSTimeInterval)maxDelayStart; + (NSString *)baseUrl; @@ -45,16 +31,12 @@ + (NSString *)subscriptionUrl; + (BOOL)iAdFrameworkEnabled; -+ (void)setPackageHandler:(id)packageHandler; -+ (void)setRequestHandler:(id)requestHandler; -+ (void)setActivityHandler:(id)activityHandler; -+ (void)setSdkClickHandler:(id)sdkClickHandler; + (void)setLogger:(id)logger; + (void)setSessionInterval:(double)sessionInterval; + (void)setSubsessionInterval:(double)subsessionInterval; ++ (void)setRequestTimeout:(double)requestTimeout; + (void)setTimerInterval:(NSTimeInterval)timerInterval; + (void)setTimerStart:(NSTimeInterval)timerStart; -+ (void)setAttributionHandler:(id)attributionHandler; + (void)setPackageHandlerBackoffStrategy:(ADJBackoffStrategy *)backoffStrategy; + (void)setSdkClickHandlerBackoffStrategy:(ADJBackoffStrategy *)backoffStrategy; + (void)setTesting:(BOOL)testing; diff --git a/Adjust/ADJAdjustFactory.m b/Adjust/ADJAdjustFactory.m index 70ad0b4d2..5be3e469b 100644 --- a/Adjust/ADJAdjustFactory.m +++ b/Adjust/ADJAdjustFactory.m @@ -7,16 +7,14 @@ // #import "ADJAdjustFactory.h" +#import "ADJActivityHandler.h" +#import "ADJPackageHandler.h" -static id internalPackageHandler = nil; -static id internalRequestHandler = nil; -static id internalActivityHandler = nil; static id internalLogger = nil; -static id internalAttributionHandler = nil; -static id internalSdkClickHandler = nil; static double internalSessionInterval = -1; static double intervalSubsessionInterval = -1; +static double internalRequestTimeout = -1; static NSTimeInterval internalTimerInterval = -1; static NSTimeInterval intervalTimerStart = -1; static ADJBackoffStrategy * packageHandlerBackoffStrategy = nil; @@ -35,37 +33,6 @@ @implementation ADJAdjustFactory -+ (id)packageHandlerForActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending { - if (internalPackageHandler == nil) { - return [ADJPackageHandler handlerWithActivityHandler:activityHandler startsSending:startsSending]; - } - - return [internalPackageHandler initWithActivityHandler:activityHandler startsSending:startsSending]; -} - -+ (id)requestHandlerForPackageHandler:(id)packageHandler - andActivityHandler:(id)activityHandler { - if (internalRequestHandler == nil) { - return [ADJRequestHandler handlerWithPackageHandler:packageHandler - andActivityHandler:activityHandler]; - } - return [internalRequestHandler initWithPackageHandler:packageHandler - andActivityHandler:activityHandler]; -} - -+ (id)activityHandlerWithConfig:(ADJConfig *)adjustConfig - savedPreLaunch:(ADJSavedPreLaunch *)savedPreLaunch -{ - if (internalActivityHandler == nil) { - return [ADJActivityHandler handlerWithConfig:adjustConfig - savedPreLaunch:savedPreLaunch - ]; - } - return [internalActivityHandler initWithConfig:adjustConfig - savedPreLaunch:savedPreLaunch]; -} - + (id)logger { if (internalLogger == nil) { // same instance of logger @@ -88,6 +55,13 @@ + (double)subsessionInterval { return intervalSubsessionInterval; } ++ (double)requestTimeout { + if (internalRequestTimeout == -1) { + return 60; // 60 second + } + return internalRequestTimeout; +} + + (NSTimeInterval)timerInterval { if (internalTimerInterval < 0) { return 60; // 1 minute @@ -123,28 +97,6 @@ + (ADJBackoffStrategy *)installSessionBackoffStrategy { return installSessionBackoffStrategy; } -+ (id)attributionHandlerForActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending -{ - if (internalAttributionHandler == nil) { - return [ADJAttributionHandler handlerWithActivityHandler:activityHandler - startsSending:startsSending]; - } - - return [internalAttributionHandler initWithActivityHandler:activityHandler - startsSending:startsSending]; -} - -+ (id)sdkClickHandlerForActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending -{ - if (internalSdkClickHandler == nil) { - return [ADJSdkClickHandler handlerWithActivityHandler:activityHandler startsSending:startsSending]; - } - - return [internalSdkClickHandler initWithActivityHandler:activityHandler startsSending:startsSending]; -} - + (BOOL)testing { return internalTesting; } @@ -172,18 +124,6 @@ + (NSString *)subscriptionUrl { return internalSubscriptionUrl; } -+ (void)setPackageHandler:(id)packageHandler { - internalPackageHandler = packageHandler; -} - -+ (void)setRequestHandler:(id)requestHandler { - internalRequestHandler = requestHandler; -} - -+ (void)setActivityHandler:(id)activityHandler { - internalActivityHandler = activityHandler; -} - + (void)setLogger:(id)logger { internalLogger = logger; } @@ -196,6 +136,10 @@ + (void)setSubsessionInterval:(double)subsessionInterval { intervalSubsessionInterval = subsessionInterval; } ++ (void)setRequestTimeout:(double)requestTimeout { + internalRequestTimeout = requestTimeout; +} + + (void)setTimerInterval:(NSTimeInterval)timerInterval { internalTimerInterval = timerInterval; } @@ -204,14 +148,6 @@ + (void)setTimerStart:(NSTimeInterval)timerStart { intervalTimerStart = timerStart; } -+ (void)setAttributionHandler:(id)attributionHandler { - internalAttributionHandler = attributionHandler; -} - -+ (void)setSdkClickHandler:(id)sdkClickHandler { - internalSdkClickHandler = sdkClickHandler; -} - + (void)setPackageHandlerBackoffStrategy:(ADJBackoffStrategy *)backoffStrategy { packageHandlerBackoffStrategy = backoffStrategy; } @@ -291,17 +227,13 @@ + (void)teardown:(BOOL)deleteState { [ADJActivityHandler deleteState]; [ADJPackageHandler deleteState]; } - internalPackageHandler = nil; - internalRequestHandler = nil; - internalActivityHandler = nil; internalLogger = nil; - internalAttributionHandler = nil; - internalSdkClickHandler = nil; internalSessionInterval = -1; intervalSubsessionInterval = -1; internalTimerInterval = -1; intervalTimerStart = -1; + internalRequestTimeout = -1; packageHandlerBackoffStrategy = nil; sdkClickHandlerBackoffStrategy = nil; internalTesting = NO; diff --git a/Adjust/ADJAttributionHandler.h b/Adjust/ADJAttributionHandler.h index 783e6f079..f7a5ff372 100644 --- a/Adjust/ADJAttributionHandler.h +++ b/Adjust/ADJAttributionHandler.h @@ -9,11 +9,14 @@ #import #import "ADJActivityHandler.h" #import "ADJActivityPackage.h" +#import "ADJRequestHandler.h" -@protocol ADJAttributionHandler +@interface ADJAttributionHandler : NSObject - (id)initWithActivityHandler:(id) activityHandler - startsSending:(BOOL)startsSending; + startsSending:(BOOL)startsSending + userAgent:(NSString *)userAgent + extraPath:(NSString *)extraPath; - (void)checkSessionResponse:(ADJSessionResponseData *)sessionResponseData; @@ -30,10 +33,3 @@ - (void)teardown; @end - -@interface ADJAttributionHandler : NSObject - -+ (id)handlerWithActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending; - -@end diff --git a/Adjust/ADJAttributionHandler.m b/Adjust/ADJAttributionHandler.m index 22f2b77da..d46c8f027 100644 --- a/Adjust/ADJAttributionHandler.m +++ b/Adjust/ADJAttributionHandler.m @@ -13,6 +13,7 @@ #import "NSString+ADJAdditions.h" #import "ADJTimerOnce.h" #import "ADJPackageBuilder.h" +#import "ADJUtil.h" static const char * const kInternalQueueName = "com.adjust.AttributionQueue"; static NSString * const kAttributionTimerName = @"Attribution timer"; @@ -20,35 +21,36 @@ @interface ADJAttributionHandler() @property (nonatomic, strong) dispatch_queue_t internalQueue; +@property (nonatomic, strong) ADJRequestHandler *requestHandler; @property (nonatomic, weak) id activityHandler; @property (nonatomic, weak) id logger; @property (nonatomic, strong) ADJTimerOnce *attributionTimer; @property (atomic, assign) BOOL paused; -@property (nonatomic, copy) NSString *basePath; @property (nonatomic, copy) NSString *lastInitiatedBy; @end @implementation ADJAttributionHandler - -+ (id)handlerWithActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending; -{ - return [[ADJAttributionHandler alloc] initWithActivityHandler:activityHandler - startsSending:startsSending]; -} - - (id)initWithActivityHandler:(id) activityHandler - startsSending:(BOOL)startsSending; + startsSending:(BOOL)startsSending + userAgent:(NSString *)userAgent + extraPath:(NSString *)extraPath { self = [super init]; if (self == nil) return nil; self.internalQueue = dispatch_queue_create(kInternalQueueName, DISPATCH_QUEUE_SERIAL); + self.requestHandler = [[ADJRequestHandler alloc] + initWithResponseCallback:self + extraPath:extraPath + baseUrl:[ADJAdjustFactory baseUrl] + gdprUrl:[ADJAdjustFactory gdprUrl] + subscriptionUrl:[ADJAdjustFactory subscriptionUrl] + userAgent:userAgent + requestTimeout:[ADJAdjustFactory requestTimeout]]; self.activityHandler = activityHandler; self.logger = ADJAdjustFactory.logger; self.paused = !startsSending; - self.basePath = [activityHandler getBasePath]; __weak __typeof__(self) weakSelf = self; self.attributionTimer = [ADJTimerOnce timerWithBlock:^{ __typeof__(self) strongSelf = weakSelf; @@ -190,25 +192,33 @@ - (void)requestAttributionI:(ADJAttributionHandler*)selfI { [selfI.logger verbose:@"%@", attributionPackage.extendedString]; - NSURL * baseUrl = [NSURL URLWithString:[ADJAdjustFactory baseUrl]]; - - [ADJUtil sendGetRequest:baseUrl - basePath:selfI.basePath - prefixErrorMessage:@"Failed to get attribution" - activityPackage:attributionPackage - responseDataHandler:^(ADJResponseData * responseData) - { - // 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.activityHandler setTrackingStateOptedOut]; - return; - } - - if ([responseData isKindOfClass:[ADJAttributionResponseData class]]) { - [selfI checkAttributionResponse:(ADJAttributionResponseData*)responseData]; - } - }]; + NSDictionary *sendingParameters = @{ + @"sent_at": [ADJUtil formatSeconds1970:[NSDate.date timeIntervalSince1970]] + }; + + [selfI.requestHandler sendPackageByGET:attributionPackage + sendingParameters:sendingParameters]; +} + +- (void)responseCallback:(ADJResponseData *)responseData { + if (responseData.jsonResponse) { + [self.logger debug: + @"Got attribution JSON response with message: %@", responseData.message]; + } else { + [self.logger error: + @"Could not get attribution JSON response with message: %@", responseData.message]; + } + + // 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) { + [self.activityHandler setTrackingStateOptedOut]; + return; + } + + if ([responseData isKindOfClass:[ADJAttributionResponseData class]]) { + [self checkAttributionResponse:(ADJAttributionResponseData*)responseData]; + } } - (void)waitRequestAttributionWithDelayI:(ADJAttributionHandler*)selfI @@ -256,6 +266,7 @@ - (void)teardown { self.activityHandler = nil; self.logger = nil; self.attributionTimer = nil; + self.requestHandler = nil; } @end diff --git a/Adjust/ADJPackageBuilder.h b/Adjust/ADJPackageBuilder.h index 3b1349dd1..7d2723b67 100644 --- a/Adjust/ADJPackageBuilder.h +++ b/Adjust/ADJPackageBuilder.h @@ -62,4 +62,8 @@ setString:(NSString *)value forKey:(NSString *)key; ++ (void)parameters:(NSMutableDictionary *)parameters + setInt:(int)value + forKey:(NSString *)key; + @end diff --git a/Adjust/ADJPackageHandler.h b/Adjust/ADJPackageHandler.h index 12d4f3a01..06dc9d488 100644 --- a/Adjust/ADJPackageHandler.h +++ b/Adjust/ADJPackageHandler.h @@ -12,32 +12,23 @@ #import "ADJActivityHandler.h" #import "ADJResponseData.h" #import "ADJSessionParameters.h" +#import "ADJRequestHandler.h" -@protocol ADJPackageHandler +@interface ADJPackageHandler : NSObject - (id)initWithActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending; + startsSending:(BOOL)startsSending + userAgent:(NSString *)userAgent + extraPath:(NSString *)extraPath; - (void)addPackage:(ADJActivityPackage *)package; - (void)sendFirstPackage; -- (void)sendNextPackage:(ADJResponseData *)responseData; -- (void)closeFirstPackage:(ADJResponseData *)responseData - activityPackage:(ADJActivityPackage *)activityPackage; - (void)pauseSending; - (void)resumeSending; - (void)updatePackages:(ADJSessionParameters *)sessionParameters; - (void)flush; -- (NSString *)getBasePath; -- (NSString *)getGdprPath; -- (NSString *)getSubscriptionPath; - (void)teardown; + (void)deleteState; -@end - -@interface ADJPackageHandler : NSObject - -+ (id)handlerWithActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending; @end diff --git a/Adjust/ADJPackageHandler.m b/Adjust/ADJPackageHandler.m index c918f4dce..29942b1b7 100644 --- a/Adjust/ADJPackageHandler.m +++ b/Adjust/ADJPackageHandler.m @@ -6,7 +6,7 @@ // Copyright (c) 2013 adjust GmbH. All rights reserved. // -#import "ADJRequestHandler.h" +#import "ADJPackageHandler.h" #import "ADJActivityPackage.h" #import "ADJLogger.h" #import "ADJUtil.h" @@ -24,16 +24,13 @@ @interface ADJPackageHandler() @property (nonatomic, strong) dispatch_queue_t internalQueue; @property (nonatomic, strong) dispatch_semaphore_t sendingSemaphore; -@property (nonatomic, strong) id requestHandler; +@property (nonatomic, strong) ADJRequestHandler *requestHandler; @property (nonatomic, strong) NSMutableArray *packageQueue; @property (nonatomic, strong) ADJBackoffStrategy *backoffStrategy; @property (nonatomic, strong) ADJBackoffStrategy *backoffStrategyForInstallSession; @property (nonatomic, assign) BOOL paused; @property (nonatomic, weak) id activityHandler; @property (nonatomic, weak) id logger; -@property (nonatomic, copy) NSString *basePath; -@property (nonatomic, copy) NSString *gdprPath; -@property (nonatomic, copy) NSString *subscriptionPath; @property (nonatomic, assign) NSInteger lastPackageRetriesCount; @end @@ -41,14 +38,10 @@ @interface ADJPackageHandler() #pragma mark - @implementation ADJPackageHandler -+ (id)handlerWithActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending -{ - return [[ADJPackageHandler alloc] initWithActivityHandler:activityHandler startsSending:startsSending]; -} - - (id)initWithActivityHandler:(id)activityHandler startsSending:(BOOL)startsSending + userAgent:(NSString *)userAgent + extraPath:(NSString *)extraPath { self = [super init]; if (self == nil) return nil; @@ -56,9 +49,6 @@ - (id)initWithActivityHandler:(id)activityHandler self.internalQueue = dispatch_queue_create(kInternalQueueName, DISPATCH_QUEUE_SERIAL); self.backoffStrategy = [ADJAdjustFactory packageHandlerBackoffStrategy]; self.backoffStrategyForInstallSession = [ADJAdjustFactory installSessionBackoffStrategy]; - self.basePath = [activityHandler getBasePath]; - self.gdprPath = [activityHandler getGdprPath]; - self.subscriptionPath = [activityHandler getSubscriptionPath]; self.lastPackageRetriesCount = 0; [ADJUtil launchInQueue:self.internalQueue @@ -66,7 +56,9 @@ - (id)initWithActivityHandler:(id)activityHandler block:^(ADJPackageHandler * selfI) { [selfI initI:selfI activityHandler:activityHandler - startsSending:startsSending]; + startsSending:startsSending + userAgent:userAgent + extraPath:extraPath]; }]; return self; @@ -88,6 +80,25 @@ - (void)sendFirstPackage { }]; } +- (void)responseCallback:(ADJResponseData *)responseData { + if (responseData.jsonResponse) { + [self.logger debug:@"Got JSON response with message: %@", responseData.message]; + } else { + [self.logger error:@"Could not get JSON response with message: %@", responseData.message]; + } + // 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) { + [self.activityHandler setTrackingStateOptedOut]; + return; + } + if (responseData.jsonResponse == nil) { + [self closeFirstPackage:responseData]; + } else { + [self sendNextPackage:responseData]; + } +} + - (void)sendNextPackage:(ADJResponseData *)responseData { self.lastPackageRetriesCount = 0; @@ -101,28 +112,14 @@ - (void)sendNextPackage:(ADJResponseData *)responseData { } - (void)closeFirstPackage:(ADJResponseData *)responseData - activityPackage:(ADJActivityPackage *)activityPackage { responseData.willRetry = YES; [self.activityHandler finishedTracking:responseData]; - dispatch_block_t work = ^{ - [self.logger verbose:@"Package handler can send"]; - dispatch_semaphore_signal(self.sendingSemaphore); - - [self sendFirstPackage]; - }; - - if (activityPackage == nil) { - self.lastPackageRetriesCount = 0; - work(); - return; - } - self.lastPackageRetriesCount++; NSTimeInterval waitTime; - if ([activityPackage activityKind] == ADJActivityKindSession && [ADJUserDefaults getInstallTracked] == NO) { + if (responseData.activityKind == ADJActivityKindSession && [ADJUserDefaults getInstallTracked] == NO) { waitTime = [ADJUtil waitingTime:self.lastPackageRetriesCount backoffStrategy:self.backoffStrategyForInstallSession]; } else { waitTime = [ADJUtil waitingTime:self.lastPackageRetriesCount backoffStrategy:self.backoffStrategy]; @@ -130,7 +127,16 @@ - (void)closeFirstPackage:(ADJResponseData *)responseData NSString *waitTimeFormatted = [ADJUtil secondsNumberFormat:waitTime]; [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); + dispatch_after + (dispatch_time(DISPATCH_TIME_NOW, (int64_t)(waitTime * NSEC_PER_SEC)), + self.internalQueue, + ^{ + [self.logger verbose:@"Package handler finished waiting"]; + + dispatch_semaphore_signal(self.sendingSemaphore); + + [self sendFirstPackage]; + }); } - (void)pauseSending { @@ -159,26 +165,11 @@ - (void)flush { }]; } -- (NSString *)getBasePath { - return _basePath; -} - -- (NSString *)getGdprPath { - return _gdprPath; -} - -- (NSString *)getSubscriptionPath { - return _subscriptionPath; -} - - (void)teardown { [ADJAdjustFactory.logger verbose:@"ADJPackageHandler teardown"]; if (self.sendingSemaphore != nil) { dispatch_semaphore_signal(self.sendingSemaphore); } - if (self.requestHandler != nil) { - [self.requestHandler teardown]; - } [self teardownPackageQueueS]; self.internalQueue = nil; self.sendingSemaphore = nil; @@ -200,11 +191,19 @@ + (void)deletePackageQueue { - (void)initI:(ADJPackageHandler *)selfI activityHandler:(id)activityHandler startsSending:(BOOL)startsSending + userAgent:(NSString *)userAgent + extraPath:(NSString *)extraPath { selfI.activityHandler = activityHandler; selfI.paused = !startsSending; - selfI.requestHandler = [ADJAdjustFactory requestHandlerForPackageHandler:selfI - andActivityHandler:selfI.activityHandler]; + selfI.requestHandler = [[ADJRequestHandler alloc] + initWithResponseCallback:self + extraPath:extraPath + baseUrl:[ADJAdjustFactory baseUrl] + gdprUrl:[ADJAdjustFactory gdprUrl] + subscriptionUrl:[ADJAdjustFactory subscriptionUrl] + userAgent:userAgent + requestTimeout:[ADJAdjustFactory requestTimeout]]; selfI.logger = ADJAdjustFactory.logger; selfI.sendingSemaphore = dispatch_semaphore_create(1); [selfI readPackageQueueI:selfI]; @@ -242,8 +241,18 @@ - (void)sendFirstI:(ADJPackageHandler *)selfI return; } - [selfI.requestHandler sendPackage:activityPackage - queueSize:queueSize - 1]; + NSMutableDictionary *sendingParameters = [NSMutableDictionary dictionaryWithCapacity:2]; + if (queueSize - 1 > 0) { + [ADJPackageBuilder parameters:sendingParameters + setInt:(int)queueSize - 1 + forKey:@"queue_size"]; + } + [ADJPackageBuilder parameters:sendingParameters + setString:[ADJUtil formatSeconds1970:[NSDate.date timeIntervalSince1970]] + forKey:@"sent_at"]; + + [selfI.requestHandler sendPackageByPOST:activityPackage + sendingParameters:[sendingParameters copy]]; } - (void)sendNextI:(ADJPackageHandler *)selfI { diff --git a/Adjust/ADJRequestHandler.h b/Adjust/ADJRequestHandler.h index 5dc8d1772..816ad331e 100644 --- a/Adjust/ADJRequestHandler.h +++ b/Adjust/ADJRequestHandler.h @@ -7,23 +7,26 @@ // #import -#import "ADJPackageHandler.h" +#import "ADJActivityPackage.h" -@protocol ADJRequestHandler - -- (id)initWithPackageHandler:(id)packageHandler - andActivityHandler:(id)activityHandler; - -- (void)sendPackage:(ADJActivityPackage *)activityPackage - queueSize:(NSUInteger)queueSize; +@protocol ADJResponseCallback +- (void)responseCallback:(ADJResponseData *)responseData; +@end -- (void)teardown; +@interface ADJRequestHandler : NSObject -@end +- (id)initWithResponseCallback:(id)responseCallback + extraPath:(NSString *)extraPath + baseUrl:(NSString *)baseUrl + gdprUrl:(NSString *)gdprUrl + subscriptionUrl:(NSString *)subscriptionUrl + userAgent:(NSString *)userAgent + requestTimeout:(double)requestTimeout; -@interface ADJRequestHandler : NSObject +- (void)sendPackageByPOST:(ADJActivityPackage *)activityPackage + sendingParameters:(NSDictionary *)sendingParameters; -+ (id)handlerWithPackageHandler:(id)packageHandler - andActivityHandler:(id)activityHandler; +- (void)sendPackageByGET:(ADJActivityPackage *)activityPackage + sendingParameters:(NSDictionary *)sendingParameters; @end diff --git a/Adjust/ADJRequestHandler.m b/Adjust/ADJRequestHandler.m index ec2fb6eb1..de2232918 100644 --- a/Adjust/ADJRequestHandler.m +++ b/Adjust/ADJRequestHandler.m @@ -14,23 +14,21 @@ #import "ADJActivityPackage.h" #import "NSString+ADJAdditions.h" -static const char * const kInternalQueueName = "io.adjust.RequestQueue"; - @interface ADJRequestHandler() -@property (nonatomic, strong) dispatch_queue_t internalQueue; +@property (nonatomic, copy) NSString *baseUrlString; +@property (nonatomic, copy) NSString *gdrpUrlString; +@property (nonatomic, copy) NSString *subscriptionUrlString; +@property (nonatomic, copy) NSString *extraPath; +@property (nonatomic, copy) NSString *userAgent; +@property (nonatomic, assign) double requestTimeout; +@property (nonatomic, weak) id responseCallback; @property (nonatomic, weak) id logger; -@property (nonatomic, weak) id packageHandler; - -@property (nonatomic, weak) id activityHandler; - -@property (nonatomic, copy) NSString *basePath; - -@property (nonatomic, copy) NSString *gdprPath; +@property (nonatomic, copy) NSURLSessionConfiguration *defaultSessionConfiguration; -@property (nonatomic, copy) NSString *subscriptionPath; +@property (nonatomic, strong) NSHashTable *exceptionKeys; @end @@ -38,95 +36,497 @@ @implementation ADJRequestHandler #pragma mark - Public methods -+ (ADJRequestHandler *)handlerWithPackageHandler:(id)packageHandler - andActivityHandler:(id)activityHandler { - return [[ADJRequestHandler alloc] initWithPackageHandler:packageHandler - andActivityHandler:activityHandler]; -} - -- (id)initWithPackageHandler:(id)packageHandler - andActivityHandler:(id)activityHandler { +- (id)initWithResponseCallback:(id)responseCallback + extraPath:(NSString *)extraPath + baseUrl:(NSString *)baseUrl + gdprUrl:(NSString *)gdprUrl + subscriptionUrl:(NSString *)subscriptionUrl + userAgent:(NSString *)userAgent + requestTimeout:(double)requestTimeout +{ self = [super init]; if (self == nil) { return nil; } - - self.internalQueue = dispatch_queue_create(kInternalQueueName, DISPATCH_QUEUE_SERIAL); - self.packageHandler = packageHandler; - self.activityHandler = activityHandler; + self.baseUrlString = baseUrl; + self.gdrpUrlString = gdprUrl; + self.subscriptionUrlString = subscriptionUrl; + self.extraPath = extraPath ?: @""; + self.userAgent = userAgent; + self.requestTimeout = requestTimeout; + self.responseCallback = responseCallback; + self.logger = ADJAdjustFactory.logger; - self.basePath = [packageHandler getBasePath]; - self.gdprPath = [packageHandler getGdprPath]; - self.subscriptionPath = [packageHandler getSubscriptionPath]; + self.defaultSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; + + self.exceptionKeys = + [NSHashTable hashTableWithOptions:NSHashTableStrongMemory]; + [self.exceptionKeys addObject:@"event_callback_id"]; + [self.exceptionKeys addObject:@"secret_id"]; + [self.exceptionKeys addObject:@"signature"]; + [self.exceptionKeys addObject:@"headers_id"]; + [self.exceptionKeys addObject:@"native_version"]; + [self.exceptionKeys addObject:@"algorithm"]; + [self.exceptionKeys addObject:@"app_secret"]; return self; } -- (void)sendPackage:(ADJActivityPackage *)activityPackage queueSize:(NSUInteger)queueSize { - [ADJUtil launchInQueue:self.internalQueue - selfInject:self - block:^(ADJRequestHandler* selfI) { - [selfI sendI:selfI activityPackage:activityPackage queueSize:queueSize]; - }]; +- (void)sendPackageByPOST:(ADJActivityPackage *)activityPackage + sendingParameters:(NSDictionary *)sendingParameters +{ + NSDictionary *parameters = [[NSDictionary alloc] + initWithDictionary:activityPackage.parameters + copyItems:YES]; + NSString *path = [activityPackage.path copy]; + NSString *clientSdk = [activityPackage.clientSdk copy]; + ADJActivityKind activityKind = activityPackage.activityKind; + + NSString *urlHostString; + if (activityKind == ADJActivityKindGdpr) { + urlHostString = self.gdrpUrlString; + } else if (activityKind == ADJActivityKindSubscription) { + urlHostString = self.subscriptionUrlString; + } else { + urlHostString = self.baseUrlString; + } + + ADJResponseData *responseData = + [ADJResponseData buildResponseData:activityPackage]; + + NSString * authorizationHeader = [self buildAuthorizationHeader:parameters activityKind:activityKind]; + + NSMutableURLRequest *urlRequest = + [self requestForPostPackage:path + clientSdk:clientSdk + parameters:parameters + urlHostString:urlHostString + sendingParameters:sendingParameters]; + + [self sendRequest:urlRequest + authorizationHeader:authorizationHeader + responseData:responseData]; } -- (void)teardown { - [ADJAdjustFactory.logger verbose:@"ADJRequestHandler teardown"]; - - self.logger = nil; - self.internalQueue = nil; - self.packageHandler = nil; - self.activityHandler = nil; +- (void)sendPackageByGET:(ADJActivityPackage *)activityPackage + sendingParameters:(NSDictionary *)sendingParameters +{ + NSDictionary *parameters = [[NSDictionary alloc] + initWithDictionary:activityPackage.parameters + copyItems:YES]; + NSString *path = [activityPackage.path copy]; + NSString *clientSdk = [activityPackage.clientSdk copy]; + ADJActivityKind activityKind = activityPackage.activityKind; + + ADJResponseData *responseData = + [ADJResponseData buildResponseData:activityPackage]; + + NSString * authorizationHeader = [self buildAuthorizationHeader:parameters activityKind:activityKind]; + + NSMutableURLRequest *urlRequest = + [self requestForGetPackage:path + clientSdk:clientSdk + parameters:parameters + urlHostString:self.baseUrlString + sendingParameters:sendingParameters]; + + [self sendRequest:urlRequest + authorizationHeader:authorizationHeader + responseData:responseData]; } -#pragma mark - Private & helper methods +#pragma mark Internal methods +- (void)sendRequest:(NSMutableURLRequest *)request +authorizationHeader:(NSString *)authorizationHeader + responseData:(ADJResponseData *)responseData +{ + if (authorizationHeader != nil) { + [ADJAdjustFactory.logger debug:@"authorizationHeader %@", authorizationHeader]; + [request setValue:authorizationHeader forHTTPHeaderField:@"Authorization"]; + } + if (self.userAgent != nil) { + [request setValue:self.userAgent forHTTPHeaderField:@"User-Agent"]; + } -- (void)sendI:(ADJRequestHandler *)selfI activityPackage:(ADJActivityPackage *)activityPackage queueSize:(NSUInteger)queueSize { - NSURL *url; + Class NSURLSessionClass = NSClassFromString(@"NSURLSession"); + if (NSURLSessionClass != nil) { + [self sendNSURLSessionRequest:request + responseData:responseData]; + } else { + [self sendNSURLConnectionRequest:request + responseData:responseData]; + } +} + +- (void)sendNSURLSessionRequest:(NSMutableURLRequest *)request + responseData:(ADJResponseData *)responseData +{ + NSURLSession *session = [NSURLSession sessionWithConfiguration:self.defaultSessionConfiguration]; + NSURLSessionDataTask *task = + [session dataTaskWithRequest:request + completionHandler: + ^(NSData *data, NSURLResponse *response, NSError *error) + { + [self handleResponseWithData:data + response:(NSHTTPURLResponse *)response + error:error + responseData:responseData]; + }]; + [task resume]; + [session finishTasksAndInvalidate]; +} - if (activityPackage.activityKind == ADJActivityKindGdpr) { - NSString *gdprUrl = [ADJAdjustFactory gdprUrl]; - if (selfI.gdprPath != nil) { - url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", gdprUrl, selfI.gdprPath]]; - } else { - url = [NSURL URLWithString:gdprUrl]; +- (void)sendNSURLConnectionRequest:(NSMutableURLRequest *)request + responseData:(ADJResponseData *)responseData +{ + dispatch_async + (dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), + ^{ + NSError *error = nil; + NSURLResponse *response = nil; + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + NSData *data = [NSURLConnection sendSynchronousRequest:request + returningResponse:&response + error:&error]; + #pragma clang diagnostic pop + [self handleResponseWithData:data + response:(NSHTTPURLResponse *)response + error:error + responseData:responseData]; + }); +} + +- (void)handleResponseWithData:(NSData *)data + response:(NSHTTPURLResponse *)urlResponse + error:(NSError *)responseError + responseData:(ADJResponseData *)responseData +{ + // Connection error + if (responseError != nil) { + responseData.message = responseError.description; + [self.responseCallback responseCallback:responseData]; + return; + } + if ([ADJUtil isNull:data]) { + responseData.message = @"nil response data"; + [self.responseCallback responseCallback:responseData]; + return; + } + + NSString *responseString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] adjTrim]; + NSInteger statusCode = urlResponse.statusCode; + [self.logger verbose:@"Response: %@", responseString]; + + if (statusCode == 429) { + responseData.message = @"Too frequent requests to the endpoint (429)"; + [self.responseCallback responseCallback:responseData]; + return; + } + + [self saveJsonResponse:data responseData:responseData]; + if (responseData.jsonResponse == nil) { + [self.responseCallback responseCallback:responseData]; + return; + } + + NSString *messageResponse = [responseData.jsonResponse objectForKey:@"message"]; + responseData.message = messageResponse; + responseData.timeStamp = [responseData.jsonResponse objectForKey:@"timestamp"]; + responseData.adid = [responseData.jsonResponse objectForKey:@"adid"]; + + NSString *trackingState = [responseData.jsonResponse objectForKey:@"tracking_state"]; + if (trackingState != nil) { + if ([trackingState isEqualToString:@"opted_out"]) { + responseData.trackingState = ADJTrackingStateOptedOut; } - } else if (activityPackage.activityKind == ADJActivityKindSubscription) { - NSString *subscriptionUrl = [ADJAdjustFactory subscriptionUrl]; - if (selfI.subscriptionPath != nil) { - url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", subscriptionUrl, selfI.subscriptionPath]]; - } else { - url = [NSURL URLWithString:subscriptionUrl]; + } + + if (statusCode == 200) { + responseData.success = YES; + } + + [self.responseCallback responseCallback:responseData]; +} +#pragma mark - URL Request +- (NSMutableURLRequest *) + requestForPostPackage:(NSString *)path + clientSdk:(NSString *)clientSdk + parameters:(NSDictionary *)parameters + urlHostString:(NSString *)urlHostString + sendingParameters: + (NSDictionary *)sendingParameters +{ + NSString *urlString = [NSString stringWithFormat:@"%@%@%@", + urlHostString, self.extraPath, path]; + + [self.logger debug:@"TORMV Post final url: %@", urlString]; + + NSURL *url = [NSURL URLWithString:urlString]; + //NSURL *url = [baseUrl URLByAppendingPathComponent:path]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + request.timeoutInterval = self.requestTimeout; + request.HTTPMethod = @"POST"; + [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; + [request setValue:clientSdk forHTTPHeaderField:@"Client-Sdk"]; + + NSUInteger sendingParametersCount = sendingParameters? sendingParameters.count : 0; + NSMutableArray *kvParameters = + [NSMutableArray arrayWithCapacity: + parameters.count + sendingParametersCount]; + + [self injectParameters:parameters + kvArray:kvParameters]; + [self injectParameters:sendingParameters + kvArray:kvParameters]; + + NSString *bodyString = [kvParameters componentsJoinedByString:@"&"]; + NSData *body = [NSData dataWithBytes:bodyString.UTF8String length:bodyString.length]; + [request setHTTPBody:body]; + return request; +} + +- (NSMutableURLRequest *) + requestForGetPackage:(NSString *)path + clientSdk:(NSString *)clientSdk + parameters:(NSDictionary *)parameters + urlHostString:(NSString *)urlHostString + sendingParameters:(NSDictionary *)sendingParameters +{ + NSUInteger sendingParametersCount = sendingParameters? sendingParameters.count : 0; + NSMutableArray *kvParameters = + [NSMutableArray arrayWithCapacity: + parameters.count + sendingParametersCount]; + + [self injectParameters:parameters + kvArray:kvParameters]; + [self injectParameters:sendingParameters + kvArray:kvParameters]; + + NSString *queryStringParameters = [kvParameters componentsJoinedByString:@"&"]; + + NSString *urlString = + [NSString stringWithFormat:@"%@%@%@?%@", + urlHostString, self.extraPath, path, queryStringParameters]; + + [self.logger debug:@"TORMV Get final url: %@", urlString]; + + NSURL *url = [NSURL URLWithString:urlString]; + + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + request.timeoutInterval = self.requestTimeout; + request.HTTPMethod = @"GET"; + [request setValue:clientSdk forHTTPHeaderField:@"Client-Sdk"]; + return request; +} + +- (void) + injectParameters:(NSDictionary *)parameters + kvArray:(NSMutableArray *)kvArray +{ + if (parameters == nil || parameters.count == 0) { + return; + } + + for (NSString *key in parameters) { + if ([self.exceptionKeys containsObject:key]) { + continue; } + NSString *value = [parameters objectForKey:key]; + NSString *escapedValue = [value adjUrlEncode]; + NSString *escapedKey = [key adjUrlEncode]; + NSString *pair = [NSString stringWithFormat:@"%@=%@", escapedKey, escapedValue]; + [kvArray addObject:pair]; + } +} + +#pragma mark - Authorization Header +- (NSString *)buildAuthorizationHeader:(NSDictionary *)parameters + activityKind:(ADJActivityKind)activityKind +{ + NSString *secretId = [parameters objectForKey:@"secret_id"]; + NSString *signature = [parameters objectForKey:@"signature"]; + NSString *headersId = [parameters objectForKey:@"headers_id"]; + NSString *nativeVersion = [parameters objectForKey:@"native_version"]; + NSString *algorithm = [parameters objectForKey:@"algorithm"]; + NSString *authorizationHeader = [self buildAuthorizationHeaderV2:signature + secretId:secretId + headersId:headersId + nativeVersion:nativeVersion + algorithm:algorithm]; + if (authorizationHeader != nil) { + return authorizationHeader; + } + + NSString * appSecret = [parameters objectForKey:@"app_secret"]; + return [self buildAuthorizationHeaderV1:appSecret + secretId:secretId + parameters:parameters + activityKind:activityKind]; +} + +- (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; + } + + 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=\"%@\"", algorithm != nil ? algorithm : @"adj1"]; + + NSString * authorizationHeader = [NSString stringWithFormat:@"Signature %@,%@,%@,%@", + signatureHeader, secretIdHeader, algorithmHeader, idHeader]; + + if (nativeVersion == nil) { + return [authorizationHeader stringByAppendingFormat:@",native_version=\"\""]; + } + return [authorizationHeader stringByAppendingFormat:@",native_version=\"%@\"", nativeVersion]; +} + +- (NSString *)buildAuthorizationHeaderV1:(NSString *)appSecret + secretId:(NSString *)secretId + parameters:(NSDictionary *)parameters + activityKind:(ADJActivityKind)activityKind +{ + if (appSecret == nil) { + return nil; + } + + NSString *activityKindS = [ADJActivityKindUtil activityKindToString:activityKind]; + NSDictionary *signatureParameters = [self buildSignatureParameters:parameters + appSecret:appSecret + activityKindS:activityKindS]; + NSMutableString *fields = [[NSMutableString alloc] initWithCapacity:5]; + NSMutableString *clearSignature = [[NSMutableString alloc] initWithCapacity:5]; + + // signature part of header + for (NSDictionary *key in signatureParameters) { + [fields appendFormat:@"%@ ", key]; + NSString *value = [signatureParameters objectForKey:key]; + [clearSignature appendString:value]; + } + + NSString *secretIdHeader = [NSString stringWithFormat:@"secret_id=\"%@\"", secretId]; + // algorithm part of header + NSString *algorithm = @"sha256"; + NSString *signature = [clearSignature adjSha256]; + NSString *signatureHeader = [NSString stringWithFormat:@"signature=\"%@\"", signature]; + NSString *algorithmHeader = [NSString stringWithFormat:@"algorithm=\"%@\"", algorithm]; + // fields part of header + // Remove last empty space. + if (fields.length > 0) { + [fields deleteCharactersInRange:NSMakeRange(fields.length - 1, 1)]; + } + + NSString *fieldsHeader = [NSString stringWithFormat:@"headers=\"%@\"", fields]; + // putting it all together + NSString *authorizationHeader = [NSString stringWithFormat:@"Signature %@,%@,%@,%@", + secretIdHeader, + signatureHeader, + algorithmHeader, + fieldsHeader]; + return authorizationHeader; +} + +- (NSDictionary *)buildSignatureParameters:(NSDictionary *)parameters + appSecret:(NSString *)appSecret + activityKindS:(NSString *)activityKindS { + NSString *appSecretName = @"app_secret"; + NSString *sourceName = @"source"; + NSString *payloadName = @"payload"; + NSString *activityKindName = @"activity_kind"; + NSString *activityKindValue = activityKindS; + NSString *createdAtName = @"created_at"; + NSString *createdAtValue = [parameters objectForKey:createdAtName]; + NSString *deviceIdentifierName = [self getValidIdentifier:parameters]; + NSString *deviceIdentifierValue = [parameters objectForKey:deviceIdentifierName]; + NSMutableDictionary *signatureParameters = [[NSMutableDictionary alloc] initWithCapacity:6]; + + [self checkAndAddEntry:signatureParameters key:appSecretName value:appSecret]; + [self checkAndAddEntry:signatureParameters key:createdAtName value:createdAtValue]; + [self checkAndAddEntry:signatureParameters key:activityKindName value:activityKindValue]; + [self checkAndAddEntry:signatureParameters key:deviceIdentifierName value:deviceIdentifierValue]; + [self checkAndAddEntry:signatureParameters key:sourceName value:parameters[sourceName]]; + [self checkAndAddEntry:signatureParameters key:payloadName value:parameters[payloadName]]; + + return signatureParameters; +} + +- (void)checkAndAddEntry:(NSMutableDictionary *)parameters + key:(NSString *)key + value:(NSString *)value { + if (key == nil) { + return; + } + + if (value == nil) { + return; + } + + [parameters setObject:value forKey:key]; +} + +- (NSString *)getValidIdentifier:(NSDictionary *)parameters { + NSString *idfaName = @"idfa"; + NSString *persistentUUIDName = @"persistent_ios_uuid"; + NSString *uuidName = @"ios_uuid"; + + if ([parameters objectForKey:idfaName] != nil) { + return idfaName; + } + if ([parameters objectForKey:persistentUUIDName] != nil) { + return persistentUUIDName; + } + if ([parameters objectForKey:uuidName] != nil) { + return uuidName; + } + return nil; +} + +#pragma mark - JSON +- (void)saveJsonResponse:(NSData *)jsonData responseData:(ADJResponseData *)responseData { + NSError *error = nil; + NSException *exception = nil; + NSDictionary *jsonDict = + [self buildJsonDict:jsonData exceptionPtr:&exception errorPtr:&error]; + + if (exception != nil) { + responseData.message = + [NSString stringWithFormat: + @"Failed to parse json response. (%@)", exception.description]; + } else if (error != nil) { + responseData.message = + [NSString stringWithFormat: + @"Failed to parse json response. (%@)", error.localizedDescription]; + } else if ([ADJUtil isNull:jsonDict]) { + responseData.message = [NSString stringWithFormat:@"Failed to parse json response "]; } else { - NSString *baseUrl = [ADJAdjustFactory baseUrl]; - if (selfI.basePath != nil) { - url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", baseUrl, selfI.basePath]]; - } else { - url = [NSURL URLWithString:baseUrl]; - } + responseData.jsonResponse = jsonDict; + } +} + +- (NSDictionary *)buildJsonDict:(NSData *)jsonData + exceptionPtr:(NSException **)exceptionPtr + errorPtr:(NSError **)error { + if (jsonData == nil) { + return nil; } - [ADJUtil sendPostRequest:url - queueSize:queueSize - prefixErrorMessage:activityPackage.failureMessage - suffixErrorMessage:@"Will retry later" - activityPackage:activityPackage - responseDataHandler:^(ADJResponseData *responseData) { - // 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.activityHandler setTrackingStateOptedOut]; - return; - } - if (responseData.jsonResponse == nil) { - [selfI.packageHandler closeFirstPackage:responseData activityPackage:activityPackage]; - return; - } - - [selfI.packageHandler sendNextPackage:responseData]; - }]; + NSDictionary *jsonDict = nil; + @try { + jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:error]; + } @catch (NSException *ex) { + *exceptionPtr = ex; + return nil; + } + return jsonDict; } @end diff --git a/Adjust/ADJResponseData.h b/Adjust/ADJResponseData.h index 57b209398..d1b7c4fa0 100644 --- a/Adjust/ADJResponseData.h +++ b/Adjust/ADJResponseData.h @@ -39,9 +39,9 @@ typedef NS_ENUM(int, ADJTrackingState) { @property (nonatomic, copy) ADJAttribution *attribution; -- (id)init; +@property (nonatomic, copy) NSDictionary *sendingParameters; -+ (ADJResponseData *)responseData; +@property (nonatomic, strong) ADJActivityPackage *sdkClickPackage; + (id)buildResponseData:(ADJActivityPackage *)activityPackage; @@ -68,9 +68,8 @@ typedef NS_ENUM(int, ADJTrackingState) { - (ADJEventFailure *)failureResponseData; -- (id)initWithActivityPackage:(ADJActivityPackage *)activityPackage; - -+ (ADJResponseData *)responseDataWithActivityPackage:(ADJActivityPackage *)activityPackage; +- (id)initWithEventToken:(NSString *)eventToken + callbackId:(NSString *)callbackId; @end diff --git a/Adjust/ADJResponseData.m b/Adjust/ADJResponseData.m index 986043723..16f81a63e 100644 --- a/Adjust/ADJResponseData.m +++ b/Adjust/ADJResponseData.m @@ -11,13 +11,14 @@ @implementation ADJResponseData -- (id)init { +- (id)init +{ self = [super init]; if (self == nil) { return nil; } - + return self; } @@ -42,9 +43,16 @@ + (id)buildResponseData:(ADJActivityPackage *)activityPackage { break; case ADJActivityKindClick: responseData = [[ADJSdkClickResponseData alloc] init]; + responseData.sdkClickPackage = activityPackage; break; case ADJActivityKindEvent: - responseData = [[ADJEventResponseData alloc] initWithActivityPackage:activityPackage]; + responseData = [[ADJEventResponseData alloc] + initWithEventToken: + [activityPackage.parameters + objectForKey:@"event_token"] + callbackId: + [activityPackage.parameters + objectForKey:@"event_callback_id"]]; break; case ADJActivityKindAttribution: responseData = [[ADJAttributionResponseData alloc] init]; @@ -73,7 +81,6 @@ - (id)copyWithZone:(NSZone *)zone { copy.message = [self.message copyWithZone:zone]; copy.timeStamp = [self.timeStamp copyWithZone:zone]; copy.adid = [self.adid copyWithZone:zone]; - copy.success = self.success; copy.willRetry = self.willRetry; copy.trackingState = self.trackingState; copy.jsonResponse = [self.jsonResponse copyWithZone:zone]; @@ -87,16 +94,6 @@ - (id)copyWithZone:(NSZone *)zone { @implementation ADJSessionResponseData -- (id)initWithActivityPackage:(ADJActivityPackage *)activityPackage { - self = [super init]; - - if (self == nil) { - return nil; - } - - return self; -} - - (ADJSessionSuccess *)successResponseData { ADJSessionSuccess *successResponseData = [ADJSessionSuccess sessionSuccessResponseData]; @@ -133,19 +130,17 @@ @implementation ADJSdkClickResponseData @implementation ADJEventResponseData -+ (ADJEventResponseData *)responseDataWithActivityPackage:(ADJActivityPackage *)activityPackage { - return [[ADJEventResponseData alloc] initWithActivityPackage:activityPackage]; -} - -- (id)initWithActivityPackage:(ADJActivityPackage *)activityPackage { +- (id)initWithEventToken:(NSString *)eventToken + callbackId:(NSString *)callbackId +{ self = [super init]; if (self == nil) { return nil; } - self.eventToken = [activityPackage.parameters objectForKey:@"event_token"]; - self.callbackId = [activityPackage.parameters objectForKey:@"event_callback_id"]; + self.eventToken = eventToken; + self.callbackId = callbackId; return self; } @@ -196,16 +191,6 @@ - (id)copyWithZone:(NSZone *)zone { @implementation ADJAttributionResponseData -- (id)initWithActivityPackage:(ADJActivityPackage *)activityPackage { - self = [super init]; - - if (self == nil) { - return nil; - } - - return self; -} - - (id)copyWithZone:(NSZone *)zone { ADJAttributionResponseData *copy = [super copyWithZone:zone]; diff --git a/Adjust/ADJSdkClickHandler.h b/Adjust/ADJSdkClickHandler.h index b74ddfda7..dbd49720d 100644 --- a/Adjust/ADJSdkClickHandler.h +++ b/Adjust/ADJSdkClickHandler.h @@ -9,21 +9,17 @@ #import #import "ADJActivityPackage.h" #import "ADJActivityHandler.h" +#import "ADJRequestHandler.h" -@protocol ADJSdkClickHandler +@interface ADJSdkClickHandler : NSObject - (id)initWithActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending; + startsSending:(BOOL)startsSending + userAgent:(NSString *)userAgent + extraPath:(NSString *)extraPath; - (void)pauseSending; - (void)resumeSending; - (void)sendSdkClick:(ADJActivityPackage *)sdkClickPackage; - (void)teardown; @end - -@interface ADJSdkClickHandler : NSObject - -+ (id)handlerWithActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending; - -@end diff --git a/Adjust/ADJSdkClickHandler.m b/Adjust/ADJSdkClickHandler.m index 73ff01e7e..830e97b0f 100644 --- a/Adjust/ADJSdkClickHandler.m +++ b/Adjust/ADJSdkClickHandler.m @@ -16,9 +16,9 @@ @interface ADJSdkClickHandler() -@property (nonatomic, copy) NSString *basePath; @property (nonatomic, strong) NSMutableArray *packageQueue; @property (nonatomic, strong) dispatch_queue_t internalQueue; +@property (nonatomic, strong) ADJRequestHandler *requestHandler; @property (nonatomic, assign) BOOL paused; @property (nonatomic, strong) ADJBackoffStrategy *backoffStrategy; @@ -32,18 +32,13 @@ @interface ADJSdkClickHandler() @implementation ADJSdkClickHandler -#pragma mark - Public class methods - -+ (id)handlerWithActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending { - return [[ADJSdkClickHandler alloc] initWithActivityHandler:activityHandler - startsSending:startsSending]; -} - #pragma mark - Public instance methods - (id)initWithActivityHandler:(id)activityHandler - startsSending:(BOOL)startsSending { + startsSending:(BOOL)startsSending + userAgent:(NSString *)userAgent + extraPath:(NSString *)extraPath +{ self = [super init]; if (self == nil) { return nil; @@ -51,9 +46,17 @@ - (id)initWithActivityHandler:(id)activityHandler self.internalQueue = dispatch_queue_create(kInternalQueueName, DISPATCH_QUEUE_SERIAL); self.logger = ADJAdjustFactory.logger; - self.basePath = [activityHandler getBasePath]; self.lastPackageRetriesCount = 0; + self.requestHandler = [[ADJRequestHandler alloc] + initWithResponseCallback:self + extraPath:extraPath + baseUrl:[ADJAdjustFactory baseUrl] + gdprUrl:[ADJAdjustFactory gdprUrl] + subscriptionUrl:[ADJAdjustFactory subscriptionUrl] + userAgent:userAgent + requestTimeout:[ADJAdjustFactory requestTimeout]]; + [ADJUtil launchInQueue:self.internalQueue selfInject:self block:^(ADJSdkClickHandler *selfI) { @@ -144,38 +147,13 @@ - (void)sendNextSdkClickI:(ADJSdkClickHandler *)selfI { return; } - NSURL *url; - NSString *baseUrl = [ADJAdjustFactory baseUrl]; - if (selfI.basePath != nil) { - url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", baseUrl, selfI.basePath]]; - } else { - url = [NSURL URLWithString:baseUrl]; - } - dispatch_block_t work = ^{ - [ADJUtil sendPostRequest:url - queueSize:queueSize - 1 - prefixErrorMessage:sdkClickPackage.failureMessage - suffixErrorMessage:@"Will retry later" - activityPackage:sdkClickPackage - responseDataHandler:^(ADJResponseData *responseData) { - // 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) { - 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]; - }]; + NSDictionary *sendingParameters = @{ + @"sent_at": [ADJUtil formatSeconds1970:[NSDate.date timeIntervalSince1970]] + }; + + [selfI.requestHandler sendPackageByPOST:sdkClickPackage + sendingParameters:sendingParameters]; [selfI sendNextSdkClick]; }; @@ -192,4 +170,30 @@ - (void)sendNextSdkClickI:(ADJSdkClickHandler *)selfI { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(waitTime * NSEC_PER_SEC)), self.internalQueue, work); } +- (void)responseCallback:(ADJResponseData *)responseData { + if (responseData.jsonResponse) { + [self.logger debug: + @"Got click JSON response with message: %@", responseData.message]; + } else { + [self.logger error: + @"Could not get click JSON response with message: %@", responseData.message]; + } + // 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) { + self.lastPackageRetriesCount = 0; + [self.activityHandler setTrackingStateOptedOut]; + return; + } + if (responseData.jsonResponse == nil) { + self.lastPackageRetriesCount++; + [self.logger error:@"Retrying sdk_click package for the %d time", self.lastPackageRetriesCount]; + [self sendSdkClick:responseData.sdkClickPackage]; + return; + } + self.lastPackageRetriesCount = 0; + + [self.activityHandler finishedTracking:responseData]; +} + @end diff --git a/Adjust/ADJUtil.h b/Adjust/ADJUtil.h index dff12afca..758d1dea9 100644 --- a/Adjust/ADJUtil.h +++ b/Adjust/ADJUtil.h @@ -52,19 +52,6 @@ typedef void (^isInactiveInjected)(BOOL); selfInject:(id)selfInject block:(selfInjectedBlock)block; -+ (void)sendGetRequest:(NSURL *)baseUrl - basePath:(NSString *)basePath - prefixErrorMessage:(NSString *)prefixErrorMessage - activityPackage:(ADJActivityPackage *)activityPackage - responseDataHandler:(void (^)(ADJResponseData *responseData))responseDataHandler; - -+ (void)sendPostRequest:(NSURL *)baseUrl - queueSize:(NSUInteger)queueSize - prefixErrorMessage:(NSString *)prefixErrorMessage - suffixErrorMessage:(NSString *)suffixErrorMessage - activityPackage:(ADJActivityPackage *)activityPackage - responseDataHandler:(void (^)(ADJResponseData *responseData))responseDataHandler; - + (NSString *)idfa; + (NSString *)clientSdk; @@ -81,6 +68,9 @@ typedef void (^isInactiveInjected)(BOOL); + (NSString *)queryString:(NSDictionary *)parameters; ++ (NSString *)queryString:(NSDictionary *)parameters + queueSize:(NSUInteger)queueSize; + + (NSString *)convertDeviceToken:(NSData *)deviceToken; + (BOOL)isNull:(id)value; @@ -97,10 +87,6 @@ typedef void (^isInactiveInjected)(BOOL); + (NSDictionary *)convertDictionaryValues:(NSDictionary *)dictionary; -+ (NSDictionary *)buildJsonDict:(NSData *)jsonData - exceptionPtr:(NSException **)exceptionPtr - errorPtr:(NSError **)error; - + (NSDictionary *)mergeParameters:(NSDictionary *)target source:(NSDictionary *)source parameterName:(NSString *)parameterName; diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index ef867f2ed..347f05a96 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -36,7 +36,6 @@ static NSRegularExpression *optionalRedirectRegex = nil; static NSRegularExpression *shortUniversalLinkRegex = nil; static NSRegularExpression *excludedDeeplinkRegex = nil; -static NSURLSessionConfiguration *urlSessionConfiguration = nil; #if !TARGET_OS_TV && !TARGET_OS_MACCATALYST static CTCarrier *carrier = nil; @@ -65,7 +64,6 @@ + (void)initialize { [self initializeShortUniversalLinkRegex]; [self initializeOptionalRedirectRegex]; [self initializeExcludedDeeplinkRegex]; - [self initializeUrlSessionConfiguration]; [self initializeReachability]; #if !TARGET_OS_TV && !TARGET_OS_MACCATALYST [self initializeNetworkInfoAndCarrier]; @@ -78,7 +76,6 @@ + (void)teardown { secondsNumberFormatter = nil; optionalRedirectRegex = nil; shortUniversalLinkRegex = nil; - urlSessionConfiguration = nil; #if !TARGET_OS_TV && !TARGET_OS_MACCATALYST networkInfo = nil; carrier = nil; @@ -139,18 +136,6 @@ + (void)initializeSecondsNumberFormatter { [secondsNumberFormatter setPositiveFormat:@"0.0"]; } -+ (NSURLSessionConfiguration *)getUrlSessionConfiguration { - if (urlSessionConfiguration != nil) { - return urlSessionConfiguration; - } else { - return [NSURLSessionConfiguration defaultSessionConfiguration]; - } -} - -+ (void)initializeUrlSessionConfiguration { - urlSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; -} - #if !TARGET_OS_TV && !TARGET_OS_MACCATALYST + (void)initializeNetworkInfoAndCarrier { networkInfo = [[CTTelephonyNetworkInfo alloc] init]; @@ -248,44 +233,6 @@ + (NSString *)formatDate:(NSDate *)value { return [dateFormatter stringFromDate:value]; } -+ (void)saveJsonResponse:(NSData *)jsonData responseData:(ADJResponseData *)responseData { - NSError *error = nil; - NSException *exception = nil; - NSDictionary *jsonDict = [ADJUtil buildJsonDict:jsonData exceptionPtr:&exception errorPtr:&error]; - - if (exception != nil) { - NSString *message = [NSString stringWithFormat:@"Failed to parse json response. (%@)", exception.description]; - [ADJAdjustFactory.logger error:message]; - responseData.message = message; - return; - } - if (error != nil) { - NSString *message = [NSString stringWithFormat:@"Failed to parse json response. (%@)", error.localizedDescription]; - [ADJAdjustFactory.logger error:message]; - responseData.message = message; - return; - } - - responseData.jsonResponse = jsonDict; -} - -+ (NSDictionary *)buildJsonDict:(NSData *)jsonData - exceptionPtr:(NSException **)exceptionPtr - errorPtr:(NSError **)error { - if (jsonData == nil) { - return nil; - } - - NSDictionary *jsonDict = nil; - @try { - jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:error]; - } @catch (NSException *ex) { - *exceptionPtr = ex; - return nil; - } - return jsonDict; -} - + (id)readObject:(NSString *)fileName objectName:(NSString *)objectName class:(Class)classToRead @@ -506,425 +453,20 @@ + (BOOL)isNotNull:(id)value { return value != nil && value != (id)[NSNull null]; } -+ (NSString *)formatErrorMessage:(NSString *)prefixErrorMessage - systemErrorMessage:(NSString *)systemErrorMessage - suffixErrorMessage:(NSString *)suffixErrorMessage { - NSString *errorMessage = [NSString stringWithFormat:@"%@ (%@)", prefixErrorMessage, systemErrorMessage]; - if (suffixErrorMessage == nil) { - return errorMessage; - } else { - return [errorMessage stringByAppendingFormat:@" %@", suffixErrorMessage]; - } -} - -+ (void)sendGetRequest:(NSURL *)baseUrl - basePath:(NSString *)basePath - prefixErrorMessage:(NSString *)prefixErrorMessage - activityPackage:(ADJActivityPackage *)activityPackage - responseDataHandler:(void (^)(ADJResponseData *responseData))responseDataHandler { - NSMutableDictionary *parametersCopy = [[NSMutableDictionary alloc] initWithCapacity:[activityPackage.parameters count]]; - [parametersCopy addEntriesFromDictionary:activityPackage.parameters]; - - [ADJUtil extractEventCallbackId:parametersCopy]; - - NSString * authorizationHeader = [ADJUtil buildAuthorizationHeader:parametersCopy activityKind:activityPackage.activityKind]; - - NSMutableURLRequest *request = [ADJUtil requestForGetPackage:activityPackage.path - clientSdk:activityPackage.clientSdk - parameters:parametersCopy - baseUrl:baseUrl - basePath:basePath]; - [ADJUtil sendRequest:request - prefixErrorMessage:prefixErrorMessage - activityPackage:activityPackage - authorizationHeader:authorizationHeader - responseDataHandler:responseDataHandler]; -} - -+ (void)sendRequest:(NSMutableURLRequest *)request - prefixErrorMessage:(NSString *)prefixErrorMessage - activityPackage:(ADJActivityPackage *)activityPackage -authorizationHeader:(NSString *)authorizationHeader -responseDataHandler:(void (^)(ADJResponseData *responseData))responseDataHandler { - [ADJUtil sendRequest:request - prefixErrorMessage:prefixErrorMessage - suffixErrorMessage:nil - authorizationHeader:authorizationHeader - activityPackage:activityPackage - responseDataHandler:responseDataHandler]; -} - -+ (void)sendPostRequest:(NSURL *)baseUrl - queueSize:(NSUInteger)queueSize - prefixErrorMessage:(NSString *)prefixErrorMessage - suffixErrorMessage:(NSString *)suffixErrorMessage - activityPackage:(ADJActivityPackage *)activityPackage - responseDataHandler:(void (^)(ADJResponseData *responseData))responseDataHandler -{ - NSMutableDictionary *parametersCopy = [[NSMutableDictionary alloc] initWithCapacity:[activityPackage.parameters count]]; - [parametersCopy addEntriesFromDictionary:activityPackage.parameters]; - - [ADJUtil extractEventCallbackId:parametersCopy]; - - NSString * authorizationHeader = [ADJUtil buildAuthorizationHeader:parametersCopy activityKind:activityPackage.activityKind]; - - NSMutableURLRequest *request = [ADJUtil requestForPostPackage:activityPackage.path - clientSdk:activityPackage.clientSdk - parameters:parametersCopy - baseUrl:baseUrl queueSize:queueSize]; - [ADJUtil sendRequest:request - prefixErrorMessage:prefixErrorMessage - suffixErrorMessage:suffixErrorMessage - authorizationHeader:authorizationHeader - activityPackage:activityPackage - responseDataHandler:responseDataHandler]; -} - -+ (void)sendRequest:(NSMutableURLRequest *)request - prefixErrorMessage:(NSString *)prefixErrorMessage - suffixErrorMessage:(NSString *)suffixErrorMessage -authorizationHeader:(NSString *)authorizationHeader - activityPackage:(ADJActivityPackage *)activityPackage -responseDataHandler:(void (^)(ADJResponseData *responseData))responseDataHandler -{ - if (authorizationHeader != nil) { - [ADJAdjustFactory.logger debug:@"authorizationHeader %@", authorizationHeader]; - [request setValue:authorizationHeader forHTTPHeaderField:@"Authorization"]; - } - if (userAgent != nil) { - [request setValue:userAgent forHTTPHeaderField:@"User-Agent"]; - } - - Class NSURLSessionClass = NSClassFromString(@"NSURLSession"); - if (NSURLSessionClass != nil) { - [ADJUtil sendNSURLSessionRequest:request - prefixErrorMessage:prefixErrorMessage - suffixErrorMessage:suffixErrorMessage - activityPackage:activityPackage - responseDataHandler:responseDataHandler]; - } else { - [ADJUtil sendNSURLConnectionRequest:request - prefixErrorMessage:prefixErrorMessage - suffixErrorMessage:suffixErrorMessage - activityPackage:activityPackage - responseDataHandler:responseDataHandler]; - } -} - -+ (NSString *)buildAuthorizationHeader:(NSMutableDictionary *)parameters - activityKind:(ADJActivityKind)activityKind -{ - NSString *secretId = [ADJUtil extractEntry:parameters - key:@"secret_id"]; - NSString *signature = [ADJUtil extractEntry:parameters - key:@"signature"]; - NSString *headersId = [ADJUtil extractEntry: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 - algorithm:algorithm]; - if (authorizationHeader != nil) { - return authorizationHeader; - } - - NSString * appSecret = [ADJUtil extractEntry:parameters key:@"app_secret"]; - return [ADJUtil buildAuthorizationHeaderV1:appSecret - secretId:secretId - parameters:parameters - activityKind:activityKind]; -} - -+ (NSString *)extractEntry:(NSMutableDictionary *)parameters - key:(NSString *)key -{ - NSString *stringValue = [parameters objectForKey:key]; - if (stringValue == nil) { - return nil; - } - [parameters removeObjectForKey:key]; - return stringValue; -} - -+ (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; - } - 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=\"%@\"", algorithm != nil ? algorithm : @"adj1"]; - NSString * authorizationHeader = [NSString stringWithFormat:@"Signature %@,%@,%@,%@", - signatureHeader, secretIdHeader, algorithmHeader, idHeader]; - if (nativeVersion == nil) { - return [authorizationHeader stringByAppendingFormat:@",native_version=\"\""]; - } - return [authorizationHeader stringByAppendingFormat:@",native_version=\"%@\"", nativeVersion]; -} -+ (void)extractEventCallbackId:(NSMutableDictionary *)parameters { - NSString *eventCallbackId = [parameters objectForKey:@"event_callback_id"]; - if (eventCallbackId == nil) { - return; - } - [parameters removeObjectForKey:@"event_callback_id"]; -} -+ (NSMutableURLRequest *)requestForGetPackage:(NSString *)path - clientSdk:(NSString *)clientSdk - parameters:(NSDictionary *)parameters - baseUrl:(NSURL *)baseUrl - basePath:(NSString *)basePath { - NSString *queryStringParameters = [ADJUtil queryString:parameters]; - NSString *relativePath; - if (basePath != nil) { - relativePath = [NSString stringWithFormat:@"%@%@?%@", basePath, path, queryStringParameters]; - } else { - relativePath = [NSString stringWithFormat:@"%@?%@", path, queryStringParameters]; - } - NSURL *url = [NSURL URLWithString:relativePath relativeToURL:baseUrl]; - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; - request.timeoutInterval = kRequestTimeout; - request.HTTPMethod = @"GET"; - [request setValue:clientSdk forHTTPHeaderField:@"Client-Sdk"]; - return request; -} -+ (NSMutableURLRequest *)requestForPostPackage:(NSString *)path - clientSdk:(NSString *)clientSdk - parameters:(NSDictionary *)parameters - baseUrl:(NSURL *)baseUrl - queueSize:(NSUInteger)queueSize { - NSURL *url = [baseUrl URLByAppendingPathComponent:path]; - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; - request.timeoutInterval = kRequestTimeout; - request.HTTPMethod = @"POST"; - [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; - [request setValue:clientSdk forHTTPHeaderField:@"Client-Sdk"]; - - NSString *bodyString = [ADJUtil queryString:parameters queueSize:queueSize]; - NSData *body = [NSData dataWithBytes:bodyString.UTF8String length:bodyString.length]; - [request setHTTPBody:body]; - return request; -} -+ (NSString *)buildAuthorizationHeaderV1:(NSString *)appSecret - secretId:(NSString *)secretId - parameters:(NSMutableDictionary *)parameters - activityKind:(ADJActivityKind)activityKind -{ - if (appSecret == nil) { - return nil; - } - NSString *activityKindS = [ADJActivityKindUtil activityKindToString:activityKind]; - NSDictionary *signatureParameters = [ADJUtil buildSignatureParameters:parameters - appSecret:appSecret - activityKindS:activityKindS]; - NSMutableString *fields = [[NSMutableString alloc] initWithCapacity:5]; - NSMutableString *clearSignature = [[NSMutableString alloc] initWithCapacity:5]; - - // signature part of header - for (NSDictionary *key in signatureParameters) { - [fields appendFormat:@"%@ ", key]; - NSString *value = [signatureParameters objectForKey:key]; - [clearSignature appendString:value]; - } - - NSString *secretIdHeader = [NSString stringWithFormat:@"secret_id=\"%@\"", secretId]; - // algorithm part of header - NSString *algorithm = @"sha256"; - NSString *signature = [clearSignature adjSha256]; - NSString *signatureHeader = [NSString stringWithFormat:@"signature=\"%@\"", signature]; - NSString *algorithmHeader = [NSString stringWithFormat:@"algorithm=\"%@\"", algorithm]; - // fields part of header - // Remove last empty space. - if (fields.length > 0) { - [fields deleteCharactersInRange:NSMakeRange(fields.length - 1, 1)]; - } - - NSString *fieldsHeader = [NSString stringWithFormat:@"headers=\"%@\"", fields]; - // putting it all together - NSString *authorizationHeader = [NSString stringWithFormat:@"Signature %@,%@,%@,%@", - secretIdHeader, - signatureHeader, - algorithmHeader, - fieldsHeader]; - return authorizationHeader; -} -+ (NSDictionary *)buildSignatureParameters:(NSMutableDictionary *)parameters - appSecret:(NSString *)appSecret - activityKindS:(NSString *)activityKindS { - NSString *appSecretName = @"app_secret"; - NSString *sourceName = @"source"; - NSString *payloadName = @"payload"; - NSString *activityKindName = @"activity_kind"; - NSString *activityKindValue = activityKindS; - NSString *createdAtName = @"created_at"; - NSString *createdAtValue = [parameters objectForKey:createdAtName]; - NSString *deviceIdentifierName = [ADJUtil getValidIdentifier:parameters]; - NSString *deviceIdentifierValue = [parameters objectForKey:deviceIdentifierName]; - NSMutableDictionary *signatureParameters = [[NSMutableDictionary alloc] initWithCapacity:6]; - - [ADJUtil checkAndAddEntry:signatureParameters key:appSecretName value:appSecret]; - [ADJUtil checkAndAddEntry:signatureParameters key:createdAtName value:createdAtValue]; - [ADJUtil checkAndAddEntry:signatureParameters key:activityKindName value:activityKindValue]; - [ADJUtil checkAndAddEntry:signatureParameters key:deviceIdentifierName value:deviceIdentifierValue]; - [ADJUtil checkAndAddEntry:signatureParameters key:sourceName value:parameters[sourceName]]; - [ADJUtil checkAndAddEntry:signatureParameters key:payloadName value:parameters[payloadName]]; - - return signatureParameters; -} -+ (void)checkAndAddEntry:(NSMutableDictionary *)parameters - key:(NSString *)key - value:(NSString *)value { - if (key == nil) { - return; - } - if (value == nil) { - return; - } - - [parameters setObject:value forKey:key]; -} - -+ (NSString *)getValidIdentifier:(NSMutableDictionary *)parameters { - NSString *idfaName = @"idfa"; - NSString *persistentUUIDName = @"persistent_ios_uuid"; - NSString *uuidName = @"ios_uuid"; - - if ([parameters objectForKey:idfaName] != nil) { - return idfaName; - } - if ([parameters objectForKey:persistentUUIDName] != nil) { - return persistentUUIDName; - } - if ([parameters objectForKey:uuidName] != nil) { - return uuidName; - } - return nil; -} - -+ (void)sendNSURLSessionRequest:(NSMutableURLRequest *)request - prefixErrorMessage:(NSString *)prefixErrorMessage - suffixErrorMessage:(NSString *)suffixErrorMessage - activityPackage:(ADJActivityPackage *)activityPackage - responseDataHandler:(void (^)(ADJResponseData *responseData))responseDataHandler { - NSURLSession *session = [NSURLSession sessionWithConfiguration:[ADJUtil getUrlSessionConfiguration]]; - NSURLSessionDataTask *task = [session dataTaskWithRequest:request - completionHandler: - ^(NSData *data, NSURLResponse *response, NSError *error) { - ADJResponseData *responseData = [ADJUtil completionHandler:data - response:(NSHTTPURLResponse *)response - error:error - prefixErrorMessage:prefixErrorMessage - suffixErrorMessage:suffixErrorMessage - activityPackage:activityPackage]; - responseDataHandler(responseData); - }]; - [task resume]; - [session finishTasksAndInvalidate]; -} -+ (void)sendNSURLConnectionRequest:(NSMutableURLRequest *)request - prefixErrorMessage:(NSString *)prefixErrorMessage - suffixErrorMessage:(NSString *)suffixErrorMessage - activityPackage:(ADJActivityPackage *)activityPackage - responseDataHandler:(void (^)(ADJResponseData *responseData))responseDataHandler { - NSError *responseError = nil; - NSHTTPURLResponse *urlResponse = nil; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - NSData *data = [NSURLConnection sendSynchronousRequest:request - returningResponse:&urlResponse - error:&responseError]; -#pragma clang diagnostic pop - ADJResponseData *responseData = [ADJUtil completionHandler:data - response:(NSHTTPURLResponse *)urlResponse - error:responseError - prefixErrorMessage:prefixErrorMessage - suffixErrorMessage:suffixErrorMessage - activityPackage:activityPackage]; - responseDataHandler(responseData); -} -+ (ADJResponseData *)completionHandler:(NSData *)data - response:(NSHTTPURLResponse *)urlResponse - error:(NSError *)responseError - prefixErrorMessage:(NSString *)prefixErrorMessage - suffixErrorMessage:(NSString *)suffixErrorMessage - activityPackage:(ADJActivityPackage *)activityPackage { - ADJResponseData *responseData = [ADJResponseData buildResponseData:activityPackage]; - // Connection error - if (responseError != nil) { - NSString *errorMessage = [ADJUtil formatErrorMessage:prefixErrorMessage - systemErrorMessage:responseError.localizedDescription - suffixErrorMessage:suffixErrorMessage]; - [ADJAdjustFactory.logger error:errorMessage]; - responseData.message = errorMessage; - return responseData; - } - if ([ADJUtil isNull:data]) { - NSString *errorMessage = [ADJUtil formatErrorMessage:prefixErrorMessage - systemErrorMessage:@"empty error" - suffixErrorMessage:suffixErrorMessage]; - [ADJAdjustFactory.logger error:errorMessage]; - responseData.message = errorMessage; - return responseData; - } - - NSString *responseString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] adjTrim]; - NSInteger statusCode = urlResponse.statusCode; - [ADJAdjustFactory.logger verbose:@"Response: %@", responseString]; - - if (statusCode == 429) { - [ADJAdjustFactory.logger error:@"Too frequent requests to the endpoint (429)"]; - return responseData; - } - [ADJUtil saveJsonResponse:data responseData:responseData]; - if ([ADJUtil isNull:responseData.jsonResponse]) { - return responseData; - } - - NSString *messageResponse = [responseData.jsonResponse objectForKey:@"message"]; - responseData.message = messageResponse; - responseData.timeStamp = [responseData.jsonResponse objectForKey:@"timestamp"]; - responseData.adid = [responseData.jsonResponse objectForKey:@"adid"]; - - NSString *trackingState = [responseData.jsonResponse objectForKey:@"tracking_state"]; - if (trackingState != nil) { - if ([trackingState isEqualToString:@"opted_out"]) { - responseData.trackingState = ADJTrackingStateOptedOut; - } - } - if (messageResponse == nil) { - messageResponse = @"No message found"; - } - if (statusCode == 200) { - [ADJAdjustFactory.logger info:@"%@", messageResponse]; - responseData.success = YES; - } else { - [ADJAdjustFactory.logger error:@"%@", messageResponse]; - } - return responseData; -} // Convert all values to strings, if value is dictionary -> recursive call + (NSDictionary *)convertDictionaryValues:(NSDictionary *)dictionary { diff --git a/Adjust/Adjust.h b/Adjust/Adjust.h index c6c55a5f6..d980579e6 100644 --- a/Adjust/Adjust.h +++ b/Adjust/Adjust.h @@ -17,9 +17,7 @@ @property (nonatomic, copy, nullable) NSString *baseUrl; @property (nonatomic, copy, nullable) NSString *gdprUrl; @property (nonatomic, copy, nullable) NSString *subscriptionUrl; -@property (nonatomic, copy, nullable) NSString *basePath; -@property (nonatomic, copy, nullable) NSString *gdprPath; -@property (nonatomic, copy, nullable) NSString *subscriptionPath; +@property (nonatomic, copy, nullable) NSString *extraPath; @property (nonatomic, copy, nullable) NSNumber *timerIntervalInMilliseconds; @property (nonatomic, copy, nullable) NSNumber *timerStartInMilliseconds; @property (nonatomic, copy, nullable) NSNumber *sessionIntervalInMilliseconds; diff --git a/Adjust/Adjust.m b/Adjust/Adjust.m index 873afa13d..201769dd6 100644 --- a/Adjust/Adjust.m +++ b/Adjust/Adjust.m @@ -267,8 +267,9 @@ - (void)appDidLaunch:(ADJConfig *)adjustConfig { return; } - self.activityHandler = [ADJAdjustFactory activityHandlerWithConfig:adjustConfig - savedPreLaunch:self.savedPreLaunch]; + self.activityHandler = [[ADJActivityHandler alloc] + initWithConfig:adjustConfig + savedPreLaunch:self.savedPreLaunch]; } - (void)trackEvent:(ADJEvent *)event { @@ -525,14 +526,8 @@ - (void)teardown { } - (void)setTestOptions:(AdjustTestOptions *)testOptions { - if (testOptions.basePath != nil) { - self.savedPreLaunch.basePath = testOptions.basePath; - } - if (testOptions.gdprPath != nil) { - self.savedPreLaunch.gdprPath = testOptions.gdprPath; - } - if (testOptions.subscriptionPath != nil) { - self.savedPreLaunch.subscriptionPath = testOptions.subscriptionPath; + if (testOptions.extraPath != nil) { + self.savedPreLaunch.extraPath = testOptions.extraPath; } if (testOptions.baseUrl != nil) { [ADJAdjustFactory setBaseUrl:testOptions.baseUrl]; diff --git a/AdjustBridge/AdjustBridge.m b/AdjustBridge/AdjustBridge.m index 29d79d6b6..f8ee8edc5 100644 --- a/AdjustBridge/AdjustBridge.m +++ b/AdjustBridge/AdjustBridge.m @@ -486,8 +486,7 @@ - (void)loadWKWebViewBridge:(WKWebView *)wkWebView [self.bridgeRegister registerHandler:@"adjust_setTestOptions" handler:^(id data, WVJBResponseCallback responseCallback) { NSString *baseUrl = [data objectForKey:@"baseUrl"]; NSString *gdprUrl = [data objectForKey:@"gdprUrl"]; - NSString *basePath = [data objectForKey:@"basePath"]; - NSString *gdprPath = [data objectForKey:@"gdprPath"]; + NSString *extraPath = [data objectForKey:@"extraPath"]; NSNumber *timerIntervalInMilliseconds = [data objectForKey:@"timerIntervalInMilliseconds"]; NSNumber *timerStartInMilliseconds = [data objectForKey:@"timerStartInMilliseconds"]; NSNumber *sessionIntervalInMilliseconds = [data objectForKey:@"sessionIntervalInMilliseconds"]; @@ -505,11 +504,8 @@ - (void)loadWKWebViewBridge:(WKWebView *)wkWebView if ([self isFieldValid:gdprUrl]) { testOptions.gdprUrl = gdprUrl; } - if ([self isFieldValid:basePath]) { - testOptions.basePath = basePath; - } - if ([self isFieldValid:gdprPath]) { - testOptions.gdprPath = gdprPath; + if ([self isFieldValid:extraPath]) { + testOptions.extraPath = extraPath; } if ([self isFieldValid:timerIntervalInMilliseconds]) { testOptions.timerIntervalInMilliseconds = timerIntervalInMilliseconds; diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m b/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m index f8a24d4cc..bbacbef8a 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/ATAAdjustCommandExecutor.m @@ -20,9 +20,7 @@ @interface ATAAdjustCommandExecutor () -@property (nonatomic, copy) NSString *basePath; -@property (nonatomic, copy) NSString *gdprPath; -@property (nonatomic, copy) NSString *subscriptionPath; +@property (nonatomic, copy) NSString *extraPath; @property (nonatomic, strong) NSMutableDictionary *savedConfigs; @property (nonatomic, strong) NSMutableDictionary *savedEvents; @property (nonatomic, strong) NSObject *adjustDelegate; @@ -41,9 +39,7 @@ - (id)init { self.savedConfigs = [NSMutableDictionary dictionary]; self.savedEvents = [NSMutableDictionary dictionary]; self.adjustDelegate = nil; - self.basePath = nil; - self.gdprPath = nil; - self.subscriptionPath = nil; + self.extraPath = nil; return self; } @@ -107,9 +103,7 @@ - (void)testOptions:(NSDictionary *)parameters { testOptions.subscriptionUrl = subscriptionUrl; if ([parameters objectForKey:@"basePath"]) { - self.basePath = [parameters objectForKey:@"basePath"][0]; - self.gdprPath = [parameters objectForKey:@"basePath"][0]; - self.subscriptionPath = [parameters objectForKey:@"basePath"][0]; + self.extraPath = [parameters objectForKey:@"basePath"][0]; } if ([parameters objectForKey:@"timerInterval"]) { NSString *timerIntervalMilliS = [parameters objectForKey:@"timerInterval"][0]; @@ -161,9 +155,7 @@ - (void)testOptions:(NSDictionary *)parameters { NSString *teardownOption = teardownOptions[i]; if ([teardownOption isEqualToString:@"resetSdk"]) { testOptions.teardown = YES; - testOptions.basePath = self.basePath; - testOptions.gdprPath = self.gdprPath; - testOptions.subscriptionPath = self.subscriptionPath; + testOptions.extraPath = self.extraPath; } if ([teardownOption isEqualToString:@"deleteState"]) { testOptions.deleteState = YES; @@ -179,17 +171,13 @@ - (void)testOptions:(NSDictionary *)parameters { } if ([teardownOption isEqualToString:@"sdk"]) { testOptions.teardown = YES; - testOptions.basePath = nil; - testOptions.gdprPath = nil; - testOptions.subscriptionPath = nil; + testOptions.extraPath = nil; } if ([teardownOption isEqualToString:@"test"]) { self.savedConfigs = nil; self.savedEvents = nil; self.adjustDelegate = nil; - self.basePath = nil; - self.gdprPath = nil; - self.subscriptionPath = nil; + self.extraPath = nil; testOptions.timerIntervalInMilliseconds = [NSNumber numberWithInt:-1000]; testOptions.timerStartInMilliseconds = [NSNumber numberWithInt:-1000]; testOptions.sessionIntervalInMilliseconds = [NSNumber numberWithInt:-1000]; @@ -320,40 +308,47 @@ - (void)config:(NSDictionary *)parameters { if ([parameters objectForKey:@"attributionCallbackSendAll"]) { NSLog(@"attributionCallbackSendAll detected"); - self.adjustDelegate = [[ATAAdjustDelegateAttribution alloc] initWithTestLibrary:self.testLibrary - andBasePath:self.basePath]; + self.adjustDelegate = + [[ATAAdjustDelegateAttribution alloc] initWithTestLibrary:self.testLibrary + andExtraPath:self.extraPath]; } if ([parameters objectForKey:@"sessionCallbackSendSuccess"]) { NSLog(@"sessionCallbackSendSuccess detected"); - self.adjustDelegate = [[ATAAdjustDelegateSessionSuccess alloc] initWithTestLibrary:self.testLibrary - andBasePath:self.basePath]; + self.adjustDelegate = + [[ATAAdjustDelegateSessionSuccess alloc] initWithTestLibrary:self.testLibrary + andExtraPath:self.extraPath]; } if ([parameters objectForKey:@"sessionCallbackSendFailure"]) { NSLog(@"sessionCallbackSendFailure detected"); - self.adjustDelegate = [[ATAAdjustDelegateSessionFailure alloc] initWithTestLibrary:self.testLibrary - andBasePath:self.basePath]; + self.adjustDelegate = + [[ATAAdjustDelegateSessionFailure alloc] initWithTestLibrary:self.testLibrary + andExtraPath:self.extraPath]; } if ([parameters objectForKey:@"eventCallbackSendSuccess"]) { NSLog(@"eventCallbackSendSuccess detected"); - self.adjustDelegate = [[ATAAdjustDelegateEventSuccess alloc] initWithTestLibrary:self.testLibrary - andBasePath:self.basePath]; + self.adjustDelegate = + [[ATAAdjustDelegateEventSuccess alloc] initWithTestLibrary:self.testLibrary + andExtraPath:self.extraPath]; } if ([parameters objectForKey:@"eventCallbackSendFailure"]) { NSLog(@"eventCallbackSendFailure detected"); - self.adjustDelegate = [[ATAAdjustDelegateEventFailure alloc] initWithTestLibrary:self.testLibrary - andBasePath:self.basePath]; + self.adjustDelegate = + [[ATAAdjustDelegateEventFailure alloc] initWithTestLibrary:self.testLibrary + andExtraPath:self.extraPath]; } if ([parameters objectForKey:@"deferredDeeplinkCallback"]) { NSLog(@"deferredDeeplinkCallback detected"); NSString *shouldOpenDeeplinkS = [parameters objectForKey:@"deferredDeeplinkCallback"][0]; - self.adjustDelegate = [[ATAAdjustDelegateDeferredDeeplink alloc] initWithTestLibrary:self.testLibrary - basePath:self.basePath - andReturnValue:[shouldOpenDeeplinkS boolValue]]; + self.adjustDelegate = + [[ATAAdjustDelegateDeferredDeeplink alloc] + initWithTestLibrary:self.testLibrary + extraPath:self.extraPath + andReturnValue:[shouldOpenDeeplinkS boolValue]]; } [adjustConfig setDelegate:self.adjustDelegate]; diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateAttribution.h b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateAttribution.h index 0aaf1f8bd..9512b5247 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateAttribution.h +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateAttribution.h @@ -12,6 +12,6 @@ @interface ATAAdjustDelegateAttribution : NSObject -- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *)basePath; +- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andExtraPath:(NSString *)extraPath; @end diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateAttribution.m b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateAttribution.m index 745a528bb..2a4a24cde 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateAttribution.m +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateAttribution.m @@ -11,13 +11,13 @@ @interface ATAAdjustDelegateAttribution () @property (nonatomic, strong) ATLTestLibrary *testLibrary; -@property (nonatomic, copy) NSString *basePath; +@property (nonatomic, copy) NSString *extraPath; @end @implementation ATAAdjustDelegateAttribution -- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *)basePath { +- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andExtraPath:(NSString *)extraPath { self = [super init]; if (nil == self) { @@ -25,7 +25,7 @@ - (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *) } self.testLibrary = testLibrary; - self.basePath = basePath; + self.extraPath = extraPath; return self; } @@ -43,7 +43,7 @@ - (void)adjustAttributionChanged:(ADJAttribution *)attribution { [self.testLibrary addInfoToSend:@"clickLabel" value:attribution.clickLabel]; [self.testLibrary addInfoToSend:@"adid" value:attribution.adid]; - [self.testLibrary sendInfoToServer:self.basePath]; + [self.testLibrary sendInfoToServer:self.extraPath]; } @end diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateDeferredDeeplink.h b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateDeferredDeeplink.h index 89e3683de..0316700dc 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateDeferredDeeplink.h +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateDeferredDeeplink.h @@ -12,6 +12,6 @@ @interface ATAAdjustDelegateDeferredDeeplink : NSObject -- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary basePath:(NSString *)basePath andReturnValue:(BOOL)returnValue; +- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary extraPath:(NSString *)extraPath andReturnValue:(BOOL)returnValue; @end diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateDeferredDeeplink.m b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateDeferredDeeplink.m index 6e30364d5..43fc29e5a 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateDeferredDeeplink.m +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateDeferredDeeplink.m @@ -11,14 +11,14 @@ @interface ATAAdjustDelegateDeferredDeeplink () @property (nonatomic, strong) ATLTestLibrary *testLibrary; -@property (nonatomic, copy) NSString *basePath; +@property (nonatomic, copy) NSString *extraPath; @property (nonatomic, assign) BOOL returnValue; @end @implementation ATAAdjustDelegateDeferredDeeplink -- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary basePath:(NSString *)basePath andReturnValue:(BOOL)returnValue { +- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary extraPath:(NSString *)extraPath andReturnValue:(BOOL)returnValue { self = [super init]; if (nil == self) { @@ -26,7 +26,7 @@ - (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary basePath:(NSString *)bas } self.testLibrary = testLibrary; - self.basePath = basePath; + self.extraPath = extraPath; self.returnValue = returnValue; return self; @@ -37,7 +37,7 @@ - (BOOL)adjustDeeplinkResponse:(nullable NSURL *)deeplink { NSLog(@"Deep link: %@", deeplink); [self.testLibrary addInfoToSend:@"deeplink" value:[deeplink absoluteString]]; - [self.testLibrary sendInfoToServer:self.basePath]; + [self.testLibrary sendInfoToServer:self.extraPath]; return self.returnValue; } diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventFailure.h b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventFailure.h index 072a88c1a..5e5ee05b5 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventFailure.h +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventFailure.h @@ -12,6 +12,6 @@ @interface ATAAdjustDelegateEventFailure : NSObject -- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *)basePath; +- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andExtraPath:(NSString *)extraPath; @end diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventFailure.m b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventFailure.m index 17ba3479f..313442736 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventFailure.m +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventFailure.m @@ -11,13 +11,13 @@ @interface ATAAdjustDelegateEventFailure () @property (nonatomic, strong) ATLTestLibrary *testLibrary; -@property (nonatomic, copy) NSString *basePath; +@property (nonatomic, copy) NSString *extraPath; @end @implementation ATAAdjustDelegateEventFailure -- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *)basePath { +- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andExtraPath:(NSString *)extraPath { self = [super init]; if (nil == self) { @@ -25,7 +25,7 @@ - (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *) } self.testLibrary = testLibrary; - self.basePath = basePath; + self.extraPath = extraPath; return self; } @@ -53,7 +53,7 @@ - (void)adjustEventTrackingFailed:(ADJEventFailure *)eventFailureResponseData { [self.testLibrary addInfoToSend:@"jsonResponse" value:jsonString]; } - [self.testLibrary sendInfoToServer:self.basePath]; + [self.testLibrary sendInfoToServer:self.extraPath]; } @end diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventSuccess.h b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventSuccess.h index 129bbece5..19ab41717 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventSuccess.h +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventSuccess.h @@ -12,6 +12,6 @@ @interface ATAAdjustDelegateEventSuccess : NSObject -- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *)basePath; +- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andExtraPath:(NSString *)extraPath; @end diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventSuccess.m b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventSuccess.m index 573eafce7..d71fadad2 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventSuccess.m +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateEventSuccess.m @@ -11,13 +11,13 @@ @interface ATAAdjustDelegateEventSuccess () @property (nonatomic, strong) ATLTestLibrary *testLibrary; -@property (nonatomic, copy) NSString *basePath; +@property (nonatomic, copy) NSString *extraPath; @end @implementation ATAAdjustDelegateEventSuccess -- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *)basePath { +- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andExtraPath:(NSString *)extraPath { self = [super init]; if (nil == self) { @@ -25,7 +25,7 @@ - (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *) } self.testLibrary = testLibrary; - self.basePath = basePath; + self.extraPath = extraPath; return self; } @@ -52,7 +52,7 @@ - (void)adjustEventTrackingSucceeded:(ADJEventSuccess *)eventSuccessResponseData [self.testLibrary addInfoToSend:@"jsonResponse" value:jsonString]; } - [self.testLibrary sendInfoToServer:self.basePath]; + [self.testLibrary sendInfoToServer:self.extraPath]; } @end diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionFailure.h b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionFailure.h index 70f1e939b..a680fd3b2 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionFailure.h +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionFailure.h @@ -12,6 +12,6 @@ @interface ATAAdjustDelegateSessionFailure : NSObject -- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *)basePath; +- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andExtraPath:(NSString *)extraPath; @end diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionFailure.m b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionFailure.m index e1008cc7e..3b59a2619 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionFailure.m +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionFailure.m @@ -11,13 +11,13 @@ @interface ATAAdjustDelegateSessionFailure () @property (nonatomic, strong) ATLTestLibrary *testLibrary; -@property (nonatomic, copy) NSString *basePath; +@property (nonatomic, copy) NSString *extraPath; @end @implementation ATAAdjustDelegateSessionFailure -- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *)basePath { +- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andExtraPath:(NSString *)extraPath { self = [super init]; if (nil == self) { @@ -25,7 +25,7 @@ - (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *) } self.testLibrary = testLibrary; - self.basePath = basePath; + self.extraPath = extraPath; return self; } @@ -51,7 +51,7 @@ - (void)adjustSessionTrackingFailed:(ADJSessionFailure *)sessionFailureResponseD [self.testLibrary addInfoToSend:@"jsonResponse" value:jsonString]; } - [self.testLibrary sendInfoToServer:self.basePath]; + [self.testLibrary sendInfoToServer:self.extraPath]; } @end diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionSuccess.h b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionSuccess.h index 134d419b4..437650ac8 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionSuccess.h +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionSuccess.h @@ -12,6 +12,6 @@ @interface ATAAdjustDelegateSessionSuccess : NSObject -- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *)basePath; +- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andExtraPath:(NSString *)extraPath; @end diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionSuccess.m b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionSuccess.m index ef7c717a4..7015a95fb 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionSuccess.m +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/Delegates/ATAAdjustDelegateSessionSuccess.m @@ -11,13 +11,13 @@ @interface ATAAdjustDelegateSessionSuccess () @property (nonatomic, strong) ATLTestLibrary *testLibrary; -@property (nonatomic, copy) NSString *basePath; +@property (nonatomic, copy) NSString *extraPath; @end @implementation ATAAdjustDelegateSessionSuccess -- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *)basePath { +- (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andExtraPath:(NSString *)extraPath { self = [super init]; if (nil == self) { @@ -25,7 +25,7 @@ - (id)initWithTestLibrary:(ATLTestLibrary *)testLibrary andBasePath:(NSString *) } self.testLibrary = testLibrary; - self.basePath = basePath; + self.extraPath = extraPath; return self; } @@ -50,7 +50,7 @@ - (void)adjustSessionTrackingSucceeded:(ADJSessionSuccess *)sessionSuccessRespon [self.testLibrary addInfoToSend:@"jsonResponse" value:jsonString]; } - [self.testLibrary sendInfoToServer:self.basePath]; + [self.testLibrary sendInfoToServer:self.extraPath]; } @end diff --git a/AdjustTests/AdjustTestApp/AdjustTestApp/ViewController.m b/AdjustTests/AdjustTestApp/AdjustTestApp/ViewController.m index 9eb837814..6b62c40cb 100644 --- a/AdjustTests/AdjustTestApp/AdjustTestApp/ViewController.m +++ b/AdjustTests/AdjustTestApp/AdjustTestApp/ViewController.m @@ -30,8 +30,8 @@ - (void)viewDidLoad { andCommandDelegate:self.adjustCommandExecutor]; [self.adjustCommandExecutor setTestLibrary:self.testLibrary]; - // [self.testLibrary addTestDirectory:@"current/third-party-sharing"]; - [self.testLibrary addTest:@"Test_iOs_Subscription_subscription"]; + //[self.testLibrary addTestDirectory:@"event-callbacks"]; + //[self.testLibrary addTest:@"Test_AdRevenue_ad_revenue"]; // [self.testLibrary doNotExitAfterEnd]; [self startTestSession]; From c227e647af30a35a34a0e0c2a66512c2f6077ac9 Mon Sep 17 00:00:00 2001 From: uerceg Date: Mon, 25 May 2020 13:37:38 +0200 Subject: [PATCH 073/173] New version 4.22.0 --- 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 316a436b0..d26e45e01 100644 --- a/Adjust.podspec +++ b/Adjust.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = "Adjust" - s.version = "4.21.3" + s.version = "4.22.0" 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.3" } + s.source = { :git => "https://github.com/adjust/ios_sdk.git", :tag => "v4.22.0" } 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 347f05a96..03ee102a8 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -42,7 +42,7 @@ static CTTelephonyNetworkInfo *networkInfo = nil; #endif -static NSString * const kClientSdk = @"ios4.21.3"; +static NSString * const kClientSdk = @"ios4.22.0"; 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 d980579e6..6e6acda59 100644 --- a/Adjust/Adjust.h +++ b/Adjust/Adjust.h @@ -2,7 +2,7 @@ // Adjust.h // Adjust // -// V4.21.3 +// V4.22.0 // 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 b87799a2d..62b58c204 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.3'; + return 'web-bridge4.22.0'; } }, setTestOptions: function(testOptions) { diff --git a/AdjustTests/AdjustUnitTests/ADJPackageFields.m b/AdjustTests/AdjustUnitTests/ADJPackageFields.m index ab7a0b56e..d41d85980 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.3"; + self.clientSdk = @"ios4.22.0"; self.suffix = @""; self.environment = @"sandbox"; diff --git a/README.md b/README.md index b65b65a3d..8faa04cbb 100644 --- a/README.md +++ b/README.md @@ -75,13 +75,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.3' +pod 'Adjust', '~> 4.22.0' ``` or: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.3' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.0' ``` --- diff --git a/VERSION b/VERSION index fedb11348..d7638f377 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.21.3 +4.22.0 diff --git a/doc/chinese/README.md b/doc/chinese/README.md index 4d497188b..07e41ebe5 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.3' +pod 'Adjust', '~> 4.22.0' ``` 或: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.3' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.0' ``` --- diff --git a/doc/english/migrate.md b/doc/english/migrate.md index 754f75536..1b4b98dc5 100644 --- a/doc/english/migrate.md +++ b/doc/english/migrate.md @@ -1,4 +1,4 @@ -## Migrate your Adjust SDK for iOS to v4.21.3 from v3.4.0 +## Migrate your Adjust SDK for iOS to v4.22.0 from v3.4.0 ### Initial setup diff --git a/doc/english/web_views.md b/doc/english/web_views.md index 3758dc7f3..3e1b83d49 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.3' +pod 'Adjust/WebBridge', '~> 4.22.0' ``` --- diff --git a/doc/japanese/README.md b/doc/japanese/README.md index 068d4cc50..e6ffc2957 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.3' +pod 'Adjust', '~> 4.22.0' ``` または ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.3' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.0' ``` --- diff --git a/doc/korean/README.md b/doc/korean/README.md index 98586b073..16d6727cd 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.3' +pod 'Adjust', '~> 4.22.0' ``` 또는: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.21.3' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.0' ``` --- diff --git a/doc/korean/web_views.md b/doc/korean/web_views.md index e191eb289..2775d6800 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.3' +pod 'Adjust/WebBridge', '~> 4.22.0' ``` --- diff --git a/doc/migrate.md b/doc/migrate.md index 754f75536..1b4b98dc5 100644 --- a/doc/migrate.md +++ b/doc/migrate.md @@ -1,4 +1,4 @@ -## Migrate your Adjust SDK for iOS to v4.21.3 from v3.4.0 +## Migrate your Adjust SDK for iOS to v4.22.0 from v3.4.0 ### Initial setup From 201c5403af16d9166c2f466da790ebb6316aeaac Mon Sep 17 00:00:00 2001 From: uerceg Date: Mon, 25 May 2020 13:39:33 +0200 Subject: [PATCH 074/173] CHANGELOG.md update --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3251a15ce..b996d6f8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### Version 4.22.0 (xxth May 2020) +#### Added +- Added subscription tracking feature (`trackSubscription:` method added to `Adjust` API). + +--- + ### Version 4.21.3 (22nd April 2020) #### Changed - Added copying of each injected mutable property of `ADJEvent` class. From a8061c5b1c16145da4e16399c918b31f8cfeb097 Mon Sep 17 00:00:00 2001 From: mcoombs <52657116+mcoombs@users.noreply.github.com> Date: Tue, 26 May 2020 19:23:33 +0200 Subject: [PATCH 075/173] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8faa04cbb..20254df7a 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Read this in other languages: [English][en-readme], [中文][zh-readme], [日本 * [Delay start](#delay-start) * [Attribution callback](#attribution-callback) * [Ad revenue tracking](#ad-revenue) - * [Subscriptions tracking](#subscriptions) + * [Subscription tracking](#subscriptions) * [Event and session callbacks](#event-session-callbacks) * [Disable tracking](#disable-tracking) * [Offline mode](#offline-mode) @@ -519,11 +519,11 @@ Currently we support the below `source` parameter values: - `ADJAdRevenueSourceMopub` - representing MoPub mediation platform (for more information, check [integration guide][sdk2sdk-mopub]) -### Subscriptions tracking +### Subscription tracking -**Note**: This feature is available only in the native SDK v4.22.0 and above. +**Note**: This feature is only available in the native SDK v4.22.0 and above. -You can track App Store subscriptions and verify their validity with Adjust SDK. After subscription has been successfully purchased, you need to make following call to Adjust SDK: +You can track App Store subscriptions and verify their validity with the Adjust SDK. After a subscription has been successfully purchased, make the following call to the Adjust SDK: ```objc ADJSubscription *subscription = [[ADJSubscription alloc] initWithPrice:price @@ -548,7 +548,7 @@ Subscription tracking parameters: - [transactionDate](https://developer.apple.com/documentation/storekit/skpaymenttransaction/1411273-transactiondate?language=objc) - salesRegion (you need to pass [countryCode](https://developer.apple.com/documentation/foundation/nslocale/1643060-countrycode?language=objc) of the [priceLocale](https://developer.apple.com/documentation/storekit/skproduct/1506145-pricelocale?language=objc) object) -In same fashion like with event tracking, you can attach callback and partner parameters to subscription object as well: +Just like with event tracking, you can attach callback and partner parameters to the subscription object as well: ```objc ADJSubscription *subscription = [[ADJSubscription alloc] initWithPrice:price From 2c439697857a4f4b1b83711eaac9503ab0c776f4 Mon Sep 17 00:00:00 2001 From: mcoombs <52657116+mcoombs@users.noreply.github.com> Date: Tue, 26 May 2020 19:45:17 +0200 Subject: [PATCH 076/173] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 20254df7a..6116015a9 100644 --- a/README.md +++ b/README.md @@ -536,8 +536,7 @@ ADJSubscription *subscription = [[ADJSubscription alloc] initWithPrice:price [Adjust trackSubscription:subscription]; ``` - -Make sure to do this before making a call to `finishTransaction` in `paymentQueue:updatedTransaction` only if the state changed to `SKPaymentTransactionStatePurchased` or `SKPaymentTransactionStateRestored`. +Only do this when the state has changed to `SKPaymentTransactionStatePurchased` or `SKPaymentTransactionStateRestored`. Then make a call to `finishTransaction` in `paymentQueue:updatedTransaction` . Subscription tracking parameters: From 505d0837765cede3c7f68c92332f19db2fb56a82 Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 26 May 2020 23:05:13 +0200 Subject: [PATCH 077/173] Remove some log messages --- Adjust/ADJRequestHandler.m | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Adjust/ADJRequestHandler.m b/Adjust/ADJRequestHandler.m index de2232918..b34e25506 100644 --- a/Adjust/ADJRequestHandler.m +++ b/Adjust/ADJRequestHandler.m @@ -261,8 +261,6 @@ - (void)handleResponseWithData:(NSData *)data NSString *urlString = [NSString stringWithFormat:@"%@%@%@", urlHostString, self.extraPath, path]; - [self.logger debug:@"TORMV Post final url: %@", urlString]; - NSURL *url = [NSURL URLWithString:urlString]; //NSURL *url = [baseUrl URLByAppendingPathComponent:path]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; @@ -310,8 +308,6 @@ - (void)handleResponseWithData:(NSData *)data [NSString stringWithFormat:@"%@%@%@?%@", urlHostString, self.extraPath, path, queryStringParameters]; - [self.logger debug:@"TORMV Get final url: %@", urlString]; - NSURL *url = [NSURL URLWithString:urlString]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; From 6e6afffdbba65d0c897e628ce09d2a303af196cc Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 27 May 2020 10:30:07 +0200 Subject: [PATCH 078/173] Remove unused timeout constant --- Adjust/ADJUtil.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 03ee102a8..b3c1b1e29 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -27,8 +27,6 @@ // 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 - static NSString *userAgent = nil; static ADJReachability *reachability = nil; static NSRegularExpression *universalLinkRegex = nil; From 7f65052cfd02110bb936433db23aac39f9648320 Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 27 May 2020 15:54:27 +0200 Subject: [PATCH 079/173] Activity state synchronisation --- Adjust/ADJActivityHandler.m | 168 +++++++++++++++++++++++++++--------- Adjust/ADJPackageHandler.m | 5 +- Adjust/ADJUtil.h | 7 +- Adjust/ADJUtil.m | 12 ++- 4 files changed, 146 insertions(+), 46 deletions(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index d119c9d9f..c47acd00d 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -149,7 +149,10 @@ - (id)initWithConfig:(ADJConfig *)adjustConfig [self.logger lockLogLevel]; // inject app token be available in activity state - [ADJActivityState saveAppToken:adjustConfig.appToken]; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + [ADJActivityState saveAppToken:adjustConfig.appToken]; + }]; // read files to have sync values available [self readAttribution]; @@ -480,8 +483,11 @@ - (void)sendIad3ClickPackage:(ADJActivityHandler *)selfI double now = [NSDate.date timeIntervalSince1970]; if (selfI.activityState != nil) { - double lastInterval = now - selfI.activityState.lastActivity; - selfI.activityState.lastInterval = lastInterval; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + double lastInterval = now - selfI.activityState.lastActivity; + selfI.activityState.lastInterval = lastInterval; + }]; } ADJPackageBuilder *clickBuilder = [[ADJPackageBuilder alloc] initWithDeviceInfo:selfI.deviceInfo @@ -500,7 +506,10 @@ - (void)saveAttributionDetailsI:(ADJActivityHandler *)selfI attributionDetails:(NSDictionary *)attributionDetails { // save new iAd details - selfI.activityState.attributionDetails = attributionDetails; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.attributionDetails = attributionDetails; + }]; [selfI writeAttributionI:selfI]; } @@ -838,7 +847,10 @@ - (void)processSessionI:(ADJActivityHandler *)selfI { NSData *deviceToken = [ADJUserDefaults getPushTokenData]; NSString *deviceTokenString = [ADJUtil convertDeviceToken:deviceToken]; NSString *pushToken = [ADJUserDefaults getPushTokenString]; - selfI.activityState.deviceToken = deviceTokenString != nil ? deviceTokenString : pushToken; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.deviceToken = deviceTokenString != nil ? deviceTokenString : pushToken; + }]; // track the first session package only if it's enabled if ([selfI.internalState isEnabled]) { @@ -850,14 +862,20 @@ - (void)processSessionI:(ADJActivityHandler *)selfI { if ([ADJUserDefaults getDisableThirdPartySharing]) { [selfI disableThirdPartySharingI:selfI]; } - selfI.activityState.sessionCount = 1; // this is the first session + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.sessionCount = 1; // this is the first session + }]; [selfI transferSessionPackageI:selfI now:now]; } } - [selfI.activityState resetSessionAttributes:now]; - selfI.activityState.enabled = [selfI.internalState isEnabled]; - selfI.activityState.updatePackages = [selfI.internalState itHasToUpdatePackages]; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + [selfI.activityState resetSessionAttributes:now]; + selfI.activityState.enabled = [selfI.internalState isEnabled]; + selfI.activityState.updatePackages = [selfI.internalState itHasToUpdatePackages]; + }]; [selfI writeActivityStateI:selfI]; [ADJUserDefaults removePushToken]; @@ -869,7 +887,10 @@ - (void)processSessionI:(ADJActivityHandler *)selfI { double lastInterval = now - selfI.activityState.lastActivity; if (lastInterval < 0) { [selfI.logger error:@"Time travel!"]; - selfI.activityState.lastActivity = now; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.lastActivity = now; + }]; [selfI writeActivityStateI:selfI]; return; } @@ -882,9 +903,12 @@ - (void)processSessionI:(ADJActivityHandler *)selfI { // new subsession if (lastInterval > kSubSessionInterval) { - selfI.activityState.subsessionCount++; - selfI.activityState.sessionLength += lastInterval; - selfI.activityState.lastActivity = now; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.subsessionCount++; + selfI.activityState.sessionLength += lastInterval; + selfI.activityState.lastActivity = now; + }]; [selfI.logger verbose:@"Started subsession %d of session %d", selfI.activityState.subsessionCount, selfI.activityState.sessionCount]; @@ -901,10 +925,16 @@ - (void)trackNewSessionI:(double)now withActivityHandler:(ADJActivityHandler *)s } double lastInterval = now - selfI.activityState.lastActivity; - selfI.activityState.sessionCount++; - selfI.activityState.lastInterval = lastInterval; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.sessionCount++; + selfI.activityState.lastInterval = lastInterval; + }]; [selfI transferSessionPackageI:selfI now:now]; - [selfI.activityState resetSessionAttributes:now]; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + [selfI.activityState resetSessionAttributes:now]; + }]; [selfI writeActivityStateI:selfI]; } @@ -977,7 +1007,10 @@ - (void)eventI:(ADJActivityHandler *)selfI double now = [NSDate.date timeIntervalSince1970]; - selfI.activityState.eventCount++; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.eventCount++; + }]; [selfI updateActivityStateI:selfI now:now]; // create and populate event package @@ -1075,7 +1108,10 @@ - (void)disableThirdPartySharingI:(ADJActivityHandler *)selfI { return; } - selfI.activityState.isThirdPartySharingDisabled = YES; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.isThirdPartySharingDisabled = YES; + }]; [selfI writeActivityStateI:selfI]; double now = [NSDate.date timeIntervalSince1970]; @@ -1241,7 +1277,10 @@ - (void)updateAdidI:(ADJActivityHandler *)selfI return; } - selfI.activityState.adid = adid; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.adid = adid; + }]; [selfI writeActivityStateI:selfI]; } @@ -1300,7 +1339,10 @@ - (void)setEnabledI:(ADJActivityHandler *)selfI enabled:(BOOL)enabled { } // Save new enabled state in activity state. - selfI.activityState.enabled = enabled; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.enabled = enabled; + }]; [selfI writeActivityStateI:selfI]; // Check if upon enabling install has been tracked. @@ -1448,8 +1490,11 @@ - (void)appWillOpenUrlI:(ADJActivityHandler *)selfI } double now = [NSDate.date timeIntervalSince1970]; - double lastInterval = now - selfI.activityState.lastActivity; - selfI.activityState.lastInterval = lastInterval; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + double lastInterval = now - selfI.activityState.lastActivity; + selfI.activityState.lastInterval = lastInterval; + }]; ADJPackageBuilder *clickBuilder = [[ADJPackageBuilder alloc] initWithDeviceInfo:selfI.deviceInfo activityState:selfI.activityState config:selfI.adjustConfig @@ -1543,7 +1588,10 @@ - (void)setDeviceTokenI:(ADJActivityHandler *)selfI } // save new push token - selfI.activityState.deviceToken = deviceTokenString; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.deviceToken = deviceTokenString; + }]; [selfI writeActivityStateI:selfI]; // send info package @@ -1587,7 +1635,10 @@ - (void)setPushTokenI:(ADJActivityHandler *)selfI } // save new push token - selfI.activityState.deviceToken = pushToken; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.deviceToken = pushToken; + }]; [selfI writeActivityStateI:selfI]; // send info package @@ -1622,7 +1673,10 @@ - (void)setGdprForgetMeI:(ADJActivityHandler *)selfI { return; } - selfI.activityState.isGdprForgotten = YES; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.isGdprForgotten = YES; + }]; [selfI writeActivityStateI:selfI]; // Send GDPR package @@ -1648,7 +1702,10 @@ - (void)setGdprForgetMeI:(ADJActivityHandler *)selfI { - (void)setTrackingStateOptedOutI:(ADJActivityHandler *)selfI { // In case of web opt out, once response from backend arrives isGdprForgotten field in this moment defaults to NO. // Set it to YES regardless of state, since at this moment it should be YES. - selfI.activityState.isGdprForgotten = YES; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.isGdprForgotten = YES; + }]; [selfI writeActivityStateI:selfI]; [selfI setEnabled:NO]; @@ -1691,14 +1748,20 @@ - (BOOL)updateActivityStateI:(ADJActivityHandler *)selfI // ignore late updates if (lastInterval > kSessionInterval) return NO; - selfI.activityState.lastActivity = now; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.lastActivity = now; + }]; if (lastInterval < 0) { [selfI.logger error:@"Time travel!"]; return YES; } else { - selfI.activityState.sessionLength += lastInterval; - selfI.activityState.timeSpent += lastInterval; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.sessionLength += lastInterval; + selfI.activityState.timeSpent += lastInterval; + }]; } return YES; @@ -1706,12 +1769,16 @@ - (BOOL)updateActivityStateI:(ADJActivityHandler *)selfI - (void)writeActivityStateI:(ADJActivityHandler *)selfI { - @synchronized ([ADJActivityState class]) { + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ if (selfI.activityState == nil) { return; } - [ADJUtil writeObject:selfI.activityState fileName:kActivityStateFilename objectName:@"Activity state"]; - } + [ADJUtil writeObject:selfI.activityState + fileName:kActivityStateFilename + objectName:@"Activity state" + syncObject:[ADJActivityState class]]; + }]; } - (void)teardownActivityStateS @@ -1729,7 +1796,10 @@ - (void)writeAttributionI:(ADJActivityHandler *)selfI { if (selfI.attribution == nil) { return; } - [ADJUtil writeObject:selfI.attribution fileName:kAttributionFilename objectName:@"Attribution"]; + [ADJUtil writeObject:selfI.attribution + fileName:kAttributionFilename + objectName:@"Attribution" + syncObject:[ADJAttribution class]]; } } @@ -1744,10 +1814,13 @@ - (void)teardownAttributionS } - (void)readActivityState { - [NSKeyedUnarchiver setClass:[ADJActivityState class] forClassName:@"AIActivityState"]; - self.activityState = [ADJUtil readObject:kActivityStateFilename - objectName:@"Activity state" - class:[ADJActivityState class]]; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + [NSKeyedUnarchiver setClass:[ADJActivityState class] forClassName:@"AIActivityState"]; + self.activityState = [ADJUtil readObject:kActivityStateFilename + objectName:@"Activity state" + class:[ADJActivityState class]]; + }]; } - (void)readAttribution { @@ -1763,7 +1836,8 @@ - (void)writeSessionCallbackParametersI:(ADJActivityHandler *)selfI { } [ADJUtil writeObject:selfI.sessionParameters.callbackParameters fileName:kSessionCallbackParametersFilename - objectName:@"Session Callback parameters"]; + objectName:@"Session Callback parameters" + syncObject:[ADJSessionParameters class]]; } } @@ -1774,7 +1848,8 @@ - (void)writeSessionPartnerParametersI:(ADJActivityHandler *)selfI { } [ADJUtil writeObject:selfI.sessionParameters.partnerParameters fileName:kSessionPartnerParametersFilename - objectName:@"Session Partner parameters"]; + objectName:@"Session Partner parameters" + syncObject:[ADJSessionParameters class]]; } } @@ -1885,7 +1960,10 @@ - (BOOL)toSendI:(ADJActivityHandler *)selfI - (void)setAskingAttributionI:(ADJActivityHandler *)selfI askingAttribution:(BOOL)askingAttribution { - selfI.activityState.askingAttribution = askingAttribution; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.askingAttribution = askingAttribution; + }]; [selfI writeActivityStateI:selfI]; } @@ -1984,7 +2062,10 @@ - (void)delayStartI:(ADJActivityHandler *)selfI { selfI.internalState.updatePackages = YES; if (selfI.activityState != nil) { - selfI.activityState.updatePackages = YES; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.updatePackages = YES; + }]; [selfI writeActivityStateI:selfI]; } } @@ -2012,7 +2093,10 @@ - (void)updatePackagesI:(ADJActivityHandler *)selfI { // no longer needs to update packages selfI.internalState.updatePackages = NO; if (selfI.activityState != nil) { - selfI.activityState.updatePackages = NO; + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + selfI.activityState.updatePackages = NO; + }]; [selfI writeActivityStateI:selfI]; } } diff --git a/Adjust/ADJPackageHandler.m b/Adjust/ADJPackageHandler.m index 29942b1b7..9bd82a966 100644 --- a/Adjust/ADJPackageHandler.m +++ b/Adjust/ADJPackageHandler.m @@ -319,7 +319,10 @@ - (void)writePackageQueueS:(ADJPackageHandler *)selfS { return; } - [ADJUtil writeObject:selfS.packageQueue fileName:kPackageQueueFilename objectName:@"Package queue"]; + [ADJUtil writeObject:selfS.packageQueue + fileName:kPackageQueueFilename + objectName:@"Package queue" + syncObject:[ADJPackageHandler class]]; } } diff --git a/Adjust/ADJUtil.h b/Adjust/ADJUtil.h index 758d1dea9..c62606199 100644 --- a/Adjust/ADJUtil.h +++ b/Adjust/ADJUtil.h @@ -16,6 +16,7 @@ #import "ADJBackoffStrategy.h" typedef void (^selfInjectedBlock)(id); +typedef void (^synchronisedBlock)(void); typedef void (^isInactiveInjected)(BOOL); @interface ADJUtil : NSObject @@ -42,7 +43,8 @@ typedef void (^isInactiveInjected)(BOOL); + (void)writeObject:(id)object fileName:(NSString *)fileName - objectName:(NSString *)objectName; + objectName:(NSString *)objectName + syncObject:(id)syncObject; + (void)launchInMainThread:(NSObject *)receiver selector:(SEL)selector @@ -52,6 +54,9 @@ typedef void (^isInactiveInjected)(BOOL); selfInject:(id)selfInject block:(selfInjectedBlock)block; ++ (void)launchSynchronisedWithObject:(id)synchronisationObject + block:(synchronisedBlock)block; + + (NSString *)idfa; + (NSString *)clientSdk; diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index b3c1b1e29..4e94be28b 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -315,8 +315,9 @@ + (id)readObject:(NSString *)fileName + (void)writeObject:(id)object fileName:(NSString *)fileName - objectName:(NSString *)objectName { - @synchronized([ADJUtil class]) { + objectName:(NSString *)objectName + syncObject:(id)syncObject { + @synchronized(syncObject) { @try { BOOL result; NSString *filePath = [ADJUtil getFilePathInAppSupportDir:fileName]; @@ -781,6 +782,13 @@ + (void)launchInQueue:(dispatch_queue_t)queue }); } ++ (void)launchSynchronisedWithObject:(id)synchronisationObject + block:(synchronisedBlock)block { + @synchronized (synchronisationObject) { + block(); + } +} + + (BOOL)deleteFileWithName:(NSString *)fileName { NSString *documentsFilePath = [ADJUtil getFilePathInDocumentsDir:fileName]; NSString *appSupportFilePath = [ADJUtil getFilePathInAppSupportDir:fileName]; From 8fa2ea089f7152fd1eb3aa7b4a0e45c471376587 Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 27 May 2020 16:19:02 +0200 Subject: [PATCH 080/173] Package queue synchronisation --- Adjust/ADJActivityHandler.m | 12 ++-- Adjust/ADJPackageHandler.m | 106 +++++++++++++++++++++--------------- Adjust/ADJUtil.h | 3 +- Adjust/ADJUtil.m | 3 +- 4 files changed, 75 insertions(+), 49 deletions(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index c47acd00d..5d5be4629 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -1819,14 +1819,16 @@ - (void)readActivityState { [NSKeyedUnarchiver setClass:[ADJActivityState class] forClassName:@"AIActivityState"]; self.activityState = [ADJUtil readObject:kActivityStateFilename objectName:@"Activity state" - class:[ADJActivityState class]]; + class:[ADJActivityState class] + syncObject:[ADJActivityState class]]; }]; } - (void)readAttribution { self.attribution = [ADJUtil readObject:kAttributionFilename objectName:@"Attribution" - class:[ADJAttribution class]]; + class:[ADJAttribution class] + syncObject:[ADJAttribution class]]; } - (void)writeSessionCallbackParametersI:(ADJActivityHandler *)selfI { @@ -1867,13 +1869,15 @@ - (void)teardownAllSessionParametersS { - (void)readSessionCallbackParametersI:(ADJActivityHandler *)selfI { selfI.sessionParameters.callbackParameters = [ADJUtil readObject:kSessionCallbackParametersFilename objectName:@"Session Callback parameters" - class:[NSDictionary class]]; + class:[NSDictionary class] + syncObject:[ADJSessionParameters class]]; } - (void)readSessionPartnerParametersI:(ADJActivityHandler *)selfI { selfI.sessionParameters.partnerParameters = [ADJUtil readObject:kSessionPartnerParametersFilename objectName:@"Session Partner parameters" - class:[NSDictionary class]]; + class:[NSDictionary class] + syncObject:[ADJSessionParameters class]]; } # pragma mark - handlers status diff --git a/Adjust/ADJPackageHandler.m b/Adjust/ADJPackageHandler.m index 9bd82a966..e62d247a8 100644 --- a/Adjust/ADJPackageHandler.m +++ b/Adjust/ADJPackageHandler.m @@ -212,7 +212,10 @@ - (void)initI:(ADJPackageHandler *)selfI - (void)addI:(ADJPackageHandler *)selfI package:(ADJActivityPackage *)newPackage { - [selfI.packageQueue addObject:newPackage]; + [ADJUtil launchSynchronisedWithObject:[ADJPackageHandler class] + block:^{ + [selfI.packageQueue addObject:newPackage]; + }]; [selfI.logger debug:@"Added package %d (%@)", selfI.packageQueue.count, newPackage]; [selfI.logger verbose:@"%@", newPackage.extendedString]; @@ -257,7 +260,10 @@ - (void)sendFirstI:(ADJPackageHandler *)selfI - (void)sendNextI:(ADJPackageHandler *)selfI { if ([selfI.packageQueue count] > 0) { - [selfI.packageQueue removeObjectAtIndex:0]; + [ADJUtil launchSynchronisedWithObject:[ADJPackageHandler class] + block:^{ + [selfI.packageQueue removeObjectAtIndex:0]; + }]; [selfI writePackageQueueS:selfI]; } @@ -272,69 +278,83 @@ - (void)updatePackagesI:(ADJPackageHandler *)selfI [selfI.logger verbose:@"Session callback parameters: %@", sessionParameters.callbackParameters]; [selfI.logger verbose:@"Session partner parameters: %@", sessionParameters.partnerParameters]; - for (ADJActivityPackage * activityPackage in selfI.packageQueue) { - // callback parameters - NSDictionary * mergedCallbackParameters = [ADJUtil mergeParameters:sessionParameters.callbackParameters - source:activityPackage.callbackParameters - parameterName:@"Callback"]; - - [ADJPackageBuilder parameters:activityPackage.parameters - setDictionary:mergedCallbackParameters - forKey:@"callback_params"]; - - // partner parameters - NSDictionary * mergedPartnerParameters = [ADJUtil mergeParameters:sessionParameters.partnerParameters - source:activityPackage.partnerParameters - parameterName:@"Partner"]; - - [ADJPackageBuilder parameters:activityPackage.parameters - setDictionary:mergedPartnerParameters - forKey:@"partner_params"]; - } + [ADJUtil launchSynchronisedWithObject:[ADJPackageHandler class] + block:^{ + for (ADJActivityPackage * activityPackage in selfI.packageQueue) { + // callback parameters + NSDictionary * mergedCallbackParameters = [ADJUtil mergeParameters:sessionParameters.callbackParameters + source:activityPackage.callbackParameters + parameterName:@"Callback"]; + + [ADJPackageBuilder parameters:activityPackage.parameters + setDictionary:mergedCallbackParameters + forKey:@"callback_params"]; + + // partner parameters + NSDictionary * mergedPartnerParameters = [ADJUtil mergeParameters:sessionParameters.partnerParameters + source:activityPackage.partnerParameters + parameterName:@"Partner"]; + + [ADJPackageBuilder parameters:activityPackage.parameters + setDictionary:mergedPartnerParameters + forKey:@"partner_params"]; + } + }]; [selfI writePackageQueueS:selfI]; } - (void)flushI:(ADJPackageHandler *)selfI { - [selfI.packageQueue removeAllObjects]; + [ADJUtil launchSynchronisedWithObject:[ADJPackageHandler class] + block:^{ + [selfI.packageQueue removeAllObjects]; + }]; [selfI writePackageQueueS:selfI]; } #pragma mark - private - (void)readPackageQueueI:(ADJPackageHandler *)selfI { - [NSKeyedUnarchiver setClass:[ADJActivityPackage class] forClassName:@"AIActivityPackage"]; - - id object = [ADJUtil readObject:kPackageQueueFilename objectName:@"Package queue" class:[NSArray class]]; - - if (object != nil) { - selfI.packageQueue = object; - } else { - selfI.packageQueue = [NSMutableArray array]; - } + [ADJUtil launchSynchronisedWithObject:[ADJPackageHandler class] + block:^{ + [NSKeyedUnarchiver setClass:[ADJActivityPackage class] forClassName:@"AIActivityPackage"]; + + id object = [ADJUtil readObject:kPackageQueueFilename + objectName:@"Package queue" + class:[NSArray class] + syncObject:[ADJPackageHandler class]]; + + if (object != nil) { + selfI.packageQueue = object; + } else { + selfI.packageQueue = [NSMutableArray array]; + } + }]; } - (void)writePackageQueueS:(ADJPackageHandler *)selfS { - @synchronized ([ADJPackageHandler class]) { - if (selfS.packageQueue == nil) { - return; - } - + if (selfS.packageQueue == nil) { + return; + } + + [ADJUtil launchSynchronisedWithObject:[ADJPackageHandler class] + block:^{ [ADJUtil writeObject:selfS.packageQueue fileName:kPackageQueueFilename objectName:@"Package queue" syncObject:[ADJPackageHandler class]]; - } + }]; } - (void)teardownPackageQueueS { - @synchronized ([ADJPackageHandler class]) { - if (self.packageQueue == nil) { - return; - } - + if (self.packageQueue == nil) { + return; + } + + [ADJUtil launchSynchronisedWithObject:[ADJPackageHandler class] + block:^{ [self.packageQueue removeAllObjects]; self.packageQueue = nil; - } + }]; } - (void)dealloc { diff --git a/Adjust/ADJUtil.h b/Adjust/ADJUtil.h index c62606199..d63421745 100644 --- a/Adjust/ADJUtil.h +++ b/Adjust/ADJUtil.h @@ -25,7 +25,8 @@ typedef void (^isInactiveInjected)(BOOL); + (id)readObject:(NSString *)fileName objectName:(NSString *)objectName - class:(Class)classToRead; + class:(Class)classToRead + syncObject:(id)syncObject; + (void)excludeFromBackup:(NSString *)filename; diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 4e94be28b..d380749c0 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -234,8 +234,9 @@ + (NSString *)formatDate:(NSDate *)value { + (id)readObject:(NSString *)fileName objectName:(NSString *)objectName class:(Class)classToRead + syncObject:(id)syncObject { - @synchronized([ADJUtil class]) { + @synchronized(syncObject) { NSString *documentsFilePath = [ADJUtil getFilePathInDocumentsDir:fileName]; NSString *appSupportFilePath = [ADJUtil getFilePathInAppSupportDir:fileName]; From 925e47e3d56d060d7dddd7e55c6abc019ddea826 Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 27 May 2020 16:19:08 +0200 Subject: [PATCH 081/173] Xcode update --- 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 84695aeec..1aa7520a0 100644 --- a/Adjust.xcodeproj/project.pbxproj +++ b/Adjust.xcodeproj/project.pbxproj @@ -2232,7 +2232,7 @@ 9679920518BBAE2800394606 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1140; + LastUpgradeCheck = 1150; ORGANIZATIONNAME = "adjust GmbH"; TargetAttributes = { 9615158E1CD2CB2C0022D336 = { diff --git a/Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdk.xcscheme b/Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdk.xcscheme index 1f5e13c3a..fafe60d22 100644 --- a/Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdk.xcscheme +++ b/Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdk.xcscheme @@ -1,6 +1,6 @@ Date: Thu, 28 May 2020 14:27:11 +0200 Subject: [PATCH 082/173] CHANGELOG.md update --- CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b996d6f8a..f5e366ac0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ -### Version 4.22.0 (xxth May 2020) +### Version 4.22.0 (28th May 2020) #### Added -- Added subscription tracking feature (`trackSubscription:` method added to `Adjust` API). +- Added subscription tracking feature. + +### Changed +- Refactored networking part and moved it to request handler. +- Added additional synchronisation in various cases of access to package queue and activity state. --- From a8a06a29351f9098a1f314b83b75fa9b80b0b245 Mon Sep 17 00:00:00 2001 From: uerceg Date: Thu, 28 May 2020 17:09:00 +0200 Subject: [PATCH 083/173] CHANGELOG.md update --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5e366ac0..abacf3aba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### Version 4.22.0 (28th May 2020) +### Version 4.22.0 (29th May 2020) #### Added - Added subscription tracking feature. From fa721bc8a0bdbeb370c01ba5253df35e52b9031a Mon Sep 17 00:00:00 2001 From: uerceg Date: Fri, 29 May 2020 00:11:18 +0200 Subject: [PATCH 084/173] Migrate web bridge test app to use extra path --- .../TestLibraryBridge.js | 44 ++++++++----------- .../TestLibraryBridge.m | 4 +- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.js b/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.js index e787699e8..bf0f7729d 100644 --- a/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.js +++ b/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.js @@ -35,8 +35,7 @@ var TestLibraryBridge = { var AdjustCommandExecutor = function(baseUrl, gdprUrl) { this.baseUrl = baseUrl; this.gdprUrl = gdprUrl; - this.basePath = null; - this.gdprPath = null; + this.extraPath = null; this.savedEvents = {}; this.savedConfigs = {}; this.savedCommands = []; @@ -50,8 +49,7 @@ AdjustCommandExecutor.prototype.testOptions = function(params) { var TestOptions = function() { this.baseUrl = null; this.gdprUrl = null; - this.basePath = null; - this.gdprPath = null; + this.extraPath = null; this.timerIntervalInMilliseconds = null; this.timerStartInMilliseconds = null; this.sessionIntervalInMilliseconds = null; @@ -67,10 +65,7 @@ AdjustCommandExecutor.prototype.testOptions = function(params) { testOptions.gdprUrl = this.gdprUrl; if ('basePath' in params) { - var basePath = getFirstValue(params, 'basePath'); - console.log('TestLibraryBridge hasOwnProperty basePath, first: ' + basePath); - this.basePath = basePath; - this.gdprPath = basePath; + this.extraPath = getFirstValue(params, 'basePath'); } if ('timerInterval' in params) { testOptions.timerIntervalInMilliseconds = getFirstValue(params, 'timerInterval'); @@ -106,8 +101,7 @@ AdjustCommandExecutor.prototype.testOptions = function(params) { switch(teardownOption) { case 'resetSdk': testOptions.teardown = true; - testOptions.basePath = this.basePath; - testOptions.gdprPath = this.gdprPath; + testOptions.extraPath = this.extraPath; break; case 'deleteState': testOptions.deleteState = true; @@ -122,15 +116,13 @@ AdjustCommandExecutor.prototype.testOptions = function(params) { break; case 'sdk': testOptions.teardown = true; - testOptions.basePath = null; - testOptions.gdprPath = null; + testOptions.extraPath = null; break; case 'test': // TODO: null configs // TODO: null events // TODO: null delegate - this.basePath = null; - this.gdprPath = null; + this.extraPath = null; testOptions.timerIntervalInMilliseconds = -1; testOptions.timerStartInMilliseconds = -1; testOptions.sessionIntervalInMilliseconds = -1; @@ -260,7 +252,7 @@ AdjustCommandExecutor.prototype.config = function(params) { if ('attributionCallbackSendAll' in params) { console.log('AdjustCommandExecutor.prototype.config attributionCallbackSendAll'); - var basePath = this.basePath; + var extraPath = this.extraPath; adjustConfig.setAttributionCallback( function(attribution) { console.log('attributionCallback: ' + JSON.stringify(attribution)); @@ -272,14 +264,14 @@ AdjustCommandExecutor.prototype.config = function(params) { addInfoToSend('creative', attribution.creative); addInfoToSend('clickLabel', attribution.click_label); addInfoToSend('adid', attribution.adid); - WebViewJavascriptBridge.callHandler('adjustTLB_sendInfoToServer', basePath, null); + WebViewJavascriptBridge.callHandler('adjustTLB_sendInfoToServer', extraPath, null); } ); } if ('sessionCallbackSendSuccess' in params) { console.log('AdjustCommandExecutor.prototype.config sessionCallbackSendSuccess'); - var basePath = this.basePath; + var extraPath = this.extraPath; adjustConfig.setSessionSuccessCallback( function(sessionSuccessResponseData) { console.log('sessionSuccessCallback: ' + JSON.stringify(sessionSuccessResponseData)); @@ -287,14 +279,14 @@ AdjustCommandExecutor.prototype.config = function(params) { addInfoToSend('timestamp', sessionSuccessResponseData.timestamp); addInfoToSend('adid', sessionSuccessResponseData.adid); addInfoToSend('jsonResponse', sessionSuccessResponseData.jsonResponse); - WebViewJavascriptBridge.callHandler('adjustTLB_sendInfoToServer', basePath, null); + WebViewJavascriptBridge.callHandler('adjustTLB_sendInfoToServer', extraPath, null); } ); } if ('sessionCallbackSendFailure' in params) { console.log('AdjustCommandExecutor.prototype.config sessionCallbackSendFailure'); - var basePath = this.basePath; + var extraPath = this.extraPath; adjustConfig.setSessionFailureCallback( function(sessionFailureResponseData) { console.log('sessionFailureCallback: ' + JSON.stringify(sessionFailureResponseData)); @@ -303,14 +295,14 @@ AdjustCommandExecutor.prototype.config = function(params) { addInfoToSend('adid', sessionFailureResponseData.adid); addInfoToSend('willRetry', sessionFailureResponseData.willRetry ? 'true' : 'false'); addInfoToSend('jsonResponse', sessionFailureResponseData.jsonResponse); - WebViewJavascriptBridge.callHandler('adjustTLB_sendInfoToServer', basePath, null); + WebViewJavascriptBridge.callHandler('adjustTLB_sendInfoToServer', extraPath, null); } ); } if ('eventCallbackSendSuccess' in params) { console.log('AdjustCommandExecutor.prototype.config eventCallbackSendSuccess'); - var basePath = this.basePath; + var extraPath = this.extraPath; adjustConfig.setEventSuccessCallback( function(eventSuccessResponseData) { console.log('eventSuccessCallback: ' + JSON.stringify(eventSuccessResponseData)); @@ -320,14 +312,14 @@ AdjustCommandExecutor.prototype.config = function(params) { addInfoToSend('eventToken', eventSuccessResponseData.eventToken); addInfoToSend('callbackId', eventSuccessResponseData.callbackId); addInfoToSend('jsonResponse', eventSuccessResponseData.jsonResponse); - WebViewJavascriptBridge.callHandler('adjustTLB_sendInfoToServer', basePath, null); + WebViewJavascriptBridge.callHandler('adjustTLB_sendInfoToServer', extraPath, null); } ); } if ('eventCallbackSendFailure' in params) { console.log('AdjustCommandExecutor.prototype.config eventCallbackSendFailure'); - var basePath = this.basePath; + var extraPath = this.extraPath; adjustConfig.setEventFailureCallback( function(eventFailureResponseData) { console.log('eventFailureCallback: ' + JSON.stringify(eventFailureResponseData)); @@ -338,7 +330,7 @@ AdjustCommandExecutor.prototype.config = function(params) { addInfoToSend('callbackId', eventFailureResponseData.callbackId); addInfoToSend('willRetry', eventFailureResponseData.willRetry ? 'true' : 'false'); addInfoToSend('jsonResponse', eventFailureResponseData.jsonResponse); - WebViewJavascriptBridge.callHandler('adjustTLB_sendInfoToServer', basePath, null); + WebViewJavascriptBridge.callHandler('adjustTLB_sendInfoToServer', extraPath, null); } ); } @@ -352,12 +344,12 @@ AdjustCommandExecutor.prototype.config = function(params) { if (shouldOpenDeeplinkS === 'false') { adjustConfig.setOpenDeferredDeeplink(false); } - var basePath = this.basePath; + var extraPath = this.extraPath; adjustConfig.setDeferredDeeplinkCallback( function(deeplink) { console.log('deferredDeeplinkCallback: ' + JSON.stringify(deeplink)); addInfoToSend('deeplink', deeplink); - WebViewJavascriptBridge.callHandler('adjustTLB_sendInfoToServer', basePath, null); + WebViewJavascriptBridge.callHandler('adjustTLB_sendInfoToServer', extraPath, null); } ); } diff --git a/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.m b/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.m index 6d3ab136f..dce90ea9b 100644 --- a/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.m +++ b/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp/TestLibraryBridge.m @@ -49,8 +49,8 @@ - (id)initWithAdjustBridgeRegister:(AdjustBridgeRegister *)adjustBridgeRegister return; } - NSString *basePath = (NSString *)data; - [self.testLibrary sendInfoToServer:basePath]; + NSString *extraPath = (NSString *)data; + [self.testLibrary sendInfoToServer:extraPath]; }]; self.adjustBridgeRegister = adjustBridgeRegister; From 75464e7b3467ebc1c00ada13b46eabea2dd46f3c Mon Sep 17 00:00:00 2001 From: uerceg Date: Fri, 5 Jun 2020 09:50:52 +0200 Subject: [PATCH 085/173] Fix ADJSubscription copyWithZone: implementation --- Adjust/ADJSubscription.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Adjust/ADJSubscription.m b/Adjust/ADJSubscription.m index 304c37b6d..4b7b76cc1 100644 --- a/Adjust/ADJSubscription.m +++ b/Adjust/ADJSubscription.m @@ -128,10 +128,11 @@ - (id)copyWithZone:(NSZone *)zone { if (copy) { copy->_price = [self.price copyWithZone:zone]; copy->_currency = [self.currency copyWithZone:zone]; - copy->_transactionDate = [self.receipt copyWithZone:zone]; copy->_transactionId = [self.transactionId copyWithZone:zone]; copy->_receipt = [self.receipt copyWithZone:zone]; - copy->_billingStore = [self.receipt copyWithZone:zone]; + copy->_billingStore = [self.billingStore copyWithZone:zone]; + copy->_transactionDate = [self.transactionDate copyWithZone:zone]; + copy->_salesRegion = [self.salesRegion copyWithZone:zone]; copy.mutableCallbackParameters = [self.mutableCallbackParameters copyWithZone:zone]; copy.mutablePartnerParameters = [self.mutablePartnerParameters copyWithZone:zone]; } From 10d14f72975592b51e5a5595fdb4560e2d9b7039 Mon Sep 17 00:00:00 2001 From: uerceg Date: Fri, 5 Jun 2020 09:59:13 +0200 Subject: [PATCH 086/173] New version 4.22.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 d26e45e01..7d833c775 100644 --- a/Adjust.podspec +++ b/Adjust.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = "Adjust" - s.version = "4.22.0" + s.version = "4.22.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.22.0" } + s.source = { :git => "https://github.com/adjust/ios_sdk.git", :tag => "v4.22.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 d380749c0..f15627237 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -40,7 +40,7 @@ static CTTelephonyNetworkInfo *networkInfo = nil; #endif -static NSString * const kClientSdk = @"ios4.22.0"; +static NSString * const kClientSdk = @"ios4.22.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 6e6acda59..34833a0fb 100644 --- a/Adjust/Adjust.h +++ b/Adjust/Adjust.h @@ -2,7 +2,7 @@ // Adjust.h // Adjust // -// V4.22.0 +// V4.22.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 62b58c204..310cd91a2 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.22.0'; + return 'web-bridge4.22.1'; } }, setTestOptions: function(testOptions) { diff --git a/AdjustTests/AdjustUnitTests/ADJPackageFields.m b/AdjustTests/AdjustUnitTests/ADJPackageFields.m index d41d85980..53963ba7b 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.22.0"; + self.clientSdk = @"ios4.22.1"; self.suffix = @""; self.environment = @"sandbox"; diff --git a/README.md b/README.md index 6116015a9..6ff5b1630 100644 --- a/README.md +++ b/README.md @@ -75,13 +75,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.22.0' +pod 'Adjust', '~> 4.22.1' ``` or: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.0' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.1' ``` --- diff --git a/VERSION b/VERSION index d7638f377..352b26ac2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.22.0 +4.22.1 diff --git a/doc/chinese/README.md b/doc/chinese/README.md index 07e41ebe5..61911b9c3 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.22.0' +pod 'Adjust', '~> 4.22.1' ``` 或: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.0' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.1' ``` --- diff --git a/doc/english/migrate.md b/doc/english/migrate.md index 1b4b98dc5..9dfbbeceb 100644 --- a/doc/english/migrate.md +++ b/doc/english/migrate.md @@ -1,4 +1,4 @@ -## Migrate your Adjust SDK for iOS to v4.22.0 from v3.4.0 +## Migrate your Adjust SDK for iOS to v4.22.1 from v3.4.0 ### Initial setup diff --git a/doc/english/web_views.md b/doc/english/web_views.md index 3e1b83d49..a6122ea6d 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.22.0' +pod 'Adjust/WebBridge', '~> 4.22.1' ``` --- diff --git a/doc/japanese/README.md b/doc/japanese/README.md index e6ffc2957..de7342906 100644 --- a/doc/japanese/README.md +++ b/doc/japanese/README.md @@ -25,13 +25,13 @@ adjust SDKをiOSプロジェクトに連携する手順を説明します。 [こちらの手順](#sdk-integrate)に進んでください。 ```ruby -pod 'Adjust', '~> 4.22.0' +pod 'Adjust', '~> 4.22.1' ``` または ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.0' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.1' ``` --- diff --git a/doc/korean/README.md b/doc/korean/README.md index 16d6727cd..af8a463dc 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.22.0' +pod 'Adjust', '~> 4.22.1' ``` 또는: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.0' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.1' ``` --- diff --git a/doc/korean/web_views.md b/doc/korean/web_views.md index 2775d6800..c792d0510 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.22.0' +pod 'Adjust/WebBridge', '~> 4.22.1' ``` --- diff --git a/doc/migrate.md b/doc/migrate.md index 1b4b98dc5..9dfbbeceb 100644 --- a/doc/migrate.md +++ b/doc/migrate.md @@ -1,4 +1,4 @@ -## Migrate your Adjust SDK for iOS to v4.22.0 from v3.4.0 +## Migrate your Adjust SDK for iOS to v4.22.1 from v3.4.0 ### Initial setup From 0986052d201d0650529f1e9a8a92f6491e37d730 Mon Sep 17 00:00:00 2001 From: uerceg Date: Fri, 5 Jun 2020 10:01:09 +0200 Subject: [PATCH 087/173] CHANGELOG.md update --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index abacf3aba..bd1c76da7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### Version 4.22.1 (5th June 2020) +#### Added +- Fixed `copyWithZone:` method implementation in `ADJSubscription.m` (thanks to @atilimcetin). + +--- + ### Version 4.22.0 (29th May 2020) #### Added - Added subscription tracking feature. From 02ab46b4f5258c848ac80a70494c92f177dd17d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uglje=C5=A1a=20Erceg?= Date: Fri, 5 Jun 2020 10:59:51 +0200 Subject: [PATCH 088/173] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd1c76da7..c0b1251b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ ### Version 4.22.1 (5th June 2020) -#### Added +#### Fixed - Fixed `copyWithZone:` method implementation in `ADJSubscription.m` (thanks to @atilimcetin). --- From 2271c95b5e98498348959e0fd03b6c00c4c1b2a8 Mon Sep 17 00:00:00 2001 From: Marcella Coombs <52657116+mcoombs@users.noreply.github.com> Date: Fri, 3 Jul 2020 14:34:26 +0200 Subject: [PATCH 089/173] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ff5b1630..ac9714e65 100644 --- a/README.md +++ b/README.md @@ -521,7 +521,9 @@ Currently we support the below `source` parameter values: ### Subscription tracking -**Note**: This feature is only available in the native SDK v4.22.0 and above. +**Note**: This feature is only available in the native SDK v4.22.0 and above. We recommend using at least version 4.22.1. + +**Important**: The following steps only set up subscription tracking within the SDK. To complete setup, certain app-specific information must be added within Adjust’s internal interface. An Adjust representative must take this action: please contact support@adjust.com or your Technical Account Manager. You can track App Store subscriptions and verify their validity with the Adjust SDK. After a subscription has been successfully purchased, make the following call to the Adjust SDK: From 6b8396c87bd7e9af13bac6c6fa81734fd88af6cd Mon Sep 17 00:00:00 2001 From: Huiyan Date: Thu, 25 Jun 2020 16:57:19 +0200 Subject: [PATCH 090/173] Update web_views.md --- doc/korean/web_views.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/korean/web_views.md b/doc/korean/web_views.md index c792d0510..e472590f8 100644 --- a/doc/korean/web_views.md +++ b/doc/korean/web_views.md @@ -109,7 +109,7 @@ Adjust SDK를 정적/동적 프레임 워크 또는 Carthage를 통해 추가 ### AdjustBridge를 앱에 연동하기 -프로젝트 네비게이터에서 소스 파일 View Controller를 엽니 다. 파일 맨 위에`import` 문구를 추가하십시오. 인도네시아 +프로젝트 네비게이터에서 소스 파일 View Controller를 엽니 다. 파일 맨 위에`import` 문구를 추가하십시오. Web View Delegate의`viewDidLoad` 또는`viewWillAppear` 메소드는`AdjustBridge`에 다음 호출을 추가합니다. ```objc From 4cc68017297356ed75b318cced4f5631e8178220 Mon Sep 17 00:00:00 2001 From: rabc Date: Tue, 30 Jun 2020 14:03:02 +0200 Subject: [PATCH 091/173] Start github actions --- .github/build.yaml | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .github/build.yaml diff --git a/.github/build.yaml b/.github/build.yaml new file mode 100644 index 000000000..92ec6facc --- /dev/null +++ b/.github/build.yaml @@ -0,0 +1,44 @@ +on: + push: + branches: + - create_action + # create: + # tags: + # - v* +name: Build framework +jobs: + create_dirs: + name: Create dirs + steps: + - run: | + mkdir -p frameworks/static + mkdir -p frameworks/dynamic/ios + mkdir -p frameworks/dynamic/tvos + mkdir -p frameworks/dynamic/imessage + mkdir -p frameworks/dynamic/webbridge + static: + name: Build static + runs-on: macOS-latest + needs: create_dirs + steps: + - name: Checkout + uses: actions/checkout@master + - name: Build + run: | + mkdir -p frameworks/static + cd ios_sdk_dev + xcodebuild -target AdjustStatic -configuration Release clean build + tvOS: + name: Build tvOS SDK + runs-on: macOS-latest + needs: create_dirs + steps: + - name: Checkout + uses: actions/checkout@master + - name: Universal tvOS SDK + run: | + cd ios_sdk_dev + xcodebuild -configuration Release -target AdjustSdkTv -arch x86_64 -sdk appletvsimulator clean build + xcodebuild -configuration Release -target AdjustSdkTv -arch arm64 -sdk appletvos build + cp -Rv build/Release-appletvos/AdjustSdkTv.framework frameworks/static + lipo -create -output frameworks/static/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvos/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvsimulator/AdjustSdkTv.framework/AdjustSdkTv From 4e4a121a5ef7815cfa21af14eb935d7953d1f58c Mon Sep 17 00:00:00 2001 From: rabc Date: Tue, 30 Jun 2020 14:33:34 +0200 Subject: [PATCH 092/173] Try new push --- .github/build.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/build.yaml b/.github/build.yaml index 92ec6facc..f8d9247b9 100644 --- a/.github/build.yaml +++ b/.github/build.yaml @@ -42,3 +42,4 @@ jobs: xcodebuild -configuration Release -target AdjustSdkTv -arch arm64 -sdk appletvos build cp -Rv build/Release-appletvos/AdjustSdkTv.framework frameworks/static lipo -create -output frameworks/static/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvos/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvsimulator/AdjustSdkTv.framework/AdjustSdkTv + From 1de09691c7691b3a016a7ad6017f98ffcd467d07 Mon Sep 17 00:00:00 2001 From: rabc Date: Tue, 30 Jun 2020 14:36:12 +0200 Subject: [PATCH 093/173] Change dir --- .github/{ => workflows}/build.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{ => workflows}/build.yaml (100%) diff --git a/.github/build.yaml b/.github/workflows/build.yaml similarity index 100% rename from .github/build.yaml rename to .github/workflows/build.yaml From 632c332db877bf5e1db8b5bf7563c65daec8b25b Mon Sep 17 00:00:00 2001 From: rabc Date: Tue, 30 Jun 2020 14:37:37 +0200 Subject: [PATCH 094/173] Change identation --- .github/workflows/build.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f8d9247b9..adf6d9dac 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -11,11 +11,11 @@ jobs: name: Create dirs steps: - run: | - mkdir -p frameworks/static - mkdir -p frameworks/dynamic/ios - mkdir -p frameworks/dynamic/tvos - mkdir -p frameworks/dynamic/imessage - mkdir -p frameworks/dynamic/webbridge + mkdir -p frameworks/static + mkdir -p frameworks/dynamic/ios + mkdir -p frameworks/dynamic/tvos + mkdir -p frameworks/dynamic/imessage + mkdir -p frameworks/dynamic/webbridge static: name: Build static runs-on: macOS-latest From d05eb86f865556032636a83a011b73ed9110d914 Mon Sep 17 00:00:00 2001 From: rabc Date: Tue, 30 Jun 2020 14:47:48 +0200 Subject: [PATCH 095/173] Create dirs on the job --- .github/workflows/build.yaml | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index adf6d9dac..5ba522a08 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -7,15 +7,6 @@ on: # - v* name: Build framework jobs: - create_dirs: - name: Create dirs - steps: - - run: | - mkdir -p frameworks/static - mkdir -p frameworks/dynamic/ios - mkdir -p frameworks/dynamic/tvos - mkdir -p frameworks/dynamic/imessage - mkdir -p frameworks/dynamic/webbridge static: name: Build static runs-on: macOS-latest @@ -37,9 +28,10 @@ jobs: uses: actions/checkout@master - name: Universal tvOS SDK run: | + mkdir -p frameworks/static_tvos cd ios_sdk_dev xcodebuild -configuration Release -target AdjustSdkTv -arch x86_64 -sdk appletvsimulator clean build xcodebuild -configuration Release -target AdjustSdkTv -arch arm64 -sdk appletvos build - cp -Rv build/Release-appletvos/AdjustSdkTv.framework frameworks/static - lipo -create -output frameworks/static/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvos/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvsimulator/AdjustSdkTv.framework/AdjustSdkTv + cp -Rv build/Release-appletvos/AdjustSdkTv.framework frameworks/static_tvos + lipo -create -output frameworks/static_tvos/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvos/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvsimulator/AdjustSdkTv.framework/AdjustSdkTv From 50334202f43a56942a3df7cf2f0ec1e4f0150c7b Mon Sep 17 00:00:00 2001 From: rabc Date: Tue, 30 Jun 2020 14:49:14 +0200 Subject: [PATCH 096/173] Remove needs --- .github/workflows/build.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 5ba522a08..b2c8746ed 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -10,7 +10,6 @@ jobs: static: name: Build static runs-on: macOS-latest - needs: create_dirs steps: - name: Checkout uses: actions/checkout@master @@ -22,7 +21,6 @@ jobs: tvOS: name: Build tvOS SDK runs-on: macOS-latest - needs: create_dirs steps: - name: Checkout uses: actions/checkout@master From c7ce57553f79d37d07f41673e17adf28ab4fc089 Mon Sep 17 00:00:00 2001 From: rabc Date: Tue, 30 Jun 2020 14:56:38 +0200 Subject: [PATCH 097/173] Change checkout --- .github/workflows/build.yaml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index b2c8746ed..c2fb5e51c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -11,23 +11,19 @@ jobs: name: Build static runs-on: macOS-latest steps: - - name: Checkout - uses: actions/checkout@master + - uses: actions/checkout@v2 - name: Build run: | mkdir -p frameworks/static - cd ios_sdk_dev xcodebuild -target AdjustStatic -configuration Release clean build tvOS: name: Build tvOS SDK runs-on: macOS-latest steps: - - name: Checkout - uses: actions/checkout@master + - uses: actions/checkout@v2 - name: Universal tvOS SDK run: | mkdir -p frameworks/static_tvos - cd ios_sdk_dev xcodebuild -configuration Release -target AdjustSdkTv -arch x86_64 -sdk appletvsimulator clean build xcodebuild -configuration Release -target AdjustSdkTv -arch arm64 -sdk appletvos build cp -Rv build/Release-appletvos/AdjustSdkTv.framework frameworks/static_tvos From 5fc53c3894586e741b83f7dd83735915911d20f4 Mon Sep 17 00:00:00 2001 From: rabc Date: Wed, 1 Jul 2020 10:42:39 +0200 Subject: [PATCH 098/173] All steps --- .github/workflows/build.yaml | 73 ++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index c2fb5e51c..ae82f8e9f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -16,6 +16,11 @@ jobs: run: | mkdir -p frameworks/static xcodebuild -target AdjustStatic -configuration Release clean build + - name: Upload files + uses: actions/upload-artifact@v1 + with: + name: static_framework + path: frameworks/static/AdjustSdk.framework tvOS: name: Build tvOS SDK runs-on: macOS-latest @@ -28,4 +33,72 @@ jobs: xcodebuild -configuration Release -target AdjustSdkTv -arch arm64 -sdk appletvos build cp -Rv build/Release-appletvos/AdjustSdkTv.framework frameworks/static_tvos lipo -create -output frameworks/static_tvos/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvos/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvsimulator/AdjustSdkTv.framework/AdjustSdkTv + - name: Upload files + uses: actions/upload-artifact@v1 + with: + name: universal_tvos + path: frameworks/static_tvos/AdjustSdkTv.framework + + dynamic_ios_tvos: + name: Build dynamic iOS and tvOS targets with Carthage + runs-on: macOS-latest + steps: + - uses: actions/checkout@v2 + - name: Install Carthage + run: | + brew install carthage + - name: Build dynamic framework + run: | + mv Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdkIm.xcscheme \ + Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdkWebBridge.xcscheme . + carthage build --no-skip-current + - name: Upload iOS + uses: actions/upload-artifact@v1 + with: + name: dynamic_ios + path: Carthage/Build/iOS/* + - name: Upload tvOS + uses: actions/upload-artifact@v1 + with: + name: dynamic_tvos + path: Carthage/Build/tvOS/* + + dynamic_imessage: + name: Build dynamic iMessage target with Carthage + runs-on: macOS-latest + steps: + - uses: actions/checkout@v2 + - name: Install Carthage + run: | + brew install carthage + - name: Build dynamic framework + run: | + mv Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdk.xcscheme \ + Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdkTv.xcscheme . + mv AdjustSdkIm.xcscheme Adjust.xcodeproj/xcshareddata/xcschemes + carthage build --no-skip-current + - name: Upload framework + uses: actions/upload-artifact@v1 + with: + name: dynamic_imessage + path: Carthage/Build/iOS/* + + dynamic_webbridge: + name: Build dynamic WebBridge target with Carthage + runs-on: macOS-latest + steps: + - uses: actions/checkout@v2 + - name: Install Carthage + run: | + brew install carthage + - name: Build dynamic framework + run: | + mv Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdkIm.xcscheme . + mv AdjustSdkWebBridge.xcscheme Adjust.xcodeproj/xcshareddata/xcschemes + carthage build --no-skip-current + - name: Upload framework + uses: actions/upload-artifact@v1 + with: + name: dynamic_webbridge + path: Carthage/Build/iOS/* From c8f78ce2761a554d403e487acb592619d5787579 Mon Sep 17 00:00:00 2001 From: rabc Date: Wed, 1 Jul 2020 10:58:18 +0200 Subject: [PATCH 099/173] Change version --- .github/workflows/build.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index ae82f8e9f..ef9ad2bca 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -17,7 +17,7 @@ jobs: mkdir -p frameworks/static xcodebuild -target AdjustStatic -configuration Release clean build - name: Upload files - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: name: static_framework path: frameworks/static/AdjustSdk.framework @@ -34,7 +34,7 @@ jobs: cp -Rv build/Release-appletvos/AdjustSdkTv.framework frameworks/static_tvos lipo -create -output frameworks/static_tvos/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvos/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvsimulator/AdjustSdkTv.framework/AdjustSdkTv - name: Upload files - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: name: universal_tvos path: frameworks/static_tvos/AdjustSdkTv.framework @@ -53,12 +53,12 @@ jobs: Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdkWebBridge.xcscheme . carthage build --no-skip-current - name: Upload iOS - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: name: dynamic_ios path: Carthage/Build/iOS/* - name: Upload tvOS - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: name: dynamic_tvos path: Carthage/Build/tvOS/* @@ -78,7 +78,7 @@ jobs: mv AdjustSdkIm.xcscheme Adjust.xcodeproj/xcshareddata/xcschemes carthage build --no-skip-current - name: Upload framework - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: name: dynamic_imessage path: Carthage/Build/iOS/* @@ -97,7 +97,7 @@ jobs: mv AdjustSdkWebBridge.xcscheme Adjust.xcodeproj/xcshareddata/xcschemes carthage build --no-skip-current - name: Upload framework - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: name: dynamic_webbridge path: Carthage/Build/iOS/* From a7b3aebf45bc735430d0650b21a470ffcfd4626e Mon Sep 17 00:00:00 2001 From: rabc Date: Wed, 1 Jul 2020 11:19:18 +0200 Subject: [PATCH 100/173] Fix errors + zip framework --- .github/workflows/build.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index ef9ad2bca..9dd4fd9ae 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -16,11 +16,12 @@ jobs: run: | mkdir -p frameworks/static xcodebuild -target AdjustStatic -configuration Release clean build + zip AdjustSdk.framework.zip frameworks/static/AdjustSdk.framework/* - name: Upload files uses: actions/upload-artifact@v2 with: name: static_framework - path: frameworks/static/AdjustSdk.framework + path: AdjustSdk.framework.zip tvOS: name: Build tvOS SDK runs-on: macOS-latest @@ -33,11 +34,12 @@ jobs: xcodebuild -configuration Release -target AdjustSdkTv -arch arm64 -sdk appletvos build cp -Rv build/Release-appletvos/AdjustSdkTv.framework frameworks/static_tvos lipo -create -output frameworks/static_tvos/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvos/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvsimulator/AdjustSdkTv.framework/AdjustSdkTv + zip AdjustSdkTv.framework.zip frameworks/static_tvos/AdjustSdkTv.framework/* - name: Upload files uses: actions/upload-artifact@v2 with: name: universal_tvos - path: frameworks/static_tvos/AdjustSdkTv.framework + path: AdjustSdkTv.framework.zip dynamic_ios_tvos: name: Build dynamic iOS and tvOS targets with Carthage @@ -75,7 +77,6 @@ jobs: run: | mv Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdk.xcscheme \ Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdkTv.xcscheme . - mv AdjustSdkIm.xcscheme Adjust.xcodeproj/xcshareddata/xcschemes carthage build --no-skip-current - name: Upload framework uses: actions/upload-artifact@v2 @@ -94,7 +95,6 @@ jobs: - name: Build dynamic framework run: | mv Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdkIm.xcscheme . - mv AdjustSdkWebBridge.xcscheme Adjust.xcodeproj/xcshareddata/xcschemes carthage build --no-skip-current - name: Upload framework uses: actions/upload-artifact@v2 From 04c12b0e976db8b56f0781f9dc10c636f24c4094 Mon Sep 17 00:00:00 2001 From: rabc Date: Mon, 6 Jul 2020 13:40:25 +0200 Subject: [PATCH 101/173] Final action build script --- .github/workflows/build.yaml | 140 ++++++++++++++++++++++++++++++----- 1 file changed, 121 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 9dd4fd9ae..36534aa4e 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,14 +1,11 @@ on: - push: - branches: - - create_action - # create: - # tags: - # - v* + create: + tags: + - v* name: Build framework jobs: static: - name: Build static + name: Build static SDK runs-on: macOS-latest steps: - uses: actions/checkout@v2 @@ -16,14 +13,17 @@ jobs: run: | mkdir -p frameworks/static xcodebuild -target AdjustStatic -configuration Release clean build - zip AdjustSdk.framework.zip frameworks/static/AdjustSdk.framework/* + + mkdir AdjustSdkStatic + mv frameworks/static/* AdjustSdkStatic + zip -ry AdjustSdkStatic.framework.zip AdjustSdkStatic/* - name: Upload files uses: actions/upload-artifact@v2 with: name: static_framework - path: AdjustSdk.framework.zip + path: AdjustSdkStatic.framework.zip tvOS: - name: Build tvOS SDK + name: Build Static tvOS SDK runs-on: macOS-latest steps: - uses: actions/checkout@v2 @@ -34,12 +34,15 @@ jobs: xcodebuild -configuration Release -target AdjustSdkTv -arch arm64 -sdk appletvos build cp -Rv build/Release-appletvos/AdjustSdkTv.framework frameworks/static_tvos lipo -create -output frameworks/static_tvos/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvos/AdjustSdkTv.framework/AdjustSdkTv build/Release-appletvsimulator/AdjustSdkTv.framework/AdjustSdkTv - zip AdjustSdkTv.framework.zip frameworks/static_tvos/AdjustSdkTv.framework/* + + mkdir AdjustSdkTvStatic + mv frameworks/static_tvos/* AdjustSdkTvStatic + zip -ry AdjustSdkTvStatic.framework.zip AdjustSdkTvStatic/* - name: Upload files uses: actions/upload-artifact@v2 with: name: universal_tvos - path: AdjustSdkTv.framework.zip + path: AdjustSdkTvStatic.framework.zip dynamic_ios_tvos: name: Build dynamic iOS and tvOS targets with Carthage @@ -54,16 +57,24 @@ jobs: mv Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdkIm.xcscheme \ Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdkWebBridge.xcscheme . carthage build --no-skip-current + + mkdir AdjustSdkDynamic + mv Carthage/Build/iOS/* AdjustSdkDynamic + zip -ry AdjustSdkDynamic.framework.zip AdjustSdkDynamic/* + + mkdir AdjustSdkTvDynamic + mv Carthage/Build/tvOS/* AdjustSdkTvDynamic + zip -ry AdjustSdkTvDynamic.framework.zip AdjustSdkTvDynamic/* - name: Upload iOS uses: actions/upload-artifact@v2 with: name: dynamic_ios - path: Carthage/Build/iOS/* + path: AdjustSdkDynamic.framework.zip - name: Upload tvOS uses: actions/upload-artifact@v2 with: name: dynamic_tvos - path: Carthage/Build/tvOS/* + path: AdjustSdkTvDynamic.framework.zip dynamic_imessage: name: Build dynamic iMessage target with Carthage @@ -75,14 +86,19 @@ jobs: brew install carthage - name: Build dynamic framework run: | - mv Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdk.xcscheme \ - Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdkTv.xcscheme . + mv Adjust.xcodeproj/xcshareddata/xcschemes/*.xcscheme . + mv AdjustSdkIm.xcscheme Adjust.xcodeproj/xcshareddata/xcschemes + carthage build --no-skip-current + + mkdir AdjustSdkImDynamic + mv Carthage/Build/iOS/* AdjustSdkImDynamic + zip -ry AdjustSdkIm.framework.zip AdjustSdkImDynamic/* - name: Upload framework uses: actions/upload-artifact@v2 with: name: dynamic_imessage - path: Carthage/Build/iOS/* + path: AdjustSdkIm.framework.zip dynamic_webbridge: name: Build dynamic WebBridge target with Carthage @@ -94,11 +110,97 @@ jobs: brew install carthage - name: Build dynamic framework run: | - mv Adjust.xcodeproj/xcshareddata/xcschemes/AdjustSdkIm.xcscheme . + mv Adjust.xcodeproj/xcshareddata/xcschemes/*.xcscheme . + mv AdjustSdkWebBridge.xcscheme Adjust.xcodeproj/xcshareddata/xcschemes + carthage build --no-skip-current + mkdir AdjustSdkWebBridgeDynamic + mv Carthage/Build/iOS/* AdjustSdkWebBridgeDynamic + zip -ry AdjustSdkWebBridge.framework.zip AdjustSdkWebBridgeDynamic/* - name: Upload framework uses: actions/upload-artifact@v2 with: name: dynamic_webbridge - path: Carthage/Build/iOS/* + path: AdjustSdkWebBridge.framework.zip + + release: + name: Create new release and upload assets + runs-on: ubuntu-latest + needs: [static, tvOS, dynamic_ios_tvos, dynamic_imessage, dynamic_webbridge] + steps: + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Version ${{ github.ref }} + draft: true + prerelease: false + + - name: Download all frameworks + uses: actions/download-artifact@v2 + with: + path: frameworks + + - name: Upload static framework + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: frameworks/static_framework/AdjustSdkStatic.framework.zip + asset_name: AdjustSdkStatic.framework.zip + asset_content_type: application/zip + + - name: Upload tvOS framework + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: frameworks/universal_tvos/AdjustSdkTvStatic.framework.zip + asset_name: AdjustSdkTvStatic.framework.zip + asset_content_type: application/zip + + - name: Upload dynamic iOS framework + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: frameworks/dynamic_ios/AdjustSdkDynamic.framework.zip + asset_name: AdjustSdkDynamic.framework.zip + asset_content_type: application/zip + + - name: Upload dynamic tvOS framework + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: frameworks/dynamic_tvos/AdjustSdkTvDynamic.framework.zip + asset_name: AdjustSdkTvDynamic.framework.zip + asset_content_type: application/zip + + - name: Upload dynamic iMessage framework + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: frameworks/dynamic_imessage/AdjustSdkIm.framework.zip + asset_name: AdjustSdkIm.framework.zip + asset_content_type: application/zip + + - name: Upload dynamic WebBridge framework + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: frameworks/dynamic_webbridge/AdjustSdkWebBridge.framework.zip + asset_name: AdjustSdkWebBridge.framework.zip + asset_content_type: application/zip From 09955bade6fdcc5bb66358fb134b8fea18fae700 Mon Sep 17 00:00:00 2001 From: rabc Date: Mon, 20 Jul 2020 10:42:48 +0200 Subject: [PATCH 102/173] Add timeout for iAd --- Adjust/ADJActivityHandler.m | 17 +++----- Adjust/ADJAdditions/UIDevice+ADJAdditions.h | 2 +- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 45 +++++++++++++++++---- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 5d5be4629..cfcb91523 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -109,6 +109,7 @@ typedef NS_ENUM(NSInteger, AdjADClientError) { AdjADClientErrorLimitAdTracking = 1, AdjADClientErrorMissingData = 2, AdjADClientErrorCorruptResponse = 3, + AdjCustomErrorTimeout = 100, }; #pragma mark - @@ -400,6 +401,7 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails // - AdjADClientErrorUnknown // - AdjADClientErrorMissingData // - AdjADClientErrorCorruptResponse + // - AdjCustomErrorTimeout // apply following retry logic: // - 1st retry after 5 seconds // - 2nd retry after 2 seconds @@ -407,7 +409,8 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails switch (error.code) { case AdjADClientErrorUnknown: case AdjADClientErrorMissingData: - case AdjADClientErrorCorruptResponse: { + case AdjADClientErrorCorruptResponse: + case AdjCustomErrorTimeout: { int64_t iAdRetryDelay = 0; switch (self.iAdRetriesLeft) { case 2: @@ -1365,7 +1368,7 @@ - (void)setEnabledI:(ADJActivityHandler *)selfI enabled:(BOOL)enabled { [selfI disableThirdPartySharing]; } if (selfI.adjustConfig.allowiAdInfoReading == YES) { - [selfI checkForiAdI:selfI]; + [selfI checkForiAd]; } } @@ -1377,15 +1380,7 @@ - (void)setEnabledI:(ADJActivityHandler *)selfI enabled:(BOOL)enabled { } - (void)checkForiAd { - [ADJUtil launchInQueue:self.internalQueue - selfInject:self - block:^(ADJActivityHandler *selfI) { - [selfI checkForiAdI:selfI]; - }]; -} - -- (void)checkForiAdI:(ADJActivityHandler *)selfI { - [[UIDevice currentDevice] adjCheckForiAd:selfI]; + [[UIDevice currentDevice] adjCheckForiAd:self queue:self.internalQueue]; } - (void)setOfflineModeI:(ADJActivityHandler *)selfI diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h index b1778204d..bc7baeb37 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h @@ -20,5 +20,5 @@ - (NSString *)adjDeviceName; - (NSString *)adjCreateUuid; - (NSString *)adjVendorId; -- (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler; +- (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler queue:(dispatch_queue_t)queue; @end diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index b62da6d2f..5c4d72a61 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -158,7 +158,7 @@ - (NSString *)adjVendorId { return @""; } -- (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler { +- (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler queue:(dispatch_queue_t)queue { // if no tries for iad v3 left, stop trying id logger = [ADJAdjustFactory logger]; @@ -190,7 +190,8 @@ - (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler { [logger debug:@"iAd framework successfully found in user's app"]; BOOL iAdInformationAvailable = [self setiAdWithDetails:activityHandler - adcClientSharedInstance:ADClientSharedClientInstance]; + adcClientSharedInstance:ADClientSharedClientInstance + queue:queue]; if (!iAdInformationAvailable) { [logger warn:@"iAd information not available"]; @@ -201,20 +202,50 @@ - (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler { } - (BOOL)setiAdWithDetails:(ADJActivityHandler *)activityHandler - adcClientSharedInstance:(id)ADClientSharedClientInstance { + adcClientSharedInstance:(id)ADClientSharedClientInstance + queue:(dispatch_queue_t)queue { SEL iAdDetailsSelector = NSSelectorFromString(@"requestAttributionDetailsWithBlock:"); if (![ADClientSharedClientInstance respondsToSelector:iAdDetailsSelector]) { return NO; } - + + __block Class lock = [ADJActivityHandler class]; + __block BOOL completed = NO; + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [ADClientSharedClientInstance performSelector:iAdDetailsSelector withObject:^(NSDictionary *attributionDetails, NSError *error) { - [activityHandler setAttributionDetails:attributionDetails - error:error]; - }]; + + @synchronized (lock) { + if (completed) { + return; + } else { + completed = YES; + } + } + + [activityHandler setAttributionDetails:attributionDetails + error:error]; + }]; #pragma clang diagnostic pop + + // 5 seconds of timeout + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), queue, ^{ + @synchronized (lock) { + if (completed) { + return; + } else { + completed = YES; + } + } + + [activityHandler setAttributionDetails:nil + error:[NSError errorWithDomain:@"com.adjust.sdk.iAd" + code:100 + userInfo:@{@"Error reason": @"iAd request timed out"}]]; + }); + return YES; } From a382b810f2b4e06d340a995ae88b93a91d6f5ad1 Mon Sep 17 00:00:00 2001 From: rabc Date: Tue, 21 Jul 2020 15:24:01 +0200 Subject: [PATCH 103/173] Save and send iAd errors --- Adjust/ADJActivityHandler.m | 25 ++++++++++++++++++++++++- Adjust/ADJPackageBuilder.m | 14 ++++++++++++++ Adjust/ADJUserDefaults.h | 4 ++++ Adjust/ADJUserDefaults.m | 29 +++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index cfcb91523..126688e8f 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -411,6 +411,9 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails case AdjADClientErrorMissingData: case AdjADClientErrorCorruptResponse: case AdjCustomErrorTimeout: { + + [self saveiAdErrorCode:error.code]; + int64_t iAdRetryDelay = 0; switch (self.iAdRetriesLeft) { case 2: @@ -472,6 +475,26 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails }]; } +- (void)saveiAdErrorCode:(NSInteger)code { + NSString *codeKey; + switch (code) { + case AdjADClientErrorUnknown: + codeKey = @"AdjADClientErrorUnknown"; + case AdjADClientErrorMissingData: + codeKey = @"AdjADClientErrorMissingData"; + case AdjADClientErrorCorruptResponse: + codeKey = @"AdjADClientErrorCorruptResponse"; + case AdjCustomErrorTimeout: + codeKey = @"AdjCustomErrorTimeout"; + default: + codeKey = @""; + } + + if (![codeKey isEqualToString:@""]) { + [ADJUserDefaults saveiAdErrorKey:codeKey]; + } +} + - (void)sendIad3ClickPackage:(ADJActivityHandler *)selfI attributionDetails:(NSDictionary *)attributionDetails { @@ -501,7 +524,7 @@ - (void)sendIad3ClickPackage:(ADJActivityHandler *)selfI clickBuilder.attributionDetails = attributionDetails; - ADJActivityPackage *clickPackage = [clickBuilder buildClickPackage:@"iad3"]; + ADJActivityPackage *clickPackage = [clickBuilder buildClickPackage:@"iad3"]; [selfI.sdkClickHandler sendSdkClick:clickPackage]; } diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index e66e83753..3707416e2 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -13,6 +13,7 @@ #import "ADJActivityPackage.h" #import "NSData+ADJAdditions.h" #import "UIDevice+ADJAdditions.h" +#import "ADJUserDefaults.h" @interface ADJPackageBuilder() @@ -113,6 +114,19 @@ - (ADJActivityPackage *)buildAdRevenuePackage:(NSString *)source payload:(NSData - (ADJActivityPackage *)buildClickPackage:(NSString *)clickSource { NSMutableDictionary *parameters = [self getClickParameters:clickSource]; + + if ([clickSource isEqualToString:@"iad3"]) { + // send iAd errors in the parameters + NSDictionary *iAdErrors = [ADJUserDefaults getiAdErrors]; + if (iAdErrors) { + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:iAdErrors options:0 error:nil]; + NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + parameters[@"iad_errors"] = jsonStr; + + [ADJUserDefaults cleariAdErrors]; + } + } + ADJActivityPackage *clickPackage = [self defaultActivityPackage]; clickPackage.path = @"/sdk_click"; clickPackage.activityKind = ADJActivityKindClick; diff --git a/Adjust/ADJUserDefaults.h b/Adjust/ADJUserDefaults.h index 300cb73d0..8849702f0 100644 --- a/Adjust/ADJUserDefaults.h +++ b/Adjust/ADJUserDefaults.h @@ -47,4 +47,8 @@ + (void)clearAdjustStuff; ++ (void)saveiAdErrorKey:(NSString *)key; ++ (NSDictionary *)getiAdErrors; ++ (void)cleariAdErrors; + @end diff --git a/Adjust/ADJUserDefaults.m b/Adjust/ADJUserDefaults.m index 97cb7e643..5be4d07ff 100644 --- a/Adjust/ADJUserDefaults.m +++ b/Adjust/ADJUserDefaults.m @@ -15,6 +15,7 @@ static NSString * const PREFS_KEY_DEEPLINK_URL = @"adj_deeplink_url"; static NSString * const PREFS_KEY_DEEPLINK_CLICK_TIME = @"adj_deeplink_click_time"; static NSString * const PREFS_KEY_DISABLE_THIRD_PARTY_SHARING = @"adj_disable_third_party_sharing"; +static NSString * const PREFS_KEY_IAD_ERRORS = @"adj_iad_errors"; @implementation ADJUserDefaults @@ -101,6 +102,34 @@ + (void)removeDisableThirdPartySharing { [[NSUserDefaults standardUserDefaults] synchronize]; } ++ (void)saveiAdErrorKey:(NSString *)key { + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + + NSMutableDictionary *errors = [[userDefaults dictionaryForKey:PREFS_KEY_IAD_ERRORS] mutableCopy]; + if (errors) { + NSNumber *value = errors[key]; + if (!value) { + value = @(1); + } else { + value = @([value integerValue] + 1); + } + + errors[key] = value; + } else { + errors[key] = @(1); + } + + [userDefaults setObject:errors forKey:PREFS_KEY_IAD_ERRORS]; +} + ++ (NSDictionary *)getiAdErrors { + return [[NSUserDefaults standardUserDefaults] dictionaryForKey:PREFS_KEY_IAD_ERRORS]; +} + ++ (void)cleariAdErrors { + [[NSUserDefaults standardUserDefaults] removeObjectForKey:PREFS_KEY_IAD_ERRORS]; +} + + (void)clearAdjustStuff { [[NSUserDefaults standardUserDefaults] removeObjectForKey:PREFS_KEY_PUSH_TOKEN_DATA]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:PREFS_KEY_PUSH_TOKEN_STRING]; From ce52b9a048fe6d45654bbdcc733c399bba18c2fc Mon Sep 17 00:00:00 2001 From: rabc Date: Wed, 22 Jul 2020 06:57:21 +0200 Subject: [PATCH 104/173] Inject self --- Adjust/ADJActivityHandler.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 126688e8f..788609c60 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -426,7 +426,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), ^{ - [self checkForiAd]; + [self checkForiAdI:self]; }); return; } @@ -1391,7 +1391,7 @@ - (void)setEnabledI:(ADJActivityHandler *)selfI enabled:(BOOL)enabled { [selfI disableThirdPartySharing]; } if (selfI.adjustConfig.allowiAdInfoReading == YES) { - [selfI checkForiAd]; + [selfI checkForiAdI:selfI]; } } @@ -1402,8 +1402,8 @@ - (void)setEnabledI:(ADJActivityHandler *)selfI enabled:(BOOL)enabled { unPausingMessage:@"Resuming handlers due to SDK being enabled"]; } -- (void)checkForiAd { - [[UIDevice currentDevice] adjCheckForiAd:self queue:self.internalQueue]; +- (void)checkForiAdI:(ADJActivityHandler *)selfI { + [[UIDevice currentDevice] adjCheckForiAd:selfI queue:selfI.internalQueue]; } - (void)setOfflineModeI:(ADJActivityHandler *)selfI From c52cd28779ce3720eb30b08b47c6a3668892d7be Mon Sep 17 00:00:00 2001 From: rabc Date: Thu, 23 Jul 2020 09:31:34 +0200 Subject: [PATCH 105/173] Clear iAd errors when receiving package response --- Adjust/ADJActivityHandler.h | 2 ++ Adjust/ADJActivityHandler.m | 10 +++++++++- Adjust/ADJPackageBuilder.m | 4 +--- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Adjust/ADJActivityHandler.h b/Adjust/ADJActivityHandler.h index 360699ced..bea883a80 100644 --- a/Adjust/ADJActivityHandler.h +++ b/Adjust/ADJActivityHandler.h @@ -127,3 +127,5 @@ - (void)resetSessionPartnerParametersI:(ADJActivityHandler *)selfI; @end + +extern NSString * const ADJiAdPackageKey; diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 788609c60..7ecd1b5dd 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -21,6 +21,8 @@ #import "ADJSdkClickHandler.h" #import "ADJUserDefaults.h" +NSString * const ADJiAdPackageKey = @"iad3"; + typedef void (^activityHandlerBlockI)(ADJActivityHandler * activityHandler); static NSString * const kActivityStateFilename = @"AdjustIoActivityState"; @@ -263,6 +265,12 @@ - (void)trackEvent:(ADJEvent *)event { } - (void)finishedTracking:(ADJResponseData *)responseData { + + if ([responseData.sdkClickPackage.parameters.allValues containsObject:ADJiAdPackageKey]) { + // received iAd click package response, clear the errors from UserDefaults + [ADJUserDefaults cleariAdErrors]; + } + // redirect session responses to attribution handler to check for attribution information if ([responseData isKindOfClass:[ADJSessionResponseData class]]) { [self.attributionHandler checkSessionResponse:(ADJSessionResponseData*)responseData]; @@ -524,7 +532,7 @@ - (void)sendIad3ClickPackage:(ADJActivityHandler *)selfI clickBuilder.attributionDetails = attributionDetails; - ADJActivityPackage *clickPackage = [clickBuilder buildClickPackage:@"iad3"]; + ADJActivityPackage *clickPackage = [clickBuilder buildClickPackage:ADJiAdPackageKey]; [selfI.sdkClickHandler sendSdkClick:clickPackage]; } diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index 3707416e2..648d0a0bb 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -115,15 +115,13 @@ - (ADJActivityPackage *)buildAdRevenuePackage:(NSString *)source payload:(NSData - (ADJActivityPackage *)buildClickPackage:(NSString *)clickSource { NSMutableDictionary *parameters = [self getClickParameters:clickSource]; - if ([clickSource isEqualToString:@"iad3"]) { + if ([clickSource isEqualToString:ADJiAdPackageKey]) { // send iAd errors in the parameters NSDictionary *iAdErrors = [ADJUserDefaults getiAdErrors]; if (iAdErrors) { NSData *jsonData = [NSJSONSerialization dataWithJSONObject:iAdErrors options:0 error:nil]; NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; parameters[@"iad_errors"] = jsonStr; - - [ADJUserDefaults cleariAdErrors]; } } From cc04ca1a2342d008a685876a78cded89d3c26280 Mon Sep 17 00:00:00 2001 From: rabc Date: Fri, 24 Jul 2020 08:20:52 +0200 Subject: [PATCH 106/173] Add break in switch --- Adjust/ADJActivityHandler.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 7ecd1b5dd..735a96b63 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -488,14 +488,19 @@ - (void)saveiAdErrorCode:(NSInteger)code { switch (code) { case AdjADClientErrorUnknown: codeKey = @"AdjADClientErrorUnknown"; + break; case AdjADClientErrorMissingData: codeKey = @"AdjADClientErrorMissingData"; + break; case AdjADClientErrorCorruptResponse: codeKey = @"AdjADClientErrorCorruptResponse"; + break; case AdjCustomErrorTimeout: codeKey = @"AdjCustomErrorTimeout"; + break; default: codeKey = @""; + break; } if (![codeKey isEqualToString:@""]) { From 91cfd73cdfa39fb9544423fe23f64d462fd2ed8a Mon Sep 17 00:00:00 2001 From: rabc Date: Fri, 24 Jul 2020 08:21:41 +0200 Subject: [PATCH 107/173] Remove NSUserDefaults synchronize --- Adjust/ADJUserDefaults.m | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Adjust/ADJUserDefaults.m b/Adjust/ADJUserDefaults.m index 5be4d07ff..c28db5045 100644 --- a/Adjust/ADJUserDefaults.m +++ b/Adjust/ADJUserDefaults.m @@ -23,12 +23,10 @@ @implementation ADJUserDefaults + (void)savePushTokenData:(NSData *)pushToken { [[NSUserDefaults standardUserDefaults] setObject:pushToken forKey:PREFS_KEY_PUSH_TOKEN_DATA]; - [[NSUserDefaults standardUserDefaults] synchronize]; } + (void)savePushTokenString:(NSString *)pushToken { [[NSUserDefaults standardUserDefaults] setObject:pushToken forKey:PREFS_KEY_PUSH_TOKEN_STRING]; - [[NSUserDefaults standardUserDefaults] synchronize]; } + (NSData *)getPushTokenData { @@ -42,12 +40,10 @@ + (NSString *)getPushTokenString { + (void)removePushToken { [[NSUserDefaults standardUserDefaults] removeObjectForKey:PREFS_KEY_PUSH_TOKEN_DATA]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:PREFS_KEY_PUSH_TOKEN_STRING]; - [[NSUserDefaults standardUserDefaults] synchronize]; } + (void)setInstallTracked { [[NSUserDefaults standardUserDefaults] setBool:YES forKey:PREFS_KEY_INSTALL_TRACKED]; - [[NSUserDefaults standardUserDefaults] synchronize]; } + (BOOL)getInstallTracked { @@ -56,7 +52,6 @@ + (BOOL)getInstallTracked { + (void)setGdprForgetMe { [[NSUserDefaults standardUserDefaults] setBool:YES forKey:PREFS_KEY_GDPR_FORGET_ME]; - [[NSUserDefaults standardUserDefaults] synchronize]; } + (BOOL)getGdprForgetMe { @@ -65,13 +60,11 @@ + (BOOL)getGdprForgetMe { + (void)removeGdprForgetMe { [[NSUserDefaults standardUserDefaults] removeObjectForKey:PREFS_KEY_GDPR_FORGET_ME]; - [[NSUserDefaults standardUserDefaults] synchronize]; } + (void)saveDeeplinkUrl:(NSURL *)deeplink andClickTime:(NSDate *)clickTime { [[NSUserDefaults standardUserDefaults] setURL:deeplink forKey:PREFS_KEY_DEEPLINK_URL]; [[NSUserDefaults standardUserDefaults] setObject:clickTime forKey:PREFS_KEY_DEEPLINK_CLICK_TIME]; - [[NSUserDefaults standardUserDefaults] synchronize]; } + (NSURL *)getDeeplinkUrl { @@ -85,12 +78,10 @@ + (NSDate *)getDeeplinkClickTime { + (void)removeDeeplink { [[NSUserDefaults standardUserDefaults] removeObjectForKey:PREFS_KEY_DEEPLINK_URL]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:PREFS_KEY_DEEPLINK_CLICK_TIME]; - [[NSUserDefaults standardUserDefaults] synchronize]; } + (void)setDisableThirdPartySharing { [[NSUserDefaults standardUserDefaults] setBool:YES forKey:PREFS_KEY_DISABLE_THIRD_PARTY_SHARING]; - [[NSUserDefaults standardUserDefaults] synchronize]; } + (BOOL)getDisableThirdPartySharing { @@ -99,7 +90,6 @@ + (BOOL)getDisableThirdPartySharing { + (void)removeDisableThirdPartySharing { [[NSUserDefaults standardUserDefaults] removeObjectForKey:PREFS_KEY_DISABLE_THIRD_PARTY_SHARING]; - [[NSUserDefaults standardUserDefaults] synchronize]; } + (void)saveiAdErrorKey:(NSString *)key { @@ -138,7 +128,6 @@ + (void)clearAdjustStuff { [[NSUserDefaults standardUserDefaults] removeObjectForKey:PREFS_KEY_DEEPLINK_URL]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:PREFS_KEY_DEEPLINK_CLICK_TIME]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:PREFS_KEY_DISABLE_THIRD_PARTY_SHARING]; - [[NSUserDefaults standardUserDefaults] synchronize]; } @end From 879ad13f20d9128a039c6a475c64f1d306087c4f Mon Sep 17 00:00:00 2001 From: rabc Date: Fri, 24 Jul 2020 08:25:26 +0200 Subject: [PATCH 108/173] Move clear iAd errors to sdk click handler --- Adjust/ADJActivityHandler.m | 6 ------ Adjust/ADJSdkClickHandler.m | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 735a96b63..75c7cfd64 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -265,12 +265,6 @@ - (void)trackEvent:(ADJEvent *)event { } - (void)finishedTracking:(ADJResponseData *)responseData { - - if ([responseData.sdkClickPackage.parameters.allValues containsObject:ADJiAdPackageKey]) { - // received iAd click package response, clear the errors from UserDefaults - [ADJUserDefaults cleariAdErrors]; - } - // redirect session responses to attribution handler to check for attribution information if ([responseData isKindOfClass:[ADJSessionResponseData class]]) { [self.attributionHandler checkSessionResponse:(ADJSessionResponseData*)responseData]; diff --git a/Adjust/ADJSdkClickHandler.m b/Adjust/ADJSdkClickHandler.m index 830e97b0f..17d3488da 100644 --- a/Adjust/ADJSdkClickHandler.m +++ b/Adjust/ADJSdkClickHandler.m @@ -11,6 +11,7 @@ #import "ADJAdjustFactory.h" #import "ADJSdkClickHandler.h" #import "ADJBackoffStrategy.h" +#import "ADJUserDefaults.h" static const char * const kInternalQueueName = "com.adjust.SdkClickQueue"; @@ -192,6 +193,11 @@ - (void)responseCallback:(ADJResponseData *)responseData { return; } self.lastPackageRetriesCount = 0; + + if ([responseData.sdkClickPackage.parameters.allValues containsObject:ADJiAdPackageKey]) { + // received iAd click package response, clear the errors from UserDefaults + [ADJUserDefaults cleariAdErrors]; + } [self.activityHandler finishedTracking:responseData]; } From 8d2c668370a5849f750ca7a8189ea514da099f9c Mon Sep 17 00:00:00 2001 From: ugi Date: Fri, 24 Jul 2020 14:32:31 +0200 Subject: [PATCH 109/173] new version 4.22.2 --- 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 7d833c775..01175234a 100644 --- a/Adjust.podspec +++ b/Adjust.podspec @@ -1,11 +1,11 @@ Pod::Spec.new do |s| s.name = "Adjust" - s.version = "4.22.1" + s.version = "4.22.2" 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.22.1" } + s.source = { :git => "https://github.com/adjust/ios_sdk.git", :tag => "v4.22.2" } 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 f15627237..eca7b23af 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -40,7 +40,7 @@ static CTTelephonyNetworkInfo *networkInfo = nil; #endif -static NSString * const kClientSdk = @"ios4.22.1"; +static NSString * const kClientSdk = @"ios4.22.2"; 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 34833a0fb..d6e7b0595 100644 --- a/Adjust/Adjust.h +++ b/Adjust/Adjust.h @@ -2,7 +2,7 @@ // Adjust.h // Adjust // -// V4.22.1 +// V4.22.2 // 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 310cd91a2..39cdc8e74 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.22.1'; + return 'web-bridge4.22.2'; } }, setTestOptions: function(testOptions) { diff --git a/AdjustTests/AdjustUnitTests/ADJPackageFields.m b/AdjustTests/AdjustUnitTests/ADJPackageFields.m index 53963ba7b..9b8ed182d 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.22.1"; + self.clientSdk = @"ios4.22.2"; self.suffix = @""; self.environment = @"sandbox"; diff --git a/README.md b/README.md index ac9714e65..1f35e7fcb 100644 --- a/README.md +++ b/README.md @@ -75,13 +75,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.22.1' +pod 'Adjust', '~> 4.22.2' ``` or: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.1' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.2' ``` --- diff --git a/VERSION b/VERSION index 352b26ac2..1c8437353 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.22.1 +4.22.2 diff --git a/doc/chinese/README.md b/doc/chinese/README.md index 61911b9c3..d73ff8495 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.22.1' +pod 'Adjust', '~> 4.22.2' ``` 或: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.1' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.2' ``` --- diff --git a/doc/english/migrate.md b/doc/english/migrate.md index 9dfbbeceb..e4a0f84fd 100644 --- a/doc/english/migrate.md +++ b/doc/english/migrate.md @@ -1,4 +1,4 @@ -## Migrate your Adjust SDK for iOS to v4.22.1 from v3.4.0 +## Migrate your Adjust SDK for iOS to v4.22.2 from v3.4.0 ### Initial setup diff --git a/doc/english/web_views.md b/doc/english/web_views.md index a6122ea6d..b20525fc1 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.22.1' +pod 'Adjust/WebBridge', '~> 4.22.2' ``` --- diff --git a/doc/japanese/README.md b/doc/japanese/README.md index de7342906..c6a71d3b8 100644 --- a/doc/japanese/README.md +++ b/doc/japanese/README.md @@ -25,13 +25,13 @@ adjust SDKをiOSプロジェクトに連携する手順を説明します。 [こちらの手順](#sdk-integrate)に進んでください。 ```ruby -pod 'Adjust', '~> 4.22.1' +pod 'Adjust', '~> 4.22.2' ``` または ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.1' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.2' ``` --- diff --git a/doc/korean/README.md b/doc/korean/README.md index af8a463dc..dfa7f3af0 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.22.1' +pod 'Adjust', '~> 4.22.2' ``` 또는: ```ruby -pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.1' +pod 'Adjust', :git => 'https://github.com/adjust/ios_sdk.git', :tag => 'v4.22.2' ``` --- diff --git a/doc/korean/web_views.md b/doc/korean/web_views.md index e472590f8..c7125d32e 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.22.1' +pod 'Adjust/WebBridge', '~> 4.22.2' ``` --- diff --git a/doc/migrate.md b/doc/migrate.md index 9dfbbeceb..e4a0f84fd 100644 --- a/doc/migrate.md +++ b/doc/migrate.md @@ -1,4 +1,4 @@ -## Migrate your Adjust SDK for iOS to v4.22.1 from v3.4.0 +## Migrate your Adjust SDK for iOS to v4.22.2 from v3.4.0 ### Initial setup From b6dbe628745847f69e68b9ca43033cec6d220854 Mon Sep 17 00:00:00 2001 From: ugi Date: Fri, 24 Jul 2020 15:21:13 +0200 Subject: [PATCH 110/173] update CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0b1251b0..3f196595b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### Version 4.22.2 (24th July 2020) +#### Added +- Added collection iAd framework communication errors metrics. + +--- + ### Version 4.22.1 (5th June 2020) #### Fixed - Fixed `copyWithZone:` method implementation in `ADJSubscription.m` (thanks to @atilimcetin). From bfc8d9e8e31c50ac9d022a3d0b9df230ef2242b4 Mon Sep 17 00:00:00 2001 From: rabc Date: Thu, 16 Jul 2020 16:06:32 +0200 Subject: [PATCH 111/173] Include AppTrackingTransparency.framework --- .../AdjustExample-ObjC.xcodeproj/project.pbxproj | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/examples/AdjustExample-ObjC/AdjustExample-ObjC.xcodeproj/project.pbxproj b/examples/AdjustExample-ObjC/AdjustExample-ObjC.xcodeproj/project.pbxproj index 1477a31bc..7d5c58e84 100644 --- a/examples/AdjustExample-ObjC/AdjustExample-ObjC.xcodeproj/project.pbxproj +++ b/examples/AdjustExample-ObjC/AdjustExample-ObjC.xcodeproj/project.pbxproj @@ -50,6 +50,7 @@ 9DC95F261C104CEF00138E4B /* ViewControllerObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DC95F251C104CEF00138E4B /* ViewControllerObjC.m */; }; 9DC95F2A1C10515300138E4B /* Constants.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DC95F291C10515300138E4B /* Constants.m */; }; 9DD0E9BE1F457EF800B2A759 /* ADJUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DD0E9BD1F457EF800B2A759 /* ADJUserDefaults.m */; }; + D799022C24C093AA00C7D11C /* AppTrackingTransparency.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D799022B24C093AA00C7D11C /* AppTrackingTransparency.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -137,6 +138,7 @@ 9DCA5CF01DD5B6BE000296B2 /* AdjustExample-ObjC.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "AdjustExample-ObjC.entitlements"; sourceTree = ""; }; 9DD0E9BC1F457EF800B2A759 /* ADJUserDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADJUserDefaults.h; sourceTree = ""; }; 9DD0E9BD1F457EF800B2A759 /* ADJUserDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADJUserDefaults.m; sourceTree = ""; }; + D799022B24C093AA00C7D11C /* AppTrackingTransparency.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppTrackingTransparency.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.16.sdk/System/Library/Frameworks/AppTrackingTransparency.framework; sourceTree = DEVELOPER_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -144,6 +146,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D799022C24C093AA00C7D11C /* AppTrackingTransparency.framework in Frameworks */, 9639095F1BCBFD3B00A2E8A4 /* iAd.framework in Frameworks */, 963909611BCBFD4200A2E8A4 /* AdSupport.framework in Frameworks */, ); @@ -157,6 +160,7 @@ children = ( 9639093E1BCBFCF300A2E8A4 /* AdjustExample-ObjC */, 9639093D1BCBFCF300A2E8A4 /* Products */, + D799022A24C093AA00C7D11C /* Frameworks */, ); sourceTree = ""; }; @@ -291,6 +295,14 @@ name = Frameworks; sourceTree = ""; }; + D799022A24C093AA00C7D11C /* Frameworks */ = { + isa = PBXGroup; + children = ( + D799022B24C093AA00C7D11C /* AppTrackingTransparency.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ From ae0d1e46dd91c44d2392a3aaf4fe5e35e55583a8 Mon Sep 17 00:00:00 2001 From: rabc Date: Thu, 16 Jul 2020 16:07:02 +0200 Subject: [PATCH 112/173] Use ATTrackingManager to check status --- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 59 ++++++++++++++++----- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index 5c4d72a61..3d774f64c 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -13,6 +13,7 @@ #if !ADJUST_NO_IDFA #import +#import #endif #if !ADJUST_NO_IAD && !TARGET_OS_TV @@ -24,25 +25,56 @@ @implementation UIDevice(ADJAdditions) +- (Class)adSupportManager { + NSString *className = [NSString adjJoin:@"A", @"S", @"identifier", @"manager", nil]; + Class class = NSClassFromString(className); + + return class; +} + +- (Class)appTrackingManager { + NSString *className = [NSString adjJoin:@"A", @"T", @"tracking", @"manager", nil]; + Class class = NSClassFromString(className); + + return class; +} + - (BOOL)adjTrackingEnabled { #if ADJUST_NO_IDFA return NO; #else - // return [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]; - NSString *className = [NSString adjJoin:@"A", @"S", @"identifier", @"manager", nil]; - Class class = NSClassFromString(className); - if (class == nil) { - return NO; - } + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" +// [ATTrackingManager trackingAuthorizationStatus]; + Class appTrackingClass = [self appTrackingManager]; + if (appTrackingClass != nil) { + NSString *keyAuthorization = [NSString adjJoin:@"tracking", @"authorization", @"status", nil]; + SEL selAuthorization = NSSelectorFromString(keyAuthorization); + if ([appTrackingClass respondsToSelector:selAuthorization]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" + ATTrackingManagerAuthorizationStatus status = (ATTrackingManagerAuthorizationStatus)[appTrackingClass performSelector:selAuthorization]; + return status == ATTrackingManagerAuthorizationStatusAuthorized; +#pragma clang diagnostic pop + } + } + + // Fallback iOS 13 and earlier versions + +// return [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]; + Class adSupportClass = [self adSupportManager]; + if (adSupportClass == nil) { + return NO; + } + NSString *keyManager = [NSString adjJoin:@"shared", @"manager", nil]; SEL selManager = NSSelectorFromString(keyManager); - if (![class respondsToSelector:selManager]) { + if (![adSupportClass respondsToSelector:selManager]) { return NO; } - id manager = [class performSelector:selManager]; - + id manager = [adSupportClass performSelector:selManager]; + NSString *keyEnabled = [NSString adjJoin:@"is", @"advertising", @"tracking", @"enabled", nil]; SEL selEnabled = NSSelectorFromString(keyEnabled); if (![manager respondsToSelector:selEnabled]) { @@ -59,9 +91,8 @@ - (NSString *)adjIdForAdvertisers { return @""; #else // return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; - NSString *className = [NSString adjJoin:@"A", @"S", @"identifier", @"manager", nil]; - Class class = NSClassFromString(className); - if (class == nil) { + Class adSupportClass = [self adSupportManager]; + if (adSupportClass == nil) { return @""; } #pragma clang diagnostic push @@ -69,10 +100,10 @@ - (NSString *)adjIdForAdvertisers { NSString *keyManager = [NSString adjJoin:@"shared", @"manager", nil]; SEL selManager = NSSelectorFromString(keyManager); - if (![class respondsToSelector:selManager]) { + if (![adSupportClass respondsToSelector:selManager]) { return @""; } - id manager = [class performSelector:selManager]; + id manager = [adSupportClass performSelector:selManager]; NSString *keyIdentifier = [NSString adjJoin:@"advertising", @"identifier", nil]; SEL selIdentifier = NSSelectorFromString(keyIdentifier); From 4f81addf62eb3c258cf243332f2e3759660953d1 Mon Sep 17 00:00:00 2001 From: rabc Date: Fri, 17 Jul 2020 10:31:31 +0200 Subject: [PATCH 113/173] Add and handle new iAd error codes --- Adjust/ADJActivityHandler.m | 342 ++++++++++++++++++++++++++++++------ 1 file changed, 291 insertions(+), 51 deletions(-) diff --git a/Adjust/ADJActivityHandler.m b/Adjust/ADJActivityHandler.m index 75c7cfd64..2cfa7cc95 100644 --- a/Adjust/ADJActivityHandler.m +++ b/Adjust/ADJActivityHandler.m @@ -20,6 +20,7 @@ #import "NSString+ADJAdditions.h" #import "ADJSdkClickHandler.h" #import "ADJUserDefaults.h" +#import "ADJUrlStrategy.h" NSString * const ADJiAdPackageKey = @"iad3"; @@ -108,9 +109,13 @@ @interface ADJActivityHandler() // copy from ADClientError typedef NS_ENUM(NSInteger, AdjADClientError) { AdjADClientErrorUnknown = 0, - AdjADClientErrorLimitAdTracking = 1, + AdjADClientErrorTrackingRestrictedOrDenied = 1, AdjADClientErrorMissingData = 2, AdjADClientErrorCorruptResponse = 3, + AdjADClientErrorRequestClientError = 4, + AdjADClientErrorRequestServerError = 5, + AdjADClientErrorRequestNetworkError = 6, + AdjADClientErrorUnsupportedPlatform = 7, AdjCustomErrorTimeout = 100, }; @@ -118,6 +123,7 @@ typedef NS_ENUM(NSInteger, AdjADClientError) { @implementation ADJActivityHandler @synthesize attribution = _attribution; +@synthesize trackingStatusManager = _trackingStatusManager; - (id)initWithConfig:(ADJConfig *)adjustConfig savedPreLaunch:(ADJSavedPreLaunch *)savedPreLaunch @@ -160,6 +166,9 @@ - (id)initWithConfig:(ADJConfig *)adjustConfig // read files to have sync values available [self readAttribution]; [self readActivityState]; + + // register SKAdNetwork attribution + [self registerForSKAdNetworkAttribution]; self.internalState = [[ADJInternalState alloc] init]; @@ -198,6 +207,8 @@ - (id)initWithConfig:(ADJConfig *)adjustConfig self.iAdRetriesLeft = kiAdRetriesCount; + self.trackingStatusManager = [[ADJTrackingStatusManager alloc] initWithActivityHandler:self]; + self.internalQueue = dispatch_queue_create(kInternalQueueName, DISPATCH_QUEUE_SERIAL); [ADJUtil launchInQueue:self.internalQueue selfInject:self @@ -265,6 +276,8 @@ - (void)trackEvent:(ADJEvent *)event { } - (void)finishedTracking:(ADJResponseData *)responseData { + [self checkConversionValue:responseData]; + // redirect session responses to attribution handler to check for attribution information if ([responseData isKindOfClass:[ADJSessionResponseData class]]) { [self.attributionHandler checkSessionResponse:(ADJSessionResponseData*)responseData]; @@ -399,19 +412,18 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails return; } - // if first request was unsuccessful and ended up with one of the following error codes: - // - AdjADClientErrorUnknown - // - AdjADClientErrorMissingData - // - AdjADClientErrorCorruptResponse - // - AdjCustomErrorTimeout - // apply following retry logic: - // - 1st retry after 5 seconds - // - 2nd retry after 2 seconds - // - 3rd retry after 2 seconds switch (error.code) { + // if first request was unsuccessful and ended up with one of the following error codes: + // apply following retry logic: + // - 1st retry after 5 seconds + // - 2nd retry after 2 seconds + // - 3rd retry after 2 seconds case AdjADClientErrorUnknown: case AdjADClientErrorMissingData: case AdjADClientErrorCorruptResponse: + case AdjADClientErrorRequestClientError: + case AdjADClientErrorRequestServerError: + case AdjADClientErrorRequestNetworkError: case AdjCustomErrorTimeout: { [self saveiAdErrorCode:error.code]; @@ -432,7 +444,8 @@ - (void)setAttributionDetails:(NSDictionary *)attributionDetails }); return; } - case AdjADClientErrorLimitAdTracking: + case AdjADClientErrorTrackingRestrictedOrDenied: + case AdjADClientErrorUnsupportedPlatform: return; default: return; @@ -527,6 +540,7 @@ - (void)sendIad3ClickPackage:(ADJActivityHandler *)selfI activityState:selfI.activityState config:selfI.adjustConfig sessionParameters:self.sessionParameters + trackingStatusManager:self.trackingStatusManager createdAt:now]; clickBuilder.attributionDetails = attributionDetails; @@ -653,6 +667,42 @@ - (void)disableThirdPartySharing { }]; } +- (void)writeActivityState { + [ADJUtil launchInQueue:self.internalQueue + selfInject:self + block:^(ADJActivityHandler * selfI) { + [selfI writeActivityStateI:selfI]; + }]; +} + +- (void)trackAttStatusUpdate { + [ADJUtil launchInQueue:self.internalQueue + selfInject:self + block:^(ADJActivityHandler * selfI) { + [selfI trackAttStatusUpdateI:selfI]; + }]; +} +- (void)trackAttStatusUpdateI:(ADJActivityHandler *)selfI { + double now = [NSDate.date timeIntervalSince1970]; + + ADJPackageBuilder *infoBuilder = [[ADJPackageBuilder alloc] + initWithDeviceInfo:selfI.deviceInfo + activityState:selfI.activityState + config:selfI.adjustConfig + sessionParameters:selfI.sessionParameters + trackingStatusManager:self.trackingStatusManager + createdAt:now]; + + ADJActivityPackage *infoPackage = [infoBuilder buildInfoPackage:@"att"]; + [selfI.packageHandler addPackage:infoPackage]; + + if (selfI.adjustConfig.eventBufferingEnabled) { + [selfI.logger info:@"Buffered event %@", infoPackage.suffix]; + } else { + [selfI.packageHandler sendFirstPackage]; + } +} + - (NSString *)getBasePath { return _basePath; } @@ -808,35 +858,53 @@ - (void)initI:(ADJActivityHandler *)selfI [ADJUtil updateUrlSessionConfiguration:selfI.adjustConfig]; + ADJUrlStrategy *packageHandlerUrlStrategy = + [[ADJUrlStrategy alloc] + initWithUrlStrategyInfo:selfI.adjustConfig.urlStrategy + extraPath:preLaunchActions.extraPath]; + selfI.packageHandler = [[ADJPackageHandler alloc] initWithActivityHandler:selfI startsSending: [selfI toSendI:selfI sdkClickHandlerOnly:NO] userAgent:selfI.adjustConfig.userAgent - extraPath:preLaunchActions.extraPath]; + urlStrategy:packageHandlerUrlStrategy]; // update session parameters in package queue if ([selfI itHasToUpdatePackagesI:selfI]) { [selfI updatePackagesI:selfI]; } + + ADJUrlStrategy *attributionHandlerUrlStrategy = + [[ADJUrlStrategy alloc] + initWithUrlStrategyInfo:selfI.adjustConfig.urlStrategy + extraPath:preLaunchActions.extraPath]; + selfI.attributionHandler = [[ADJAttributionHandler alloc] initWithActivityHandler:selfI startsSending: [selfI toSendI:selfI sdkClickHandlerOnly:NO] userAgent:selfI.adjustConfig.userAgent - extraPath:preLaunchActions.extraPath]; + urlStrategy:attributionHandlerUrlStrategy]; + + ADJUrlStrategy *sdkClickHandlerUrlStrategy = + [[ADJUrlStrategy alloc] + initWithUrlStrategyInfo:selfI.adjustConfig.urlStrategy + extraPath:preLaunchActions.extraPath]; selfI.sdkClickHandler = [[ADJSdkClickHandler alloc] initWithActivityHandler:selfI startsSending:[selfI toSendI:selfI sdkClickHandlerOnly:YES] userAgent:selfI.adjustConfig.userAgent - extraPath:preLaunchActions.extraPath]; + urlStrategy:sdkClickHandlerUrlStrategy]; if (selfI.adjustConfig.allowiAdInfoReading == YES) { [selfI checkForiAdI:selfI]; } + [selfI.trackingStatusManager checkForNewAttStatus]; + [selfI preLaunchActionsI:selfI preLaunchActionsArray:preLaunchActions.preLaunchActionsArray]; @@ -978,6 +1046,7 @@ - (void)transferSessionPackageI:(ADJActivityHandler *)selfI activityState:selfI.activityState config:selfI.adjustConfig sessionParameters:selfI.sessionParameters + trackingStatusManager:self.trackingStatusManager createdAt:now]; ADJActivityPackage *sessionPackage = [sessionBuilder buildSessionPackage:[selfI.internalState isInDelayedStart]]; [selfI.packageHandler addPackage:sessionPackage]; @@ -1052,6 +1121,7 @@ - (void)eventI:(ADJActivityHandler *)selfI activityState:selfI.activityState config:selfI.adjustConfig sessionParameters:selfI.sessionParameters + trackingStatusManager:self.trackingStatusManager createdAt:now]; ADJActivityPackage *eventPackage = [eventBuilder buildEventPackage:event isInDelay:[selfI.internalState isInDelayedStart]]; @@ -1087,14 +1157,21 @@ - (void)adRevenueI:(ADJActivityHandler *)selfI double now = [NSDate.date timeIntervalSince1970]; // Create and submit ad revenue package. - ADJPackageBuilder *adRevenueBuilder = [[ADJPackageBuilder alloc] initWithDeviceInfo:selfI.deviceInfo - activityState:selfI.activityState - config:selfI.adjustConfig - sessionParameters:selfI.sessionParameters - createdAt:now]; + ADJPackageBuilder *adRevenueBuilder = [[ADJPackageBuilder alloc] + initWithDeviceInfo:selfI.deviceInfo + activityState:selfI.activityState + config:selfI.adjustConfig + sessionParameters:selfI.sessionParameters + trackingStatusManager:self.trackingStatusManager + createdAt:now]; + ADJActivityPackage *adRevenuePackage = [adRevenueBuilder buildAdRevenuePackage:source payload:payload]; [selfI.packageHandler addPackage:adRevenuePackage]; - [selfI.packageHandler sendFirstPackage]; + if (selfI.adjustConfig.eventBufferingEnabled) { + [selfI.logger info:@"Buffered event %@", adRevenuePackage.suffix]; + } else { + [selfI.packageHandler sendFirstPackage]; + } } - (void)trackSubscriptionI:(ADJActivityHandler *)selfI @@ -1112,15 +1189,22 @@ - (void)trackSubscriptionI:(ADJActivityHandler *)selfI double now = [NSDate.date timeIntervalSince1970]; // Create and submit ad revenue package. - ADJPackageBuilder *subscriptionBuilder = [[ADJPackageBuilder alloc] initWithDeviceInfo:selfI.deviceInfo - activityState:selfI.activityState - config:selfI.adjustConfig - sessionParameters:selfI.sessionParameters - createdAt:now]; + ADJPackageBuilder *subscriptionBuilder = [[ADJPackageBuilder alloc] + initWithDeviceInfo:selfI.deviceInfo + activityState:selfI.activityState + config:selfI.adjustConfig + sessionParameters:selfI.sessionParameters + trackingStatusManager:self.trackingStatusManager + createdAt:now]; + ADJActivityPackage *subscriptionPackage = [subscriptionBuilder buildSubscriptionPackage:subscription isInDelay:[selfI.internalState isInDelayedStart]]; [selfI.packageHandler addPackage:subscriptionPackage]; - [selfI.packageHandler sendFirstPackage]; + if (selfI.adjustConfig.eventBufferingEnabled) { + [selfI.logger info:@"Buffered event %@", subscriptionPackage.suffix]; + } else { + [selfI.packageHandler sendFirstPackage]; + } } - (void)disableThirdPartySharingI:(ADJActivityHandler *)selfI { @@ -1151,11 +1235,12 @@ - (void)disableThirdPartySharingI:(ADJActivityHandler *)selfI { // build package ADJPackageBuilder *dtpsBuilder = [[ADJPackageBuilder alloc] - initWithDeviceInfo:selfI.deviceInfo - activityState:selfI.activityState - config:selfI.adjustConfig - sessionParameters:selfI.sessionParameters - createdAt:now]; + initWithDeviceInfo:selfI.deviceInfo + activityState:selfI.activityState + config:selfI.adjustConfig + sessionParameters:selfI.sessionParameters + trackingStatusManager:self.trackingStatusManager + createdAt:now]; ADJActivityPackage *dtpsPackage = [dtpsBuilder buildDisableThirdPartySharingPackage]; @@ -1259,6 +1344,8 @@ - (void)launchSdkClickResponseTasksI:(ADJActivityHandler *)selfI - (void)launchAttributionResponseTasksI:(ADJActivityHandler *)selfI attributionResponseData:(ADJAttributionResponseData *)attributionResponseData { + [selfI checkConversionValue:attributionResponseData]; + [selfI updateAdidI:selfI adid:attributionResponseData.adid]; BOOL toLaunchAttributionDelegate = [selfI updateAttributionI:selfI @@ -1520,11 +1607,14 @@ - (void)appWillOpenUrlI:(ADJActivityHandler *)selfI double lastInterval = now - selfI.activityState.lastActivity; selfI.activityState.lastInterval = lastInterval; }]; - ADJPackageBuilder *clickBuilder = [[ADJPackageBuilder alloc] initWithDeviceInfo:selfI.deviceInfo - activityState:selfI.activityState - config:selfI.adjustConfig - sessionParameters:selfI.sessionParameters - createdAt:now]; + ADJPackageBuilder *clickBuilder = [[ADJPackageBuilder alloc] + initWithDeviceInfo:selfI.deviceInfo + activityState:selfI.activityState + config:selfI.adjustConfig + sessionParameters:selfI.sessionParameters + trackingStatusManager:self.trackingStatusManager + createdAt:now]; + clickBuilder.deeplinkParameters = [adjustDeepLinks copy]; clickBuilder.attribution = deeplinkAttribution; clickBuilder.clickTime = clickTime; @@ -1621,11 +1711,13 @@ - (void)setDeviceTokenI:(ADJActivityHandler *)selfI // send info package double now = [NSDate.date timeIntervalSince1970]; - ADJPackageBuilder *infoBuilder = [[ADJPackageBuilder alloc] initWithDeviceInfo:selfI.deviceInfo - activityState:selfI.activityState - config:selfI.adjustConfig - sessionParameters:selfI.sessionParameters - createdAt:now]; + ADJPackageBuilder *infoBuilder = [[ADJPackageBuilder alloc] + initWithDeviceInfo:selfI.deviceInfo + activityState:selfI.activityState + config:selfI.adjustConfig + sessionParameters:selfI.sessionParameters + trackingStatusManager:self.trackingStatusManager + createdAt:now]; ADJActivityPackage *infoPackage = [infoBuilder buildInfoPackage:@"push"]; @@ -1668,11 +1760,14 @@ - (void)setPushTokenI:(ADJActivityHandler *)selfI // send info package double now = [NSDate.date timeIntervalSince1970]; - ADJPackageBuilder *infoBuilder = [[ADJPackageBuilder alloc] initWithDeviceInfo:selfI.deviceInfo - activityState:selfI.activityState - config:selfI.adjustConfig - sessionParameters:selfI.sessionParameters - createdAt:now]; + ADJPackageBuilder *infoBuilder = [[ADJPackageBuilder alloc] + initWithDeviceInfo:selfI.deviceInfo + activityState:selfI.activityState + config:selfI.adjustConfig + sessionParameters:selfI.sessionParameters + trackingStatusManager:self.trackingStatusManager + createdAt:now]; + ADJActivityPackage *infoPackage = [infoBuilder buildInfoPackage:@"push"]; [selfI.packageHandler addPackage:infoPackage]; @@ -1706,11 +1801,13 @@ - (void)setGdprForgetMeI:(ADJActivityHandler *)selfI { // Send GDPR package double now = [NSDate.date timeIntervalSince1970]; - ADJPackageBuilder *gdprBuilder = [[ADJPackageBuilder alloc] initWithDeviceInfo:selfI.deviceInfo - activityState:selfI.activityState - config:selfI.adjustConfig - sessionParameters:selfI.sessionParameters - createdAt:now]; + ADJPackageBuilder *gdprBuilder = [[ADJPackageBuilder alloc] + initWithDeviceInfo:selfI.deviceInfo + activityState:selfI.activityState + config:selfI.adjustConfig + sessionParameters:selfI.sessionParameters + trackingStatusManager:self.trackingStatusManager + createdAt:now]; ADJActivityPackage *gdprPackage = [gdprBuilder buildGdprPackage]; [selfI.packageHandler addPackage:gdprPackage]; @@ -2025,6 +2122,8 @@ - (void)foregroundTimerFiredI:(ADJActivityHandler *)selfI { if ([selfI updateActivityStateI:selfI now:now]) { [selfI writeActivityStateI:selfI]; } + + [selfI.trackingStatusManager checkForNewAttStatus]; } - (void)startBackgroundTimerI:(ADJActivityHandler *)selfI { @@ -2334,4 +2433,145 @@ - (BOOL)checkActivityStateI:(ADJActivityHandler *)selfI { } return YES; } + +- (void)registerForSKAdNetworkAttribution { + if (!self.adjustConfig.isSKAdNetworkHandlingActive) { + return; + } + id logger = [ADJAdjustFactory logger]; + + Class skAdNetwork = NSClassFromString(@"SKAdNetwork"); + if (skAdNetwork == nil) { + [logger warn:@"StoreKit framework not found in user's app (SKAdNetwork not found)"]; + return; + } + + SEL registerAttributionSelector = NSSelectorFromString(@"registerAppForAdNetworkAttribution"); + if ([skAdNetwork respondsToSelector:registerAttributionSelector]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + [skAdNetwork performSelector:registerAttributionSelector]; +#pragma clang diagnostic pop + } +} + +- (void)checkConversionValue:(ADJResponseData *)responseData { + if (!self.adjustConfig.isSKAdNetworkHandlingActive) { + return; + } + if (responseData.jsonResponse == nil) { + return; + } + + NSNumber *conversionValue = [responseData.jsonResponse objectForKey:@"skadn_conv_value"]; + + if (!conversionValue) { + return; + } + + id logger = [ADJAdjustFactory logger]; + + Class skAdNetwork = NSClassFromString(@"SKAdNetwork"); + if (skAdNetwork == nil) { + [logger warn:@"StoreKit framework not found in user's app (SKAdNetwork not found)"]; + return; + } + + SEL updateConversionValueSelector = NSSelectorFromString(@"updateConversionValue:"); + if ([skAdNetwork respondsToSelector:updateConversionValueSelector]) { + NSInteger intValue = [conversionValue integerValue]; + + NSMethodSignature *conversionValueMethodSignature = [skAdNetwork methodSignatureForSelector:updateConversionValueSelector]; + NSInvocation *conversionInvocation = [NSInvocation invocationWithMethodSignature:conversionValueMethodSignature]; + [conversionInvocation setSelector:updateConversionValueSelector]; + [conversionInvocation setTarget:skAdNetwork]; + + [conversionInvocation setArgument:&intValue atIndex:2]; + [conversionInvocation invoke]; + } +} + +- (void)updateAttStatusFromUserCallback:(int)newAttStatusFromUser { + [self.trackingStatusManager updateAttStatusFromUserCallback:newAttStatusFromUser]; +} + +@end + +@interface ADJTrackingStatusManager () + +@property (nonatomic, readonly, weak) ADJActivityHandler *activityHandler; + +@end + +@implementation ADJTrackingStatusManager +// constructors +- (instancetype)initWithActivityHandler:(ADJActivityHandler *)activityHandler { + self = [super init]; + + _activityHandler = activityHandler; + + return self; +} +// public api +- (BOOL)canGetAttStatus { + return SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0"); +} + +- (BOOL)trackingEnabled { + return UIDevice.currentDevice.adjTrackingEnabled; +} + +- (int)attStatus { + int readAttStatus = UIDevice.currentDevice.adjATTStatus; + + [self updateAttStatus:readAttStatus]; + + // does not need to track AttStatus update, since it will be send with package + + return readAttStatus; +} + +- (void)checkForNewAttStatus { + int readAttStatus = UIDevice.currentDevice.adjATTStatus; + + BOOL didUpdateAttStatus = [self updateAttStatus:readAttStatus]; + + if (!didUpdateAttStatus) { + return; + } + + [self.activityHandler trackAttStatusUpdate]; +} +- (void)updateAttStatusFromUserCallback:(int)newAttStatusFromUser { + BOOL didUpdateAttStatus = [self updateAttStatus:newAttStatusFromUser]; + + if (!didUpdateAttStatus) { + return; + } + + [self.activityHandler trackAttStatusUpdate]; +} + +// internal methods +- (BOOL)updateAttStatus:(int)readAttStatus { + if (readAttStatus < 0) { + return NO; + } + + if (self.activityHandler == nil || self.activityHandler.activityState == nil) { + return NO; + } + + if (readAttStatus == self.activityHandler.activityState.trackingManagerAuthorizationStatus) { + return NO; + } + + [ADJUtil launchSynchronisedWithObject:[ADJActivityState class] + block:^{ + self.activityHandler.activityState.trackingManagerAuthorizationStatus = readAttStatus; + }]; + [self.activityHandler writeActivityState]; + + return YES; +} @end From c8ed4632a09b1986a0e7befe48792c6680f34f1d Mon Sep 17 00:00:00 2001 From: rabc Date: Fri, 7 Aug 2020 10:55:39 +0200 Subject: [PATCH 114/173] Add att_status parameter --- Adjust/ADJAdditions/UIDevice+ADJAdditions.h | 1 + Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 17 +++++++++ Adjust/ADJPackageBuilder.m | 42 ++++++++++++++++++--- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h index bc7baeb37..bbcc7fb5d 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h @@ -13,6 +13,7 @@ @interface UIDevice(ADJAdditions) +- (NSUInteger)adjATTStatus; - (BOOL)adjTrackingEnabled; - (NSString *)adjIdForAdvertisers; - (NSString *)adjFbAnonymousId; diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index 3d774f64c..d9622fd35 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -39,6 +39,23 @@ - (Class)appTrackingManager { return class; } +- (NSUInteger)adjATTStatus { + Class appTrackingClass = [self appTrackingManager]; + if (appTrackingClass != nil) { + NSString *keyAuthorization = [NSString adjJoin:@"tracking", @"authorization", @"status", nil]; + SEL selAuthorization = NSSelectorFromString(keyAuthorization); + if ([appTrackingClass respondsToSelector:selAuthorization]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + return (NSUInteger)[appTrackingClass performSelector:selAuthorization]; + } + } + + return (NSUInteger)ATTrackingManagerAuthorizationStatusNotDetermined; +#pragma clang diagnostic pop +} + - (BOOL)adjTrackingEnabled { #if ADJUST_NO_IDFA return NO; diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index 648d0a0bb..50d1af25d 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -309,7 +309,12 @@ - (NSMutableDictionary *)getSessionParameters:(BOOL)isInDelay { [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.osName forKey:@"os_name"]; [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.systemVersion forKey:@"os_version"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + + if (@available(iOS 14, *)) { + [ADJPackageBuilder parameters:parameters setNumber:[NSNumber numberWithUnsignedLong:UIDevice.currentDevice.adjATTStatus] forKey:@"att_status"]; + } else { + [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + } if (self.adjustConfig.isDeviceKnown) { [ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.isDeviceKnown forKey:@"device_known"]; @@ -378,7 +383,12 @@ - (NSMutableDictionary *)getEventParameters:(BOOL)isInDelay forEventPackage:(ADJ [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.systemVersion forKey:@"os_version"]; [ADJPackageBuilder parameters:parameters setNumber:event.revenue forKey:@"revenue"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + + if (@available(iOS 14, *)) { + [ADJPackageBuilder parameters:parameters setNumber:[NSNumber numberWithUnsignedLong:UIDevice.currentDevice.adjATTStatus] forKey:@"att_status"]; + } else { + [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + } if (self.adjustConfig.isDeviceKnown) { [ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.isDeviceKnown forKey:@"device_known"]; @@ -498,7 +508,12 @@ - (NSMutableDictionary *)getAdRevenueParameters:(NSString *)source payload:(NSDa [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; [ADJPackageBuilder parameters:parameters setString:source forKey:@"source"]; [ADJPackageBuilder parameters:parameters setData:payload forKey:@"payload"]; - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + + if (@available(iOS 14, *)) { + [ADJPackageBuilder parameters:parameters setNumber:[NSNumber numberWithUnsignedLong:UIDevice.currentDevice.adjATTStatus] forKey:@"att_status"]; + } else { + [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + } if (self.adjustConfig.isDeviceKnown) { [ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.isDeviceKnown forKey:@"device_known"]; @@ -570,7 +585,12 @@ - (NSMutableDictionary *)getClickParameters:(NSString *)source { [ADJPackageBuilder parameters:parameters setDate:self.purchaseTime forKey:@"purchase_time"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; [ADJPackageBuilder parameters:parameters setString:source forKey:@"source"]; - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + + if (@available(iOS 14, *)) { + [ADJPackageBuilder parameters:parameters setNumber:[NSNumber numberWithUnsignedLong:UIDevice.currentDevice.adjATTStatus] forKey:@"att_status"]; + } else { + [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + } if (self.adjustConfig.isDeviceKnown) { [ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.isDeviceKnown forKey:@"device_known"]; @@ -728,7 +748,12 @@ - (NSMutableDictionary *)getDisableThirdPartySharingParameters { [ADJPackageBuilder parameters:parameters setDictionary:[self.sessionParameters.partnerParameters copy] forKey:@"partner_params"]; [ADJPackageBuilder parameters:parameters setDate:self.purchaseTime forKey:@"purchase_time"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + + if (@available(iOS 14, *)) { + [ADJPackageBuilder parameters:parameters setNumber:[NSNumber numberWithUnsignedLong:UIDevice.currentDevice.adjATTStatus] forKey:@"att_status"]; + } else { + [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + } if (self.adjustConfig.isDeviceKnown) { [ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.isDeviceKnown forKey:@"device_known"]; @@ -787,7 +812,12 @@ - (NSMutableDictionary *)getSubscriptionParameters:(BOOL)isInDelay forSubscripti [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.osName forKey:@"os_name"]; [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.systemVersion forKey:@"os_version"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + + if (@available(iOS 14, *)) { + [ADJPackageBuilder parameters:parameters setNumber:[NSNumber numberWithUnsignedLong:UIDevice.currentDevice.adjATTStatus] forKey:@"att_status"]; + } else { + [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + } if (self.adjustConfig.isDeviceKnown) { [ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.isDeviceKnown forKey:@"device_known"]; From c3b04701b8faaef37f5565a1028e82d80f3d5a88 Mon Sep 17 00:00:00 2001 From: rabc Date: Wed, 8 Jul 2020 16:02:18 +0200 Subject: [PATCH 115/173] Request tracking permission --- .../AdjustExample-Swift/AdjustExample-Swift/Info.plist | 2 ++ .../AdjustExample-Swift/ViewControllerSwift.swift | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift/Info.plist b/examples/AdjustExample-Swift/AdjustExample-Swift/Info.plist index 38182b7b5..b1f4efa52 100644 --- a/examples/AdjustExample-Swift/AdjustExample-Swift/Info.plist +++ b/examples/AdjustExample-Swift/AdjustExample-Swift/Info.plist @@ -2,6 +2,8 @@ + NSUserTrackingUsageDescription + We need your permission to retrieve IDFA CFBundleDevelopmentRegion en CFBundleExecutable diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift b/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift index b18db0a52..5b8a6590c 100644 --- a/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift +++ b/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift @@ -7,6 +7,7 @@ // import UIKit +import AppTrackingTransparency class ViewControllerSwift: UIViewController { @IBOutlet weak var btnTrackEventSimple: UIButton? @@ -26,6 +27,15 @@ class ViewControllerSwift: UIViewController { override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } + + @IBAction func btnAskPermission(_sender: UIButton) { + if #available(iOS 14, *) { + ATTrackingManager.requestTrackingAuthorization { (status) in + print("authorized == \(status == .authorized)") + print("restricted == \(status == .restricted)") + } + } + } @IBAction func btnTrackEventSimpleTapped(_sender: UIButton) { let event = ADJEvent(eventToken: "g3mfiw"); From 27e51d1dfdfc913965d4df4d26845aafc1c92384 Mon Sep 17 00:00:00 2001 From: rabc Date: Fri, 24 Jul 2020 14:24:06 +0200 Subject: [PATCH 116/173] Add button --- .../project.pbxproj | 12 +++ .../xcschemes/AdjustExample-Swift.xcscheme | 78 +++++++++++++++++++ .../Base.lproj/Main.storyboard | 23 ++++-- .../ViewControllerSwift.swift | 3 + 4 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/xcshareddata/xcschemes/AdjustExample-Swift.xcscheme diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/project.pbxproj b/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/project.pbxproj index f7791b4e5..422a46a3d 100644 --- a/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/project.pbxproj +++ b/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/project.pbxproj @@ -48,6 +48,7 @@ 9DF7A9D01CB4ECA600D3591F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9DF7A9CE1CB4ECA600D3591F /* LaunchScreen.storyboard */; }; 9DFB04C21D745B22006D48FC /* iAd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DFB04C11D745B22006D48FC /* iAd.framework */; }; 9DFB04C41D745B28006D48FC /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DFB04C31D745B28006D48FC /* AdSupport.framework */; }; + D71BFB7024CAD74A00878F3E /* AppTrackingTransparency.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D71BFB6F24CAD74A00878F3E /* AppTrackingTransparency.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -130,6 +131,7 @@ 9DF7A9DF1CB4F01B00D3591F /* AdjustExample-Swift-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AdjustExample-Swift-Bridging-Header.h"; sourceTree = ""; }; 9DFB04C11D745B22006D48FC /* iAd.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = iAd.framework; path = System/Library/Frameworks/iAd.framework; sourceTree = SDKROOT; }; 9DFB04C31D745B28006D48FC /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; + D71BFB6F24CAD74A00878F3E /* AppTrackingTransparency.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppTrackingTransparency.framework; path = System/Library/Frameworks/AppTrackingTransparency.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -137,6 +139,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D71BFB7024CAD74A00878F3E /* AppTrackingTransparency.framework in Frameworks */, 9DFB04C21D745B22006D48FC /* iAd.framework in Frameworks */, 9DFB04C41D745B28006D48FC /* AdSupport.framework in Frameworks */, ); @@ -234,6 +237,7 @@ children = ( 9DF7A9C41CB4ECA600D3591F /* AdjustExample-Swift */, 9DF7A9C31CB4ECA600D3591F /* Products */, + D71BFB6E24CAD74A00878F3E /* Frameworks */, ); sourceTree = ""; }; @@ -271,6 +275,14 @@ name = Frameworks; sourceTree = ""; }; + D71BFB6E24CAD74A00878F3E /* Frameworks */ = { + isa = PBXGroup; + children = ( + D71BFB6F24CAD74A00878F3E /* AppTrackingTransparency.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/xcshareddata/xcschemes/AdjustExample-Swift.xcscheme b/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/xcshareddata/xcschemes/AdjustExample-Swift.xcscheme new file mode 100644 index 000000000..742df7c4c --- /dev/null +++ b/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/xcshareddata/xcschemes/AdjustExample-Swift.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift/Base.lproj/Main.storyboard b/examples/AdjustExample-Swift/AdjustExample-Swift/Base.lproj/Main.storyboard index 8bc65e6fb..9a04851cc 100644 --- a/examples/AdjustExample-Swift/AdjustExample-Swift/Base.lproj/Main.storyboard +++ b/examples/AdjustExample-Swift/AdjustExample-Swift/Base.lproj/Main.storyboard @@ -1,12 +1,9 @@ - - - - + + - - + @@ -113,6 +110,17 @@ + @@ -122,12 +130,14 @@ + + @@ -147,6 +157,7 @@ + diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift b/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift index 5b8a6590c..672ca84fe 100644 --- a/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift +++ b/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift @@ -8,6 +8,7 @@ import UIKit import AppTrackingTransparency +import AdSupport class ViewControllerSwift: UIViewController { @IBOutlet weak var btnTrackEventSimple: UIButton? @@ -31,7 +32,9 @@ class ViewControllerSwift: UIViewController { @IBAction func btnAskPermission(_sender: UIButton) { if #available(iOS 14, *) { ATTrackingManager.requestTrackingAuthorization { (status) in + print("IDFA == \(ASIdentifierManager.shared().advertisingIdentifier)") print("authorized == \(status == .authorized)") + print("denied == \(status == .denied)") print("restricted == \(status == .restricted)") } } From aff05fb55f45850ad8ca91a338ad2a34375c78b2 Mon Sep 17 00:00:00 2001 From: rabc Date: Wed, 5 Aug 2020 14:26:04 +0200 Subject: [PATCH 117/173] Add load SKAN product button --- .../project.pbxproj | 4 + .../Base.lproj/Main.storyboard | 17 ++- .../AdjustExample-Swift/Info.plist | 7 ++ .../LoadProductController.swift | 117 ++++++++++++++++++ .../ViewControllerSwift.swift | 27 +++- 5 files changed, 164 insertions(+), 8 deletions(-) create mode 100644 examples/AdjustExample-Swift/AdjustExample-Swift/LoadProductController.swift diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/project.pbxproj b/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/project.pbxproj index 422a46a3d..c3cefbcd1 100644 --- a/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/project.pbxproj +++ b/examples/AdjustExample-Swift/AdjustExample-Swift.xcodeproj/project.pbxproj @@ -49,6 +49,7 @@ 9DFB04C21D745B22006D48FC /* iAd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DFB04C11D745B22006D48FC /* iAd.framework */; }; 9DFB04C41D745B28006D48FC /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DFB04C31D745B28006D48FC /* AdSupport.framework */; }; D71BFB7024CAD74A00878F3E /* AppTrackingTransparency.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D71BFB6F24CAD74A00878F3E /* AppTrackingTransparency.framework */; }; + D731B41524DAAB5C0036F619 /* LoadProductController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D731B41424DAAB5C0036F619 /* LoadProductController.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -132,6 +133,7 @@ 9DFB04C11D745B22006D48FC /* iAd.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = iAd.framework; path = System/Library/Frameworks/iAd.framework; sourceTree = SDKROOT; }; 9DFB04C31D745B28006D48FC /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; }; D71BFB6F24CAD74A00878F3E /* AppTrackingTransparency.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppTrackingTransparency.framework; path = System/Library/Frameworks/AppTrackingTransparency.framework; sourceTree = SDKROOT; }; + D731B41424DAAB5C0036F619 /* LoadProductController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadProductController.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -262,6 +264,7 @@ 9DF7A9DF1CB4F01B00D3591F /* AdjustExample-Swift-Bridging-Header.h */, 9D449E331E6EDC3D00E7E80B /* Adjust */, 9DFB04C01D745B13006D48FC /* Frameworks */, + D731B41424DAAB5C0036F619 /* LoadProductController.swift */, ); path = "AdjustExample-Swift"; sourceTree = ""; @@ -395,6 +398,7 @@ 9D449E7A1E6EDC3D00E7E80B /* NSData+ADJAdditions.m in Sources */, 9D449E8D1E6EDC3D00E7E80B /* ADJSdkClickHandler.m in Sources */, 9D449E881E6EDC3D00E7E80B /* ADJLogger.m in Sources */, + D731B41524DAAB5C0036F619 /* LoadProductController.swift in Sources */, 9DF7A9C61CB4ECA600D3591F /* AppDelegate.swift in Sources */, 9D449E931E6EDC3D00E7E80B /* ADJTimerOnce.m in Sources */, 9D449E801E6EDC3D00E7E80B /* ADJBackoffStrategy.m in Sources */, diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift/Base.lproj/Main.storyboard b/examples/AdjustExample-Swift/AdjustExample-Swift/Base.lproj/Main.storyboard index 9a04851cc..1b8fc1e32 100644 --- a/examples/AdjustExample-Swift/AdjustExample-Swift/Base.lproj/Main.storyboard +++ b/examples/AdjustExample-Swift/AdjustExample-Swift/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -121,6 +121,16 @@ + @@ -143,11 +153,13 @@ + + @@ -163,6 +175,7 @@ + diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift/Info.plist b/examples/AdjustExample-Swift/AdjustExample-Swift/Info.plist index b1f4efa52..c723fa9d7 100644 --- a/examples/AdjustExample-Swift/AdjustExample-Swift/Info.plist +++ b/examples/AdjustExample-Swift/AdjustExample-Swift/Info.plist @@ -2,6 +2,13 @@ + SKAdNetworkItems + + + SKAdNetworkIdentifier + qgugw9aumk.skadnetwork + + NSUserTrackingUsageDescription We need your permission to retrieve IDFA CFBundleDevelopmentRegion diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift/LoadProductController.swift b/examples/AdjustExample-Swift/AdjustExample-Swift/LoadProductController.swift new file mode 100644 index 000000000..67b600e82 --- /dev/null +++ b/examples/AdjustExample-Swift/AdjustExample-Swift/LoadProductController.swift @@ -0,0 +1,117 @@ +// +// LoadProductController.swift +// AdjustExample-Swift +// +// Created by Ricardo Carvalho on 05/08/2020. +// Copyright © 2020 adjust GmbH. All rights reserved. +// + +import UIKit +import StoreKit + +struct ProductParameters: Codable { + let adNetworkId: String + let adNetworkVersion: String + let campaignId : String + let id: String + let nonce: String + let signature: String + let sourceAppId: String + let timestamp: String +} + +protocol ProductLoadable { + func loadProduct(from source: UIViewController) +} + +@available(iOS 14.0, *) +class LoadProductController: NSObject, ProductLoadable { + + let version = "2.0" + let store = SKStoreProductViewController() + + func loadProduct(from source: UIViewController) { + + guard var URL = URL(string: "http://10.8.2.155:8000/get-ad-impression") else {return} + let URLParams = [ + "skadnetwork_version": version, + "source_app_id": "com.adjust.examples", + ] + + URL = URL.appendingQueryParameters(URLParams) + var request = URLRequest(url: URL) + request.httpMethod = "GET" + + let semaphore = DispatchSemaphore(value: 0) + var product: ProductParameters! + + let task = URLSession.shared.dataTask(with: request, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in + + product = try! JSONDecoder().decode(ProductParameters.self, from: data!) + + semaphore.signal() + }) + task.resume() + + semaphore.wait() + + let parameters: [String: Any] = [SKStoreProductParameterITunesItemIdentifier: NSNumber(integerLiteral: Int(product.id)!), + SKStoreProductParameterAdNetworkIdentifier: product.adNetworkId, + SKStoreProductParameterAdNetworkCampaignIdentifier: NSNumber(integerLiteral: Int(product.campaignId)!), + SKStoreProductParameterAdNetworkTimestamp: NSNumber(value: Int(product.timestamp)!), + SKStoreProductParameterAdNetworkNonce: NSUUID(uuidString: product.nonce), + SKStoreProductParameterAdNetworkSourceAppStoreIdentifier: product.sourceAppId, + SKStoreProductParameterAdNetworkVersion: version, + SKStoreProductParameterAdNetworkAttributionSignature: product.signature] + + + store.loadProduct(withParameters: parameters) { (result, error) in + if let error = error { + print("Error on loading = \(error)") + } else { + print("Loaded with success") + source.present(self.store, animated: true, completion: nil) + } + } + + } + +} + +protocol URLQueryParameterStringConvertible { + var queryParameters: String {get} +} + +extension Dictionary : URLQueryParameterStringConvertible { + /** + This computed property returns a query parameters string from the given NSDictionary. For + example, if the input is @{@"day":@"Tuesday", @"month":@"January"}, the output + string will be @"day=Tuesday&month=January". + @return The computed parameters string. + */ + var queryParameters: String { + var parts: [String] = [] + for (key, value) in self { + let part = String(format: "%@=%@", + String(describing: key).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!, + String(describing: value).addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!) + parts.append(part as String) + } + return parts.joined(separator: "&") + } + +} + +extension URL { + /** + Creates a new URL by adding the given query parameters. + @param parametersDictionary The query parameter dictionary to add. + @return A new URL. + */ + func appendingQueryParameters(_ parametersDictionary : Dictionary) -> URL { + let URLString : String = String(format: "%@?%@", self.absoluteString, parametersDictionary.queryParameters) + return URL(string: URLString)! + } +} + + diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift b/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift index 672ca84fe..77702354b 100644 --- a/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift +++ b/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift @@ -20,6 +20,14 @@ class ViewControllerSwift: UIViewController { @IBOutlet weak var btnEnableSDK: UIButton? @IBOutlet weak var btnDisableSDK: UIButton? @IBOutlet weak var btnIsSDKEnabled: UIButton? + + lazy var loadProductController: ProductLoadable? = { + if #available(iOS 14.0, *) { + return LoadProductController() + } + + return nil + }() override func viewDidLoad() { super.viewDidLoad() @@ -31,14 +39,21 @@ class ViewControllerSwift: UIViewController { @IBAction func btnAskPermission(_sender: UIButton) { if #available(iOS 14, *) { - ATTrackingManager.requestTrackingAuthorization { (status) in - print("IDFA == \(ASIdentifierManager.shared().advertisingIdentifier)") - print("authorized == \(status == .authorized)") - print("denied == \(status == .denied)") - print("restricted == \(status == .restricted)") - } + print("status notDetermined == \(ATTrackingManager.trackingAuthorizationStatus == .notDetermined)") + print("status authorized == \(ATTrackingManager.trackingAuthorizationStatus == .authorized)") + print("IDFA == \(ASIdentifierManager.shared().advertisingIdentifier)") +// ATTrackingManager.requestTrackingAuthorization { (status) in +// print("IDFA == \(ASIdentifierManager.shared().advertisingIdentifier)") +// print("authorized == \(status == .authorized)") +// print("denied == \(status == .denied)") +// print("restricted == \(status == .restricted)") +// } } } + + @IBAction func btnLoadProduct(_sender: UIButton) { + loadProductController?.loadProduct(from: self) + } @IBAction func btnTrackEventSimpleTapped(_sender: UIButton) { let event = ADJEvent(eventToken: "g3mfiw"); From c76fcec867c09318b592d17469a394848719e6e2 Mon Sep 17 00:00:00 2001 From: rabc Date: Fri, 7 Aug 2020 11:05:37 +0200 Subject: [PATCH 118/173] Convert parameter to int --- Adjust/ADJAdditions/UIDevice+ADJAdditions.h | 2 +- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 6 +++--- Adjust/ADJPackageBuilder.m | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h index bbcc7fb5d..04d826dd5 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h @@ -13,7 +13,7 @@ @interface UIDevice(ADJAdditions) -- (NSUInteger)adjATTStatus; +- (int)adjATTStatus; - (BOOL)adjTrackingEnabled; - (NSString *)adjIdForAdvertisers; - (NSString *)adjFbAnonymousId; diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index d9622fd35..1415bfb86 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -39,7 +39,7 @@ - (Class)appTrackingManager { return class; } -- (NSUInteger)adjATTStatus { +- (int)adjATTStatus { Class appTrackingClass = [self appTrackingManager]; if (appTrackingClass != nil) { NSString *keyAuthorization = [NSString adjJoin:@"tracking", @"authorization", @"status", nil]; @@ -48,11 +48,11 @@ - (NSUInteger)adjATTStatus { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunguarded-availability" #pragma clang diagnostic ignored "-Warc-performSelector-leaks" - return (NSUInteger)[appTrackingClass performSelector:selAuthorization]; + return (int)[appTrackingClass performSelector:selAuthorization]; } } - return (NSUInteger)ATTrackingManagerAuthorizationStatusNotDetermined; + return (int)ATTrackingManagerAuthorizationStatusNotDetermined; #pragma clang diagnostic pop } diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index 50d1af25d..88c2058d1 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -311,7 +311,7 @@ - (NSMutableDictionary *)getSessionParameters:(BOOL)isInDelay { [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; if (@available(iOS 14, *)) { - [ADJPackageBuilder parameters:parameters setNumber:[NSNumber numberWithUnsignedLong:UIDevice.currentDevice.adjATTStatus] forKey:@"att_status"]; + [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; } else { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; } @@ -385,7 +385,7 @@ - (NSMutableDictionary *)getEventParameters:(BOOL)isInDelay forEventPackage:(ADJ [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; if (@available(iOS 14, *)) { - [ADJPackageBuilder parameters:parameters setNumber:[NSNumber numberWithUnsignedLong:UIDevice.currentDevice.adjATTStatus] forKey:@"att_status"]; + [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; } else { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; } @@ -510,7 +510,7 @@ - (NSMutableDictionary *)getAdRevenueParameters:(NSString *)source payload:(NSDa [ADJPackageBuilder parameters:parameters setData:payload forKey:@"payload"]; if (@available(iOS 14, *)) { - [ADJPackageBuilder parameters:parameters setNumber:[NSNumber numberWithUnsignedLong:UIDevice.currentDevice.adjATTStatus] forKey:@"att_status"]; + [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; } else { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; } @@ -587,7 +587,7 @@ - (NSMutableDictionary *)getClickParameters:(NSString *)source { [ADJPackageBuilder parameters:parameters setString:source forKey:@"source"]; if (@available(iOS 14, *)) { - [ADJPackageBuilder parameters:parameters setNumber:[NSNumber numberWithUnsignedLong:UIDevice.currentDevice.adjATTStatus] forKey:@"att_status"]; + [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; } else { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; } @@ -750,7 +750,7 @@ - (NSMutableDictionary *)getDisableThirdPartySharingParameters { [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; if (@available(iOS 14, *)) { - [ADJPackageBuilder parameters:parameters setNumber:[NSNumber numberWithUnsignedLong:UIDevice.currentDevice.adjATTStatus] forKey:@"att_status"]; + [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; } else { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; } @@ -814,7 +814,7 @@ - (NSMutableDictionary *)getSubscriptionParameters:(BOOL)isInDelay forSubscripti [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; if (@available(iOS 14, *)) { - [ADJPackageBuilder parameters:parameters setNumber:[NSNumber numberWithUnsignedLong:UIDevice.currentDevice.adjATTStatus] forKey:@"att_status"]; + [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; } else { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; } From 6ddd1657e4d409b1638a2f3d834d84b2fef4e370 Mon Sep 17 00:00:00 2001 From: rabc Date: Mon, 10 Aug 2020 13:58:44 +0200 Subject: [PATCH 119/173] Remove references to ATT --- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 23 +++---------------- .../ViewControllerSwift.swift | 12 +++++----- 2 files changed, 9 insertions(+), 26 deletions(-) diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index 1415bfb86..9a8624a41 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -13,7 +13,6 @@ #if !ADJUST_NO_IDFA #import -#import #endif #if !ADJUST_NO_IAD && !TARGET_OS_TV @@ -52,7 +51,7 @@ - (int)adjATTStatus { } } - return (int)ATTrackingManagerAuthorizationStatusNotDetermined; + return 0; // ATTrackingManagerAuthorizationStatusNotDetermined #pragma clang diagnostic pop } @@ -60,24 +59,6 @@ - (BOOL)adjTrackingEnabled { #if ADJUST_NO_IDFA return NO; #else - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" -// [ATTrackingManager trackingAuthorizationStatus]; - Class appTrackingClass = [self appTrackingManager]; - if (appTrackingClass != nil) { - NSString *keyAuthorization = [NSString adjJoin:@"tracking", @"authorization", @"status", nil]; - SEL selAuthorization = NSSelectorFromString(keyAuthorization); - if ([appTrackingClass respondsToSelector:selAuthorization]) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" - ATTrackingManagerAuthorizationStatus status = (ATTrackingManagerAuthorizationStatus)[appTrackingClass performSelector:selAuthorization]; - return status == ATTrackingManagerAuthorizationStatusAuthorized; -#pragma clang diagnostic pop - } - } - - // Fallback iOS 13 and earlier versions // return [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]; Class adSupportClass = [self adSupportManager]; @@ -90,6 +71,8 @@ - (BOOL)adjTrackingEnabled { if (![adSupportClass respondsToSelector:selManager]) { return NO; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" id manager = [adSupportClass performSelector:selManager]; NSString *keyEnabled = [NSString adjJoin:@"is", @"advertising", @"tracking", @"enabled", nil]; diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift b/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift index 77702354b..610a43433 100644 --- a/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift +++ b/examples/AdjustExample-Swift/AdjustExample-Swift/ViewControllerSwift.swift @@ -42,12 +42,12 @@ class ViewControllerSwift: UIViewController { print("status notDetermined == \(ATTrackingManager.trackingAuthorizationStatus == .notDetermined)") print("status authorized == \(ATTrackingManager.trackingAuthorizationStatus == .authorized)") print("IDFA == \(ASIdentifierManager.shared().advertisingIdentifier)") -// ATTrackingManager.requestTrackingAuthorization { (status) in -// print("IDFA == \(ASIdentifierManager.shared().advertisingIdentifier)") -// print("authorized == \(status == .authorized)") -// print("denied == \(status == .denied)") -// print("restricted == \(status == .restricted)") -// } + ATTrackingManager.requestTrackingAuthorization { (status) in + print("IDFA == \(ASIdentifierManager.shared().advertisingIdentifier)") + print("authorized == \(status == .authorized)") + print("denied == \(status == .denied)") + print("restricted == \(status == .restricted)") + } } } From 7b3c66c275a5d7e128bf76f8695e190dd1217da6 Mon Sep 17 00:00:00 2001 From: rabc Date: Mon, 10 Aug 2020 13:58:57 +0200 Subject: [PATCH 120/173] Change availability check --- Adjust/ADJPackageBuilder.m | 12 ++++++------ Adjust/ADJUtil.h | 3 +++ Adjust/ADJUtil.m | 3 --- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index 88c2058d1..7296bd5c7 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -310,7 +310,7 @@ - (NSMutableDictionary *)getSessionParameters:(BOOL)isInDelay { [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.systemVersion forKey:@"os_version"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; - if (@available(iOS 14, *)) { + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0")) { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; } else { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; @@ -384,7 +384,7 @@ - (NSMutableDictionary *)getEventParameters:(BOOL)isInDelay forEventPackage:(ADJ [ADJPackageBuilder parameters:parameters setNumber:event.revenue forKey:@"revenue"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; - if (@available(iOS 14, *)) { + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0")) { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; } else { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; @@ -509,7 +509,7 @@ - (NSMutableDictionary *)getAdRevenueParameters:(NSString *)source payload:(NSDa [ADJPackageBuilder parameters:parameters setString:source forKey:@"source"]; [ADJPackageBuilder parameters:parameters setData:payload forKey:@"payload"]; - if (@available(iOS 14, *)) { + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0")) { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; } else { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; @@ -586,7 +586,7 @@ - (NSMutableDictionary *)getClickParameters:(NSString *)source { [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; [ADJPackageBuilder parameters:parameters setString:source forKey:@"source"]; - if (@available(iOS 14, *)) { + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0")) { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; } else { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; @@ -749,7 +749,7 @@ - (NSMutableDictionary *)getDisableThirdPartySharingParameters { [ADJPackageBuilder parameters:parameters setDate:self.purchaseTime forKey:@"purchase_time"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; - if (@available(iOS 14, *)) { + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0")) { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; } else { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; @@ -813,7 +813,7 @@ - (NSMutableDictionary *)getSubscriptionParameters:(BOOL)isInDelay forSubscripti [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.systemVersion forKey:@"os_version"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; - if (@available(iOS 14, *)) { + if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0")) { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; } else { [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; diff --git a/Adjust/ADJUtil.h b/Adjust/ADJUtil.h index d63421745..c3873740e 100644 --- a/Adjust/ADJUtil.h +++ b/Adjust/ADJUtil.h @@ -15,6 +15,9 @@ #import "ADJActivityPackage.h" #import "ADJBackoffStrategy.h" +// https://stackoverflow.com/a/5337804/1498352 +#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) + typedef void (^selfInjectedBlock)(id); typedef void (^synchronisedBlock)(void); typedef void (^isInactiveInjected)(BOOL); diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index eca7b23af..2d5d38ce8 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -24,9 +24,6 @@ #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 NSString *userAgent = nil; static ADJReachability *reachability = nil; static NSRegularExpression *universalLinkRegex = nil; From 528b209f76e5a8fab968d4cec12e37291d266e11 Mon Sep 17 00:00:00 2001 From: rabc Date: Tue, 11 Aug 2020 13:36:16 +0200 Subject: [PATCH 121/173] Register for SKAN attribution --- Adjust/ADJAdditions/UIDevice+ADJAdditions.h | 2 ++ Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h index 04d826dd5..2a3fb2b8b 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h @@ -22,4 +22,6 @@ - (NSString *)adjCreateUuid; - (NSString *)adjVendorId; - (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler queue:(dispatch_queue_t)queue; +- (void)adjRegisterForSKANAttribution; + @end diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index 9a8624a41..fbd80fd2e 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -280,4 +280,22 @@ - (BOOL)setiAdWithDetails:(ADJActivityHandler *)activityHandler return YES; } +- (void)adjRegisterForSKANAttribution { + id logger = [ADJAdjustFactory logger]; + + Class skan = NSClassFromString(@"SKAdNetwork"); + if (skan == nil) { + [logger warn:@"StoreKit framework not found in user's app (SKAdNetwork not found)"]; + return; + } + + SEL registerAttributionSelector = NSSelectorFromString(@"registerAppForAdNetworkAttribution"); + if ([skan respondsToSelector:registerAttributionSelector]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + [skan performSelector:registerAttributionSelector]; +#pragma clang diagnostic pop + } +} + @end From c4d41ce9338bd73c00a5bd0217f2a23423b6e9f5 Mon Sep 17 00:00:00 2001 From: rabc Date: Tue, 11 Aug 2020 16:18:45 +0200 Subject: [PATCH 122/173] Register for attribution and handle conversion value --- Adjust/ADJActivityHandler.h | 4 ++++ Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 18 ------------------ Adjust/ADJAttributionHandler.m | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Adjust/ADJActivityHandler.h b/Adjust/ADJActivityHandler.h index bea883a80..b8f8b3088 100644 --- a/Adjust/ADJActivityHandler.h +++ b/Adjust/ADJActivityHandler.h @@ -98,6 +98,8 @@ - (void)disableThirdPartySharing; - (void)trackSubscription:(ADJSubscription *)subscription; +- (void)updateConversionValue:(NSNumber *)value; + - (ADJDeviceInfo *)deviceInfo; - (ADJActivityState *)activityState; - (ADJConfig *)adjustConfig; @@ -126,6 +128,8 @@ - (void)resetSessionCallbackParametersI:(ADJActivityHandler *)selfI; - (void)resetSessionPartnerParametersI:(ADJActivityHandler *)selfI; +- (void)updateConversionValue:(NSNumber *)value; + @end extern NSString * const ADJiAdPackageKey; diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index fbd80fd2e..9a8624a41 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -280,22 +280,4 @@ - (BOOL)setiAdWithDetails:(ADJActivityHandler *)activityHandler return YES; } -- (void)adjRegisterForSKANAttribution { - id logger = [ADJAdjustFactory logger]; - - Class skan = NSClassFromString(@"SKAdNetwork"); - if (skan == nil) { - [logger warn:@"StoreKit framework not found in user's app (SKAdNetwork not found)"]; - return; - } - - SEL registerAttributionSelector = NSSelectorFromString(@"registerAppForAdNetworkAttribution"); - if ([skan respondsToSelector:registerAttributionSelector]) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - [skan performSelector:registerAttributionSelector]; -#pragma clang diagnostic pop - } -} - @end diff --git a/Adjust/ADJAttributionHandler.m b/Adjust/ADJAttributionHandler.m index d46c8f027..7afa03ed0 100644 --- a/Adjust/ADJAttributionHandler.m +++ b/Adjust/ADJAttributionHandler.m @@ -115,6 +115,8 @@ - (void)resumeSending { - (void)checkSessionResponseI:(ADJAttributionHandler*)selfI sessionResponseData:(ADJSessionResponseData *)sessionResponseData { [selfI checkAttributionI:selfI responseData:sessionResponseData]; + + [selfI checkConversionValueI:selfI responseData:sessionResponseData]; [selfI.activityHandler launchSessionResponseTasks:sessionResponseData]; } @@ -122,6 +124,8 @@ - (void)checkSessionResponseI:(ADJAttributionHandler*)selfI - (void)checkSdkClickResponseI:(ADJAttributionHandler*)selfI sdkClickResponseData:(ADJSdkClickResponseData *)sdkClickResponseData { [selfI checkAttributionI:selfI responseData:sdkClickResponseData]; + + [selfI checkConversionValueI:selfI responseData:sdkClickResponseData]; [selfI.activityHandler launchSdkClickResponseTasks:sdkClickResponseData]; } @@ -131,6 +135,8 @@ - (void)checkAttributionResponseI:(ADJAttributionHandler*)selfI [selfI checkAttributionI:selfI responseData:attributionResponseData]; [selfI checkDeeplinkI:selfI attributionResponseData:attributionResponseData]; + + [selfI checkConversionValueI:selfI responseData:attributionResponseData]; [selfI.activityHandler launchAttributionResponseTasks:attributionResponseData]; } @@ -159,6 +165,19 @@ - (void)checkAttributionI:(ADJAttributionHandler*)selfI responseData.attribution = [ADJAttribution dataWithJsonDict:jsonAttribution adid:responseData.adid]; } +- (void)checkConversionValueI:(ADJAttributionHandler*)selfI + responseData:(ADJResponseData *)responseData { + if (responseData.jsonResponse == nil) { + return; + } + + NSNumber *conversionValue = [responseData.jsonResponse objectForKey:@"skadn_conv_value"]; + + if (conversionValue) { + [selfI.activityHandler updateConversionValue:conversionValue]; + } +} + - (void)checkDeeplinkI:(ADJAttributionHandler*)selfI attributionResponseData:(ADJAttributionResponseData *)attributionResponseData { if (attributionResponseData.jsonResponse == nil) { From 58aebd27de84d64ef5be4cd8d021b5a6a50b74a4 Mon Sep 17 00:00:00 2001 From: nonelse Date: Thu, 13 Aug 2020 14:52:24 +0200 Subject: [PATCH 123/173] Move update conversion value to activity handler --- Adjust/ADJActivityHandler.h | 4 ---- Adjust/ADJAttributionHandler.m | 19 ------------------- 2 files changed, 23 deletions(-) diff --git a/Adjust/ADJActivityHandler.h b/Adjust/ADJActivityHandler.h index b8f8b3088..bea883a80 100644 --- a/Adjust/ADJActivityHandler.h +++ b/Adjust/ADJActivityHandler.h @@ -98,8 +98,6 @@ - (void)disableThirdPartySharing; - (void)trackSubscription:(ADJSubscription *)subscription; -- (void)updateConversionValue:(NSNumber *)value; - - (ADJDeviceInfo *)deviceInfo; - (ADJActivityState *)activityState; - (ADJConfig *)adjustConfig; @@ -128,8 +126,6 @@ - (void)resetSessionCallbackParametersI:(ADJActivityHandler *)selfI; - (void)resetSessionPartnerParametersI:(ADJActivityHandler *)selfI; -- (void)updateConversionValue:(NSNumber *)value; - @end extern NSString * const ADJiAdPackageKey; diff --git a/Adjust/ADJAttributionHandler.m b/Adjust/ADJAttributionHandler.m index 7afa03ed0..4c6eb9a53 100644 --- a/Adjust/ADJAttributionHandler.m +++ b/Adjust/ADJAttributionHandler.m @@ -116,8 +116,6 @@ - (void)checkSessionResponseI:(ADJAttributionHandler*)selfI sessionResponseData:(ADJSessionResponseData *)sessionResponseData { [selfI checkAttributionI:selfI responseData:sessionResponseData]; - [selfI checkConversionValueI:selfI responseData:sessionResponseData]; - [selfI.activityHandler launchSessionResponseTasks:sessionResponseData]; } @@ -125,8 +123,6 @@ - (void)checkSdkClickResponseI:(ADJAttributionHandler*)selfI sdkClickResponseData:(ADJSdkClickResponseData *)sdkClickResponseData { [selfI checkAttributionI:selfI responseData:sdkClickResponseData]; - [selfI checkConversionValueI:selfI responseData:sdkClickResponseData]; - [selfI.activityHandler launchSdkClickResponseTasks:sdkClickResponseData]; } @@ -136,8 +132,6 @@ - (void)checkAttributionResponseI:(ADJAttributionHandler*)selfI [selfI checkDeeplinkI:selfI attributionResponseData:attributionResponseData]; - [selfI checkConversionValueI:selfI responseData:attributionResponseData]; - [selfI.activityHandler launchAttributionResponseTasks:attributionResponseData]; } @@ -165,19 +159,6 @@ - (void)checkAttributionI:(ADJAttributionHandler*)selfI responseData.attribution = [ADJAttribution dataWithJsonDict:jsonAttribution adid:responseData.adid]; } -- (void)checkConversionValueI:(ADJAttributionHandler*)selfI - responseData:(ADJResponseData *)responseData { - if (responseData.jsonResponse == nil) { - return; - } - - NSNumber *conversionValue = [responseData.jsonResponse objectForKey:@"skadn_conv_value"]; - - if (conversionValue) { - [selfI.activityHandler updateConversionValue:conversionValue]; - } -} - - (void)checkDeeplinkI:(ADJAttributionHandler*)selfI attributionResponseData:(ADJAttributionResponseData *)attributionResponseData { if (attributionResponseData.jsonResponse == nil) { From 204a0fa7b2499ba20abdac78da4d58cd43143db2 Mon Sep 17 00:00:00 2001 From: nonelse Date: Thu, 13 Aug 2020 14:52:51 +0200 Subject: [PATCH 124/173] Small comment and warning cleanup --- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index 9a8624a41..a18a28525 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -48,11 +48,11 @@ - (int)adjATTStatus { #pragma clang diagnostic ignored "-Wunguarded-availability" #pragma clang diagnostic ignored "-Warc-performSelector-leaks" return (int)[appTrackingClass performSelector:selAuthorization]; +#pragma clang diagnostic pop } } return 0; // ATTrackingManagerAuthorizationStatusNotDetermined -#pragma clang diagnostic pop } - (BOOL)adjTrackingEnabled { From 77f6332065fd6d08bc7ee5a035ea8cbf201a89ca Mon Sep 17 00:00:00 2001 From: nonelse Date: Thu, 13 Aug 2020 16:14:20 +0200 Subject: [PATCH 125/173] Add inactivation of sk ad network in config --- Adjust/ADJAdditions/UIDevice+ADJAdditions.h | 1 - Adjust/ADJConfig.h | 5 +++++ Adjust/ADJConfig.m | 6 ++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h index 2a3fb2b8b..f6b99f865 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h @@ -22,6 +22,5 @@ - (NSString *)adjCreateUuid; - (NSString *)adjVendorId; - (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler queue:(dispatch_queue_t)queue; -- (void)adjRegisterForSKANAttribution; @end diff --git a/Adjust/ADJConfig.h b/Adjust/ADJConfig.h index 1bcccf9a2..5ac7a1514 100644 --- a/Adjust/ADJConfig.h +++ b/Adjust/ADJConfig.h @@ -187,6 +187,11 @@ info3:(NSUInteger)info3 info4:(NSUInteger)info4; + +@property (nonatomic, assign, readonly) BOOL isSKAdNetworkHandlingActive; + +- (void)inactivateSKAdNetworkHandling; + /** * @brief Get configuration object for the initialization of the Adjust SDK. * diff --git a/Adjust/ADJConfig.m b/Adjust/ADJConfig.m index 90abe25ba..0d2af75e9 100644 --- a/Adjust/ADJConfig.m +++ b/Adjust/ADJConfig.m @@ -66,6 +66,7 @@ - (id)initWithAppToken:(NSString *)appToken self.eventBufferingEnabled = NO; self.allowIdfaReading = YES; self.allowiAdInfoReading = YES; + _isSKAdNetworkHandlingActive = YES; return self; } @@ -81,6 +82,10 @@ - (void)setLogLevel:(ADJLogLevel)logLevel isProductionEnvironment:[ADJEnvironmentProduction isEqualToString:environment]]; } +- (void)inactivateSKAdNetworkHandling { + _isSKAdNetworkHandlingActive = NO; +} + - (void)setDelegate:(NSObject *)delegate { BOOL hasResponseDelegate = NO; BOOL implementsDeeplinkCallback = NO; @@ -202,6 +207,7 @@ -(id)copyWithZone:(NSZone *)zone copy.isDeviceKnown = self.isDeviceKnown; copy->_secretId = [self.secretId copyWithZone:zone]; copy->_appSecret = [self.appSecret copyWithZone:zone]; + copy->_isSKAdNetworkHandlingActive = self.isSKAdNetworkHandlingActive; // adjust delegate not copied } From ad66cbf83270f7a2507212a8bd705285d724850a Mon Sep 17 00:00:00 2001 From: nonelse Date: Thu, 13 Aug 2020 18:57:51 +0200 Subject: [PATCH 126/173] Extract tracking status management into new class --- Adjust/ADJActivityHandler.h | 14 +++++ Adjust/ADJActivityState.h | 2 + Adjust/ADJActivityState.m | 11 ++++ Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 2 +- Adjust/ADJPackageBuilder.h | 2 + Adjust/ADJPackageBuilder.m | 59 +++++++++++++-------- 6 files changed, 68 insertions(+), 22 deletions(-) diff --git a/Adjust/ADJActivityHandler.h b/Adjust/ADJActivityHandler.h index bea883a80..d6f703fb1 100644 --- a/Adjust/ADJActivityHandler.h +++ b/Adjust/ADJActivityHandler.h @@ -128,4 +128,18 @@ @end +@interface ADJTrackingStatusManager : NSObject + +- (instancetype)initWithActivityHandler:(ADJActivityHandler *)activityHandler; + +- (void)checkForNewAttStatus; +- (void)updateAttStatusFromUserCallback:(int)newAttStatusFromUser; + +- (BOOL)canGetAttStatus; + +@property (nonatomic, readonly, assign) BOOL trackingEnabled; +@property (nonatomic, readonly, assign) int attStatus; + +@end + extern NSString * const ADJiAdPackageKey; diff --git a/Adjust/ADJActivityState.h b/Adjust/ADJActivityState.h index ac141039b..0d3b2ff96 100644 --- a/Adjust/ADJActivityState.h +++ b/Adjust/ADJActivityState.h @@ -23,6 +23,8 @@ @property (nonatomic, copy) NSString *adid; @property (nonatomic, strong) NSDictionary *attributionDetails; +@property (nonatomic, strong) int trackingManagerAuthorizationStatus; + // Global counters @property (nonatomic, assign) int eventCount; @property (nonatomic, assign) int sessionCount; diff --git a/Adjust/ADJActivityState.m b/Adjust/ADJActivityState.m index 528981d80..8891cb69f 100644 --- a/Adjust/ADJActivityState.m +++ b/Adjust/ADJActivityState.m @@ -41,6 +41,7 @@ - (id)init { self.deviceToken = nil; self.transactionIds = [NSMutableArray arrayWithCapacity:kTransactionIdCount]; self.updatePackages = NO; + self.trackingManagerAuthorizationStatus = -1; return self; } @@ -199,6 +200,13 @@ - (id)initWithCoder:(NSCoder *)decoder { self.attributionDetails = [decoder decodeObjectForKey:@"attributionDetails"]; } + if ([decoder containsValueForKey:@"trackingManagerAuthorizationStatus"]) { + self.trackingManagerAuthorizationStatus = + [decoder decodeIntForKey:@"trackingManagerAuthorizationStatus"]; + } else { + self.trackingManagerAuthorizationStatus = -1; + } + self.lastInterval = -1; return self; @@ -221,6 +229,8 @@ - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeBool:self.updatePackages forKey:@"updatePackages"]; [encoder encodeObject:self.adid forKey:@"adid"]; [encoder encodeObject:self.attributionDetails forKey:@"attributionDetails"]; + [encoder encodeInt:self.trackingManagerAuthorizationStatus + forKey:@"trackingManagerAuthorizationStatus"]; } #pragma mark - NSCopying protocol methods @@ -244,6 +254,7 @@ - (id)copyWithZone:(NSZone *)zone { copy.isThirdPartySharingDisabled = self.isThirdPartySharingDisabled; copy.deviceToken = [self.deviceToken copyWithZone:zone]; copy.updatePackages = self.updatePackages; + copy.trackingManagerAuthorizationStatus = self.trackingManagerAuthorizationStatus; } return copy; diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index a18a28525..3e70ba3a0 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -52,7 +52,7 @@ - (int)adjATTStatus { } } - return 0; // ATTrackingManagerAuthorizationStatusNotDetermined + return -1; } - (BOOL)adjTrackingEnabled { diff --git a/Adjust/ADJPackageBuilder.h b/Adjust/ADJPackageBuilder.h index 7d2723b67..e25752995 100644 --- a/Adjust/ADJPackageBuilder.h +++ b/Adjust/ADJPackageBuilder.h @@ -13,6 +13,7 @@ #import "ADJActivityPackage.h" #import "ADJSessionParameters.h" #import +#import "ADJActivityHandler.h" @interface ADJPackageBuilder : NSObject @@ -32,6 +33,7 @@ activityState:(ADJActivityState *)activityState config:(ADJConfig *)adjustConfig sessionParameters:(ADJSessionParameters *)sessionParameters + trackingStatusManager:(ADJTrackingStatusManager *)trackingStatusManager createdAt:(double)createdAt; - (ADJActivityPackage *)buildSessionPackage:(BOOL)isInDelay; diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index 7296bd5c7..208f4424a 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -27,6 +27,8 @@ @interface ADJPackageBuilder() @property (nonatomic, weak) ADJSessionParameters *sessionParameters; +@property (nonatomic, weak) ADJTrackingStatusManager *trackingStatusManager; + @end @implementation ADJPackageBuilder @@ -37,7 +39,9 @@ - (id)initWithDeviceInfo:(ADJDeviceInfo *)deviceInfo activityState:(ADJActivityState *)activityState config:(ADJConfig *)adjustConfig sessionParameters:(ADJSessionParameters *)sessionParameters - createdAt:(double)createdAt { + trackingStatusManager:(ADJTrackingStatusManager *)trackingStatusManager + createdAt:(double)createdAt +{ self = [super init]; if (self == nil) { return nil; @@ -48,6 +52,7 @@ - (id)initWithDeviceInfo:(ADJDeviceInfo *)deviceInfo self.adjustConfig = adjustConfig; self.activityState = activityState; self.sessionParameters = sessionParameters; + self.trackingStatusManager = trackingStatusManager; return self; } @@ -309,11 +314,13 @@ - (NSMutableDictionary *)getSessionParameters:(BOOL)isInDelay { [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.osName forKey:@"os_name"]; [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.systemVersion forKey:@"os_version"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; - - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0")) { - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; + + if ([self.trackingStatusManager canGetAttStatus]) { + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.attStatus + forKey:@"att_status"]; } else { - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.trackingEnabled + forKey:@"tracking_enabled"]; } if (self.adjustConfig.isDeviceKnown) { @@ -384,10 +391,12 @@ - (NSMutableDictionary *)getEventParameters:(BOOL)isInDelay forEventPackage:(ADJ [ADJPackageBuilder parameters:parameters setNumber:event.revenue forKey:@"revenue"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0")) { - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; + if ([self.trackingStatusManager canGetAttStatus]) { + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.attStatus + forKey:@"att_status"]; } else { - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.trackingEnabled + forKey:@"tracking_enabled"]; } if (self.adjustConfig.isDeviceKnown) { @@ -509,10 +518,12 @@ - (NSMutableDictionary *)getAdRevenueParameters:(NSString *)source payload:(NSDa [ADJPackageBuilder parameters:parameters setString:source forKey:@"source"]; [ADJPackageBuilder parameters:parameters setData:payload forKey:@"payload"]; - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0")) { - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; + if ([self.trackingStatusManager canGetAttStatus]) { + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.attStatus + forKey:@"att_status"]; } else { - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.trackingEnabled + forKey:@"tracking_enabled"]; } if (self.adjustConfig.isDeviceKnown) { @@ -586,10 +597,12 @@ - (NSMutableDictionary *)getClickParameters:(NSString *)source { [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; [ADJPackageBuilder parameters:parameters setString:source forKey:@"source"]; - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0")) { - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; + if ([self.trackingStatusManager canGetAttStatus]) { + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.attStatus + forKey:@"att_status"]; } else { - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.trackingEnabled + forKey:@"tracking_enabled"]; } if (self.adjustConfig.isDeviceKnown) { @@ -749,12 +762,14 @@ - (NSMutableDictionary *)getDisableThirdPartySharingParameters { [ADJPackageBuilder parameters:parameters setDate:self.purchaseTime forKey:@"purchase_time"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0")) { - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; + if ([self.trackingStatusManager canGetAttStatus]) { + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.attStatus + forKey:@"att_status"]; } else { - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.trackingEnabled + forKey:@"tracking_enabled"]; } - + if (self.adjustConfig.isDeviceKnown) { [ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.isDeviceKnown forKey:@"device_known"]; } @@ -813,10 +828,12 @@ - (NSMutableDictionary *)getSubscriptionParameters:(BOOL)isInDelay forSubscripti [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.systemVersion forKey:@"os_version"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; - if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0")) { - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjATTStatus forKey:@"att_status"]; + if ([self.trackingStatusManager canGetAttStatus]) { + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.attStatus + forKey:@"att_status"]; } else { - [ADJPackageBuilder parameters:parameters setInt:UIDevice.currentDevice.adjTrackingEnabled forKey:@"tracking_enabled"]; + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.trackingEnabled + forKey:@"tracking_enabled"]; } if (self.adjustConfig.isDeviceKnown) { From 6a7a2abce7f8119b22cb3128ca5e25d2bc9bb39b Mon Sep 17 00:00:00 2001 From: nonelse Date: Fri, 14 Aug 2020 09:57:43 +0200 Subject: [PATCH 127/173] Wrap request tracking authorization --- Adjust/ADJActivityHandler.h | 1 + Adjust/ADJAdditions/UIDevice+ADJAdditions.h | 2 ++ Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 22 +++++++++++++++++++ Adjust/Adjust.h | 4 ++++ Adjust/Adjust.m | 24 +++++++++++++++++++++ 5 files changed, 53 insertions(+) diff --git a/Adjust/ADJActivityHandler.h b/Adjust/ADJActivityHandler.h index d6f703fb1..ce36b47fa 100644 --- a/Adjust/ADJActivityHandler.h +++ b/Adjust/ADJActivityHandler.h @@ -97,6 +97,7 @@ - (void)trackAdRevenue:(NSString *)soruce payload:(NSData *)payload; - (void)disableThirdPartySharing; - (void)trackSubscription:(ADJSubscription *)subscription; +- (void)updateAttStatusFromUserCallback:(int)newAttStatusFromUser; - (ADJDeviceInfo *)deviceInfo; - (ADJActivityState *)activityState; diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h index f6b99f865..2a3a277a1 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.h +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h @@ -23,4 +23,6 @@ - (NSString *)adjVendorId; - (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler queue:(dispatch_queue_t)queue; +- (void)requestTrackingAuthorizationWithCompletionHandler:(void (^)(NSUInteger status))completion; + @end diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index 3e70ba3a0..f309e648c 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -55,6 +55,28 @@ - (int)adjATTStatus { return -1; } +- (void)requestTrackingAuthorizationWithCompletionHandler:(void (^)(NSUInteger status))completion +{ + Class appTrackingClass = [self appTrackingManager]; + if (appTrackingClass == nil) { + return; + } + NSString *requestAuthorization = [NSString adjJoin: + @"request", + @"Tracking", + @"Authorization" + @"WithCompletionHandler:", nil]; + SEL selRequestAuthorization = NSSelectorFromString(requestAuthorization); + if (![appTrackingClass respondsToSelector:selRequestAuthorization]) { + return; + } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + [appTrackingClass performSelector:selRequestAuthorization withObject:completion]; +#pragma clang diagnostic pop +} + - (BOOL)adjTrackingEnabled { #if ADJUST_NO_IDFA return NO; diff --git a/Adjust/Adjust.h b/Adjust/Adjust.h index d6e7b0595..80ffadc90 100644 --- a/Adjust/Adjust.h +++ b/Adjust/Adjust.h @@ -274,6 +274,8 @@ extern NSString * __nonnull const ADJAdRevenueSourceTapdaq; */ + (void)trackSubscription:(nonnull ADJSubscription *)subscription; ++ (void)requestTrackingAuthorizationWithCompletionHandler:(void (^_Nullable)(NSUInteger status))completion; + /** * Obtain singleton Adjust object. */ @@ -333,4 +335,6 @@ extern NSString * __nonnull const ADJAdRevenueSourceTapdaq; - (nullable NSURL *)convertUniversalLink:(nonnull NSURL *)url scheme:(nonnull NSString *)scheme; +- (void)requestTrackingAuthorizationWithCompletionHandler:(void (^_Nullable)(NSUInteger status))completion; + @end diff --git a/Adjust/Adjust.m b/Adjust/Adjust.m index 201769dd6..44d6e9edc 100644 --- a/Adjust/Adjust.m +++ b/Adjust/Adjust.m @@ -12,6 +12,7 @@ #import "ADJUserDefaults.h" #import "ADJAdjustFactory.h" #import "ADJActivityHandler.h" +#import "UIDevice+ADJAdditions.h" #if !__has_feature(objc_arc) #error Adjust requires ARC @@ -233,6 +234,13 @@ + (void)trackSubscription:(nonnull ADJSubscription *)subscription { } } ++ (void)requestTrackingAuthorizationWithCompletionHandler:(void (^_Nullable)(NSUInteger status))completion +{ + @synchronized (self) { + [[Adjust getInstance] requestTrackingAuthorizationWithCompletionHandler:completion]; + } +} + + (ADJAttribution *)attribution { @synchronized (self) { return [[Adjust getInstance] attribution]; @@ -495,6 +503,22 @@ - (void)trackSubscription:(ADJSubscription *)subscription { [self.activityHandler trackSubscription:subscription]; } +- (void)requestTrackingAuthorizationWithCompletionHandler:(void (^_Nullable)(NSUInteger status))completion +{ + [UIDevice.currentDevice requestTrackingAuthorizationWithCompletionHandler:^(NSUInteger status) + { + if (completion) { + completion(status); + } + + if (![self checkActivityHandler:@"request Tracking Authorization"]) { + return; + } + + [self.activityHandler updateAttStatusFromUserCallback:(int)status]; + }]; +} + - (ADJAttribution *)attribution { if (![self checkActivityHandler]) { return nil; From 58bb0c1d099c9070acd5a24cf78ea80736964702 Mon Sep 17 00:00:00 2001 From: nonelse Date: Fri, 14 Aug 2020 13:36:09 +0200 Subject: [PATCH 128/173] Allo tracking status manager accessible in attribution handler --- Adjust/ADJActivityHandler.h | 4 ++++ Adjust/ADJAttributionHandler.m | 1 + 2 files changed, 5 insertions(+) diff --git a/Adjust/ADJActivityHandler.h b/Adjust/ADJActivityHandler.h index ce36b47fa..c22609d8d 100644 --- a/Adjust/ADJActivityHandler.h +++ b/Adjust/ADJActivityHandler.h @@ -50,9 +50,13 @@ @end +@class ADJTrackingStatusManager; + @protocol ADJActivityHandler @property (nonatomic, copy) ADJAttribution *attribution; +@property (nonatomic, strong) ADJTrackingStatusManager *trackingStatusManager; + - (NSString *)adid; - (id)initWithConfig:(ADJConfig *)adjustConfig diff --git a/Adjust/ADJAttributionHandler.m b/Adjust/ADJAttributionHandler.m index 4c6eb9a53..06d97fea0 100644 --- a/Adjust/ADJAttributionHandler.m +++ b/Adjust/ADJAttributionHandler.m @@ -246,6 +246,7 @@ - (ADJActivityPackage *)buildAndGetAttributionPackageI:(ADJAttributionHandler*)s activityState:selfI.activityHandler.activityState config:selfI.activityHandler.adjustConfig sessionParameters:selfI.activityHandler.sessionParameters + trackingStatusManager:selfI.activityHandler.trackingStatusManager createdAt:now]; ADJActivityPackage *attributionPackage = [attributionBuilder buildAttributionPackage:selfI.lastInitiatedBy]; From 5e2ad2bba121e3521ab0283fdbeb36b9a2a50c5f Mon Sep 17 00:00:00 2001 From: nonelse Date: Fri, 14 Aug 2020 13:36:58 +0200 Subject: [PATCH 129/173] Fix type of tracking status --- Adjust/ADJActivityState.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Adjust/ADJActivityState.h b/Adjust/ADJActivityState.h index 0d3b2ff96..a6cb96fc6 100644 --- a/Adjust/ADJActivityState.h +++ b/Adjust/ADJActivityState.h @@ -23,7 +23,7 @@ @property (nonatomic, copy) NSString *adid; @property (nonatomic, strong) NSDictionary *attributionDetails; -@property (nonatomic, strong) int trackingManagerAuthorizationStatus; +@property (nonatomic, assign) int trackingManagerAuthorizationStatus; // Global counters @property (nonatomic, assign) int eventCount; From ad801e3cec29ad4d8d7f918752bfa431da935b05 Mon Sep 17 00:00:00 2001 From: ugi Date: Fri, 14 Aug 2020 15:35:09 +0200 Subject: [PATCH 130/173] make adjJoin happy --- Adjust/ADJAdditions/UIDevice+ADJAdditions.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index f309e648c..bb1755abe 100644 --- a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m +++ b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m @@ -62,10 +62,12 @@ - (void)requestTrackingAuthorizationWithCompletionHandler:(void (^)(NSUInteger s return; } NSString *requestAuthorization = [NSString adjJoin: - @"request", - @"Tracking", - @"Authorization" - @"WithCompletionHandler:", nil]; + @"request", + @"tracking", + @"authorization", + @"with", + @"completion", + @"handler:", nil]; SEL selRequestAuthorization = NSSelectorFromString(requestAuthorization); if (![appTrackingClass respondsToSelector:selRequestAuthorization]) { return; From 461e2f5b3e2358ca5b6d81c8e6974f203a91b97b Mon Sep 17 00:00:00 2001 From: ugi Date: Fri, 14 Aug 2020 15:53:00 +0200 Subject: [PATCH 131/173] add additional parameters to sdk_info and att_status to all packages --- Adjust/ADJPackageBuilder.m | 69 +++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/Adjust/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index 208f4424a..8de2914f0 100644 --- a/Adjust/ADJPackageBuilder.m +++ b/Adjust/ADJPackageBuilder.m @@ -451,27 +451,65 @@ - (NSMutableDictionary *)getEventParameters:(BOOL)isInDelay forEventPackage:(ADJ - (NSMutableDictionary *)getInfoParameters:(NSString *)source { NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; - [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.appToken forKey:@"app_token"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.appSecret forKey:@"app_secret"]; + [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.appToken forKey:@"app_token"]; + [ADJPackageBuilder parameters:parameters setString:[ADJUtil getUpdateTime] forKey:@"app_updated_at"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.bundleVersion forKey:@"app_version"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.bundleShortVersion forKey:@"app_version_short"]; [ADJPackageBuilder parameters:parameters setBool:YES forKey:@"attribution_deeplink"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.bundeIdentifier forKey:@"bundle_id"]; + [ADJPackageBuilder parameters:parameters setDictionary:[self.sessionParameters.callbackParameters copy] forKey:@"callback_params"]; + [ADJPackageBuilder parameters:parameters setDate:self.clickTime forKey:@"click_time"]; + [ADJPackageBuilder parameters:parameters setNumberInt:[ADJUtil readReachabilityFlags] forKey:@"connectivity_type"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.countryCode forKey:@"country"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.cpuSubtype forKey:@"cpu_type"]; [ADJPackageBuilder parameters:parameters setDate1970:self.createdAt forKey:@"created_at"]; + [ADJPackageBuilder parameters:parameters setString:self.deeplink forKey:@"deeplink"]; + [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.defaultTracker forKey:@"default_tracker"]; + [ADJPackageBuilder parameters:parameters setDictionary:self.attributionDetails forKey:@"details"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.deviceName forKey:@"device_name"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.deviceType forKey:@"device_type"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.environment forKey:@"environment"]; [ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.eventBufferingEnabled forKey:@"event_buffering_enabled"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.externalDeviceId forKey:@"external_device_id"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.fbAnonymousId forKey:@"fb_anon_id"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.machineModel forKey:@"hardware_name"]; if (self.adjustConfig.allowIdfaReading == YES) { [ADJPackageBuilder parameters:parameters setString:UIDevice.currentDevice.adjIdForAdvertisers forKey:@"idfa"]; } [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.vendorId forKey:@"idfv"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.installReceiptBase64 forKey:@"install_receipt"]; + [ADJPackageBuilder parameters:parameters setString:[ADJUtil getInstallTime] forKey:@"installed_at"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.languageCode forKey:@"language"]; [ADJPackageBuilder parameters:parameters setBool:YES forKey:@"needs_response_details"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.osBuild forKey:@"os_build"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.osName forKey:@"os_name"]; + [ADJPackageBuilder parameters:parameters setString:self.deviceInfo.systemVersion forKey:@"os_version"]; + [ADJPackageBuilder parameters:parameters setDictionary:self.deeplinkParameters forKey:@"params"]; + [ADJPackageBuilder parameters:parameters setDictionary:[self.sessionParameters.partnerParameters copy] forKey:@"partner_params"]; + [ADJPackageBuilder parameters:parameters setDate:self.purchaseTime forKey:@"purchase_time"]; [ADJPackageBuilder parameters:parameters setString:self.adjustConfig.secretId forKey:@"secret_id"]; [ADJPackageBuilder parameters:parameters setString:source forKey:@"source"]; + + if ([self.trackingStatusManager canGetAttStatus]) { + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.attStatus + forKey:@"att_status"]; + } else { + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.trackingEnabled + forKey:@"tracking_enabled"]; + } if (self.adjustConfig.isDeviceKnown) { [ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.isDeviceKnown forKey:@"device_known"]; } if (self.activityState != nil) { + [ADJPackageBuilder parameters:parameters setDuration:self.activityState.lastInterval forKey:@"last_interval"]; [ADJPackageBuilder parameters:parameters setString:self.activityState.deviceToken forKey:@"push_token"]; + [ADJPackageBuilder parameters:parameters setInt:self.activityState.sessionCount forKey:@"session_count"]; + [ADJPackageBuilder parameters:parameters setDuration:self.activityState.sessionLength forKey:@"session_length"]; + [ADJPackageBuilder parameters:parameters setInt:self.activityState.subsessionCount forKey:@"subsession_count"]; + [ADJPackageBuilder parameters:parameters setDuration:self.activityState.timeSpent forKey:@"time_spent"]; if (self.activityState.isPersisted) { [ADJPackageBuilder parameters:parameters setString:self.activityState.uuid forKey:@"persistent_ios_uuid"]; } else { @@ -479,6 +517,19 @@ - (NSMutableDictionary *)getInfoParameters:(NSString *)source { } } + if (self.attribution != nil) { + [ADJPackageBuilder parameters:parameters setString:self.attribution.adgroup forKey:@"adgroup"]; + [ADJPackageBuilder parameters:parameters setString:self.attribution.campaign forKey:@"campaign"]; + [ADJPackageBuilder parameters:parameters setString:self.attribution.creative forKey:@"creative"]; + [ADJPackageBuilder parameters:parameters setString:self.attribution.trackerName forKey:@"tracker"]; + } + +#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"]; +#endif + return parameters; } @@ -668,6 +719,14 @@ - (NSMutableDictionary *)getAttributionParameters:(NSString *)initiatedBy { if (self.adjustConfig.isDeviceKnown) { [ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.isDeviceKnown forKey:@"device_known"]; } + + if ([self.trackingStatusManager canGetAttStatus]) { + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.attStatus + forKey:@"att_status"]; + } else { + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.trackingEnabled + forKey:@"tracking_enabled"]; + } if (self.activityState != nil) { if (self.activityState.isPersisted) { @@ -708,6 +767,14 @@ - (NSMutableDictionary *)getGdprParameters { if (self.adjustConfig.isDeviceKnown) { [ADJPackageBuilder parameters:parameters setBool:self.adjustConfig.isDeviceKnown forKey:@"device_known"]; } + + if ([self.trackingStatusManager canGetAttStatus]) { + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.attStatus + forKey:@"att_status"]; + } else { + [ADJPackageBuilder parameters:parameters setInt:self.trackingStatusManager.trackingEnabled + forKey:@"tracking_enabled"]; + } if (self.activityState != nil) { if (self.activityState.isPersisted) { From 95c5b52c1a33f1076d0d906c9d4c59049ddac144 Mon Sep 17 00:00:00 2001 From: ugi Date: Fri, 14 Aug 2020 16:11:04 +0200 Subject: [PATCH 132/173] print att status in activity state snapshot --- Adjust/ADJActivityState.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Adjust/ADJActivityState.m b/Adjust/ADJActivityState.m index 8891cb69f..c43b67deb 100644 --- a/Adjust/ADJActivityState.m +++ b/Adjust/ADJActivityState.m @@ -121,11 +121,11 @@ - (NSString *)generateUniqueKey { } - (NSString *)description { - return [NSString stringWithFormat:@"ec:%d sc:%d ssc:%d ask:%d sl:%.1f ts:%.1f la:%.1f dt:%@ gdprf:%d dtps:%d", + return [NSString stringWithFormat:@"ec:%d sc:%d ssc:%d ask:%d sl:%.1f ts:%.1f la:%.1f dt:%@ gdprf:%d dtps:%d att:%d", self.eventCount, self.sessionCount, self.subsessionCount, self.askingAttribution, self.sessionLength, self.timeSpent, self.lastActivity, self.deviceToken, - self.isGdprForgotten, self.isThirdPartySharingDisabled]; + self.isGdprForgotten, self.isThirdPartySharingDisabled, self.trackingManagerAuthorizationStatus]; } #pragma mark - NSCoding protocol methods From 259449f6664a7c2bd31a6b32ea9324fedae4574a Mon Sep 17 00:00:00 2001 From: ugi Date: Mon, 17 Aug 2020 13:36:25 +0200 Subject: [PATCH 133/173] rename to SKAdNetwork --- .../AdjustExample-Swift/Base.lproj/Main.storyboard | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/AdjustExample-Swift/AdjustExample-Swift/Base.lproj/Main.storyboard b/examples/AdjustExample-Swift/AdjustExample-Swift/Base.lproj/Main.storyboard index 1b8fc1e32..6516585a4 100644 --- a/examples/AdjustExample-Swift/AdjustExample-Swift/Base.lproj/Main.storyboard +++ b/examples/AdjustExample-Swift/AdjustExample-Swift/Base.lproj/Main.storyboard @@ -123,7 +123,7 @@