346 lines
16 KiB
Plaintext
346 lines
16 KiB
Plaintext
//
|
|
// AdjustUnityDelegate.mm
|
|
// Adjust SDK
|
|
//
|
|
// Created by Uglješa Erceg (@uerceg) on 5th December 2016.
|
|
// Copyright © 2012-2018 Adjust GmbH. All rights reserved.
|
|
//
|
|
|
|
#import <objc/runtime.h>
|
|
#import "AdjustUnityDelegate.h"
|
|
|
|
static dispatch_once_t onceToken;
|
|
static AdjustUnityDelegate *defaultInstance = nil;
|
|
|
|
@implementation AdjustUnityDelegate
|
|
|
|
#pragma mark - Object lifecycle methods
|
|
|
|
- (id)init {
|
|
self = [super init];
|
|
if (nil == self) {
|
|
return nil;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
#pragma mark - Public methods
|
|
|
|
+ (id)getInstanceWithAttributionCallback:(AdjustDelegateAttributionCallback)attributionCallback
|
|
eventSuccessCallback:(AdjustDelegateEventSuccessCallback)eventSuccessCallback
|
|
eventFailureCallback:(AdjustDelegateEventFailureCallback)eventFailureCallback
|
|
sessionSuccessCallback:(AdjustDelegateSessionSuccessCallback)sessionSuccessCallback
|
|
sessionFailureCallback:(AdjustDelegateSessionFailureCallback)sessionFailureCallback
|
|
deferredDeeplinkCallback:(AdjustDelegateDeferredDeeplinkCallback)deferredDeeplinkCallback
|
|
skanUpdatedCallback:(AdjustDelegateSkanUpdatedCallback)skanUpdatedCallback
|
|
shouldLaunchDeferredDeeplink:(BOOL)shouldLaunchDeferredDeeplink {
|
|
dispatch_once(&onceToken, ^{
|
|
defaultInstance = [[AdjustUnityDelegate alloc] init];
|
|
|
|
// Do the swizzling where and if needed.
|
|
if (attributionCallback != nil) {
|
|
[defaultInstance swizzleOriginalSelector:@selector(adjustAttributionChanged:)
|
|
withSelector:@selector(adjustAttributionChangedWannabe:)];
|
|
}
|
|
if (eventSuccessCallback != nil) {
|
|
[defaultInstance swizzleOriginalSelector:@selector(adjustEventTrackingSucceeded:)
|
|
withSelector:@selector(adjustEventTrackingSucceededWannabe:)];
|
|
}
|
|
if (eventFailureCallback != nil) {
|
|
[defaultInstance swizzleOriginalSelector:@selector(adjustEventTrackingFailed:)
|
|
withSelector:@selector(adjustEventTrackingFailedWannabe:)];
|
|
}
|
|
if (sessionSuccessCallback != nil) {
|
|
[defaultInstance swizzleOriginalSelector:@selector(adjustSessionTrackingSucceeded:)
|
|
withSelector:@selector(adjustSessionTrackingSucceededWannabe:)];
|
|
}
|
|
if (sessionFailureCallback != nil) {
|
|
[defaultInstance swizzleOriginalSelector:@selector(adjustSessionTrackingFailed:)
|
|
withSelector:@selector(adjustSessionTrackingFailedWannabe:)];
|
|
}
|
|
if (deferredDeeplinkCallback != nil) {
|
|
[defaultInstance swizzleOriginalSelector:@selector(adjustDeferredDeeplinkReceived:)
|
|
withSelector:@selector(adjustDeferredDeeplinkReceivedWannabe:)];
|
|
}
|
|
if (skanUpdatedCallback != nil) {
|
|
[defaultInstance swizzleOriginalSelector:@selector(adjustSkanUpdatedWithConversionData:)
|
|
withSelector:@selector(adjustSkanUpdatedWithConversionDataWannabe:)];
|
|
}
|
|
|
|
[defaultInstance setAttributionCallback:attributionCallback];
|
|
[defaultInstance setEventSuccessCallback:eventSuccessCallback];
|
|
[defaultInstance setEventFailureCallback:eventFailureCallback];
|
|
[defaultInstance setSessionSuccessCallback:sessionSuccessCallback];
|
|
[defaultInstance setSessionFailureCallback:sessionFailureCallback];
|
|
[defaultInstance setDeferredDeeplinkCallback:deferredDeeplinkCallback];
|
|
[defaultInstance setSkanUpdatedCallback:skanUpdatedCallback];
|
|
[defaultInstance setShouldLaunchDeferredDeeplink:shouldLaunchDeferredDeeplink];
|
|
});
|
|
|
|
return defaultInstance;
|
|
}
|
|
|
|
+ (void)teardown {
|
|
defaultInstance = nil;
|
|
onceToken = 0;
|
|
}
|
|
|
|
#pragma mark - Private & helper methods
|
|
|
|
- (void)adjustAttributionChangedWannabe:(ADJAttribution *)attribution {
|
|
if (attribution == nil || _attributionCallback == nil) {
|
|
return;
|
|
}
|
|
|
|
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
|
|
[self addValueOrEmpty:attribution.trackerToken
|
|
forKey:@"trackerToken"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:attribution.trackerName
|
|
forKey:@"trackerName"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:attribution.network
|
|
forKey:@"network"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:attribution.campaign
|
|
forKey:@"campaign"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:attribution.creative
|
|
forKey:@"creative"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:attribution.adgroup
|
|
forKey:@"adgroup"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:attribution.clickLabel
|
|
forKey:@"clickLabel"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:attribution.costType
|
|
forKey:@"costType"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:attribution.costAmount
|
|
forKey:@"costAmount"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:attribution.costCurrency
|
|
forKey:@"costCurrency"
|
|
toDictionary:dictionary];
|
|
|
|
if (attribution.jsonResponse != nil) {
|
|
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:attribution.jsonResponse
|
|
options:0
|
|
error:nil];
|
|
NSString *strJsonResponse = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
|
[self addValueOrEmpty:strJsonResponse
|
|
forKey:@"jsonResponse"
|
|
toDictionary:dictionary];
|
|
}
|
|
|
|
NSData *dataAttribution = [NSJSONSerialization dataWithJSONObject:dictionary
|
|
options:0
|
|
error:nil];
|
|
NSString *stringAttribution = [[NSString alloc] initWithBytes:[dataAttribution bytes]
|
|
length:[dataAttribution length]
|
|
encoding:NSUTF8StringEncoding];
|
|
const char* charArrayAttribution = [stringAttribution UTF8String];
|
|
_attributionCallback(charArrayAttribution);
|
|
}
|
|
|
|
- (void)adjustEventTrackingSucceededWannabe:(ADJEventSuccess *)eventSuccessResponseData {
|
|
if (nil == eventSuccessResponseData || _eventSuccessCallback == nil) {
|
|
return;
|
|
}
|
|
|
|
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
|
|
[self addValueOrEmpty:eventSuccessResponseData.message
|
|
forKey:@"message"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:eventSuccessResponseData.timestamp
|
|
forKey:@"timestamp"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:eventSuccessResponseData.adid
|
|
forKey:@"adid"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:eventSuccessResponseData.eventToken
|
|
forKey:@"eventToken"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:eventSuccessResponseData.callbackId
|
|
forKey:@"callbackId"
|
|
toDictionary:dictionary];
|
|
if (eventSuccessResponseData.jsonResponse != nil) {
|
|
[dictionary setObject:eventSuccessResponseData.jsonResponse
|
|
forKey:@"jsonResponse"];
|
|
}
|
|
|
|
NSData *dataEventSuccess = [NSJSONSerialization dataWithJSONObject:dictionary
|
|
options:0
|
|
error:nil];
|
|
NSString *stringEventSuccess = [[NSString alloc] initWithBytes:[dataEventSuccess bytes]
|
|
length:[dataEventSuccess length]
|
|
encoding:NSUTF8StringEncoding];
|
|
const char* charArrayEventSuccess = [stringEventSuccess UTF8String];
|
|
_eventSuccessCallback(charArrayEventSuccess);
|
|
}
|
|
|
|
- (void)adjustEventTrackingFailedWannabe:(ADJEventFailure *)eventFailureResponseData {
|
|
if (nil == eventFailureResponseData || _eventFailureCallback == nil) {
|
|
return;
|
|
}
|
|
|
|
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
|
|
[self addValueOrEmpty:eventFailureResponseData.message
|
|
forKey:@"message"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:eventFailureResponseData.timestamp
|
|
forKey:@"timestamp"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:eventFailureResponseData.adid
|
|
forKey:@"adid"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:eventFailureResponseData.eventToken
|
|
forKey:@"eventToken"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:eventFailureResponseData.callbackId
|
|
forKey:@"callbackId"
|
|
toDictionary:dictionary];
|
|
[dictionary setObject:(eventFailureResponseData.willRetry ? @"true" : @"false")
|
|
forKey:@"willRetry"];
|
|
if (eventFailureResponseData.jsonResponse != nil) {
|
|
[dictionary setObject:eventFailureResponseData.jsonResponse
|
|
forKey:@"jsonResponse"];
|
|
}
|
|
|
|
NSData *dataEventFailure = [NSJSONSerialization dataWithJSONObject:dictionary
|
|
options:0
|
|
error:nil];
|
|
NSString *stringEventFailure = [[NSString alloc] initWithBytes:[dataEventFailure bytes]
|
|
length:[dataEventFailure length]
|
|
encoding:NSUTF8StringEncoding];
|
|
const char* charArrayEventFailure = [stringEventFailure UTF8String];
|
|
_eventFailureCallback(charArrayEventFailure);
|
|
}
|
|
|
|
- (void)adjustSessionTrackingSucceededWannabe:(ADJSessionSuccess *)sessionSuccessResponseData {
|
|
if (nil == sessionSuccessResponseData || _sessionSuccessCallback == nil) {
|
|
return;
|
|
}
|
|
|
|
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
|
|
[self addValueOrEmpty:sessionSuccessResponseData.message
|
|
forKey:@"message"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:sessionSuccessResponseData.timestamp
|
|
forKey:@"timestamp"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:sessionSuccessResponseData.adid
|
|
forKey:@"adid"
|
|
toDictionary:dictionary];
|
|
if (sessionSuccessResponseData.jsonResponse != nil) {
|
|
[dictionary setObject:sessionSuccessResponseData.jsonResponse
|
|
forKey:@"jsonResponse"];
|
|
}
|
|
|
|
NSData *dataSessionSuccess = [NSJSONSerialization dataWithJSONObject:dictionary
|
|
options:0
|
|
error:nil];
|
|
NSString *stringSessionSuccess = [[NSString alloc] initWithBytes:[dataSessionSuccess bytes]
|
|
length:[dataSessionSuccess length]
|
|
encoding:NSUTF8StringEncoding];
|
|
const char* charArraySessionSuccess = [stringSessionSuccess UTF8String];
|
|
_sessionSuccessCallback(charArraySessionSuccess);
|
|
}
|
|
|
|
- (void)adjustSessionTrackingFailedWannabe:(ADJSessionFailure *)sessionFailureResponseData {
|
|
if (nil == sessionFailureResponseData || _sessionFailureCallback == nil) {
|
|
return;
|
|
}
|
|
|
|
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
|
|
[self addValueOrEmpty:sessionFailureResponseData.message
|
|
forKey:@"message"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:sessionFailureResponseData.timestamp
|
|
forKey:@"timestamp"
|
|
toDictionary:dictionary];
|
|
[self addValueOrEmpty:sessionFailureResponseData.adid
|
|
forKey:@"adid"
|
|
toDictionary:dictionary];
|
|
[dictionary setObject:(sessionFailureResponseData.willRetry ? @"true" : @"false")
|
|
forKey:@"willRetry"];
|
|
if (sessionFailureResponseData.jsonResponse != nil) {
|
|
[dictionary setObject:sessionFailureResponseData.jsonResponse
|
|
forKey:@"jsonResponse"];
|
|
}
|
|
|
|
NSData *dataSessionFailure = [NSJSONSerialization dataWithJSONObject:dictionary
|
|
options:0
|
|
error:nil];
|
|
NSString *stringSessionFailure = [[NSString alloc] initWithBytes:[dataSessionFailure bytes]
|
|
length:[dataSessionFailure length]
|
|
encoding:NSUTF8StringEncoding];
|
|
const char* charArraySessionFailure = [stringSessionFailure UTF8String];
|
|
_sessionFailureCallback(charArraySessionFailure);
|
|
}
|
|
|
|
- (BOOL)adjustDeferredDeeplinkReceivedWannabe:(NSURL *)deeplink {
|
|
if (_deferredDeeplinkCallback != nil) {
|
|
NSString *stringDeeplink = [deeplink absoluteString];
|
|
const char* charDeeplink = [stringDeeplink UTF8String];
|
|
_deferredDeeplinkCallback(charDeeplink);
|
|
}
|
|
return _shouldLaunchDeferredDeeplink;
|
|
}
|
|
|
|
- (void)adjustSkanUpdatedWithConversionDataWannabe:(NSDictionary<NSString *,NSString *> *)data {
|
|
if (data == nil || _skanUpdatedCallback == nil) {
|
|
return;
|
|
}
|
|
|
|
NSData *dataSkanUpdatedData = [NSJSONSerialization dataWithJSONObject:data
|
|
options:0
|
|
error:nil];
|
|
NSString *strSkanUpdatedData = [[NSString alloc] initWithBytes:[dataSkanUpdatedData bytes]
|
|
length:[dataSkanUpdatedData length]
|
|
encoding:NSUTF8StringEncoding];
|
|
const char* charSkanUpdatedData = [strSkanUpdatedData UTF8String];
|
|
_skanUpdatedCallback(charSkanUpdatedData);
|
|
}
|
|
|
|
- (void)swizzleOriginalSelector:(SEL)originalSelector
|
|
withSelector:(SEL)swizzledSelector {
|
|
Class className = [self class];
|
|
Method originalMethod = class_getInstanceMethod(className, originalSelector);
|
|
Method swizzledMethod = class_getInstanceMethod(className, swizzledSelector);
|
|
|
|
BOOL didAddMethod = class_addMethod(className,
|
|
originalSelector,
|
|
method_getImplementation(swizzledMethod),
|
|
method_getTypeEncoding(swizzledMethod));
|
|
if (didAddMethod) {
|
|
class_replaceMethod(className,
|
|
swizzledSelector,
|
|
method_getImplementation(originalMethod),
|
|
method_getTypeEncoding(originalMethod));
|
|
} else {
|
|
method_exchangeImplementations(originalMethod, swizzledMethod);
|
|
}
|
|
}
|
|
|
|
- (void)addValueOrEmpty:(NSObject *)value
|
|
forKey:(NSString *)key
|
|
toDictionary:(NSMutableDictionary *)dictionary {
|
|
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];
|
|
}
|
|
}
|
|
|
|
@end
|