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.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 @@ )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 7c46373d6..bf0fc9335 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 @@ -89,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; @@ -108,6 +107,9 @@ @interface ADJActivityHandler() typedef NS_ENUM(NSInteger, AdjADClientError) { AdjADClientErrorUnknown = 0, AdjADClientErrorLimitAdTracking = 1, + AdjADClientErrorMissingData = 2, + AdjADClientErrorCorruptResponse = 3, + AdjCustomErrorTimeout = 100, }; #pragma mark - @@ -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,23 +398,52 @@ - (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) { - [self.logger warn:@"Limit number of retry for iAd v3 surpassed"]; + if (self.iAdRetriesLeft < 0) { + [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 + // - AdjCustomErrorTimeout + // 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: + case AdjCustomErrorTimeout: { + int64_t iAdRetryDelay = 0; + switch (self.iAdRetriesLeft) { + case 2: + iAdRetryDelay = 5 * NSEC_PER_SEC; + break; + default: + 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), ^{ + [self checkForIad]; + }); + return; + } + case AdjADClientErrorLimitAdTracking: + return; + default: + return; } - return; } // check if it's a valid attribution details @@ -603,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]; } @@ -630,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; @@ -757,7 +794,7 @@ - (void)initI:(ADJActivityHandler *)selfI sdkClickHandlerOnly:YES]]; if (self.adjustConfig.allowiAdInfoReading == YES) { - [[UIDevice currentDevice] adjSetIad:selfI triesV3Left:kTryIadV3]; + [self checkForIad]; } [selfI preLaunchActionsI:selfI preLaunchActionsArray:preLaunchActionsArray]; @@ -1261,7 +1298,7 @@ - (void)setEnabledI:(ADJActivityHandler *)selfI enabled:(BOOL)enabled { [selfI disableThirdPartySharing]; } if (self.adjustConfig.allowiAdInfoReading == YES) { - [[UIDevice currentDevice] adjSetIad:selfI triesV3Left:kTryIadV3]; + [self checkForIad]; } } @@ -1272,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/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 6231e28ab..a92954361 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]; @@ -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/ADJAdditions/UIDevice+ADJAdditions.h b/Adjust/ADJAdditions/UIDevice+ADJAdditions.h index a506ac0eb..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) @@ -19,6 +20,6 @@ - (NSString *)adjDeviceName; - (NSString *)adjCreateUuid; - (NSString *)adjVendorId; -- (void)adjSetIad:(ADJActivityHandler *)activityHandler - triesV3Left:(int)triesV3Left; +- (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler + iAdTimeoutTimer:(ADJTimerOnce *)iAdTimeoutTimer; @end diff --git a/Adjust/ADJAdditions/UIDevice+ADJAdditions.m b/Adjust/ADJAdditions/UIDevice+ADJAdditions.m index ca185e7e4..b6b081e0e 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) @@ -96,20 +97,33 @@ - (NSString *)adjFbAnonymousId { #if TARGET_OS_TV return @""; #else + // pre FB SDK v6.0.0 // return [FBSDKAppEventsUtility retrievePersistedAnonymousID]; - Class class = NSClassFromString(@"FBSDKAppEventsUtility"); - if (class == nil) { - return @""; - } + // post FB SDK v6.0.0 + // return [FBSDKBasicUtility retrievePersistedAnonymousID]; + Class class = nil; 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 } @@ -144,8 +158,10 @@ - (NSString *)adjVendorId { return @""; } -- (void)adjSetIad:(ADJActivityHandler *)activityHandler - triesV3Left:(int)triesV3Left { +- (void)adjCheckForiAd:(ADJActivityHandler *)activityHandler + iAdTimeoutTimer:(ADJTimerOnce *)iAdTimeoutTimer +{ + // if no tries for iad v3 left, stop trying id logger = [ADJAdjustFactory logger]; #if ADJUST_NO_IAD || TARGET_OS_TV @@ -174,42 +190,37 @@ - (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; - } - BOOL isIadV3Avaliable = [self adjSetIadWithDetails:activityHandler - ADClientSharedClientInstance:ADClientSharedClientInstance - retriesLeft:(triesV3Left - 1)]; + BOOL iAdInformationAvailable = [self setiAdWithDetails:activityHandler + adcClientSharedInstance:ADClientSharedClientInstance + iAdTimeoutTimer:iAdTimeoutTimer]; - // 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 { - SEL iadDetailsSelector = NSSelectorFromString(@"requestAttributionDetailsWithBlock:"); - if (![ADClientSharedClientInstance respondsToSelector:iadDetailsSelector]) { +- (BOOL)setiAdWithDetails:(ADJActivityHandler *)activityHandler + adcClientSharedInstance:(id)ADClientSharedClientInstance + iAdTimeoutTimer:(ADJTimerOnce *)iAdTimeoutTimer +{ + 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 retriesLeft:retriesLeft]; + [activityHandler setAttributionDetails:attributionDetails + error:error]; }]; #pragma clang diagnostic pop + [iAdTimeoutTimer startIn:5.0]; return YES; } 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/ADJPackageBuilder.m b/Adjust/ADJPackageBuilder.m index bd961883b..c3f927521 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 { @@ -277,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"]; @@ -363,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"]; @@ -461,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"]; @@ -540,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"]; @@ -691,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/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); } 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; diff --git a/Adjust/ADJUtil.m b/Adjust/ADJUtil.m index 523ab3450..96d1058f8 100644 --- a/Adjust/ADJUtil.m +++ b/Adjust/ADJUtil.m @@ -19,11 +19,14 @@ #import "UIDevice+ADJAdditions.h" #import "NSString+ADJAdditions.h" -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST #import #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 static NSString *userAgent = nil; @@ -35,12 +38,12 @@ 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 -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"; @@ -64,7 +67,7 @@ + (void)initialize { [self initializeExcludedDeeplinkRegex]; [self initializeUrlSessionConfiguration]; [self initializeReachability]; -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST [self initializeNetworkInfoAndCarrier]; #endif } @@ -76,7 +79,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 @@ -148,7 +151,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]; @@ -285,120 +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 !TARGET_OS_TV - if (@available(iOS 11.0, *)) { -#else - if (@available(tvOS 11.0, *)) { -#endif - 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 !TARGET_OS_TV - if (@available(iOS 11.0, *)) { -#else - if (@available(tvOS 11.0, *)) { -#endif - 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]; + } - return documentsObject; - } else { - // [[ADJAdjustFactory logger] error:@"Failed to read %@ file", documentsFilePath]; - [[ADJAdjustFactory logger] debug:@"File %@ not found in Documents folder", fileName]; + // 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]; + } + } @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 !TARGET_OS_TV - if (@available(iOS 11.0, *)) { -#else - if (@available(tvOS 11.0, *)) { -#endif - NSError *errorArchiving = nil; - NSError *errorWriting = nil; - NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object requiringSecureCoding:NO error:&errorArchiving]; - [data writeToFile:filePath options:NSDataWritingAtomic error:&errorWriting]; - result = (filePath != nil) && (errorArchiving == nil) && (errorWriting == nil); - } else { - result = (filePath != nil) && [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 (!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; +#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]; + result = result && (errorWriting == nil); + } else { + result = NO; + } } else { - [[ADJAdjustFactory logger] debug:@"Wrote %@: %@", objectName, object]; + result = [NSKeyedArchiver archiveRootObject:object toFile:filePath]; } - } else { - [[ADJAdjustFactory logger] error:@"Failed to write %@ file", objectName]; + 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] error:@"Failed to write %@ file", objectName]; + } + } } @@ -604,62 +613,48 @@ + (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 *nativeVersion = [ADJUtil extractEntry:parameters + key:@"native_version"]; + NSString *algorithm = [ADJUtil extractEntry:parameters + key:@"algorithm"]; + NSString *authorizationHeader = [ADJUtil buildAuthorizationHeaderV2:signature secretId:secretId - headersId:headersId]; + headersId:headersId + nativeVersion:nativeVersion + algorithm:algorithm]; 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 - secretId:(NSString*)secretId - headersId:(NSString*)headersId + secretId:(NSString *)secretId + headersId:(NSString *)headersId + nativeVersion:(NSString *)nativeVersion + algorithm:(NSString *)algorithm { if (secretId == nil || signature == nil || headersId == nil) { return nil; @@ -668,12 +663,15 @@ + (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]; - return authorizationHeader; + if (nativeVersion == nil) { + return [authorizationHeader stringByAppendingFormat:@",native_version=\"\""]; + } + return [authorizationHeader stringByAppendingFormat:@",native_version=\"%@\"", nativeVersion]; } + (void)extractEventCallbackId:(NSMutableDictionary *)parameters { @@ -1327,7 +1325,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]]]; } @@ -1415,7 +1413,7 @@ + (NSString *)sdkVersion { return kClientSdk; } -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST + (NSString *)readMCC { if (carrier == nil) { return nil; 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/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..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) { @@ -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/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/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp.xcodeproj/xcshareddata/xcschemes/AdjustWebBridgeTestApp.xcscheme b/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp.xcodeproj/xcshareddata/xcschemes/AdjustWebBridgeTestApp.xcscheme index 5f563c310..31618ca94 100644 --- a/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp.xcodeproj/xcshareddata/xcschemes/AdjustWebBridgeTestApp.xcscheme +++ b/AdjustTests/AdjustWebBridgeTestApp/AdjustWebBridgeTestApp.xcodeproj/xcshareddata/xcschemes/AdjustWebBridgeTestApp.xcscheme @@ -1,6 +1,6 @@ 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 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 + diff --git a/examples/AdjustExample-iMessage/AdjustExample-iMessage.xcodeproj/xcshareddata/xcschemes/AdjustExample-iMessage MessagesExtension.xcscheme b/examples/AdjustExample-iMessage/AdjustExample-iMessage.xcodeproj/xcshareddata/xcschemes/AdjustExample-iMessage MessagesExtension.xcscheme index cd4c7302b..449dd11e7 100644 --- a/examples/AdjustExample-iMessage/AdjustExample-iMessage.xcodeproj/xcshareddata/xcschemes/AdjustExample-iMessage MessagesExtension.xcscheme +++ b/examples/AdjustExample-iMessage/AdjustExample-iMessage.xcodeproj/xcshareddata/xcschemes/AdjustExample-iMessage MessagesExtension.xcscheme @@ -1,6 +1,6 @@