bingo 项目提交
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8e38b03e8a02476990867b3533da7be
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44d3d607da645444caf451c0ef1b7027
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5666dcb6f872a48299f472e42ea2e4d9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 409380c074b194f2fb87ff280bc34046
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* The class is used in invocation when we want to pass any primitive values to a function with NSInvocation
|
||||
*
|
||||
* @discussion
|
||||
* The problem: NSInvocation category accepts arguments as NSArray that operates with id. We could have used NSValue for those purposes but
|
||||
* in this case we would loose the ability to operate with NSNumbers. NSNumber is subclass of NSValue and since NSInvocation uses typecast to a box
|
||||
* this creates the problem. For that reason NSPrimitivesBox provides the solution by expecting any primitives for a function been wrapped into it
|
||||
*
|
||||
*/
|
||||
@interface UASupportPrimitivesBox : NSValue
|
||||
+ (instancetype)newWithBytes: (nonnull const void *)bytes objCType: (nonnull const char *)type;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09a260cc498cc4d0f833b74d4ed69328
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
#import "UASupportPrimitivesBox.h"
|
||||
#import "UASupportTools.h"
|
||||
|
||||
@interface UASupportPrimitivesBox ()
|
||||
@property (nonatomic, strong) NSValue *box;
|
||||
@end
|
||||
|
||||
@implementation UASupportPrimitivesBox
|
||||
+ (instancetype)newWithBytes: (nonnull const void *)bytes objCType: (nonnull const char *)type {
|
||||
return [[self alloc] initWithBytes: bytes
|
||||
objCType: type];
|
||||
}
|
||||
|
||||
// Suppressing unnecessary warnings. Its expected behaviour when subclassing NSValue, according to the notes from apple docs
|
||||
// https://developer.apple.com/documentation/foundation/nsvalue?language=objc
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wobjc-designated-initializers"
|
||||
- (instancetype)initWithBytes: (const void *)value objCType: (const char *)type {
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wobjc-designated-initializers"
|
||||
SUPER_INIT
|
||||
#pragma GCC diagnostic push
|
||||
self.box = [NSValue valueWithBytes: value
|
||||
objCType: type];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)getValue: (void *)value {
|
||||
return [_box getValue: value];
|
||||
}
|
||||
|
||||
- (const char *)objCType {
|
||||
return [_box objCType];
|
||||
}
|
||||
|
||||
@end
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61b23861e38444442a4fbeb2ea469fe7
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*
|
||||
* Category that provides convenience static methods to create and perform invocations.
|
||||
*
|
||||
*/
|
||||
@interface NSInvocation (Category)
|
||||
|
||||
|
||||
/// Invokes a method on a Class or on an instance with a set of arguments
|
||||
/// @note If a target is nil, will try to perform static method on a class.
|
||||
/// @param methodName Full name of a selector
|
||||
/// @param classType Class
|
||||
/// @param target target of type Class
|
||||
/// @param arguments arguments required by the a function
|
||||
///
|
||||
/// @note When we need to pass an enum as an argument, use NSEnumWrapper
|
||||
/// @code NSEnumWrapper *typeWrapped = [NSEnumWrapper newWithBytes:&`EnumValue` objCType: @encode(EnumType)];
|
||||
+ (void)uads_invokeUsingMethod: (NSString *)methodName
|
||||
classType: (Class)classType
|
||||
target: (_Nullable id)target
|
||||
args: (NSArray *)arguments;
|
||||
|
||||
|
||||
/// Creates a prepared NSInvocation to perform a method of a Class or on an instance with a set of arguments
|
||||
/// @note If a target is nil, will try to perform static method on a class.
|
||||
/// @param methodName Full name of a selector
|
||||
/// @param classType Class
|
||||
/// @param target target of type Class
|
||||
/// @param arguments arguments required by the a function
|
||||
///
|
||||
/// @note When we need to pass an enum as an argument, use NSEnumWrapper
|
||||
/// @code NSEnumWrapper *typeWrapped = [NSEnumWrapper newWithBytes:&`EnumValue` objCType: @encode(EnumType)];
|
||||
+ (nullable instancetype)uads_newUsingMethod: (NSString *)methodName
|
||||
classType: (Class)classType
|
||||
target: (_Nullable id)target
|
||||
args: (NSArray *)arguments;
|
||||
|
||||
|
||||
/// Invokes a method on a Class or on an instance with a set of arguments. Returns a result of invoked function
|
||||
/// @note If a target is nil, will try to perform static method on a class.
|
||||
///
|
||||
/// @param methodName Full name of a selector
|
||||
/// @param classType Class
|
||||
/// @param target target of type Class
|
||||
/// @param arguments arguments required by the a function
|
||||
///
|
||||
/// @note When we need to pass an enum as an argument, use NSEnumWrapper
|
||||
/// @code NSEnumWrapper *typeWrapped = [NSEnumWrapper newWithBytes:&`EnumValue` objCType: @encode(EnumType)];
|
||||
+ (nullable id)uads_invokeWithReturnedUsingMethod: (NSString *)methodName
|
||||
classType: (Class)classType
|
||||
target: (_Nullable id)target
|
||||
args: (NSArray *)arguments;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee3d752a5dcf64f46a2c110958ba2126
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
#import "NSInvocation+Convenience.h"
|
||||
#import "UASupportPrimitivesBox.h"
|
||||
#import "UASupportTools.h"
|
||||
|
||||
@implementation NSInvocation (Category)
|
||||
|
||||
+ (void)uads_invokeUsingMethod: (NSString *)methodName
|
||||
classType: (Class)classType
|
||||
target: (_Nullable id)target
|
||||
args: (NSArray *)arguments {
|
||||
NSInvocation *invocation = [self uads_newUsingMethod: methodName
|
||||
classType: classType
|
||||
target: target
|
||||
args: arguments];
|
||||
|
||||
[invocation invoke];
|
||||
}
|
||||
|
||||
+ (nullable id)uads_invokeWithReturnedUsingMethod: (NSString *)methodName
|
||||
classType: (Class)classType
|
||||
target: (_Nullable id)target
|
||||
args: (NSArray *)arguments {
|
||||
__autoreleasing id returnedValue;
|
||||
NSInvocation *invocation = [self uads_newUsingMethod: methodName
|
||||
classType: classType
|
||||
target: target
|
||||
args: arguments];
|
||||
|
||||
[invocation invoke];
|
||||
[invocation getReturnValue: &returnedValue];
|
||||
return returnedValue;
|
||||
}
|
||||
|
||||
+ (nullable instancetype)uads_newUsingMethod: (NSString *)methodName
|
||||
classType: (Class)classType
|
||||
target: (_Nullable id)target
|
||||
args: (NSArray *)arguments {
|
||||
SEL selector = NSSelectorFromString(methodName);
|
||||
|
||||
GUARD_OR_NIL(selector)
|
||||
|
||||
__autoreleasing id targetArg;
|
||||
NSMethodSignature *signature;
|
||||
|
||||
if (!target) {
|
||||
targetArg = classType;
|
||||
signature = [classType methodSignatureForSelector: selector];
|
||||
} else {
|
||||
targetArg = target;
|
||||
signature = [classType instanceMethodSignatureForSelector: selector];
|
||||
}
|
||||
|
||||
GUARD_OR_NIL(signature)
|
||||
|
||||
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: signature];
|
||||
[invocation setSelector: selector];
|
||||
[invocation setTarget: targetArg];
|
||||
|
||||
for (int i = 0; i < [arguments count]; i++) {
|
||||
__autoreleasing id argument = arguments[i];
|
||||
|
||||
UASupportPrimitivesBox *value = uasupport_typecast(argument, [UASupportPrimitivesBox class]);
|
||||
|
||||
if (value) {
|
||||
void *pointerToPrimitives;
|
||||
[value getValue: &pointerToPrimitives];
|
||||
|
||||
/** from https://developer.apple.com/documentation/foundation/nsinvocation/1437834-setargument
|
||||
* An integer specifying the index of the argument.
|
||||
* Indices 0 and 1 indicate the hidden arguments self and _cmd, respectively; you should set these values directly with the target and selector properties. Use indices 2 and greater for the arguments normally passed in a message.
|
||||
*/
|
||||
|
||||
[invocation setArgument: &pointerToPrimitives
|
||||
atIndex: 2 + i];
|
||||
} else {
|
||||
[invocation setArgument: &argument
|
||||
atIndex: 2 + i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!invocation.argumentsRetained) {
|
||||
[invocation retainArguments];
|
||||
}
|
||||
|
||||
return invocation;
|
||||
} /* uads_newUsingMethod */
|
||||
|
||||
@end
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f62205c65beab4f23ae7993dfc41d6f4
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
Macro that replaces boilerplate code like:
|
||||
@code
|
||||
|
||||
if ([obj isKindOfClass: class]) {
|
||||
return obj;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
*/
|
||||
#define TYPECAST(obj, class) typecast(obj, class)
|
||||
|
||||
/**
|
||||
Macro that replaces boilerplate code when calling super init
|
||||
*/
|
||||
#define SUPER_INIT self = [super init]; if (!self) { return nil; }
|
||||
|
||||
|
||||
/**
|
||||
Convenience macro to check for condition and return nil if false
|
||||
*/
|
||||
#define GUARD_OR_NIL(condition) if (!condition) { return nil; }
|
||||
|
||||
|
||||
_Nullable id uasupport_typecast(id obj, Class class);
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5deb7e6ab2bc42ea9a88ef5e90d83d4
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
#import "UASupportTools.h"
|
||||
|
||||
|
||||
_Nullable id uasupport_typecast(id obj, Class class) {
|
||||
if ([obj isKindOfClass: class]) {
|
||||
return obj;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a87088279aff24786b336034505be994
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "SkAdNetworkManager.h"
|
||||
|
||||
extern void InterfaceSkAdNetworkUpdateConversionValue(NSInteger conversionValue) {
|
||||
[[SkAdNetworkManager sharedInstance] updateConversionValue:(NSInteger)conversionValue];
|
||||
}
|
||||
|
||||
extern void InterfaceSkAdNetworkRegisterAppForNetworkAttribution() {
|
||||
[[SkAdNetworkManager sharedInstance] registerAppForAdNetworkAttribution];
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42e354c20cf98414e8592511aefeb841
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,11 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface SkAdNetworkManager : NSObject
|
||||
|
||||
+ (SkAdNetworkManager *)sharedInstance;
|
||||
|
||||
- (BOOL)isAvailable;
|
||||
- (void)updateConversionValue:(NSInteger)conversionValue;
|
||||
- (void)registerAppForAdNetworkAttribution;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,27 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46c89ccf14bf540fbbfe2b3fc0adbc8e
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,105 @@
|
||||
#import "SkAdNetworkManager.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <dlfcn.h>
|
||||
#import <objc/runtime.h>
|
||||
#import <sys/utsname.h>
|
||||
#import "NSInvocation+Convenience.h"
|
||||
#import "UASupportPrimitivesBox.h"
|
||||
|
||||
@interface SkAdNetworkManager ()
|
||||
@property (strong, nonatomic) Class SkAdNetworkClass;
|
||||
@end
|
||||
|
||||
@implementation SkAdNetworkManager
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
if (![SkAdNetworkManager loadFramework]) {
|
||||
NSLog(@"Can't load StoreKit DLL");
|
||||
}
|
||||
self.SkAdNetworkClass = NSClassFromString(@"SKAdNetwork");
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (SkAdNetworkManager *)sharedInstance {
|
||||
static SkAdNetworkManager *instance = nil;
|
||||
static dispatch_once_t token;
|
||||
|
||||
dispatch_once(&token, ^{
|
||||
instance = [[SkAdNetworkManager alloc] init];
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
- (void)updateConversionValue:(NSInteger)conversionValue {
|
||||
if (!self.isAvailable) {
|
||||
NSLog(@"SkAdNetwork not available");
|
||||
return;
|
||||
}
|
||||
UASupportPrimitivesBox *index = [UASupportPrimitivesBox newWithBytes: &conversionValue objCType: @encode(NSInteger)];
|
||||
[NSInvocation uads_invokeUsingMethod: @"updateConversionValue:" classType: self.SkAdNetworkClass target: nil args: @[index] ];
|
||||
}
|
||||
|
||||
- (void)registerAppForAdNetworkAttribution {
|
||||
if (!self.isAvailable) {
|
||||
NSLog(@"SkAdNetwork not available");
|
||||
return;
|
||||
}
|
||||
|
||||
[NSInvocation uads_invokeUsingMethod: @"registerAppForAdNetworkAttribution" classType: self.SkAdNetworkClass target: nil args: @[] ];
|
||||
}
|
||||
|
||||
- (BOOL)isAvailable {
|
||||
return self.SkAdNetworkClass != nil;
|
||||
}
|
||||
|
||||
+ (BOOL)isFrameworkPresent {
|
||||
id attClass = objc_getClass("SKAdNetwork");
|
||||
|
||||
if (attClass)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ (BOOL)isDeviceSimulator {
|
||||
struct utsname systemInfo;
|
||||
uname(&systemInfo);
|
||||
|
||||
NSString *model = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
|
||||
if ([model isEqualToString:@"x86_64"] || [model isEqualToString:@"i386"])
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ (BOOL)loadFramework {
|
||||
NSString *frameworkLocation;
|
||||
|
||||
if (![SkAdNetworkManager isFrameworkPresent]) {
|
||||
NSLog(@"StoreKit.framework is not present, trying to load it.");
|
||||
if ([SkAdNetworkManager isDeviceSimulator]) {
|
||||
NSString *frameworkPath = [[NSProcessInfo processInfo] environment][@"DYLD_FALLBACK_FRAMEWORK_PATH"];
|
||||
if (frameworkPath) {
|
||||
frameworkLocation = [NSString pathWithComponents:@[ frameworkPath, @"StoreKit.framework", @"StoreKit" ]];
|
||||
}
|
||||
} else {
|
||||
frameworkLocation = [NSString stringWithFormat:@"/System/Library/Frameworks/StoreKit.framework/StoreKit"];
|
||||
}
|
||||
dlopen([frameworkLocation cStringUsingEncoding:NSUTF8StringEncoding], RTLD_LAZY);
|
||||
|
||||
if (![SkAdNetworkManager isFrameworkPresent]) {
|
||||
NSLog(@"StoreKit.framework still no present!");
|
||||
return FALSE;
|
||||
} else {
|
||||
NSLog(@"Successfully loaded StoreKit.framework");
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
NSLog(@"StoreKit.framework already present");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,37 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f3b9ec31803d4f0aa7c3b0a90910a42
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TrackingAuthorizationManager.h"
|
||||
|
||||
|
||||
extern void InterfaceTrackingAuthorizationRequest(TrackingAuthorizationCompletion completion) {
|
||||
[[TrackingAuthorizationManager sharedInstance] trackingAuthorizationRequest:completion];
|
||||
}
|
||||
|
||||
extern NSUInteger InterfaceGetTrackingAuthorizationStatus() {
|
||||
return [[TrackingAuthorizationManager sharedInstance] getTrackingAuthorizationStatus];
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7fd241e3b5fcd40709c2dc9f615a5eff
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef void (*TrackingAuthorizationCompletion)(NSUInteger status);
|
||||
|
||||
@interface TrackingAuthorizationManager : NSObject
|
||||
|
||||
+ (TrackingAuthorizationManager *)sharedInstance;
|
||||
|
||||
- (BOOL)isAvailable;
|
||||
- (void)trackingAuthorizationRequest:(TrackingAuthorizationCompletion)completion;
|
||||
- (NSUInteger)getTrackingAuthorizationStatus;
|
||||
|
||||
@end
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25d2f3238e3504e7f90b802740ce28b4
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
#import <AdSupport/AdSupport.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <dlfcn.h>
|
||||
#import <objc/runtime.h>
|
||||
#import <sys/utsname.h>
|
||||
|
||||
#import "TrackingAuthorizationManager.h"
|
||||
|
||||
@interface TrackingAuthorizationManager ()
|
||||
@property (strong, nonatomic) Class trackingManagerAuthorizationClass;
|
||||
@end
|
||||
|
||||
@implementation TrackingAuthorizationManager
|
||||
|
||||
+ (TrackingAuthorizationManager *)sharedInstance {
|
||||
static TrackingAuthorizationManager *instance = nil;
|
||||
static dispatch_once_t token;
|
||||
|
||||
dispatch_once(&token, ^{
|
||||
instance = [[TrackingAuthorizationManager alloc] init];
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
if (![TrackingAuthorizationManager loadFramework]) {
|
||||
NSLog(@"Can't load ATTrackingManager");
|
||||
}
|
||||
self.trackingManagerAuthorizationClass = NSClassFromString(@"ATTrackingManager");
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isAvailable {
|
||||
return self.trackingManagerAuthorizationClass != nil && [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSUserTrackingUsageDescription"] != nil;
|
||||
}
|
||||
|
||||
- (void)trackingAuthorizationRequest:(TrackingAuthorizationCompletion)completion {
|
||||
if (!self.isAvailable) {
|
||||
if (completion != nil) {
|
||||
completion(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
id handler = ^(NSUInteger result) {
|
||||
NSLog(@"Result request tracking authorization : %lu", (unsigned long)result);
|
||||
if (completion != nil) {
|
||||
completion(result);
|
||||
}
|
||||
};
|
||||
|
||||
SEL requestSelector = NSSelectorFromString(@"requestTrackingAuthorizationWithCompletionHandler:");
|
||||
if ([self.trackingManagerAuthorizationClass respondsToSelector:requestSelector]) {
|
||||
[self.trackingManagerAuthorizationClass performSelector:requestSelector withObject:handler];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)getTrackingAuthorizationStatus {
|
||||
if (!self.isAvailable)
|
||||
return 0;
|
||||
|
||||
NSUInteger value = [[self.trackingManagerAuthorizationClass valueForKey:@"trackingAuthorizationStatus"] unsignedIntegerValue];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
+ (BOOL)isFrameworkPresent {
|
||||
id attClass = objc_getClass("ATTrackingManager");
|
||||
|
||||
if (attClass)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ (BOOL)isDeviceSimulator {
|
||||
struct utsname systemInfo;
|
||||
uname(&systemInfo);
|
||||
|
||||
NSString *model = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
|
||||
if ([model isEqualToString:@"x86_64"] || [model isEqualToString:@"i386"])
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+ (BOOL)loadFramework {
|
||||
NSString *frameworkLocation;
|
||||
if (![TrackingAuthorizationManager isFrameworkPresent]) {
|
||||
NSLog(@"AppTrackingTransparency Framework is not present, trying to load it.");
|
||||
if ([TrackingAuthorizationManager isDeviceSimulator]) {
|
||||
NSString *frameworkPath = [[NSProcessInfo processInfo] environment]
|
||||
[@"DYLD_FALLBACK_FRAMEWORK_PATH"];
|
||||
if (frameworkPath) {
|
||||
frameworkLocation = [NSString pathWithComponents:@[ frameworkPath, @"AppTrackingTransparency.framework", @"AppTrackingTransparency" ]];
|
||||
}
|
||||
} else {
|
||||
frameworkLocation = [NSString stringWithFormat:@"/System/Library/Frameworks/AppTrackingTransparency.framework/AppTrackingTransparency"];
|
||||
}
|
||||
dlopen([frameworkLocation cStringUsingEncoding:NSUTF8StringEncoding], RTLD_LAZY);
|
||||
|
||||
if (![TrackingAuthorizationManager isFrameworkPresent]) {
|
||||
NSLog(@"AppTrackingTransparency still not present!");
|
||||
return FALSE;
|
||||
} else {
|
||||
NSLog(@"Successfully loaded AppTrackingTransparency framework");
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
NSLog(@"AppTrackingTransparency framework already present");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81160d7556a4c4e6bb1b9b8b9e08307f
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user