Created
August 3, 2023 21:09
-
-
Save guthyerrz/1a54dbdb3dd4b8189fb1898f156f7a89 to your computer and use it in GitHub Desktop.
Classes to circunvent the problem of SKAN V4 bein zerod out by the +[AAAttribution attributionTokenWithError:] method as presented by this article https://www.singular.net/blog/skan-4-cv-reset-bug/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// WLSConversionValueUtils.h | |
// Unity-iPhone | |
// | |
// Created by Guthyerrz Silva on 03/08/23. | |
// | |
#ifndef WLSSKAdNetworkCVUtils_h | |
#define WLSSKAdNetworkCVUtils_h | |
#import <StoreKit/SKAdNetwork.h> | |
typedef NS_ENUM(NSInteger, WLSSKANCoarseConversionValue) { | |
WLSSKANCoarseConversionValueLow = 0, | |
WLSSKANCoarseConversionValueMedium, | |
WLSSKANCoarseConversionValueHigh, | |
} ; | |
@interface WLSConversionValueUtils : NSObject | |
+ (void)sendUpdatedConversionValue:(NSInteger)conversionValue | |
coarseConversionValue:(WLSSKANCoarseConversionValue)coarseConversionValue | |
lockWindow:(BOOL)lockWindow | |
completionHandler:(void (^)(NSError *error))completionHandler; | |
@end | |
#endif /* WLSSKAdNetworkUtils_h */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// WLSConversionValueUtils.m | |
// Unity-iPhone | |
// | |
// Created by Guthyerrz Silva on 03/08/23. | |
// | |
#import <Foundation/Foundation.h> | |
#import "WLSConversionValueUtils.h" | |
#import <objc/runtime.h> | |
#import <StoreKit/SKAdNetwork.h> | |
#define CV_KEY @"WLSSKAdNetworkCVUtils_CV_KEY" | |
#define COARSE_CV_KEY @"WLSSKAdNetworkCVUtils_COARSE_CV_KEY" | |
#define LOCK_WINDOW_KEY @"WLSSKAdNetworkCVUtils_LOCK_WINDOW_KEY" | |
@implementation WLSConversionValueUtils | |
static NSInteger conversionValue = 0; | |
static WLSSKANCoarseConversionValue coarseCV = WLSSKANCoarseConversionValueLow; | |
static BOOL lockWindow = false; | |
+ (void)load { | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
[WLSConversionValueUtils loadVariables]; | |
Class originalClass = [SKAdNetwork class]; | |
Class newClass = [self class]; | |
SEL swizzledSelector = @selector(wlsUpdatePostbackConversionValue:coarseValue:lockWindow:completionHandler:); | |
SEL originalSelector = @selector(updatePostbackConversionValue:coarseValue:lockWindow:completionHandler:); | |
Method originalMethod = class_getClassMethod(originalClass, originalSelector); | |
Method swizzledMethod = class_getClassMethod(newClass, swizzledSelector); | |
method_exchangeImplementations(originalMethod,swizzledMethod); | |
swizzledSelector = @selector(wlsUpdatePostbackConversionValue:coarseValue:completionHandler:); | |
originalSelector = @selector(updatePostbackConversionValue:coarseValue:completionHandler:); | |
originalMethod = class_getClassMethod(originalClass, originalSelector); | |
swizzledMethod = class_getClassMethod(newClass, swizzledSelector); | |
method_exchangeImplementations(originalMethod,swizzledMethod); | |
swizzledSelector = @selector(wlsUpdatePostbackConversionValue:completionHandler:); | |
originalSelector = @selector(updatePostbackConversionValue:completionHandler:); | |
originalMethod = class_getClassMethod(originalClass, originalSelector); | |
swizzledMethod = class_getClassMethod(newClass, swizzledSelector); | |
method_exchangeImplementations(originalMethod,swizzledMethod); | |
swizzledSelector = @selector(wlsUpdateConversionValue:); | |
originalSelector = @selector(updateConversionValue:); | |
originalMethod = class_getClassMethod(originalClass, originalSelector); | |
swizzledMethod = class_getClassMethod(newClass, swizzledSelector); | |
method_exchangeImplementations(originalMethod,swizzledMethod); | |
}); | |
} | |
+(void)sendUpdatedConversionValue:(NSInteger)conversionValue | |
coarseConversionValue:(WLSSKANCoarseConversionValue)coarse | |
lockWindow:(BOOL)lockWindow | |
completionHandler:(void (^)(NSError *))completionHandler{ | |
[WLSConversionValueUtils saveConversionValue:conversionValue | |
coarseConversionValue:coarse | |
lockWindow:lockWindow]; | |
if (@available(iOS 16.1, *)) { | |
SKAdNetworkCoarseConversionValue coarseCV = [WLSConversionValueUtils mapToSKAdNetworkCoarseCV:coarse]; | |
[WLSConversionValueUtils wlsUpdatePostbackConversionValue:conversionValue | |
coarseValue:coarseCV | |
lockWindow:lockWindow | |
completionHandler:completionHandler]; | |
} else if(@available (iOS 15.4,*)) { | |
[WLSConversionValueUtils wlsUpdatePostbackConversionValue:conversionValue | |
completionHandler:completionHandler]; | |
} else if(@available (iOS 14.0,*)){ | |
[WLSConversionValueUtils wlsUpdateConversionValue:conversionValue]; | |
} | |
} | |
+ (void)wlsUpdatePostbackConversionValue:(NSInteger)fineValue coarseValue:(SKAdNetworkCoarseConversionValue)coarseValue lockWindow:(BOOL)lock completionHandler:(nullable void (^)(NSError *__nullable error))completion API_AVAILABLE(ios(16.1)){ | |
SKAdNetworkCoarseConversionValue coarse = [WLSConversionValueUtils mapToSKAdNetworkCoarseCV:coarseCV]; | |
[WLSConversionValueUtils wlsUpdatePostbackConversionValue:conversionValue coarseValue:coarse lockWindow:lockWindow completionHandler:completion]; | |
} | |
+ (void)wlsUpdatePostbackConversionValue:(NSInteger)fineValue completionHandler:(nullable void (^)(NSError *__nullable error))completion API_AVAILABLE(ios(15.4)){ | |
[WLSConversionValueUtils wlsUpdatePostbackConversionValue:conversionValue completionHandler:completion]; | |
} | |
+ (void)wlsUpdateConversionValue:(NSInteger)fineValue API_DEPRECATED("Use updatePostbackConversionValue:completionHandler: instead", ios(14.0, 15.4)){ | |
[WLSConversionValueUtils wlsUpdateConversionValue:conversionValue]; | |
} | |
+ (void)wlsUpdatePostbackConversionValue:(NSInteger)fineValue coarseValue:(SKAdNetworkCoarseConversionValue)coarseValue completionHandler:(nullable void (^)(NSError *__nullable error))completion API_AVAILABLE(ios(16.1)){ | |
SKAdNetworkCoarseConversionValue coarse = [WLSConversionValueUtils mapToSKAdNetworkCoarseCV:coarseCV]; | |
[WLSConversionValueUtils wlsUpdatePostbackConversionValue:conversionValue coarseValue:coarse completionHandler:completion]; | |
} | |
+(void) loadVariables{ | |
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; | |
conversionValue = [userDefaults integerForKey:CV_KEY]; | |
coarseCV = (WLSSKANCoarseConversionValue) [userDefaults integerForKey:COARSE_CV_KEY]; | |
lockWindow = [userDefaults boolForKey:LOCK_WINDOW_KEY]; | |
} | |
+(void)saveConversionValue:(NSInteger)fineValue | |
coarseConversionValue:(WLSSKANCoarseConversionValue)coarse | |
lockWindow:(BOOL)lk{ | |
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; | |
[userDefaults setInteger:fineValue forKey:CV_KEY]; | |
[userDefaults setInteger:coarse forKey:COARSE_CV_KEY]; | |
[userDefaults setBool:lk forKey:LOCK_WINDOW_KEY]; | |
conversionValue = fineValue; | |
coarseCV = coarse; | |
lockWindow = lk; | |
} | |
+ (SKAdNetworkCoarseConversionValue)mapToSKAdNetworkCoarseCV:(WLSSKANCoarseConversionValue)coarseConversionValue API_AVAILABLE(ios(16.0)){ | |
SKAdNetworkCoarseConversionValue coarseCV = SKAdNetworkCoarseConversionValueLow; | |
switch (coarseConversionValue) { | |
case WLSSKANCoarseConversionValueMedium: | |
coarseCV = SKAdNetworkCoarseConversionValueMedium; | |
break; | |
case WLSSKANCoarseConversionValueHigh: | |
coarseCV = SKAdNetworkCoarseConversionValueHigh; | |
break; | |
default: | |
//Use SKAdNetworkCoarseConversionValueLow (for WLSSKANCoarseConversionValueLow or any other value) | |
break; | |
} | |
return coarseCV; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment