271 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
			
		
		
	
	
			271 lines
		
	
	
		
			14 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)getInstanceWithSwizzleOfAttributionCallback:(BOOL)swizzleAttributionCallback
 | |
|                              eventSuccessCallback:(BOOL)swizzleEventSuccessCallback
 | |
|                              eventFailureCallback:(BOOL)swizzleEventFailureCallback
 | |
|                            sessionSuccessCallback:(BOOL)swizzleSessionSuccessCallback
 | |
|                            sessionFailureCallback:(BOOL)swizzleSessionFailureCallback
 | |
|                          deferredDeeplinkCallback:(BOOL)swizzleDeferredDeeplinkCallback
 | |
|                    conversionValueUpdatedCallback:(BOOL)swizzleConversionValueUpdatedCallback
 | |
|               skad4ConversionValueUpdatedCallback:(BOOL)swizzleSkad4ConversionValueUpdatedCallback
 | |
|                      shouldLaunchDeferredDeeplink:(BOOL)shouldLaunchDeferredDeeplink
 | |
|                          withAdjustUnitySceneName:(NSString *)adjustUnitySceneName {
 | |
|     dispatch_once(&onceToken, ^{
 | |
|         defaultInstance = [[AdjustUnityDelegate alloc] init];
 | |
| 
 | |
|         // Do the swizzling where and if needed.
 | |
|         if (swizzleAttributionCallback) {
 | |
|             [defaultInstance swizzleOriginalSelector:@selector(adjustAttributionChanged:)
 | |
|                                         withSelector:@selector(adjustAttributionChangedWannabe:)];
 | |
|         }
 | |
|         if (swizzleEventSuccessCallback) {
 | |
|             [defaultInstance swizzleOriginalSelector:@selector(adjustEventTrackingSucceeded:)
 | |
|                                         withSelector:@selector(adjustEventTrackingSucceededWannabe:)];
 | |
|         }
 | |
|         if (swizzleEventFailureCallback) {
 | |
|             [defaultInstance swizzleOriginalSelector:@selector(adjustEventTrackingFailed:)
 | |
|                                         withSelector:@selector(adjustEventTrackingFailedWannabe:)];
 | |
|         }
 | |
|         if (swizzleSessionSuccessCallback) {
 | |
|             [defaultInstance swizzleOriginalSelector:@selector(adjustSessionTrackingSucceeded:)
 | |
|                                         withSelector:@selector(adjustSessionTrackingSucceededWannabe:)];
 | |
|         }
 | |
|         if (swizzleSessionFailureCallback) {
 | |
|             [defaultInstance swizzleOriginalSelector:@selector(adjustSessionTrackingFailed:)
 | |
|                                         withSelector:@selector(adjustSessionTrackingFailedWannabe:)];
 | |
|         }
 | |
|         if (swizzleDeferredDeeplinkCallback) {
 | |
|             [defaultInstance swizzleOriginalSelector:@selector(adjustDeeplinkResponse:)
 | |
|                                         withSelector:@selector(adjustDeeplinkResponseWannabe:)];
 | |
|         }
 | |
|         if (swizzleConversionValueUpdatedCallback) {
 | |
|             [defaultInstance swizzleOriginalSelector:@selector(adjustConversionValueUpdated:)
 | |
|                                         withSelector:@selector(adjustConversionValueUpdatedWannabe:)];
 | |
|         }
 | |
|         if (swizzleSkad4ConversionValueUpdatedCallback) {
 | |
|             [defaultInstance swizzleOriginalSelector:@selector(adjustConversionValueUpdated:coarseValue:lockWindow:)
 | |
|                                         withSelector:@selector(adjustConversionValueUpdatedWannabe:coarseValue:lockWindow:)];
 | |
|         }
 | |
| 
 | |
|         [defaultInstance setShouldLaunchDeferredDeeplink:shouldLaunchDeferredDeeplink];
 | |
|         [defaultInstance setAdjustUnitySceneName:adjustUnitySceneName];
 | |
|     });
 | |
|     
 | |
|     return defaultInstance;
 | |
| }
 | |
| 
 | |
| + (void)teardown {
 | |
|     defaultInstance = nil;
 | |
|     onceToken = 0;
 | |
| }
 | |
| 
 | |
