930 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
		
		
			
		
	
	
			930 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
|  | // | ||
|  | //  AdjustUnity.mm | ||
|  | //  Adjust SDK | ||
|  | // | ||
|  | //  Created by Pedro Silva (@nonelse) on 27th March 2014. | ||
|  | //  Copyright © 2012-2018 Adjust GmbH. All rights reserved. | ||
|  | // | ||
|  | 
 | ||
|  | #import <AdjustSdk/AdjustSdk.h> | ||
|  | #import "AdjustUnity.h" | ||
|  | #import "AdjustUnityDelegate.h" | ||
|  | #import "AdjustUnityAppDelegate.h" | ||
|  | 
 | ||
|  | @implementation AdjustUnity | ||
|  | 
 | ||
|  | #pragma mark - Object lifecycle methods | ||
|  | 
 | ||
|  | + (void)load { | ||
|  |     // swizzle AppDelegate on the load | ||
|  |     // it should be done as early as possible | ||
|  |     [AdjustUnityAppDelegate swizzleAppDelegateCallbacks]; | ||
|  | } | ||
|  | 
 | ||
|  | @end | ||
|  | 
 | ||
|  | #pragma mark - Helper C methods | ||
|  | 
 | ||
|  | // method for converting JSON stirng parameters into NSArray object | ||
|  | NSArray* convertArrayParameters(const char* cStringJsonArrayParameters) { | ||
|  |     if (cStringJsonArrayParameters == NULL) { | ||
|  |         return nil; | ||
|  |     } | ||
|  | 
 | ||
|  |     NSError *error = nil; | ||
|  |     NSArray *arrayParameters = nil; | ||
|  |     NSString *stringJsonArrayParameters = [NSString stringWithUTF8String:cStringJsonArrayParameters]; | ||
|  | 
 | ||
|  |     if (stringJsonArrayParameters != nil) { | ||
|  |         NSData *dataJson = [stringJsonArrayParameters dataUsingEncoding:NSUTF8StringEncoding]; | ||
|  |         arrayParameters = [NSJSONSerialization JSONObjectWithData:dataJson options:0 error:&error]; | ||
|  |     } | ||
|  |     if (error != nil) { | ||
|  |         NSString *errorMessage = @"Failed to parse json parameters!"; | ||
|  |         NSLog(@"%@", errorMessage); | ||
|  |     } | ||
|  | 
 | ||
|  |     return arrayParameters; | ||
|  | } | ||
|  | 
 | ||
|  | BOOL isStringValid(const char* cString) { | ||
|  |     if (cString == NULL) { | ||
|  |         return false; | ||
|  |     } | ||
|  | 
 | ||
|  |     NSString *objcString = [NSString stringWithUTF8String:cString]; | ||
|  |     if (objcString == nil) { | ||
|  |         return false; | ||
|  |     } | ||
|  |     if ([objcString isEqualToString:@"ADJ_INVALID"]) { | ||
|  |         return false; | ||
|  |     } | ||
|  | 
 | ||
|  |     return true; | ||
|  | } | ||
|  | 
 | ||
