com.guru.unity.adjust/Adjust/iOS/AdjustUnity.mm

977 lines
41 KiB
Plaintext
Raw Permalink Normal View History

2023-12-26 03:52:53 +00:00
//
// AdjustUnity.mm
// Adjust SDK
//
// Created by Pedro Silva (@nonelse) on 27th March 2014.
// Copyright © 2012-2018 Adjust GmbH. All rights reserved.
//
#import "Adjust.h"
#import "ADJEvent.h"
#import "ADJConfig.h"
#import "AdjustUnity.h"
#import "AdjustUnityAppDelegate.h"
#import "AdjustUnityDelegate.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 _AdjustLaunchApp(const char* appToken,
const char* environment,
const char* sdkPrefix,
const char* userAgent,
const char* defaultTracker,
const char* externalDeviceId,
const char* urlStrategy,
const char* sceneName,
int allowSuppressLogLevel,
int logLevel,
int isDeviceKnown,
int eventBuffering,
int sendInBackground,
int allowAdServicesInfoReading,
int allowIdfaReading,
int deactivateSkAdNetworkHandling,
int linkMeEnabled,
int needsCost,
int coppaCompliant,
2024-04-16 05:30:31 +00:00
int readDeviceInfoOnce,
2023-12-26 03:52:53 +00:00
int64_t secretId,
int64_t info1,
int64_t info2,
int64_t info3,
int64_t info4,
double delayStart,
int attConsentWaitingInterval,
int launchDeferredDeeplink,
int isAttributionCallbackImplemented,
int isEventSuccessCallbackImplemented,
int isEventFailureCallbackImplemented,
int isSessionSuccessCallbackImplemented,
int isSessionFailureCallbackImplemented,
int isDeferredDeeplinkCallbackImplemented,
int isConversionValueUpdatedCallbackImplemented,
int isSkad4ConversionValueUpdatedCallbackImplemented) {
NSString *stringAppToken = isStringValid(appToken) == true ? [NSString stringWithUTF8String:appToken] : nil;
NSString *stringEnvironment = isStringValid(environment) == true ? [NSString stringWithUTF8String:environment] : nil;
NSString *stringSdkPrefix = isStringValid(sdkPrefix) == true ? [NSString stringWithUTF8String:sdkPrefix] : nil;
NSString *stringUserAgent = isStringValid(userAgent) == true ? [NSString stringWithUTF8String:userAgent] : nil;
NSString *stringDefaultTracker = isStringValid(defaultTracker) == true ? [NSString stringWithUTF8String:defaultTracker] : nil;
NSString *stringExternalDeviceId = isStringValid(externalDeviceId) == true ? [NSString stringWithUTF8String:externalDeviceId] : nil;
NSString *stringUrlStrategy = isStringValid(urlStrategy) == true ? [NSString stringWithUTF8String:urlStrategy] : nil;
NSString *stringSceneName = isStringValid(sceneName) == true ? [NSString stringWithUTF8String:sceneName] : nil;
ADJConfig *adjustConfig;
if (allowSuppressLogLevel != -1) {
adjustConfig = [ADJConfig configWithAppToken:stringAppToken
environment:stringEnvironment
allowSuppressLogLevel:(BOOL)allowSuppressLogLevel];
} else {
adjustConfig = [ADJConfig configWithAppToken:stringAppToken
environment:stringEnvironment];
}
// Set SDK prefix.
[adjustConfig setSdkPrefix:stringSdkPrefix];
// Check if user has selected to implement any of the callbacks.
if (isAttributionCallbackImplemented
|| isEventSuccessCallbackImplemented
|| isEventFailureCallbackImplemented
|| isSessionSuccessCallbackImplemented
|| isSessionFailureCallbackImplemented
|| isDeferredDeeplinkCallbackImplemented
|| isConversionValueUpdatedCallbackImplemented
|| isSkad4ConversionValueUpdatedCallbackImplemented) {
[adjustConfig setDelegate:
[AdjustUnityDelegate getInstanceWithSwizzleOfAttributionCallback:isAttributionCallbackImplemented
eventSuccessCallback:isEventSuccessCallbackImplemented
eventFailureCallback:isEventFailureCallbackImplemented
sessionSuccessCallback:isSessionSuccessCallbackImplemented
sessionFailureCallback:isSessionFailureCallbackImplemented
deferredDeeplinkCallback:isDeferredDeeplinkCallbackImplemented
conversionValueUpdatedCallback:isConversionValueUpdatedCallbackImplemented
skad4ConversionValueUpdatedCallback:isSkad4ConversionValueUpdatedCallbackImplemented
shouldLaunchDeferredDeeplink:launchDeferredDeeplink
withAdjustUnitySceneName:stringSceneName]];
}
// Log level.
if (logLevel != -1) {
[adjustConfig setLogLevel:(ADJLogLevel)logLevel];
}
// Event buffering.
if (eventBuffering != -1) {
[adjustConfig setEventBufferingEnabled:(BOOL)eventBuffering];
}
// Send in background.
if (sendInBackground != -1) {
[adjustConfig setSendInBackground:(BOOL)sendInBackground];
}
// Allow AdServices info reading.
if (allowAdServicesInfoReading != -1) {
[adjustConfig setAllowAdServicesInfoReading:(BOOL)allowAdServicesInfoReading];
}
// Deactivate default SKAdNetwork handling.
if (deactivateSkAdNetworkHandling != -1) {
[adjustConfig deactivateSKAdNetworkHandling];
}
// Allow IDFA reading.
if (allowIdfaReading != -1) {
[adjustConfig setAllowIdfaReading:(BOOL)allowIdfaReading];
}
// Enable LinkMe feature.
if (linkMeEnabled != -1) {
[adjustConfig setLinkMeEnabled:(BOOL)linkMeEnabled];
}
// Device known.
if (isDeviceKnown != -1) {
[adjustConfig setIsDeviceKnown:(BOOL)isDeviceKnown];
}
// Delay start.
if (delayStart != -1) {
[adjustConfig setDelayStart:delayStart];
}
// ATT dialog delay.
if (attConsentWaitingInterval != -1) {
[adjustConfig setAttConsentWaitingInterval:attConsentWaitingInterval];
}
// Cost data in attribution callback.
if (needsCost != -1) {
[adjustConfig setNeedsCost:(BOOL)needsCost];
}
// COPPA compliance.
if (coppaCompliant != -1) {
[adjustConfig setCoppaCompliantEnabled:(BOOL)coppaCompliant];
}
2024-04-16 05:30:31 +00:00
// Read device info just once.
if (readDeviceInfoOnce != -1) {
[adjustConfig setReadDeviceInfoOnceEnabled:(BOOL)readDeviceInfoOnce];
}
2023-12-26 03:52:53 +00:00
// User agent.
if (stringUserAgent != nil) {
[adjustConfig setUserAgent:stringUserAgent];
}
// Default tracker.
if (stringDefaultTracker != nil) {
[adjustConfig setDefaultTracker:stringDefaultTracker];
}
// External device identifier.
if (stringExternalDeviceId != nil) {
[adjustConfig setExternalDeviceId:stringExternalDeviceId];
}
// URL strategy.
if (stringUrlStrategy != nil) {
if ([stringUrlStrategy isEqualToString:@"china"]) {
[adjustConfig setUrlStrategy:ADJUrlStrategyChina];
} else if ([stringUrlStrategy isEqualToString:@"india"]) {
[adjustConfig setUrlStrategy:ADJUrlStrategyIndia];
} else if ([stringUrlStrategy isEqualToString:@"cn"]) {
[adjustConfig setUrlStrategy:ADJUrlStrategyCn];
} else if ([stringUrlStrategy isEqualToString:@"cn-only"]) {
[adjustConfig setUrlStrategy:ADJUrlStrategyCnOnly];
} else if ([stringUrlStrategy isEqualToString:@"data-residency-eu"]) {
[adjustConfig setUrlStrategy:ADJDataResidencyEU];
} else if ([stringUrlStrategy isEqualToString:@"data-residency-tr"]) {
[adjustConfig setUrlStrategy:ADJDataResidencyTR];
} else if ([stringUrlStrategy isEqualToString:@"data-residency-us"]) {
[adjustConfig setUrlStrategy:ADJDataResidencyUS];
}
}
// App secret.
if (secretId != -1 && info1 != -1 && info2 != -1 && info3 != -1 && info4 != 1) {
[adjustConfig setAppSecret:secretId info1:info1 info2:info2 info3:info3 info4:info4];
}
// Start the SDK.
[Adjust appDidLaunch:adjustConfig];
[Adjust trackSubsessionStart];
}
void _AdjustTrackEvent(const char* eventToken,
double revenue,
const char* currency,
const char* receipt,
2024-04-16 05:30:31 +00:00
const char* receiptBase64,
2023-12-26 03:52:53 +00:00
const char* productId,
const char* transactionId,
const char* callbackId,
int isReceiptSet,
const char* jsonCallbackParameters,
const char* jsonPartnerParameters) {
NSString *stringEventToken = isStringValid(eventToken) == true ? [NSString stringWithUTF8String:eventToken] : nil;
ADJEvent *event = [ADJEvent eventWithEventToken:stringEventToken];
// 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];
}
}
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 *stringTransactionId = [NSString stringWithUTF8String:transactionId];
[event setTransactionId:stringTransactionId];
}
// Product ID.
if (productId != NULL) {
NSString *stringProductId = [NSString stringWithUTF8String:productId];
[event setProductId:stringProductId];
}
// Receipt.
if (receipt != NULL) {
NSString *stringReceipt = [NSString stringWithUTF8String:receipt];
[event setReceipt:[stringReceipt dataUsingEncoding:NSUTF8StringEncoding]];
}
2024-04-16 05:30:31 +00:00
// Base64 encoded receipt.
if (receiptBase64 != NULL) {
// If both (receipt and receiptBase64) set, receiptBase64 will be used.
NSString *stringReceiptBase64 = [NSString stringWithUTF8String:receiptBase64];
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:stringReceiptBase64 options:0];
[event setReceipt:decodedData];
}
2023-12-26 03:52:53 +00:00
// Callback ID.
if (callbackId != NULL) {
NSString *stringCallbackId = [NSString stringWithUTF8String:callbackId];
[event setCallbackId:stringCallbackId];
}
// Receipt (legacy).
// if ([[NSNumber numberWithInt:isReceiptSet] boolValue]) {
// NSString *stringReceipt = nil;
// NSString *stringTransactionId = nil;
// if (receipt != NULL) {
// stringReceipt = [NSString stringWithUTF8String:receipt];
// }
// if (transactionId != NULL) {
// stringTransactionId = [NSString stringWithUTF8String:transactionId];
// }
// [event setReceipt:[stringReceipt dataUsingEncoding:NSUTF8StringEncoding] transactionId:stringTransactionId];
// }
// Track event.
[Adjust trackEvent:event];
}
void _AdjustTrackSubsessionStart() {
[Adjust trackSubsessionStart];
}
void _AdjustTrackSubsessionEnd() {
[Adjust trackSubsessionEnd];
}
void _AdjustSetEnabled(int enabled) {
BOOL bEnabled = (BOOL)enabled;
[Adjust setEnabled:bEnabled];
}
int _AdjustIsEnabled() {
BOOL isEnabled = [Adjust isEnabled];
int iIsEnabled = (int)isEnabled;
return iIsEnabled;
}
void _AdjustSetOfflineMode(int enabled) {
BOOL bEnabled = (BOOL)enabled;
[Adjust setOfflineMode:bEnabled];
}
void _AdjustSetDeviceToken(const char* deviceToken) {
if (deviceToken != NULL) {
NSString *stringDeviceToken = [NSString stringWithUTF8String:deviceToken];
[Adjust setPushToken:stringDeviceToken];
}
}
void _AdjustAppWillOpenUrl(const char* url) {
if (url != NULL) {
NSString *stringUrl = [NSString stringWithUTF8String:url];
NSURL *nsUrl;
if ([NSString instancesRespondToSelector:@selector(stringByAddingPercentEncodingWithAllowedCharacters:)]) {
nsUrl = [NSURL URLWithString:[stringUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]];
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
nsUrl = [NSURL URLWithString:[stringUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
#pragma clang diagnostic pop
[Adjust appWillOpenUrl:nsUrl];
}
}
char* _AdjustGetIdfa() {
NSString *idfa = [Adjust idfa];
if (nil == idfa) {
return NULL;
}
const char* idfaCString = [idfa UTF8String];
if (NULL == idfaCString) {
return NULL;
}
char* idfaCStringCopy = strdup(idfaCString);
return idfaCStringCopy;
}
char* _AdjustGetIdfv() {
NSString *idfv = [Adjust idfv];
if (nil == idfv) {
return NULL;
}
const char* idfvCString = [idfv UTF8String];
if (NULL == idfvCString) {
return NULL;
}
char* idfvCStringCopy = strdup(idfvCString);
return idfvCStringCopy;
}
char* _AdjustGetAdid() {
NSString *adid = [Adjust adid];
if (nil == adid) {
return NULL;
}
const char* adidCString = [adid UTF8String];
if (NULL == adidCString) {
return NULL;
}
char* adidCStringCopy = strdup(adidCString);
return adidCStringCopy;
}
char* _AdjustGetSdkVersion() {
NSString *sdkVersion = [Adjust sdkVersion];
if (nil == sdkVersion) {
return NULL;
}
const char* sdkVersionCString = [sdkVersion UTF8String];
if (NULL == sdkVersionCString) {
return NULL;
}
char* sdkVersionCStringCopy = strdup(sdkVersionCString);
return sdkVersionCStringCopy;
}
char* _AdjustGetAttribution() {
ADJAttribution *attribution = [Adjust attribution];
if (nil == attribution) {
return NULL;
}
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, @"adid", attribution.adid);
addValueOrEmpty(dictionary, @"costType", attribution.costType);
addValueOrEmpty(dictionary, @"costAmount", attribution.costAmount);
addValueOrEmpty(dictionary, @"costCurrency", attribution.costCurrency);
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];
char* attributionCStringCopy = strdup(attributionCString);
return attributionCStringCopy;
}
void _AdjustSendFirstPackages() {
[Adjust sendFirstPackages];
}
void _AdjustGdprForgetMe() {
[Adjust gdprForgetMe];
}
void _AdjustDisableThirdPartySharing() {
[Adjust disableThirdPartySharing];
}
void _AdjustAddSessionPartnerParameter(const char* key, const char* value) {
if (key != NULL && value != NULL) {
NSString *stringKey = [NSString stringWithUTF8String:key];
NSString *stringValue = [NSString stringWithUTF8String:value];
[Adjust addSessionPartnerParameter:stringKey value:stringValue];
}
}
void _AdjustAddSessionCallbackParameter(const char* key, const char* value) {
if (key != NULL && value != NULL) {
NSString *stringKey = [NSString stringWithUTF8String:key];
NSString *stringValue = [NSString stringWithUTF8String:value];
[Adjust addSessionCallbackParameter:stringKey value:stringValue];
}
}
void _AdjustRemoveSessionPartnerParameter(const char* key) {
if (key != NULL) {
NSString *stringKey = [NSString stringWithUTF8String:key];
[Adjust removeSessionPartnerParameter:stringKey];
}
}
void _AdjustRemoveSessionCallbackParameter(const char* key) {
if (key != NULL) {
NSString *stringKey = [NSString stringWithUTF8String:key];
[Adjust removeSessionCallbackParameter:stringKey];
}
}
void _AdjustResetSessionPartnerParameters() {
[Adjust resetSessionPartnerParameters];
}
void _AdjustResetSessionCallbackParameters() {
[Adjust resetSessionCallbackParameters];
}
void _AdjustTrackAdRevenue(const char* source, const char* payload) {
if (source != NULL && payload != NULL) {
NSString *stringSource = [NSString stringWithUTF8String:source];
NSString *stringPayload = [NSString stringWithUTF8String:payload];
NSData *dataPayload = [stringPayload dataUsingEncoding:NSUTF8StringEncoding];
[Adjust trackAdRevenue:stringSource payload:dataPayload];
}
}
void _AdjustTrackAdRevenueNew(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];
}
}
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];
}
void _AdjustTrackAppStoreSubscription(const char* price,
const char* currency,
const char* transactionId,
const char* receipt,
const char* billingStore,
const char* transactionDate,
const char* salesRegion,
const char* jsonCallbackParameters,
const char* jsonPartnerParameters) {
// Mandatory fields.
NSDecimalNumber *mPrice;
NSString *mCurrency;
NSString *mTransactionId;
NSData *mReceipt;
NSString *mBillingStore;
// 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];
}
// Receipt.
if (receipt != NULL) {
mReceipt = [[NSString stringWithUTF8String:receipt] dataUsingEncoding:NSUTF8StringEncoding];
}
// Billing store (not used ATM, maybe in the future).
if (billingStore != NULL) {
mBillingStore = [NSString stringWithUTF8String:billingStore];
}
ADJSubscription *subscription = [[ADJSubscription alloc] initWithPrice:mPrice
currency:mCurrency
transactionId:mTransactionId
andReceipt:mReceipt];
// Optional fields.
// 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 trackSubscription:subscription];
}
void _AdjustTrackThirdPartySharing(int enabled, const char* jsonGranularOptions, const char* jsonPartnerSharingSettings) {
NSNumber *nEnabled = enabled >= 0 ? [NSNumber numberWithInt:enabled] : nil;
ADJThirdPartySharing *adjustThirdPartySharing = [[ADJThirdPartySharing alloc] initWithIsEnabledNumberBool:nEnabled];
NSArray *arrayGranularOptions = convertArrayParameters(jsonGranularOptions);
if (arrayGranularOptions != nil) {
NSUInteger count = [arrayGranularOptions count];
for (int i = 0; i < count;) {
NSString *partnerName = arrayGranularOptions[i++];
NSString *granularOptions = arrayGranularOptions[i++];
// granularOptions is now NSString which pretty much contains array of partner key-value pairs
if (granularOptions != nil) {
NSData *dataJson = [granularOptions dataUsingEncoding:NSUTF8StringEncoding];
NSArray *partnerGranularOptions = [NSJSONSerialization JSONObjectWithData:dataJson options:0 error:nil];
if (partnerGranularOptions != nil) {
// in here we have partner and key-value pair for it
for (int j = 0; j < [partnerGranularOptions count];) {
[adjustThirdPartySharing addGranularOption:partnerName
key:partnerGranularOptions[j++]
value:partnerGranularOptions[j++]];
}
}
}
}
}
NSArray *arrayPartnerSharingSettings = convertArrayParameters(jsonPartnerSharingSettings);
if (arrayPartnerSharingSettings != nil) {
NSUInteger count = [arrayPartnerSharingSettings count];
for (int i = 0; i < count;) {
NSString *partnerName = arrayPartnerSharingSettings[i++];
NSString *sharingSettings = arrayPartnerSharingSettings[i++];
// sharingSettings is now NSString which pretty much contains array of partner key-value pairs
if (sharingSettings != nil) {
NSData *dataJson = [sharingSettings dataUsingEncoding:NSUTF8StringEncoding];
NSArray *partnerSharingSettings = [NSJSONSerialization JSONObjectWithData:dataJson options:0 error:nil];
if (partnerSharingSettings != nil) {
// in here we have partner and key-value pair for it
for (int j = 0; j < [partnerSharingSettings count];) {
[adjustThirdPartySharing addPartnerSharingSetting:partnerName
key:partnerSharingSettings[j++]
value:[partnerSharingSettings[j++] boolValue]];
}
}
}
}
}
[Adjust trackThirdPartySharing:adjustThirdPartySharing];
}
void _AdjustTrackMeasurementConsent(int enabled) {
BOOL bEnabled = (BOOL)enabled;
[Adjust trackMeasurementConsent:bEnabled];
}
void _AdjustRequestTrackingAuthorizationWithCompletionHandler(const char* sceneName) {
NSString *stringSceneName = isStringValid(sceneName) == true ? [NSString stringWithUTF8String:sceneName] : nil;
if (stringSceneName == nil) {
return;
}
[Adjust requestTrackingAuthorizationWithCompletionHandler:^(NSUInteger status) {
NSString *stringStatus = [NSString stringWithFormat:@"%tu", status];
const char* charStatus = [stringStatus UTF8String];
UnitySendMessage([stringSceneName UTF8String], "GetAuthorizationStatus", charStatus);
}];
}
void _AdjustUpdateConversionValue(int conversionValue) {
[Adjust updateConversionValue:conversionValue];
}
void _AdjustUpdateConversionValueWithCallback(int conversionValue, const char* sceneName) {
NSString *stringSceneName = isStringValid(sceneName) == true ? [NSString stringWithUTF8String:sceneName] : nil;
[Adjust updatePostbackConversionValue:conversionValue completionHandler:^(NSError * _Nullable error) {
if (stringSceneName == nil) {
return;
}
NSString *errorString = [error description];
const char* errorChar = [errorString UTF8String];
UnitySendMessage([stringSceneName UTF8String], "GetNativeSkadCompletionDelegate", errorChar);
}];
}
void _AdjustUpdateConversionValueWithCallbackSkad4(int conversionValue, const char* coarseValue, int lockWindow, const char* sceneName) {
NSString *stringSceneName = isStringValid(sceneName) == true ? [NSString stringWithUTF8String:sceneName] : nil;
if (coarseValue != NULL) {
NSString *stringCoarseValue = [NSString stringWithUTF8String:coarseValue];
BOOL bLockWindow = (BOOL)lockWindow;
[Adjust updatePostbackConversionValue:conversionValue
coarseValue:stringCoarseValue
lockWindow:bLockWindow
completionHandler:^(NSError * _Nullable error) {
if (stringSceneName == nil) {
return;
}
NSString *errorString = [error description];
const char* errorChar = [errorString UTF8String];
UnitySendMessage([stringSceneName UTF8String], "GetNativeSkad4CompletionDelegate", errorChar);
}];
}
}
void _AdjustCheckForNewAttStatus() {
[Adjust checkForNewAttStatus];
}
int _AdjustGetAppTrackingAuthorizationStatus() {
return [Adjust appTrackingAuthorizationStatus];
}
char* _AdjustGetLastDeeplink() {
NSURL *lastDeeplink = [Adjust lastDeeplink];
if (nil == lastDeeplink) {
return NULL;
}
NSString *lastDeeplinkString = [lastDeeplink absoluteString];
if (nil == lastDeeplinkString) {
return NULL;
}
const char* lastDeeplinkCString = [lastDeeplinkString UTF8String];
if (NULL == lastDeeplinkCString) {
return NULL;
}
char* lastDeeplinkCStringCopy = strdup(lastDeeplinkCString);
return lastDeeplinkCStringCopy;
}
void _AdjustVerifyAppStorePurchase(const char* transactionId,
const char* productId,
const char* receipt,
const char* sceneName) {
// Mandatory fields.
NSString *strTransactionId;
NSString *strProductId;
NSData *dataReceipt;
NSString *strSceneName;
// Transaction ID.
if (transactionId != NULL) {
strTransactionId = [NSString stringWithUTF8String:transactionId];
}
// Product ID.
if (productId != NULL) {
strProductId = [NSString stringWithUTF8String:productId];
}
// Receipt.
if (receipt != NULL) {
2024-04-16 05:30:31 +00:00
NSString *stringReceiptBase64 = [NSString stringWithUTF8String:receipt];
dataReceipt = [[NSData alloc] initWithBase64EncodedString:stringReceiptBase64 options:0];
2023-12-26 03:52:53 +00:00
}
// Scene name.
strSceneName = isStringValid(sceneName) == true ? [NSString stringWithUTF8String:sceneName] : nil;
// Verify the purchase.
ADJPurchase *purchase = [[ADJPurchase alloc] initWithTransactionId:strTransactionId
productId:strProductId
andReceipt:dataReceipt];
[Adjust verifyPurchase:purchase
completionHandler:^(ADJPurchaseVerificationResult * _Nonnull verificationResult) {
if (strSceneName == nil) {
return;
}
if (verificationResult == nil) {
return;
}
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];
UnitySendMessage([strSceneName UTF8String], "GetNativeVerificationInfo", verificationInfoCString);
}];
}
2024-04-16 05:30:31 +00:00
void _AdjustProcessDeeplink(const char* url, const char* sceneName) {
NSString *strSceneName = isStringValid(sceneName) == true ? [NSString stringWithUTF8String:sceneName] : nil;
if (url != NULL) {
NSString *stringUrl = [NSString stringWithUTF8String:url];
NSURL *nsUrl;
if ([NSString instancesRespondToSelector:@selector(stringByAddingPercentEncodingWithAllowedCharacters:)]) {
nsUrl = [NSURL URLWithString:[stringUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]];
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
nsUrl = [NSURL URLWithString:[stringUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
#pragma clang diagnostic pop
[Adjust processDeeplink:nsUrl completionHandler:^(NSString * _Nonnull resolvedLink) {
if (strSceneName == nil) {
return;
}
if (resolvedLink == nil) {
return;
}
const char* resolvedLinkCString = [resolvedLink UTF8String];
UnitySendMessage([strSceneName UTF8String], "GetNativeResolvedLink", resolvedLinkCString);
}];
}
}
void _AdjustSetTestOptions(const char* overwriteUrl,
2023-12-26 03:52:53 +00:00
const char* extraPath,
long timerIntervalInMilliseconds,
long timerStartInMilliseconds,
long sessionIntervalInMilliseconds,
long subsessionIntervalInMilliseconds,
int teardown,
int deleteState,
int noBackoffWait,
2024-04-16 05:30:31 +00:00
int adServicesFrameworkEnabled,
int attStatus,
const char *idfa) {
2023-12-26 03:52:53 +00:00
AdjustTestOptions *testOptions = [[AdjustTestOptions alloc] init];
2024-04-16 05:30:31 +00:00
NSString *stringOverwriteUrl = isStringValid(overwriteUrl) == true ? [NSString stringWithUTF8String:overwriteUrl] : nil;
if (stringOverwriteUrl != nil) {
[testOptions setUrlOverwrite:stringOverwriteUrl];
2023-12-26 03:52:53 +00:00
}
NSString *stringExtraPath = isStringValid(extraPath) == true ? [NSString stringWithUTF8String:extraPath] : nil;
if (stringExtraPath != nil && [stringExtraPath length] > 0) {
[testOptions setExtraPath:stringExtraPath];
}
2024-04-16 05:30:31 +00:00
NSString *stringIdfa = isStringValid(idfa) == true ? [NSString stringWithUTF8String:idfa] : nil;
if (stringIdfa != nil && [stringIdfa length] > 0) {
[testOptions setIdfa:stringIdfa];
}
2023-12-26 03:52:53 +00:00
testOptions.timerIntervalInMilliseconds = [NSNumber numberWithLong:timerIntervalInMilliseconds];
testOptions.timerStartInMilliseconds = [NSNumber numberWithLong:timerStartInMilliseconds];
testOptions.sessionIntervalInMilliseconds = [NSNumber numberWithLong:sessionIntervalInMilliseconds];
testOptions.subsessionIntervalInMilliseconds = [NSNumber numberWithLong:subsessionIntervalInMilliseconds];
2024-04-16 05:30:31 +00:00
testOptions.attStatusInt = [NSNumber numberWithInt:attStatus];
2023-12-26 03:52:53 +00:00
if (teardown != -1) {
[AdjustUnityDelegate teardown];
[testOptions setTeardown:(BOOL)teardown];
}
if (deleteState != -1) {
[testOptions setDeleteState:(BOOL)deleteState];
}
if (noBackoffWait != -1) {
[testOptions setNoBackoffWait:(BOOL)noBackoffWait];
}
if (adServicesFrameworkEnabled != -1) {
[testOptions setAdServicesFrameworkEnabled:(BOOL)adServicesFrameworkEnabled];
}
[Adjust setTestOptions:testOptions];
}
}