| #pragma mark - Private & helper methods
 | |
| 
 | |
| - (void)adjustAttributionChangedWannabe:(ADJAttribution *)attribution {
 | |
|     if (attribution == 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.adid forKey:@"adid" 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];
 | |
| 
 | |
|     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];
 | |
|     UnitySendMessage([self.adjustUnitySceneName UTF8String], "GetNativeAttribution", charArrayAttribution);
 | |
| }
 | |
| 
 | |
| - (void)adjustEventTrackingSucceededWannabe:(ADJEventSuccess *)eventSuccessResponseData {
 | |
|     if (nil == eventSuccessResponseData) {
 | |
|         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];
 | |
|     UnitySendMessage([self.adjustUnitySceneName UTF8String], "GetNativeEventSuccess", charArrayEventSuccess);
 | |
| }
 | |
| 
 | |
| - (void)adjustEventTrackingFailedWannabe:(ADJEventFailure *)eventFailureResponseData {
 | |
|     if (nil == eventFailureResponseData) {
 | |
|         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];
 | |
|     UnitySendMessage([self.adjustUnitySceneName UTF8String], "GetNativeEventFailure", charArrayEventFailure);
 | |
| }
 | |
| 
 | |
| - (void)adjustSessionTrackingSucceededWannabe:(ADJSessionSuccess *)sessionSuccessResponseData {
 | |
|     if (nil == sessionSuccessResponseData) {
 | |
|         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];
 | |
|     UnitySendMessage([self.adjustUnitySceneName UTF8String], "GetNativeSessionSuccess", charArraySessionSuccess);
 | |
| }
 | |
| 
 | |
| - (void)adjustSessionTrackingFailedWannabe:(ADJSessionFailure *)sessionFailureResponseData {
 | |
|     if (nil == sessionFailureResponseData) {
 | |
|         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];
 | |
|     UnitySendMessage([self.adjustUnitySceneName UTF8String], "GetNativeSessionFailure", charArraySessionFailure);
 | |
| }
 | |
| 
 | |
| - (BOOL)adjustDeeplinkResponseWannabe:(NSURL *)deeplink {
 | |
|     NSString *stringDeeplink = [deeplink absoluteString];
 | |
|     const char* charDeeplink = [stringDeeplink UTF8String];
 | |
|     UnitySendMessage([self.adjustUnitySceneName UTF8String], "GetNativeDeferredDeeplink", charDeeplink);
 | |
|     return _shouldLaunchDeferredDeeplink;
 | |
| }
 | |
| 
 | |
| - (void)adjustConversionValueUpdatedWannabe:(NSNumber *)conversionValue {
 | |
|     NSString *stringConversionValue = [conversionValue stringValue];
 | |
|     const char* charConversionValue = [stringConversionValue UTF8String];
 | |
|     UnitySendMessage([self.adjustUnitySceneName UTF8String], "GetNativeConversionValueUpdated", charConversionValue);
 | |
| }
 | |
| 
 | |
| - (void)adjustConversionValueUpdatedWannabe:(nullable NSNumber *)fineValue
 | |
|                                 coarseValue:(nullable NSString *)coarseValue
 | |
|                                  lockWindow:(nullable NSNumber *)lockWindow {
 | |
|     NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
 | |
|     [self addValueOrEmpty:fineValue forKey:@"fineValue" toDictionary:dictionary];
 | |
|     [self addValueOrEmpty:coarseValue forKey:@"coarseValue" toDictionary:dictionary];
 | |
|     [self addValueOrEmpty:lockWindow forKey:@"lockWindow" toDictionary:dictionary];
 | |
|     NSData *dataConversionValueUpdate = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil];
 | |
|     NSString *stringConversionValueUpdate = [[NSString alloc] initWithBytes:[dataConversionValueUpdate bytes]
 | |
|                                                                      length:[dataConversionValueUpdate length]
 | |
|                                                                    encoding:NSUTF8StringEncoding];
 | |
|     const char* charConversionValueUpdate = [stringConversionValueUpdate UTF8String];
 | |
|     UnitySendMessage([self.adjustUnitySceneName UTF8String], "GetNativeSkad4ConversionValueUpdated", charConversionValueUpdate);
 | |
| }
 | |
| 
 | |
| - (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
 |