|  | void addValueOrEmpty(NSMutableDictionary *dictionary, NSString *key, NSObject *value) { | ||
|  |     if (nil != value) { | ||
|  |         if ([value isKindOfClass:[NSString class]]) { | ||
|  |             [dictionary setObject:[NSString stringWithFormat:@"%@", value] forKey:key]; | ||
|  |         } else if ([value isKindOfClass:[NSNumber class]]) { | ||
|  |             [dictionary setObject:[NSString stringWithFormat:@"%@", [((NSNumber *)value) stringValue]] forKey:key]; | ||
|  |         } else { | ||
|  |             [dictionary setObject:@"" forKey:key]; | ||
|  |         } | ||
|  |     } else { | ||
|  |         [dictionary setObject:@"" forKey:key]; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | #pragma mark - Publicly available C methods | ||
|  | 
 | ||
|  | extern "C" | ||
|  | { | ||
|  |     void _AdjustInitSdk( | ||
|  |         const char* appToken, | ||
|  |         const char* environment, | ||
|  |         const char* sdkPrefix, | ||
|  |         const char* defaultTracker, | ||
|  |         const char* externalDeviceId, | ||
|  |         const char* jsonUrlStrategyDomains, | ||
|  |         const char* storeName, | ||
|  |         const char* storeAppId, | ||
|  |         int allowSuppressLogLevel, | ||
|  |         int logLevel, | ||
|  |         int attConsentWaitingInterval, | ||
|  |         int eventDeduplicationIdsMaxSize, | ||
|  |         int shouldUseSubdomains, | ||
|  |         int isCoppaComplianceEnabled, | ||
|  |         int isDataResidency, | ||
|  |         int isSendingInBackgroundEnabled, | ||
|  |         int isAdServicesEnabled, | ||
|  |         int isIdfaReadingEnabled, | ||
|  |         int isIdfvReadingEnabled, | ||
|  |         int isSkanAttributionEnabled, | ||
|  |         int isLinkMeEnabled, | ||
|  |         int isCostDataInAttributionEnabled, | ||
|  |         int isDeviceIdsReadingOnceEnabled, | ||
|  |         int isAppTrackingTransparencyUsageEnabled, | ||
|  |         int isFirstSessionDelayEnabled, | ||
|  |         int isDeferredDeeplinkOpeningEnabled, | ||
|  |         AdjustDelegateAttributionCallback attributionCallback, | ||
|  |         AdjustDelegateEventSuccessCallback eventSuccessCallback, | ||
|  |         AdjustDelegateEventFailureCallback eventFailureCallback, | ||
|  |         AdjustDelegateSessionSuccessCallback sessionSuccessCallback, | ||
|  |         AdjustDelegateSessionFailureCallback sessionFailureCallback, | ||
|  |         AdjustDelegateDeferredDeeplinkCallback deferredDeeplinkCallback, | ||
|  |         AdjustDelegateSkanUpdatedCallback skanUpdatedCallback) { | ||
|  |         NSString *strAppToken = isStringValid(appToken) == true ? [NSString stringWithUTF8String:appToken] : nil; | ||
|  |         NSString *strEnvironment = isStringValid(environment) == true ? [NSString stringWithUTF8String:environment] : nil; | ||
|  |         NSString *strSdkPrefix = isStringValid(sdkPrefix) == true ? [NSString stringWithUTF8String:sdkPrefix] : nil; | ||
|  |         NSString *strDefaultTracker = isStringValid(defaultTracker) == true ? [NSString stringWithUTF8String:defaultTracker] : nil; | ||
|  |         NSString *strExternalDeviceId = isStringValid(externalDeviceId) == true ? [NSString stringWithUTF8String:externalDeviceId] : nil; | ||
|  |         NSString *strStoreName = isStringValid(storeName) == true ? [NSString stringWithUTF8String:storeName] : nil; | ||
|  |         NSString *strStoreAppId = isStringValid(storeAppId) == true ? [NSString stringWithUTF8String:storeAppId] : nil; | ||
|  | 
 | ||
|  |         ADJConfig *adjustConfig; | ||
|  | 
 | ||
|  |         if (allowSuppressLogLevel != -1) { | ||
|  |             adjustConfig = [[ADJConfig alloc] initWithAppToken:strAppToken | ||
|  |                                                    environment:strEnvironment | ||
|  |                                               suppressLogLevel:(BOOL)allowSuppressLogLevel]; | ||
|  |         } else { | ||
|  |             adjustConfig = [[ADJConfig alloc] initWithAppToken:strAppToken | ||
|  |                                                    environment:strEnvironment]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // set SDK prefix | ||
|  |         [adjustConfig setSdkPrefix:strSdkPrefix]; | ||
|  | 
 | ||
|  |         // check if user has selected to implement any of the callbacks | ||
|  |         if (attributionCallback != nil || | ||
|  |             sessionSuccessCallback != nil || | ||
|  |             sessionFailureCallback != nil || | ||
|  |             eventSuccessCallback != nil || | ||
|  |             eventFailureCallback != nil || | ||
|  |             deferredDeeplinkCallback != nil || | ||
|  |             skanUpdatedCallback != nil) { | ||
|  |             [adjustConfig setDelegate: | ||
|  |                 [AdjustUnityDelegate getInstanceWithAttributionCallback:attributionCallback | ||
|  |                                                    eventSuccessCallback:eventSuccessCallback | ||
|  |                                                    eventFailureCallback:eventFailureCallback | ||
|  |                                                  sessionSuccessCallback:sessionSuccessCallback | ||
|  |                                                  sessionFailureCallback:sessionFailureCallback | ||
|  |                                                deferredDeeplinkCallback:deferredDeeplinkCallback | ||
|  |                                                     skanUpdatedCallback:skanUpdatedCallback | ||
|  |                                            shouldLaunchDeferredDeeplink:isDeferredDeeplinkOpeningEnabled]]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // log level | ||
|  |         if (logLevel != -1) { | ||
|  |             [adjustConfig setLogLevel:(ADJLogLevel)logLevel]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // COPPA compliance. | ||
|  |         if (isCoppaComplianceEnabled != -1) { | ||
|  |             if ((BOOL)isCoppaComplianceEnabled == YES) { | ||
|  |                 [adjustConfig enableCoppaCompliance]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // Send in background. | ||
|  |         if (isSendingInBackgroundEnabled != -1) { | ||
|  |             if ((BOOL)isSendingInBackgroundEnabled == YES) { | ||
|  |                 [adjustConfig enableSendingInBackground]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // AdServices.framework handling | ||
|  |         if (isAdServicesEnabled != -1) { | ||
|  |             if ((BOOL)isAdServicesEnabled == NO) { | ||
|  |                 [adjustConfig disableAdServices]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // SKAN attribution | ||
|  |         if (isSkanAttributionEnabled != -1) { | ||
|  |             if ((BOOL)isSkanAttributionEnabled == NO) { | ||
|  |                 [adjustConfig disableSkanAttribution]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // IDFA reading | ||
|  |         if (isIdfaReadingEnabled != -1) { | ||
|  |             if ((BOOL)isIdfaReadingEnabled == NO) { | ||
|  |                 [adjustConfig disableIdfaReading]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // IDFV reading | ||
|  |         if (isIdfvReadingEnabled != -1) { | ||
|  |             if ((BOOL)isIdfvReadingEnabled == NO) { | ||
|  |                 [adjustConfig disableIdfvReading]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // LinkMe | ||
|  |         if (isLinkMeEnabled != -1) { | ||
|  |             if ((BOOL)isLinkMeEnabled == YES) { | ||
|  |                 [adjustConfig enableLinkMe]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // ATT dialog delay | ||
|  |         if (attConsentWaitingInterval != -1) { | ||
|  |             [adjustConfig setAttConsentWaitingInterval:attConsentWaitingInterval]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // disable AppTrackingTransparency.framework interaction | ||
|  |         if (isAppTrackingTransparencyUsageEnabled != -1) { | ||
|  |             if ((BOOL)isAppTrackingTransparencyUsageEnabled == NO) { | ||
|  |                 [adjustConfig disableAppTrackingTransparencyUsage]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // first session delay | ||
|  |         if (isFirstSessionDelayEnabled != -1) { | ||
|  |             if ((BOOL)isFirstSessionDelayEnabled == YES) { | ||
|  |                 [adjustConfig enableFirstSessionDelay]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // deduplication IDs max number | ||
|  |         if (eventDeduplicationIdsMaxSize != -1) { | ||
|  |             [adjustConfig setEventDeduplicationIdsMaxSize:eventDeduplicationIdsMaxSize]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // cost data in attribution callback | ||
|  |         if (isCostDataInAttributionEnabled != -1) { | ||
|  |             if ((BOOL)isCostDataInAttributionEnabled == YES) { | ||
|  |                 [adjustConfig enableCostDataInAttribution]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // read device info only once | ||
|  |         if (isDeviceIdsReadingOnceEnabled != -1) { | ||
|  |             if ((BOOL)isDeviceIdsReadingOnceEnabled == YES) { | ||
|  |                 [adjustConfig enableDeviceIdsReadingOnce]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // default tracker | ||
|  |         if (strDefaultTracker != nil) { | ||
|  |             [adjustConfig setDefaultTracker:strDefaultTracker]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // external device identifier | ||
|  |         if (strExternalDeviceId != nil) { | ||
|  |             [adjustConfig setExternalDeviceId:strExternalDeviceId]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // URL strategy | ||
|  |         if (shouldUseSubdomains != -1 && isDataResidency != -1) { | ||
|  |             NSArray *urlStrategyDomains = convertArrayParameters(jsonUrlStrategyDomains); | ||
|  |             if (urlStrategyDomains != nil) { | ||
|  |                 [adjustConfig setUrlStrategy:urlStrategyDomains | ||
|  |                                useSubdomains:(BOOL)shouldUseSubdomains | ||
|  |                              isDataResidency:(BOOL)isDataResidency]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // custom store | ||
|  |         if (strStoreName != nil) { | ||
|  |             ADJStoreInfo *storeInfo = [[ADJStoreInfo alloc] initWithStoreName:strStoreName]; | ||
|  |             if (strStoreAppId != nil) { | ||
|  |                 [storeInfo setStoreAppId:strStoreAppId]; | ||
|  |             } | ||
|  |             [adjustConfig setStoreInfo:storeInfo]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // initialize the SDK | ||
|  |         [Adjust initSdk:adjustConfig]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustTrackEvent(const char* eventToken, | ||
|  |                            double revenue, | ||
|  |                            const char* currency, | ||
|  |                            const char* productId, | ||
|  |                            const char* transactionId, | ||
|  |                            const char* callbackId, | ||
|  |                            const char* deduplicationId, | ||
|  |                            const char* jsonCallbackParameters, | ||
|  |                            const char* jsonPartnerParameters) { | ||
|  |         NSString *strEventToken = isStringValid(eventToken) == true ? [NSString stringWithUTF8String:eventToken] : nil; | ||
|  |         ADJEvent *event = [[ADJEvent alloc] initWithEventToken:strEventToken]; | ||
|  | 
 | ||
|  |         // revenue and currency | ||
|  |         if (revenue != -1 && currency != NULL) { | ||
|  |             NSString *stringCurrency = [NSString stringWithUTF8String:currency]; | ||
|  |             [event setRevenue:revenue currency:stringCurrency]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // callback parameters | ||
|  |         NSArray *arrayCallbackParameters = convertArrayParameters(jsonCallbackParameters); | ||
|  |         if (arrayCallbackParameters != nil) { | ||
|  |             NSUInteger count = [arrayCallbackParameters count]; | ||
|  |             for (int i = 0; i < count;) { | ||
|  |                 NSString *key = arrayCallbackParameters[i++]; | ||
|  |                 NSString *value = arrayCallbackParameters[i++]; | ||
|  |                 [event addCallbackParameter:key value:value]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // partner parameters | ||
|  |         NSArray *arrayPartnerParameters = convertArrayParameters(jsonPartnerParameters); | ||
|  |         if (arrayPartnerParameters != nil) { | ||
|  |             NSUInteger count = [arrayPartnerParameters count]; | ||
|  |             for (int i = 0; i < count;) { | ||
|  |                 NSString *key = arrayPartnerParameters[i++]; | ||
|  |                 NSString *value = arrayPartnerParameters[i++]; | ||
|  |                 [event addPartnerParameter:key value:value]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // transaction ID | ||
|  |         if (transactionId != NULL) { | ||
|  |             NSString *strTransactionId = [NSString stringWithUTF8String:transactionId]; | ||
|  |             [event setTransactionId:strTransactionId]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // product ID | ||
|  |         if (productId != NULL) { | ||
|  |             NSString *strProductId = [NSString stringWithUTF8String:productId]; | ||
|  |             [event setProductId:strProductId]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // callback ID | ||
|  |         if (callbackId != NULL) { | ||
|  |             NSString *strCallbackId = [NSString stringWithUTF8String:callbackId]; | ||
|  |             [event setCallbackId:strCallbackId]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // deduplication ID | ||
|  |         if (deduplicationId != NULL) { | ||
|  |             NSString *strDeduplicationId = [NSString stringWithUTF8String:deduplicationId]; | ||
|  |             [event setDeduplicationId:strDeduplicationId]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // track event | ||
|  |         [Adjust trackEvent:event]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustTrackSubsessionStart() { | ||
|  |         [Adjust trackSubsessionStart]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustTrackSubsessionEnd() { | ||
|  |         [Adjust trackSubsessionEnd]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustEnable() { | ||
|  |         [Adjust enable]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustDisable() { | ||
|  |         [Adjust disable]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustSwitchToOfflineMode() { | ||
|  |         [Adjust switchToOfflineMode]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustSwitchBackToOnlineMode() { | ||
|  |         [Adjust switchBackToOnlineMode]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustSetPushToken(const char* pushToken) { | ||
|  |         if (pushToken != NULL) { | ||
|  |             NSString *strPushToken = [NSString stringWithUTF8String:pushToken]; | ||
|  |             [Adjust setPushTokenAsString:strPushToken]; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustProcessDeeplink(const char* deeplink, const char* referrer) { | ||
|  |         if (deeplink != NULL) { | ||
|  |             NSString *strDeeplink = [NSString stringWithUTF8String:deeplink]; | ||
|  |             NSURL *urlDeeplink = [NSURL URLWithString:strDeeplink]; | ||
|  |             ADJDeeplink *adjustDeeplink = [[ADJDeeplink alloc] initWithDeeplink:urlDeeplink]; | ||
|  | 
 | ||
|  |             if (referrer != NULL) { | ||
|  |                 NSString *strReferrer = [NSString stringWithUTF8String:referrer]; | ||
|  |                 NSURL *urlReferrer = [NSURL URLWithString:strReferrer]; | ||
|  |                 [adjustDeeplink setReferrer:urlReferrer]; | ||
|  |             } | ||
|  |             [Adjust processDeeplink:adjustDeeplink]; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustIsEnabled(AdjustDelegateIsEnabledGetter callback) { | ||
|  |         [Adjust isEnabledWithCompletionHandler:^(BOOL isEnabled) { | ||
|  |             callback(isEnabled); | ||
|  |         }]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustGetAttribution(AdjustDelegateAttributionGetter callback) { | ||
|  |         [Adjust attributionWithCompletionHandler:^(ADJAttribution * _Nullable attribution) { | ||
|  |             // TODO: nil checks | ||
|  |             NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; | ||
|  |             addValueOrEmpty(dictionary, @"trackerToken", attribution.trackerToken); | ||
|  |             addValueOrEmpty(dictionary, @"trackerName", attribution.trackerName); | ||
|  |             addValueOrEmpty(dictionary, @"network", attribution.network); | ||
|  |             addValueOrEmpty(dictionary, @"campaign", attribution.campaign); | ||
|  |             addValueOrEmpty(dictionary, @"creative", attribution.creative); | ||
|  |             addValueOrEmpty(dictionary, @"adgroup", attribution.adgroup); | ||
|  |             addValueOrEmpty(dictionary, @"clickLabel", attribution.clickLabel); | ||
|  |             addValueOrEmpty(dictionary, @"costType", attribution.costType); | ||
|  |             addValueOrEmpty(dictionary, @"costAmount", attribution.costAmount); | ||
|  |             addValueOrEmpty(dictionary, @"costCurrency", attribution.costCurrency); | ||
|  |             if (attribution.jsonResponse != nil) { | ||
|  |                 NSData *jsonData = [NSJSONSerialization dataWithJSONObject:attribution.jsonResponse  | ||
|  |                                                                    options:0 | ||
|  |                                                                      error:nil]; | ||
|  |                 NSString *strJsonResponse = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; | ||
|  |                 addValueOrEmpty(dictionary, @"jsonResponse", strJsonResponse); | ||
|  |             } | ||
|  | 
 | ||
|  |             NSData *dataAttribution = [NSJSONSerialization dataWithJSONObject:dictionary | ||
|  |                                                                       options:0 | ||
|  |                                                                         error:nil]; | ||
|  |             NSString *stringAttribution = [[NSString alloc] initWithBytes:[dataAttribution bytes] | ||
|  |                                                                    length:[dataAttribution length] | ||
|  |                                                                  encoding:NSUTF8StringEncoding]; | ||
|  |             const char* attributionCString = [stringAttribution UTF8String]; | ||
|  |             callback(attributionCString); | ||
|  |         }]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustGetAdid(AdjustDelegateAdidGetter callback) { | ||
|  |         [Adjust adidWithCompletionHandler:^(NSString * _Nullable adid) { | ||
|  |             // TODO: nil checks | ||
|  |             callback([adid UTF8String]); | ||
|  |         }]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustGetIdfa(AdjustDelegateIdfaGetter callback) { | ||
|  |         [Adjust idfaWithCompletionHandler:^(NSString * _Nullable idfa) { | ||
|  |             // TODO: nil checks | ||
|  |             callback([idfa UTF8String]); | ||
|  |         }]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustGetIdfv(AdjustDelegateIdfvGetter callback) { | ||
|  |         [Adjust idfvWithCompletionHandler:^(NSString * _Nullable idfv) { | ||
|  |             // TODO: nil checks | ||
|  |             callback([idfv UTF8String]); | ||
|  |         }]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustGetLastDeeplink(AdjustDelegateLastDeeplinkGetter callback) { | ||
|  |         [Adjust lastDeeplinkWithCompletionHandler:^(NSURL * _Nullable lastDeeplink) { | ||
|  |             // TODO: nil checks | ||
|  |             NSString *strLastDeeplink = [lastDeeplink absoluteString]; | ||
|  |             callback([strLastDeeplink UTF8String]); | ||
|  |         }]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustGetSdkVersion(AdjustDelegateSdkVersionGetter callback) { | ||
|  |         [Adjust sdkVersionWithCompletionHandler:^(NSString * _Nullable sdkVersion) { | ||
|  |             // TODO: nil checks | ||
|  |             callback([sdkVersion UTF8String]); | ||
|  |         }]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustGdprForgetMe() { | ||
|  |         [Adjust gdprForgetMe]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustAddGlobalPartnerParameter(const char* key, const char* value) { | ||
|  |         if (key != NULL && value != NULL) { | ||
|  |             NSString *strKey = [NSString stringWithUTF8String:key]; | ||
|  |             NSString *strValue = [NSString stringWithUTF8String:value]; | ||
|  |             [Adjust addGlobalPartnerParameter:strValue forKey:strKey]; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustAddGlobalCallbackParameter(const char* key, const char* value) { | ||
|  |         if (key != NULL && value != NULL) { | ||
|  |             NSString *strKey = [NSString stringWithUTF8String:key]; | ||
|  |             NSString *strValue = [NSString stringWithUTF8String:value]; | ||
|  |             [Adjust addGlobalCallbackParameter:strValue forKey:strKey]; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustRemoveGlobalPartnerParameter(const char* key) { | ||
|  |         if (key != NULL) { | ||
|  |             NSString *strKey = [NSString stringWithUTF8String:key]; | ||
|  |             [Adjust removeGlobalPartnerParameterForKey:strKey]; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustRemoveGlobalCallbackParameter(const char* key) { | ||
|  |         if (key != NULL) { | ||
|  |             NSString *strKey = [NSString stringWithUTF8String:key]; | ||
|  |             [Adjust removeGlobalCallbackParameterForKey:strKey]; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustRemoveGlobalPartnerParameters() { | ||
|  |         [Adjust removeGlobalPartnerParameters]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustRemoveGlobalCallbackParameters() { | ||
|  |         [Adjust removeGlobalCallbackParameters]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustTrackAdRevenue(const char* source, | ||
|  |                                double revenue, | ||
|  |                                const char* currency, | ||
|  |                                int adImpressionsCount, | ||
|  |                                const char* adRevenueNetwork, | ||
|  |                                const char* adRevenueUnit, | ||
|  |                                const char* adRevenuePlacement, | ||
|  |                                const char* jsonCallbackParameters, | ||
|  |                                const char* jsonPartnerParameters) { | ||
|  |         NSString *stringSource = isStringValid(source) == true ? [NSString stringWithUTF8String:source] : nil; | ||
|  |         ADJAdRevenue *adRevenue = [[ADJAdRevenue alloc] initWithSource:stringSource]; | ||
|  | 
 | ||
|  |         // revenue and currency | ||
|  |         if (revenue != -1 && currency != NULL) { | ||
|  |             NSString *stringCurrency = [NSString stringWithUTF8String:currency]; | ||
|  |             [adRevenue setRevenue:revenue currency:stringCurrency]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // ad impressions count | ||
|  |         if (adImpressionsCount != -1) { | ||
|  |             [adRevenue setAdImpressionsCount:adImpressionsCount]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // ad revenue network | ||
|  |         if (adRevenueNetwork != NULL) { | ||
|  |             NSString *stringAdRevenueNetwork = [NSString stringWithUTF8String:adRevenueNetwork]; | ||
|  |             [adRevenue setAdRevenueNetwork:stringAdRevenueNetwork]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // ad revenue unit | ||
|  |         if (adRevenueUnit != NULL) { | ||
|  |             NSString *stringAdRevenueUnit = [NSString stringWithUTF8String:adRevenueUnit]; | ||
|  |             [adRevenue setAdRevenueUnit:stringAdRevenueUnit]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // ad revenue placement | ||
|  |         if (adRevenuePlacement != NULL) { | ||
|  |             NSString *stringAdRevenuePlacement = [NSString stringWithUTF8String:adRevenuePlacement]; | ||
|  |             [adRevenue setAdRevenuePlacement:stringAdRevenuePlacement]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // callback parameters | ||
|  |         NSArray *arrayCallbackParameters = convertArrayParameters(jsonCallbackParameters); | ||
|  |         if (arrayCallbackParameters != nil) { | ||
|  |             NSUInteger count = [arrayCallbackParameters count]; | ||
|  |             for (int i = 0; i < count;) { | ||
|  |                 NSString *key = arrayCallbackParameters[i++]; | ||
|  |                 NSString *value = arrayCallbackParameters[i++]; | ||
|  |                 [adRevenue addCallbackParameter:key value:value]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // partner parameters | ||
|  |         NSArray *arrayPartnerParameters = convertArrayParameters(jsonPartnerParameters); | ||
|  |         if (arrayPartnerParameters != nil) { | ||
|  |             NSUInteger count = [arrayPartnerParameters count]; | ||
|  |             for (int i = 0; i < count;) { | ||
|  |                 NSString *key = arrayPartnerParameters[i++]; | ||
|  |                 NSString *value = arrayPartnerParameters[i++]; | ||
|  |                 [adRevenue addPartnerParameter:key value:value]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // track ad revenue | ||
|  |         [Adjust trackAdRevenue:adRevenue]; | ||
|  |     } | ||
|  | 
 | ||
|  |     // TODO: consider non-string types for some fields? | ||
|  |     void _AdjustTrackAppStoreSubscription(const char* price, | ||
|  |                                           const char* currency, | ||
|  |                                           const char* transactionId, | ||
|  |                                           const char* transactionDate, | ||
|  |                                           const char* salesRegion, | ||
|  |                                           const char* jsonCallbackParameters, | ||
|  |                                           const char* jsonPartnerParameters) { | ||
|  |         // mandatory fields | ||
|  |         NSDecimalNumber *mPrice; | ||
|  |         NSString *mCurrency; | ||
|  |         NSString *mTransactionId; | ||
|  | 
 | ||
|  |         // price | ||
|  |         if (price != NULL) { | ||
|  |             mPrice = [NSDecimalNumber decimalNumberWithString:[NSString stringWithUTF8String:price]]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // currency | ||
|  |         if (currency != NULL) { | ||
|  |             mCurrency = [NSString stringWithUTF8String:currency]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // transaction ID | ||
|  |         if (transactionId != NULL) { | ||
|  |             mTransactionId = [NSString stringWithUTF8String:transactionId]; | ||
|  |         } | ||
|  | 
 | ||
|  |         ADJAppStoreSubscription *subscription = | ||
|  |         [[ADJAppStoreSubscription alloc] initWithPrice:mPrice | ||
|  |                                               currency:mCurrency | ||
|  |                                          transactionId:mTransactionId]; | ||
|  | 
 | ||
|  |         // optional fields below | ||
|  | 
 | ||
|  |         // transaction date | ||
|  |         if (transactionDate != NULL) { | ||
|  |             NSTimeInterval transactionDateInterval = [[NSString stringWithUTF8String:transactionDate] doubleValue] / 1000.0; | ||
|  |             NSDate *oTransactionDate = [NSDate dateWithTimeIntervalSince1970:transactionDateInterval]; | ||
|  |             [subscription setTransactionDate:oTransactionDate]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // sales region | ||
|  |         if (salesRegion != NULL) { | ||
|  |             NSString *oSalesRegion = [NSString stringWithUTF8String:salesRegion]; | ||
|  |             [subscription setSalesRegion:oSalesRegion]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // callback parameters | ||
|  |         NSArray *arrayCallbackParameters = convertArrayParameters(jsonCallbackParameters); | ||
|  |         if (arrayCallbackParameters != nil) { | ||
|  |             NSUInteger count = [arrayCallbackParameters count]; | ||
|  |             for (int i = 0; i < count;) { | ||
|  |                 NSString *key = arrayCallbackParameters[i++]; | ||
|  |                 NSString *value = arrayCallbackParameters[i++]; | ||
|  |                 [subscription addCallbackParameter:key value:value]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // partner parameters | ||
|  |         NSArray *arrayPartnerParameters = convertArrayParameters(jsonPartnerParameters); | ||
|  |         if (arrayPartnerParameters != nil) { | ||
|  |             NSUInteger count = [arrayPartnerParameters count]; | ||
|  |             for (int i = 0; i < count;) { | ||
|  |                 NSString *key = arrayPartnerParameters[i++]; | ||
|  |                 NSString *value = arrayPartnerParameters[i++]; | ||
|  |                 [subscription addPartnerParameter:key value:value]; | ||
|  |             } | ||
|  |         } | ||
|  |          | ||
|  |         // track subscription | ||
|  |         [Adjust trackAppStoreSubscription:subscription]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustTrackThirdPartySharing(int enabled, const char* jsonGranularOptions, const char* jsonPartnerSharingSettings) { | ||
|  |         NSNumber *nEnabled = enabled >= 0 ? [NSNumber numberWithInt:enabled] : nil; | ||
|  |         ADJThirdPartySharing *adjustThirdPartySharing = [[ADJThirdPartySharing alloc] initWithIsEnabled:nEnabled]; | ||
|  | 
 | ||
|  |         NSArray *arrayGranularOptions = convertArrayParameters(jsonGranularOptions); | ||
|  |         if (arrayGranularOptions != nil) { | ||
|  |             for (int i = 0; i < [arrayGranularOptions count];) { | ||
|  |                 NSString *partnerName = arrayGranularOptions[i++]; | ||
|  |                 NSString *key = arrayGranularOptions[i++]; | ||
|  |                 NSString *value = arrayGranularOptions[i++]; | ||
|  |                 [adjustThirdPartySharing addGranularOption:partnerName | ||
|  |                                                        key:key | ||
|  |                                                      value:value]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         NSArray *arrayPartnerSharingSettings = convertArrayParameters(jsonPartnerSharingSettings); | ||
|  |         if (arrayPartnerSharingSettings != nil) { | ||
|  |             for (int i = 0; i < [arrayPartnerSharingSettings count];) { | ||
|  |                 NSString *partnerName = arrayPartnerSharingSettings[i++]; | ||
|  |                 NSString *key = arrayPartnerSharingSettings[i++]; | ||
|  |                 NSString *value = arrayPartnerSharingSettings[i++]; | ||
|  |                 [adjustThirdPartySharing addPartnerSharingSetting:partnerName | ||
|  |                                                               key:key | ||
|  |                                                             value:[value boolValue]]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         [Adjust trackThirdPartySharing:adjustThirdPartySharing]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustTrackMeasurementConsent(int enabled) { | ||
|  |         BOOL bEnabled = (BOOL)enabled; | ||
|  |         [Adjust trackMeasurementConsent:bEnabled]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustRequestAppTrackingAuthorization(AdjustDelegateAttCallback callback) { | ||
|  |         [Adjust requestAppTrackingAuthorizationWithCompletionHandler:^(NSUInteger status) { | ||
|  |             callback((int)status); | ||
|  |         }]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustUpdateSkanConversionValue(int conversionValue, | ||
|  |                                           const char* coarseValue, | ||
|  |                                           int lockWindow, | ||
|  |                                           AdjustDelegateSkanErrorCallback callback) { | ||
|  |         if (coarseValue != NULL) { | ||
|  |             NSString *strCoarseValue = [NSString stringWithUTF8String:coarseValue]; | ||
|  |             BOOL bLockWindow = (BOOL)lockWindow; | ||
|  |             [Adjust updateSkanConversionValue:conversionValue | ||
|  |                                   coarseValue:strCoarseValue | ||
|  |                                    lockWindow:[NSNumber numberWithBool:bLockWindow] | ||
|  |                         withCompletionHandler:^(NSError * _Nullable error) { | ||
|  |                 // TODO: nil checks | ||
|  |                 NSString *errorString = [error localizedDescription]; | ||
|  |                 const char* errorChar = [errorString UTF8String]; | ||
|  |                 callback(errorChar); | ||
|  |             }]; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     int _AdjustGetAppTrackingAuthorizationStatus() { | ||
|  |         return [Adjust appTrackingAuthorizationStatus]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustVerifyAppStorePurchase(const char* transactionId, | ||
|  |                                        const char* productId, | ||
|  |                                        int callbackId, | ||
|  |                                        AdjustDelegatePurchaseVerificationCallback callback) { | ||
|  |         NSString *strTransactionId; | ||
|  |         NSString *strProductId; | ||
|  | 
 | ||
|  |         // transaction ID | ||
|  |         if (transactionId != NULL) { | ||
|  |             strTransactionId = [NSString stringWithUTF8String:transactionId]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // product ID | ||
|  |         if (productId != NULL) { | ||
|  |             strProductId = [NSString stringWithUTF8String:productId]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // verify the purchase | ||
|  |         ADJAppStorePurchase *purchase = | ||
|  |         [[ADJAppStorePurchase alloc] initWithTransactionId:strTransactionId | ||
|  |                                                  productId:strProductId]; | ||
|  | 
 | ||
|  |         [Adjust verifyAppStorePurchase:purchase | ||
|  |                  withCompletionHandler:^(ADJPurchaseVerificationResult * _Nonnull verificationResult) { | ||
|  |             // TODO: nil checks | ||
|  |             NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; | ||
|  |             addValueOrEmpty(dictionary, @"verificationStatus", verificationResult.verificationStatus); | ||
|  |             addValueOrEmpty(dictionary, @"code", [NSString stringWithFormat:@"%d", verificationResult.code]); | ||
|  |             addValueOrEmpty(dictionary, @"message", verificationResult.message); | ||
|  | 
 | ||
|  |             NSData *dataVerificationInfo = [NSJSONSerialization dataWithJSONObject:dictionary | ||
|  |                                                                            options:0 | ||
|  |                                                                              error:nil]; | ||
|  |             NSString *strVerificationInfo = [[NSString alloc] initWithBytes:[dataVerificationInfo bytes] | ||
|  |                                                                      length:[dataVerificationInfo length] | ||
|  |                                                                    encoding:NSUTF8StringEncoding]; | ||
|  |             const char* verificationInfoCString = [strVerificationInfo UTF8String]; | ||
|  |             callback(verificationInfoCString, callbackId); | ||
|  |         }]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustProcessAndResolveDeeplink(const char* deeplink, AdjustDelegateResolvedDeeplinkCallback callback) { | ||
|  |         if (deeplink != NULL) { | ||
|  |             NSString *strDeeplink = [NSString stringWithUTF8String:deeplink]; | ||
|  |             NSURL *urlDeeplink = [NSURL URLWithString:strDeeplink]; | ||
|  |             ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:urlDeeplink]; | ||
|  |             [Adjust processAndResolveDeeplink:deeplink withCompletionHandler:^(NSString * _Nullable resolvedLink) { | ||
|  |                 // TODO: nil checks | ||
|  |                 const char* resolvedLinkCString = [resolvedLink UTF8String]; | ||
|  |                 callback(resolvedLinkCString); | ||
|  |             }]; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustVerifyAndTrackAppStorePurchase( | ||
|  |         const char* eventToken, | ||
|  |         double revenue, | ||
|  |         const char* currency, | ||
|  |         const char* productId, | ||
|  |         const char* transactionId, | ||
|  |         const char* callbackId, | ||
|  |         const char* deduplicationId, | ||
|  |         const char* jsonCallbackParameters, | ||
|  |         const char* jsonPartnerParameters, | ||
|  |         int verificationCallbackId, | ||
|  |         AdjustDelegateVerifyAndTrackCallback callback) { | ||
|  |         NSString *strEventToken = isStringValid(eventToken) == true ? [NSString stringWithUTF8String:eventToken] : nil; | ||
|  |         ADJEvent *event = [[ADJEvent alloc] initWithEventToken:strEventToken]; | ||
|  | 
 | ||
|  |         // revenue and currency | ||
|  |         if (revenue != -1 && currency != NULL) { | ||
|  |             NSString *stringCurrency = [NSString stringWithUTF8String:currency]; | ||
|  |             [event setRevenue:revenue currency:stringCurrency]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // callback parameters | ||
|  |         NSArray *arrayCallbackParameters = convertArrayParameters(jsonCallbackParameters); | ||
|  |         if (arrayCallbackParameters != nil) { | ||
|  |             NSUInteger count = [arrayCallbackParameters count]; | ||
|  |             for (int i = 0; i < count;) { | ||
|  |                 NSString *key = arrayCallbackParameters[i++]; | ||
|  |                 NSString *value = arrayCallbackParameters[i++]; | ||
|  |                 [event addCallbackParameter:key value:value]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // partner parameters | ||
|  |         NSArray *arrayPartnerParameters = convertArrayParameters(jsonPartnerParameters); | ||
|  |         if (arrayPartnerParameters != nil) { | ||
|  |             NSUInteger count = [arrayPartnerParameters count]; | ||
|  |             for (int i = 0; i < count;) { | ||
|  |                 NSString *key = arrayPartnerParameters[i++]; | ||
|  |                 NSString *value = arrayPartnerParameters[i++]; | ||
|  |                 [event addPartnerParameter:key value:value]; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // transaction ID | ||
|  |         if (transactionId != NULL) { | ||
|  |             NSString *strTransactionId = [NSString stringWithUTF8String:transactionId]; | ||
|  |             [event setTransactionId:strTransactionId]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // product ID | ||
|  |         if (productId != NULL) { | ||
|  |             NSString *strProductId = [NSString stringWithUTF8String:productId]; | ||
|  |             [event setProductId:strProductId]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // callback ID | ||
|  |         if (callbackId != NULL) { | ||
|  |             NSString *strCallbackId = [NSString stringWithUTF8String:callbackId]; | ||
|  |             [event setCallbackId:strCallbackId]; | ||
|  |         } | ||
|  | 
 | ||
|  |         // deduplication ID | ||
|  |         if (deduplicationId != NULL) { | ||
|  |             NSString *strDeduplicationId = [NSString stringWithUTF8String:deduplicationId]; | ||
|  |             [event setDeduplicationId:strDeduplicationId]; | ||
|  |         } | ||
|  | 
 | ||
|  |         [Adjust verifyAndTrackAppStorePurchase:event | ||
|  |                          withCompletionHandler:^(ADJPurchaseVerificationResult * _Nonnull verificationResult) { | ||
|  |             // TODO: nil checks | ||
|  |             NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; | ||
|  |             addValueOrEmpty(dictionary, @"verificationStatus", verificationResult.verificationStatus); | ||
|  |             addValueOrEmpty(dictionary, @"code", [NSString stringWithFormat:@"%d", verificationResult.code]); | ||
|  |             addValueOrEmpty(dictionary, @"message", verificationResult.message); | ||
|  | 
 | ||
|  |             NSData *dataVerificationInfo = [NSJSONSerialization dataWithJSONObject:dictionary | ||
|  |                                                                            options:0 | ||
|  |                                                                              error:nil]; | ||
|  |             NSString *strVerificationInfo = [[NSString alloc] initWithBytes:[dataVerificationInfo bytes] | ||
|  |                                                                      length:[dataVerificationInfo length] | ||
|  |                                                                    encoding:NSUTF8StringEncoding]; | ||
|  |             const char* verificationInfoCString = [strVerificationInfo UTF8String]; | ||
|  |             callback(verificationInfoCString, verificationCallbackId); | ||
|  |         }]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustEndFirstSessionDelay() { | ||
|  |         [Adjust endFirstSessionDelay]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustEnableCoppaComplianceInDelay() { | ||
|  |         [Adjust enableCoppaComplianceInDelay]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustDisableCoppaComplianceInDelay() { | ||
|  |         [Adjust disableCoppaComplianceInDelay]; | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustSetExternalDeviceIdInDelay(const char* externalDeviceId) { | ||
|  |         if (externalDeviceId != NULL) { | ||
|  |             NSString *strExternalDeviceId = [NSString stringWithUTF8String:externalDeviceId]; | ||
|  |             [Adjust setExternalDeviceIdInDelay:strExternalDeviceId]; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     void _AdjustSetTestOptions(const char* overwriteUrl, | ||
|  |                                const char* extraPath, | ||
|  |                                long timerIntervalInMilliseconds, | ||
|  |                                long timerStartInMilliseconds, | ||
|  |                                long sessionIntervalInMilliseconds, | ||
|  |                                long subsessionIntervalInMilliseconds, | ||
|  |                                int teardown, | ||
|  |                                int deleteState, | ||
|  |                                int noBackoffWait, | ||
|  |                                int adServicesFrameworkEnabled, | ||
|  |                                int attStatus, | ||
|  |                                const char *idfa) { | ||
|  |         NSMutableDictionary *testOptions = [NSMutableDictionary dictionary]; | ||
|  | 
 | ||
|  |         NSString *strOverwriteUrl = isStringValid(overwriteUrl) == true ? [NSString stringWithUTF8String:overwriteUrl] : nil; | ||
|  |         if (strOverwriteUrl != nil) { | ||
|  |             testOptions[@"testUrlOverwrite"] = strOverwriteUrl; | ||
|  |         } | ||
|  |         NSString *strExtraPath = isStringValid(extraPath) == true ? [NSString stringWithUTF8String:extraPath] : nil; | ||
|  |         if (strExtraPath != nil && [strExtraPath length] > 0) { | ||
|  |             testOptions[@"extraPath"] = strExtraPath; | ||
|  |         } | ||
|  |         NSString *strIdfa = isStringValid(idfa) == true ? [NSString stringWithUTF8String:idfa] : nil; | ||
|  |         if (strIdfa != nil && [strIdfa length] > 0) { | ||
|  |             testOptions[@"idfa"] = strIdfa; | ||
|  |         } | ||
|  | 
 | ||
|  |         testOptions[@"timerIntervalInMilliseconds"] = [NSNumber numberWithLong:timerIntervalInMilliseconds]; | ||
|  |         testOptions[@"timerStartInMilliseconds"] = [NSNumber numberWithLong:timerStartInMilliseconds]; | ||
|  |         testOptions[@"sessionIntervalInMilliseconds"] = [NSNumber numberWithLong:sessionIntervalInMilliseconds]; | ||
|  |         testOptions[@"subsessionIntervalInMilliseconds"] = [NSNumber numberWithLong:subsessionIntervalInMilliseconds]; | ||
|  |         testOptions[@"attStatusInt"] = [NSNumber numberWithInt:attStatus]; | ||
|  | 
 | ||
|  |         if (teardown != -1) { | ||
|  |             [AdjustUnityDelegate teardown]; | ||
|  |             testOptions[@"teardown"] = [NSNumber numberWithInt:teardown]; | ||
|  |         } | ||
|  |         if (deleteState != -1) { | ||
|  |             testOptions[@"deleteState"] = [NSNumber numberWithInt:deleteState]; | ||
|  |         } | ||
|  |         if (noBackoffWait != -1) { | ||
|  |             testOptions[@"noBackoffWait"] = [NSNumber numberWithInt:noBackoffWait]; | ||
|  |         } | ||
|  |         if (adServicesFrameworkEnabled != -1) { | ||
|  |             testOptions[@"adServicesFrameworkEnabled"] = [NSNumber numberWithInt:adServicesFrameworkEnabled]; | ||
|  |         } | ||
|  | 
 | ||
|  |         [Adjust setTestOptions:testOptions]; | ||
|  |     } | ||
|  | } |