增加一些游戏中的插件
This commit is contained in:
parent
8a91dab9db
commit
beedd5b8d7
@ -66,11 +66,11 @@ bool AppDelegate::applicationDidFinishLaunching()
|
||||
|
||||
se->start();
|
||||
se::AutoHandleScope hs;
|
||||
jsb_run_script("Data/js/jsb-adapter/jsb-builtin.js");
|
||||
jsb_run_script("Data/js/jcwallet.js");
|
||||
jsb_run_script("Data/js/platform.js");
|
||||
jsb_run_script("Data/js/main.js");
|
||||
jsb_run_script("Data/js/wallet.js");
|
||||
jsb_run_script("js/jsb-adapter/jsb-builtin.js");
|
||||
jsb_run_script("js/jcwallet.js");
|
||||
jsb_run_script("js/platform.js");
|
||||
jsb_run_script("js/main.js");
|
||||
jsb_run_script("js/wallet.js");
|
||||
se->addAfterCleanupHook([]() {
|
||||
JSBClassType::destroy();
|
||||
});
|
||||
|
135
Libraries/AppsFlyer/Plugins/iOS/AFUnityUtils.mm
Normal file
135
Libraries/AppsFlyer/Plugins/iOS/AFUnityUtils.mm
Normal file
@ -0,0 +1,135 @@
|
||||
//
|
||||
// AFUnityUtils.mm
|
||||
// Unity-iPhone
|
||||
//
|
||||
// Created by Jonathan Wesfield on 24/07/2019.
|
||||
//
|
||||
|
||||
#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)
|
||||
#import <AppsFlyerLib/AppsFlyerLib.h>
|
||||
#else
|
||||
#import "AppsFlyerLib.h"
|
||||
#endif
|
||||
|
||||
|
||||
static NSString* stringFromChar(const char *str) {
|
||||
return str ? [NSString stringWithUTF8String:str] : nil;
|
||||
}
|
||||
|
||||
static NSDictionary* dictionaryFromJson(const char *jsonString) {
|
||||
if(jsonString){
|
||||
NSData *jsonData = [[NSData alloc] initWithBytes:jsonString length:strlen(jsonString)];
|
||||
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:nil];
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
static const char* stringFromdictionary(NSDictionary* dictionary) {
|
||||
if(dictionary){
|
||||
NSError * err;
|
||||
NSData * jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&err];
|
||||
NSString * myString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
return [myString UTF8String];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
static NSArray<NSString*> *NSArrayFromCArray(int length, const char **arr) {
|
||||
NSMutableArray<NSString *> *res = [[NSMutableArray alloc] init];
|
||||
for(int i = 0; i < length; i++) {
|
||||
if (arr[i]) {
|
||||
[res addObject:[NSString stringWithUTF8String:arr[i]]];
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static char* getCString(const char* string){
|
||||
if (string == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* res = (char*)malloc(strlen(string) + 1);
|
||||
strcpy(res, string);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static AppsFlyerLinkGenerator* generatorFromDictionary(NSDictionary* dictionary, AppsFlyerLinkGenerator* generator) {
|
||||
|
||||
NSArray* generatorKeys = @[@"channel", @"customerID", @"campaign", @"referrerName", @"referrerImageUrl", @"deeplinkPath", @"baseDeeplink", @"brandDomain"];
|
||||
|
||||
NSMutableDictionary* mutableDictionary = [dictionary mutableCopy];
|
||||
|
||||
[generator setChannel:[dictionary objectForKey: @"channel"]];
|
||||
[generator setReferrerCustomerId:[dictionary objectForKey: @"customerID"]];
|
||||
[generator setCampaign:[dictionary objectForKey: @"campaign"]];
|
||||
[generator setReferrerName:[dictionary objectForKey: @"referrerName"]];
|
||||
[generator setReferrerImageURL:[dictionary objectForKey: @"referrerImageUrl"]];
|
||||
[generator setDeeplinkPath:[dictionary objectForKey: @"deeplinkPath"]];
|
||||
[generator setBaseDeeplink:[dictionary objectForKey: @"baseDeeplink"]];
|
||||
[generator setBrandDomain:[dictionary objectForKey: @"brandDomain"]];
|
||||
|
||||
|
||||
[mutableDictionary removeObjectsForKeys:generatorKeys];
|
||||
|
||||
[generator addParameters:mutableDictionary];
|
||||
|
||||
return generator;
|
||||
}
|
||||
|
||||
static EmailCryptType emailCryptTypeFromInt(int emailCryptTypeInt){
|
||||
|
||||
EmailCryptType emailCryptType;
|
||||
switch (emailCryptTypeInt){
|
||||
case 1:
|
||||
emailCryptType = EmailCryptTypeSHA256;
|
||||
break;
|
||||
default:
|
||||
emailCryptType = EmailCryptTypeNone;
|
||||
break;
|
||||
}
|
||||
|
||||
return emailCryptType;
|
||||
}
|
||||
|
||||
static NSString* stringFromDeepLinkResultStatus(AFSDKDeepLinkResultStatus deepLinkResult){
|
||||
NSString* result;
|
||||
switch (deepLinkResult){
|
||||
case AFSDKDeepLinkResultStatusFound:
|
||||
result = @"FOUND";
|
||||
break;
|
||||
case AFSDKDeepLinkResultStatusFailure:
|
||||
result = @"ERROR";
|
||||
break;
|
||||
case AFSDKDeepLinkResultStatusNotFound:
|
||||
result = @"NOT_FOUND";
|
||||
break;
|
||||
default:
|
||||
result = @"ERROR";
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static NSString* stringFromDeepLinkResultError(AppsFlyerDeepLinkResult *result){
|
||||
NSString* res;
|
||||
|
||||
if (result && result.error){
|
||||
if ([[result.error userInfo][NSUnderlyingErrorKey] code] == -1001) {
|
||||
res = @"TIMEOUT";
|
||||
} else if ([[result.error userInfo][NSUnderlyingErrorKey] code] == -1009) {
|
||||
res = @"NETWORK";
|
||||
}
|
||||
}
|
||||
|
||||
res = @"UNKNOWN";
|
||||
|
||||
return res;
|
||||
}
|
164
Libraries/AppsFlyer/Plugins/iOS/AppsFlyer+AppController.m
Normal file
164
Libraries/AppsFlyer/Plugins/iOS/AppsFlyer+AppController.m
Normal file
@ -0,0 +1,164 @@
|
||||
//
|
||||
// AppsFlyer+AppController.m
|
||||
// Unity-iPhone
|
||||
//
|
||||
// Created by Jonathan Wesfield on 24/07/2019.
|
||||
//
|
||||
|
||||
#import <objc/runtime.h>
|
||||
#import "UnityAppController.h"
|
||||
#import "AppsFlyeriOSWrapper.h"
|
||||
#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)
|
||||
#import <AppsFlyerLib/AppsFlyerLib.h>
|
||||
#else
|
||||
#import "AppsFlyerLib.h"
|
||||
#endif
|
||||
|
||||
|
||||
@implementation UnityAppController (AppsFlyerSwizzledAppController)
|
||||
|
||||
static BOOL didEnteredBackGround __unused;
|
||||
static IMP __original_applicationDidBecomeActive_Imp __unused;
|
||||
static IMP __original_applicationDidEnterBackground_Imp __unused;
|
||||
static IMP __original_didReceiveRemoteNotification_Imp __unused;
|
||||
static IMP __original_continueUserActivity_Imp __unused;
|
||||
static IMP __original_openUrl_Imp __unused;
|
||||
|
||||
|
||||
+ (void)load {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
|
||||
#if !AFSDK_SHOULD_SWIZZLE
|
||||
|
||||
id swizzleFlag = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppsFlyerShouldSwizzle"];
|
||||
BOOL shouldSwizzle = swizzleFlag ? [swizzleFlag boolValue] : NO;
|
||||
|
||||
if(shouldSwizzle){
|
||||
|
||||
Method method1 = class_getInstanceMethod([self class], @selector(applicationDidBecomeActive:));
|
||||
__original_applicationDidBecomeActive_Imp = method_setImplementation(method1, (IMP)__swizzled_applicationDidBecomeActive);
|
||||
|
||||
Method method2 = class_getInstanceMethod([self class], @selector(applicationDidEnterBackground:));
|
||||
__original_applicationDidEnterBackground_Imp = method_setImplementation(method2, (IMP)__swizzled_applicationDidEnterBackground);
|
||||
|
||||
|
||||
Method method3 = class_getInstanceMethod([self class], @selector(didReceiveRemoteNotification:));
|
||||
__original_didReceiveRemoteNotification_Imp = method_setImplementation(method3, (IMP)__swizzled_didReceiveRemoteNotification);
|
||||
|
||||
|
||||
Method method4 = class_getInstanceMethod([self class], @selector(application:openURL:options:));
|
||||
__original_openUrl_Imp = method_setImplementation(method4, (IMP)__swizzled_openURL);
|
||||
|
||||
if (_AppsFlyerdelegate == nil) {
|
||||
_AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];
|
||||
}
|
||||
|
||||
[self swizzleContinueUserActivity:[self class]];
|
||||
}
|
||||
#elif AFSDK_SHOULD_SWIZZLE
|
||||
Method method1 = class_getInstanceMethod([self class], @selector(applicationDidBecomeActive:));
|
||||
__original_applicationDidBecomeActive_Imp = method_setImplementation(method1, (IMP)__swizzled_applicationDidBecomeActive);
|
||||
|
||||
Method method2 = class_getInstanceMethod([self class], @selector(applicationDidEnterBackground:));
|
||||
__original_applicationDidEnterBackground_Imp = method_setImplementation(method2, (IMP)__swizzled_applicationDidEnterBackground);
|
||||
|
||||
|
||||
Method method3 = class_getInstanceMethod([self class], @selector(didReceiveRemoteNotification:));
|
||||
__original_didReceiveRemoteNotification_Imp = method_setImplementation(method3, (IMP)__swizzled_didReceiveRemoteNotification);
|
||||
|
||||
|
||||
Method method4 = class_getInstanceMethod([self class], @selector(application:openURL:options:));
|
||||
__original_openUrl_Imp = method_setImplementation(method4, (IMP)__swizzled_openURL);
|
||||
|
||||
if (_AppsFlyerdelegate == nil) {
|
||||
_AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];
|
||||
}
|
||||
|
||||
[self swizzleContinueUserActivity:[self class]];
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
+(void)swizzleContinueUserActivity:(Class)class {
|
||||
|
||||
SEL originalSelector = @selector(application:continueUserActivity:restorationHandler:);
|
||||
|
||||
Method defaultMethod = class_getInstanceMethod(class, originalSelector);
|
||||
Method swizzledMethod = class_getInstanceMethod(class, @selector(__swizzled_continueUserActivity));
|
||||
|
||||
BOOL isMethodExists = !class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
|
||||
|
||||
if (isMethodExists) {
|
||||
__original_continueUserActivity_Imp = method_setImplementation(defaultMethod, (IMP)__swizzled_continueUserActivity);
|
||||
} else {
|
||||
class_replaceMethod(class, originalSelector, (IMP)__swizzled_continueUserActivity, method_getTypeEncoding(swizzledMethod));
|
||||
}
|
||||
}
|
||||
|
||||
BOOL __swizzled_continueUserActivity(id self, SEL _cmd, UIApplication* application, NSUserActivity* userActivity, void (^restorationHandler)(NSArray*)) {
|
||||
NSLog(@"swizzled continueUserActivity");
|
||||
[[AppsFlyerAttribution shared] continueUserActivity:userActivity restorationHandler:restorationHandler];
|
||||
|
||||
if(__original_continueUserActivity_Imp){
|
||||
return ((BOOL(*)(id, SEL, UIApplication*, NSUserActivity*, void (^)(NSArray*)))__original_continueUserActivity_Imp)(self, _cmd, application, userActivity, NULL);
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void __swizzled_applicationDidBecomeActive(id self, SEL _cmd, UIApplication* launchOptions) {
|
||||
NSLog(@"swizzled applicationDidBecomeActive");
|
||||
[[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];
|
||||
|
||||
if(didEnteredBackGround && AppsFlyeriOSWarpper.didCallStart == YES){
|
||||
[[AppsFlyerLib shared] start];
|
||||
}
|
||||
|
||||
if(__original_applicationDidBecomeActive_Imp){
|
||||
((void(*)(id,SEL, UIApplication*))__original_applicationDidBecomeActive_Imp)(self, _cmd, launchOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __swizzled_applicationDidEnterBackground(id self, SEL _cmd, UIApplication* application) {
|
||||
NSLog(@"swizzled applicationDidEnterBackground");
|
||||
didEnteredBackGround = YES;
|
||||
if(__original_applicationDidEnterBackground_Imp){
|
||||
((void(*)(id,SEL, UIApplication*))__original_applicationDidEnterBackground_Imp)(self, _cmd, application);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL __swizzled_didReceiveRemoteNotification(id self, SEL _cmd, UIApplication* application, NSDictionary* userInfo,void (^UIBackgroundFetchResult)(void) ) {
|
||||
NSLog(@"swizzled didReceiveRemoteNotification");
|
||||
|
||||
[[AppsFlyerLib shared] handlePushNotification:userInfo];
|
||||
|
||||
if(__original_didReceiveRemoteNotification_Imp){
|
||||
return ((BOOL(*)(id, SEL, UIApplication*, NSDictionary*, (UIBackgroundFetchResult)))__original_didReceiveRemoteNotification_Imp)(self, _cmd, application, userInfo, nil);
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL __swizzled_openURL(id self, SEL _cmd, UIApplication* application, NSURL* url, NSDictionary * options) {
|
||||
NSLog(@"swizzled openURL");
|
||||
[[AppsFlyerAttribution shared] handleOpenUrl:url options:options];
|
||||
if(__original_openUrl_Imp){
|
||||
return ((BOOL(*)(id, SEL, UIApplication*, NSURL*, NSDictionary*))__original_openUrl_Imp)(self, _cmd, application, url, options);
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
131
Libraries/AppsFlyer/Plugins/iOS/AppsFlyerAppController.mm
Normal file
131
Libraries/AppsFlyer/Plugins/iOS/AppsFlyerAppController.mm
Normal file
@ -0,0 +1,131 @@
|
||||
//
|
||||
// AppsFlyerAppController.mm
|
||||
// Unity-iPhone
|
||||
//
|
||||
// Created by Jonathan Wesfield on 30/07/2019.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "UnityAppController.h"
|
||||
#import "AppDelegateListener.h"
|
||||
#import "AppsFlyeriOSWrapper.h"
|
||||
#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)
|
||||
#import <AppsFlyerLib/AppsFlyerLib.h>
|
||||
#else
|
||||
#import "AppsFlyerLib.h"
|
||||
#endif
|
||||
#import <objc/message.h>
|
||||
|
||||
/**
|
||||
Note if you would like to use method swizzeling see AppsFlyer+AppController.m
|
||||
If you are using swizzeling then comment out the method that is being swizzeled in AppsFlyerAppController.mm
|
||||
Only use swizzeling if there are conflicts with other plugins that needs to be resolved.
|
||||
*/
|
||||
|
||||
|
||||
@interface AppsFlyerAppController : UnityAppController <AppDelegateListener>
|
||||
{
|
||||
BOOL didEnteredBackGround;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation AppsFlyerAppController
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
|
||||
id swizzleFlag = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppsFlyerShouldSwizzle"];
|
||||
BOOL shouldSwizzle = swizzleFlag ? [swizzleFlag boolValue] : NO;
|
||||
|
||||
if(!shouldSwizzle){
|
||||
UnityRegisterAppDelegateListener(self);
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)didFinishLaunching:(NSNotification*)notification {
|
||||
NSLog(@"got didFinishLaunching = %@",notification.userInfo);
|
||||
|
||||
|
||||
if (_AppsFlyerdelegate == nil) {
|
||||
_AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];
|
||||
}
|
||||
[[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];
|
||||
|
||||
if (notification.userInfo[@"url"]) {
|
||||
[self onOpenURL:notification];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)didBecomeActive:(NSNotification*)notification {
|
||||
NSLog(@"got didBecomeActive(out) = %@", notification.userInfo);
|
||||
if (didEnteredBackGround == YES && AppsFlyeriOSWarpper.didCallStart == YES) {
|
||||
[[AppsFlyerLib shared] start];
|
||||
didEnteredBackGround = NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didEnterBackground:(NSNotification*)notification {
|
||||
NSLog(@"got didEnterBackground = %@", notification.userInfo);
|
||||
didEnteredBackGround = YES;
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler {
|
||||
[[AppsFlyerAttribution shared] continueUserActivity:userActivity restorationHandler:restorationHandler];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (void)onOpenURL:(NSNotification*)notification {
|
||||
NSLog(@"got onOpenURL = %@", notification.userInfo);
|
||||
NSURL *url = notification.userInfo[@"url"];
|
||||
NSString *sourceApplication = notification.userInfo[@"sourceApplication"];
|
||||
|
||||
if (sourceApplication == nil) {
|
||||
sourceApplication = @"";
|
||||
}
|
||||
|
||||
if (url != nil) {
|
||||
[[AppsFlyerAttribution shared] handleOpenUrl:url sourceApplication:sourceApplication annotation:nil];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void)didReceiveRemoteNotification:(NSNotification*)notification {
|
||||
NSLog(@"got didReceiveRemoteNotification = %@", notification.userInfo);
|
||||
[[AppsFlyerLib shared] handlePushNotification:notification.userInfo];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#if !(AFSDK_SHOULD_SWIZZLE)
|
||||
|
||||
IMPL_APP_CONTROLLER_SUBCLASS(AppsFlyerAppController)
|
||||
|
||||
#endif
|
||||
/**
|
||||
Note if you would not like to use IMPL_APP_CONTROLLER_SUBCLASS you can replace it with the code below.
|
||||
<code>
|
||||
+(void)load
|
||||
{
|
||||
[AppsFlyerAppController plugin];
|
||||
}
|
||||
|
||||
// Singleton accessor.
|
||||
+ (AppsFlyerAppController *)plugin
|
||||
{
|
||||
static AppsFlyerAppController *sharedInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
|
||||
dispatch_once(&onceToken, ^{
|
||||
|
||||
sharedInstance = [[AppsFlyerAppController alloc] init];
|
||||
});
|
||||
|
||||
return sharedInstance;
|
||||
}
|
||||
</code>
|
||||
**/
|
34
Libraries/AppsFlyer/Plugins/iOS/AppsFlyerAttribution.h
Normal file
34
Libraries/AppsFlyer/Plugins/iOS/AppsFlyerAttribution.h
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// AppsFlyerAttribution.h
|
||||
// UnityFramework
|
||||
//
|
||||
// Created by Margot Guetta on 11/04/2021.
|
||||
//
|
||||
|
||||
#ifndef AppsFlyerAttribution_h
|
||||
#define AppsFlyerAttribution_h
|
||||
#endif /* AppsFlyerAttribution_h */
|
||||
#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)
|
||||
#import <AppsFlyerLib/AppsFlyerLib.h>
|
||||
#else
|
||||
#import "AppsFlyerLib.h"
|
||||
#endif
|
||||
|
||||
|
||||
@interface AppsFlyerAttribution : NSObject
|
||||
@property NSUserActivity*_Nullable userActivity;
|
||||
@property (nonatomic, copy) void (^ _Nullable restorationHandler)(NSArray *_Nullable );
|
||||
@property NSURL * _Nullable url;
|
||||
@property NSDictionary * _Nullable options;
|
||||
@property NSString* _Nullable sourceApplication;
|
||||
@property id _Nullable annotation;
|
||||
@property BOOL isBridgeReady;
|
||||
|
||||
+ (AppsFlyerAttribution *_Nullable)shared;
|
||||
- (void) continueUserActivity: (NSUserActivity*_Nullable) userActivity restorationHandler: (void (^_Nullable)(NSArray * _Nullable))restorationHandler;
|
||||
- (void) handleOpenUrl:(NSURL*_Nullable)url options:(NSDictionary*_Nullable) options;
|
||||
- (void) handleOpenUrl: (NSURL *_Nonnull)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation;
|
||||
|
||||
@end
|
||||
|
||||
static NSString * _Nullable const AF_BRIDGE_SET = @"bridge is set";
|
86
Libraries/AppsFlyer/Plugins/iOS/AppsFlyerAttribution.m
Normal file
86
Libraries/AppsFlyer/Plugins/iOS/AppsFlyerAttribution.m
Normal file
@ -0,0 +1,86 @@
|
||||
//
|
||||
// NSObject+AppsFlyerAttribution.m
|
||||
// UnityFramework
|
||||
//
|
||||
// Created by Margot Guetta on 11/04/2021.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "AppsFlyerAttribution.h"
|
||||
|
||||
@implementation AppsFlyerAttribution
|
||||
|
||||
+ (id)shared {
|
||||
static AppsFlyerAttribution *shared = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
shared = [[self alloc] init];
|
||||
});
|
||||
return shared;
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
if (self = [super init]) {
|
||||
self.options = nil;
|
||||
self.restorationHandler = nil;
|
||||
self.url = nil;
|
||||
self.userActivity = nil;
|
||||
self.annotation = nil;
|
||||
self.sourceApplication = nil;
|
||||
self.isBridgeReady = NO;
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(receiveBridgeReadyNotification:)
|
||||
name:AF_BRIDGE_SET
|
||||
object:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) continueUserActivity: (NSUserActivity*_Nullable) userActivity restorationHandler: (void (^_Nullable)(NSArray * _Nullable))restorationHandler{
|
||||
if(self.isBridgeReady == YES){
|
||||
[[AppsFlyerLib shared] continueUserActivity:userActivity restorationHandler:restorationHandler];
|
||||
}else{
|
||||
[AppsFlyerAttribution shared].userActivity = userActivity;
|
||||
[AppsFlyerAttribution shared].restorationHandler = restorationHandler;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) handleOpenUrl:(NSURL *)url options:(NSDictionary *)options{
|
||||
if(self.isBridgeReady == YES){
|
||||
[[AppsFlyerLib shared] handleOpenUrl:url options:options];
|
||||
}else{
|
||||
[AppsFlyerAttribution shared].url = url;
|
||||
[AppsFlyerAttribution shared].options = options;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) handleOpenUrl:(NSURL *)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation{
|
||||
if(self.isBridgeReady == YES){
|
||||
[[AppsFlyerLib shared] handleOpenURL:url sourceApplication:sourceApplication withAnnotation:annotation];
|
||||
}else{
|
||||
[AppsFlyerAttribution shared].url = url;
|
||||
[AppsFlyerAttribution shared].sourceApplication = sourceApplication;
|
||||
[AppsFlyerAttribution shared].annotation = annotation;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (void) receiveBridgeReadyNotification:(NSNotification *) notification
|
||||
{
|
||||
NSLog (@"AppsFlyer Debug: handle deep link");
|
||||
if(self.url && self.sourceApplication){
|
||||
[[AppsFlyerLib shared] handleOpenURL:self.url sourceApplication:self.sourceApplication withAnnotation:self.annotation];
|
||||
self.url = nil;
|
||||
self.sourceApplication = nil;
|
||||
self.annotation = nil;
|
||||
}else if(self.options && self.url){
|
||||
[[AppsFlyerLib shared] handleOpenUrl:self.url options:self.options];
|
||||
self.options = nil;
|
||||
self.url = nil;
|
||||
}else if(self.userActivity){
|
||||
[[AppsFlyerLib shared] continueUserActivity:self.userActivity restorationHandler:nil];
|
||||
self.userActivity = nil;
|
||||
self.restorationHandler = nil;
|
||||
}
|
||||
}
|
||||
@end
|
47
Libraries/AppsFlyer/Plugins/iOS/AppsFlyeriOSWrapper.h
Normal file
47
Libraries/AppsFlyer/Plugins/iOS/AppsFlyeriOSWrapper.h
Normal file
@ -0,0 +1,47 @@
|
||||
//
|
||||
// AppsFlyeriOSWarpper.h
|
||||
// Unity-iPhone
|
||||
//
|
||||
// Created by Jonathan Wesfield on 24/07/2019.
|
||||
//
|
||||
|
||||
#import "AFUnityUtils.mm"
|
||||
#import "UnityAppController.h"
|
||||
#import "AppsFlyerAttribution.h"
|
||||
#if __has_include(<AppsFlyerLib/AppsFlyerLib.h>)
|
||||
#import <AppsFlyerLib/AppsFlyerLib.h>
|
||||
#else
|
||||
#import "AppsFlyerLib.h"
|
||||
#endif
|
||||
|
||||
@interface AppsFlyeriOSWarpper : NSObject <AppsFlyerLibDelegate, AppsFlyerDeepLinkDelegate>
|
||||
+ (BOOL) didCallStart;
|
||||
+ (void) setDidCallStart:(BOOL)val;
|
||||
@end
|
||||
|
||||
|
||||
static AppsFlyeriOSWarpper *_AppsFlyerdelegate;
|
||||
static const int kPushNotificationSize = 32;
|
||||
|
||||
static NSString* ConversionDataCallbackObject = @"AppsFlyerObject";
|
||||
|
||||
static const char* VALIDATE_CALLBACK = "didFinishValidateReceipt";
|
||||
static const char* VALIDATE_ERROR_CALLBACK = "didFinishValidateReceiptWithError";
|
||||
static const char* GCD_CALLBACK = "onConversionDataSuccess";
|
||||
static const char* GCD_ERROR_CALLBACK = "onConversionDataFail";
|
||||
static const char* OAOA_CALLBACK = "onAppOpenAttribution";
|
||||
static const char* OAOA_ERROR_CALLBACK = "onAppOpenAttributionFailure";
|
||||
static const char* GENERATE_LINK_CALLBACK = "onInviteLinkGenerated";
|
||||
static const char* OPEN_STORE_LINK_CALLBACK = "onOpenStoreLinkGenerated";
|
||||
static const char* START_REQUEST_CALLBACK = "requestResponseReceived";
|
||||
static const char* IN_APP_RESPONSE_CALLBACK = "inAppResponseReceived";
|
||||
static const char* ON_DEEPLINKING = "onDeepLinking";
|
||||
|
||||
|
||||
static NSString* validateObjectName = @"";
|
||||
static NSString* openStoreObjectName = @"";
|
||||
static NSString* generateInviteObjectName = @"";
|
||||
static NSString* startRequestObjectName = @"";
|
||||
static NSString* inAppRequestObjectName = @"";
|
||||
static NSString* onDeeplinkingObjectName = @"";
|
||||
|
325
Libraries/AppsFlyer/Plugins/iOS/AppsFlyeriOSWrapper.mm
Normal file
325
Libraries/AppsFlyer/Plugins/iOS/AppsFlyeriOSWrapper.mm
Normal file
@ -0,0 +1,325 @@
|
||||
//
|
||||
// AppsFlyeriOSWarpper.mm
|
||||
// Unity-iPhone
|
||||
//
|
||||
// Created by Jonathan Wesfield on 24/07/2019.
|
||||
//
|
||||
|
||||
#import "AppsFlyeriOSWrapper.h"
|
||||
|
||||
|
||||
static void unityCallBack(NSString* objectName, const char* method, const char* msg) {
|
||||
if(objectName){
|
||||
UnitySendMessage([objectName UTF8String], method, msg);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
const void _startSDK(bool shouldCallback, const char* objectName) {
|
||||
startRequestObjectName = stringFromChar(objectName);
|
||||
AppsFlyeriOSWarpper.didCallStart = YES;
|
||||
[AppsFlyerAttribution shared].isBridgeReady = YES;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:AF_BRIDGE_SET object: [AppsFlyerAttribution shared]];
|
||||
[[AppsFlyerLib shared] startWithCompletionHandler:^(NSDictionary<NSString *,id> *dictionary, NSError *error) {
|
||||
if(shouldCallback){
|
||||
if (error) {
|
||||
NSDictionary *callbackDictionary = @{@"statusCode":[NSNumber numberWithLong:[error code]]};
|
||||
unityCallBack(startRequestObjectName, START_REQUEST_CALLBACK, stringFromdictionary(callbackDictionary));
|
||||
return;
|
||||
}
|
||||
if (dictionary) {
|
||||
unityCallBack(startRequestObjectName, START_REQUEST_CALLBACK, stringFromdictionary(dictionary));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
const void _setCustomerUserID (const char* customerUserID) {
|
||||
[[AppsFlyerLib shared] setCustomerUserID:stringFromChar(customerUserID)];
|
||||
}
|
||||
|
||||
const void _setAdditionalData (const char* customData) {
|
||||
[[AppsFlyerLib shared] setAdditionalData:dictionaryFromJson(customData)];
|
||||
}
|
||||
|
||||
const void _setAppsFlyerDevKey (const char* appsFlyerDevKey) {
|
||||
[AppsFlyerLib shared].appsFlyerDevKey = stringFromChar(appsFlyerDevKey);
|
||||
}
|
||||
|
||||
const void _setAppleAppID (const char* appleAppID) {
|
||||
[AppsFlyerLib shared].appleAppID = stringFromChar(appleAppID);
|
||||
}
|
||||
|
||||
const void _setCurrencyCode (const char* currencyCode) {
|
||||
[[AppsFlyerLib shared] setCurrencyCode:stringFromChar(currencyCode)];
|
||||
}
|
||||
|
||||
const void _setDisableCollectAppleAdSupport (bool disableAdvertisingIdentifier) {
|
||||
[AppsFlyerLib shared].disableAdvertisingIdentifier = disableAdvertisingIdentifier;
|
||||
}
|
||||
|
||||
const void _setIsDebug (bool isDebug) {
|
||||
[AppsFlyerLib shared].isDebug = isDebug;
|
||||
}
|
||||
|
||||
const void _setShouldCollectDeviceName (bool shouldCollectDeviceName) {
|
||||
[AppsFlyerLib shared].shouldCollectDeviceName = shouldCollectDeviceName;
|
||||
}
|
||||
|
||||
const void _setAppInviteOneLinkID (const char* appInviteOneLinkID) {
|
||||
[[AppsFlyerLib shared] setAppInviteOneLink:stringFromChar(appInviteOneLinkID)];
|
||||
}
|
||||
|
||||
const void _anonymizeUser (bool anonymizeUser) {
|
||||
[AppsFlyerLib shared].anonymizeUser = anonymizeUser;
|
||||
}
|
||||
|
||||
const void _setDisableCollectIAd (bool disableCollectASA) {
|
||||
[AppsFlyerLib shared].disableCollectASA = disableCollectASA;
|
||||
}
|
||||
|
||||
const void _setUseReceiptValidationSandbox (bool useReceiptValidationSandbox) {
|
||||
[AppsFlyerLib shared].useReceiptValidationSandbox = useReceiptValidationSandbox;
|
||||
}
|
||||
|
||||
const void _setUseUninstallSandbox (bool useUninstallSandbox) {
|
||||
[AppsFlyerLib shared].useUninstallSandbox = useUninstallSandbox;
|
||||
}
|
||||
|
||||
const void _setResolveDeepLinkURLs (int length, const char **resolveDeepLinkURLs) {
|
||||
if(length > 0 && resolveDeepLinkURLs) {
|
||||
[[AppsFlyerLib shared] setResolveDeepLinkURLs:NSArrayFromCArray(length, resolveDeepLinkURLs)];
|
||||
}
|
||||
}
|
||||
|
||||
const void _setOneLinkCustomDomains (int length, const char **oneLinkCustomDomains) {
|
||||
if(length > 0 && oneLinkCustomDomains) {
|
||||
[[AppsFlyerLib shared] setOneLinkCustomDomains:NSArrayFromCArray(length, oneLinkCustomDomains)];
|
||||
}
|
||||
}
|
||||
|
||||
const void _afSendEvent (const char* eventName, const char* eventValues, bool shouldCallback, const char* objectName) {
|
||||
inAppRequestObjectName = stringFromChar(objectName);
|
||||
[[AppsFlyerLib shared] logEventWithEventName:stringFromChar(eventName) eventValues:dictionaryFromJson(eventValues) completionHandler:^(NSDictionary<NSString *,id> *dictionary, NSError *error) {
|
||||
if(shouldCallback){
|
||||
if (error) {
|
||||
NSDictionary *callbackDictionary = @{@"statusCode":[NSNumber numberWithLong:[error code]]};
|
||||
unityCallBack(inAppRequestObjectName, IN_APP_RESPONSE_CALLBACK, stringFromdictionary(callbackDictionary));
|
||||
return;
|
||||
}
|
||||
if (dictionary) {
|
||||
unityCallBack(inAppRequestObjectName, IN_APP_RESPONSE_CALLBACK, stringFromdictionary(dictionary));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
const void _recordLocation (double longitude, double latitude) {
|
||||
[[AppsFlyerLib shared] logLocation:longitude latitude:latitude];
|
||||
}
|
||||
|
||||
const char* _getAppsFlyerId () {
|
||||
return getCString([[[AppsFlyerLib shared] getAppsFlyerUID] UTF8String]);
|
||||
}
|
||||
|
||||
const void _registerUninstall (unsigned char* deviceToken) {
|
||||
if(deviceToken){
|
||||
NSData* tokenData = [NSData dataWithBytes:(const void *)deviceToken length:sizeof(unsigned char)*kPushNotificationSize];
|
||||
[[AppsFlyerLib shared] registerUninstall:tokenData];
|
||||
}
|
||||
}
|
||||
|
||||
const void _handlePushNotification (const char* pushPayload) {
|
||||
[[AppsFlyerLib shared] handlePushNotification:dictionaryFromJson(pushPayload)];
|
||||
}
|
||||
|
||||
const char* _getSDKVersion () {
|
||||
return getCString([[[AppsFlyerLib shared] getSDKVersion] UTF8String]);
|
||||
}
|
||||
|
||||
const void _setHost (const char* host, const char* hostPrefix) {
|
||||
[[AppsFlyerLib shared] setHost:stringFromChar(host) withHostPrefix:stringFromChar(hostPrefix)];
|
||||
}
|
||||
|
||||
const void _setMinTimeBetweenSessions (int minTimeBetweenSessions) {
|
||||
[AppsFlyerLib shared].minTimeBetweenSessions = minTimeBetweenSessions;
|
||||
}
|
||||
|
||||
const void _stopSDK (bool isStopped) {
|
||||
[AppsFlyerLib shared].isStopped = isStopped;
|
||||
}
|
||||
|
||||
const BOOL _isSDKStopped () {
|
||||
return [AppsFlyerLib shared].isStopped;
|
||||
}
|
||||
|
||||
const void _handleOpenUrl(const char *url, const char *sourceApplication, const char *annotation) {
|
||||
[[AppsFlyerLib shared] handleOpenURL:[NSURL URLWithString:stringFromChar(url)] sourceApplication:stringFromChar(sourceApplication) withAnnotation:stringFromChar(annotation)]; }
|
||||
|
||||
const void _recordCrossPromoteImpression (const char* appID, const char* campaign, const char* parameters) {
|
||||
[AppsFlyerCrossPromotionHelper logCrossPromoteImpression:stringFromChar(appID) campaign:stringFromChar(campaign) parameters:dictionaryFromJson(parameters)]; }
|
||||
|
||||
const void _attributeAndOpenStore (const char* appID, const char* campaign, const char* parameters, const char* objectName) {
|
||||
|
||||
openStoreObjectName = stringFromChar(objectName);
|
||||
|
||||
[AppsFlyerCrossPromotionHelper
|
||||
logAndOpenStore:stringFromChar(appID)
|
||||
campaign:stringFromChar(campaign)
|
||||
parameters:dictionaryFromJson(parameters)
|
||||
openStore:^(NSURLSession * _Nonnull urlSession, NSURL * _Nonnull clickURL) {
|
||||
unityCallBack(openStoreObjectName, OPEN_STORE_LINK_CALLBACK, [clickURL.absoluteString UTF8String]);
|
||||
}];
|
||||
}
|
||||
|
||||
const void _generateUserInviteLink (const char* parameters, const char* objectName) {
|
||||
|
||||
generateInviteObjectName = stringFromChar(objectName);
|
||||
|
||||
[AppsFlyerShareInviteHelper generateInviteUrlWithLinkGenerator:^AppsFlyerLinkGenerator * _Nonnull(AppsFlyerLinkGenerator * _Nonnull generator) {
|
||||
return generatorFromDictionary(dictionaryFromJson(parameters), generator);
|
||||
} completionHandler:^(NSURL * _Nullable url) {
|
||||
unityCallBack(generateInviteObjectName, GENERATE_LINK_CALLBACK, [url.absoluteString UTF8String]);
|
||||
}];
|
||||
}
|
||||
|
||||
const void _recordInvite (const char* channel, const char* parameters) {
|
||||
[AppsFlyerShareInviteHelper logInvite:stringFromChar(channel) parameters:dictionaryFromJson(parameters)];
|
||||
}
|
||||
|
||||
const void _setUserEmails (int emailCryptTypeInt , int length, const char **userEmails) {
|
||||
if(length > 0 && userEmails) {
|
||||
[[AppsFlyerLib shared] setUserEmails:NSArrayFromCArray(length, userEmails) withCryptType:emailCryptTypeFromInt(emailCryptTypeInt)];
|
||||
}
|
||||
}
|
||||
|
||||
const void _setPhoneNumber (const char* phoneNumber) {
|
||||
[[AppsFlyerLib shared] setPhoneNumber:stringFromChar(phoneNumber)];
|
||||
}
|
||||
|
||||
const void _setSharingFilterForAllPartners () {
|
||||
[[AppsFlyerLib shared] setSharingFilterForAllPartners];
|
||||
}
|
||||
|
||||
const void _setSharingFilter (int length, const char **partners) {
|
||||
if(length > 0 && partners) {
|
||||
[[AppsFlyerLib shared] setSharingFilter:NSArrayFromCArray(length, partners)];
|
||||
}
|
||||
}
|
||||
|
||||
const void _setSharingFilterForPartners (int length, const char **partners) {
|
||||
if(length > 0 && partners) {
|
||||
[[AppsFlyerLib shared] setSharingFilterForPartners:NSArrayFromCArray(length, partners)];
|
||||
} else {
|
||||
[[AppsFlyerLib shared] setSharingFilterForPartners:nil];
|
||||
}
|
||||
}
|
||||
|
||||
const void _validateAndSendInAppPurchase (const char* productIdentifier, const char* price, const char* currency, const char* tranactionId, const char* additionalParameters, const char* objectName) {
|
||||
|
||||
validateObjectName = stringFromChar(objectName);
|
||||
|
||||
[[AppsFlyerLib shared]
|
||||
validateAndLogInAppPurchase:stringFromChar(productIdentifier)
|
||||
price:stringFromChar(price)
|
||||
currency:stringFromChar(currency)
|
||||
transactionId:stringFromChar(tranactionId)
|
||||
additionalParameters:dictionaryFromJson(additionalParameters)
|
||||
success:^(NSDictionary *result){
|
||||
unityCallBack(validateObjectName, VALIDATE_CALLBACK, stringFromdictionary(result));
|
||||
} failure:^(NSError *error, id response) {
|
||||
if(response && [response isKindOfClass:[NSDictionary class]]) {
|
||||
NSDictionary* value = (NSDictionary*)response;
|
||||
unityCallBack(validateObjectName, VALIDATE_ERROR_CALLBACK, stringFromdictionary(value));
|
||||
} else {
|
||||
unityCallBack(validateObjectName, VALIDATE_ERROR_CALLBACK, error ? [[error localizedDescription] UTF8String] : "error");
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
const void _getConversionData(const char* objectName) {
|
||||
if (_AppsFlyerdelegate == nil) {
|
||||
_AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];
|
||||
}
|
||||
ConversionDataCallbackObject = stringFromChar(objectName);
|
||||
[[AppsFlyerLib shared] setDelegate:_AppsFlyerdelegate];
|
||||
}
|
||||
|
||||
const void _waitForATTUserAuthorizationWithTimeoutInterval (int timeoutInterval) {
|
||||
[[AppsFlyerLib shared] waitForATTUserAuthorizationWithTimeoutInterval:timeoutInterval];
|
||||
}
|
||||
|
||||
const void _disableSKAdNetwork (bool isDisabled) {
|
||||
[AppsFlyerLib shared].disableSKAdNetwork = isDisabled;
|
||||
}
|
||||
|
||||
const void _addPushNotificationDeepLinkPath (int length, const char **paths) {
|
||||
if(length > 0 && paths) {
|
||||
[[AppsFlyerLib shared] addPushNotificationDeepLinkPath:NSArrayFromCArray(length, paths)];
|
||||
}
|
||||
}
|
||||
|
||||
const void _subscribeForDeepLink (const char* objectName) {
|
||||
|
||||
onDeeplinkingObjectName = stringFromChar(objectName);
|
||||
|
||||
if (_AppsFlyerdelegate == nil) {
|
||||
_AppsFlyerdelegate = [[AppsFlyeriOSWarpper alloc] init];
|
||||
}
|
||||
[[AppsFlyerLib shared] setDeepLinkDelegate:_AppsFlyerdelegate];
|
||||
}
|
||||
|
||||
const void _setCurrentDeviceLanguage(const char* language) {
|
||||
[[AppsFlyerLib shared] setCurrentDeviceLanguage:stringFromChar(language)];
|
||||
}
|
||||
|
||||
const void _setPartnerData(const char* partnerId, const char* partnerInfo) {
|
||||
[[AppsFlyerLib shared] setPartnerDataWithPartnerId: stringFromChar(partnerId) partnerInfo:dictionaryFromJson(partnerInfo)];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@implementation AppsFlyeriOSWarpper
|
||||
|
||||
static BOOL didCallStart;
|
||||
+ (BOOL) didCallStart
|
||||
{ @synchronized(self) { return didCallStart; } }
|
||||
+ (void) setDidCallStart:(BOOL)val
|
||||
{ @synchronized(self) { didCallStart = val; } }
|
||||
|
||||
- (void)onConversionDataSuccess:(NSDictionary *)installData {
|
||||
unityCallBack(ConversionDataCallbackObject, GCD_CALLBACK, stringFromdictionary(installData));
|
||||
}
|
||||
|
||||
- (void)onConversionDataFail:(NSError *)error {
|
||||
unityCallBack(ConversionDataCallbackObject, GCD_ERROR_CALLBACK, [[error localizedDescription] UTF8String]);
|
||||
}
|
||||
|
||||
- (void)onAppOpenAttribution:(NSDictionary *)attributionData {
|
||||
unityCallBack(ConversionDataCallbackObject, OAOA_CALLBACK, stringFromdictionary(attributionData));
|
||||
}
|
||||
|
||||
- (void)onAppOpenAttributionFailure:(NSError *)error {
|
||||
unityCallBack(ConversionDataCallbackObject, OAOA_ERROR_CALLBACK, [[error localizedDescription] UTF8String]);
|
||||
}
|
||||
|
||||
- (void)didResolveDeepLink:(AppsFlyerDeepLinkResult *)result{
|
||||
|
||||
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
||||
|
||||
[dict setValue:stringFromDeepLinkResultError(result) forKey:@"error"];
|
||||
[dict setValue:stringFromDeepLinkResultStatus(result.status) forKey:@"status"];
|
||||
|
||||
if(result && result.deepLink){
|
||||
[dict setValue:result.deepLink.description forKey:@"deepLink"];
|
||||
[dict setValue:@(result.deepLink.isDeferred) forKey:@"is_deferred"];
|
||||
}
|
||||
|
||||
unityCallBack(onDeeplinkingObjectName, ON_DEEPLINKING, stringFromdictionary(dict));
|
||||
}
|
||||
|
||||
@end
|
||||
|
BIN
Libraries/Plugins/iOS/libYouMeCommon.a
Normal file
BIN
Libraries/Plugins/iOS/libYouMeCommon.a
Normal file
Binary file not shown.
BIN
Libraries/Plugins/iOS/libdivesensor.a
Normal file
BIN
Libraries/Plugins/iOS/libdivesensor.a
Normal file
Binary file not shown.
BIN
Libraries/Plugins/iOS/libffmpeg3.3.a
Normal file
BIN
Libraries/Plugins/iOS/libffmpeg3.3.a
Normal file
Binary file not shown.
BIN
Libraries/Plugins/iOS/libtolua.a
Normal file
BIN
Libraries/Plugins/iOS/libtolua.a
Normal file
Binary file not shown.
BIN
Libraries/Plugins/iOS/libyoume_voice_engine.a
Normal file
BIN
Libraries/Plugins/iOS/libyoume_voice_engine.a
Normal file
Binary file not shown.
@ -0,0 +1,24 @@
|
||||
//
|
||||
// UnityAppController+Notifications.h
|
||||
// Unity-iPhone
|
||||
//
|
||||
// Copyright © 2018 Unity Technologies. All rights reserved.
|
||||
//
|
||||
#if TARGET_OS_IOS
|
||||
#import "UnityAppController.h"
|
||||
|
||||
#include "Classes/PluginBase/LifeCycleListener.h"
|
||||
#include "Classes/PluginBase/AppDelegateListener.h"
|
||||
|
||||
|
||||
@interface UnityAppController (Notifications)
|
||||
|
||||
@end
|
||||
|
||||
@interface UnityNotificationLifeCycleManager : NSObject
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
@ -0,0 +1,114 @@
|
||||
//
|
||||
// UnityAppController+Notifications.m
|
||||
// Unity-iPhone
|
||||
//
|
||||
// Copyright © 2018 Unity Technologies. All rights reserved.
|
||||
//
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#import "UnityNotificationManager.h"
|
||||
#import "UnityAppController+Notifications.h"
|
||||
|
||||
#import "UnityNotificationWrapper.h"
|
||||
|
||||
@implementation UnityNotificationLifeCycleManager
|
||||
|
||||
|
||||
+ (void)load {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[UnityNotificationLifeCycleManager sharedInstance];
|
||||
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
center.delegate = [UnityNotificationManager sharedInstance];
|
||||
});
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
{
|
||||
static UnityNotificationLifeCycleManager *sharedInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[UnityNotificationLifeCycleManager alloc] init];
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
[nc addObserverForName:UIApplicationDidBecomeActiveNotification
|
||||
object:nil
|
||||
queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *notification) {
|
||||
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
[manager updateScheduledNotificationList];
|
||||
[manager updateDeliveredNotificationList];
|
||||
[manager updateNotificationSettings];
|
||||
|
||||
}];
|
||||
|
||||
[nc addObserverForName:UIApplicationDidEnterBackgroundNotification
|
||||
object:nil
|
||||
queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *notification) {
|
||||
|
||||
[UnityNotificationManager sharedInstance].lastReceivedNotification = NULL;
|
||||
}];
|
||||
|
||||
[nc addObserverForName:UIApplicationDidFinishLaunchingNotification
|
||||
object:nil
|
||||
queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *notification) {
|
||||
|
||||
BOOL authorizeOnLaunch = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"UnityNotificationRequestAuthorizationOnAppLaunch"] boolValue] ;
|
||||
BOOL supportsPushNotification = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"UnityAddRemoteNotificationCapability"] boolValue] ;
|
||||
BOOL registerRemoteOnLaunch = supportsPushNotification == YES ?
|
||||
[[[NSBundle mainBundle] objectForInfoDictionaryKey:@"UnityNotificationRequestAuthorizationForRemoteNotificationsOnAppLaunch"] boolValue] : NO ;
|
||||
|
||||
NSInteger remoteForegroundPresentationOptions = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"UnityRemoteNotificationForegroundPresentationOptions"] integerValue] ;
|
||||
|
||||
NSInteger defaultAuthorizationOptions = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"UnityNotificationDefaultAuthorizationOptions"] integerValue] ;
|
||||
|
||||
if (defaultAuthorizationOptions <= 0)
|
||||
defaultAuthorizationOptions = (UNAuthorizationOptionSound + UNAuthorizationOptionAlert + UNAuthorizationOptionBadge);
|
||||
|
||||
if (authorizeOnLaunch)
|
||||
{
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
[manager requestAuthorization:defaultAuthorizationOptions : registerRemoteOnLaunch];
|
||||
manager.remoteNotificationForegroundPresentationOptions = remoteForegroundPresentationOptions;
|
||||
}
|
||||
}];
|
||||
|
||||
[nc addObserverForName:kUnityDidRegisterForRemoteNotificationsWithDeviceToken
|
||||
object:nil
|
||||
queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *notification) {
|
||||
NSLog(@"didRegisterForRemoteNotificationsWithDeviceToken");
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
manager.remoteNotificationsRegistered = UNAuthorizationStatusDenied;
|
||||
|
||||
if ([notification.userInfo isKindOfClass:[NSData class]])
|
||||
{
|
||||
NSData* data = (NSData*)notification.userInfo;
|
||||
[manager setDeviceTokenFromNSData: (NSData*)notification.userInfo];
|
||||
}
|
||||
[manager checkAuthorizationFinished];
|
||||
}];
|
||||
|
||||
[nc addObserverForName:kUnityDidFailToRegisterForRemoteNotificationsWithError
|
||||
object:nil
|
||||
queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *notification) {
|
||||
NSLog(@"didFailToRegisterForRemoteNotificationsWithError");
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
manager.remoteNotificationsRegistered = UNAuthorizationStatusAuthorized;
|
||||
[manager checkAuthorizationFinished];
|
||||
|
||||
}];
|
||||
|
||||
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
@end
|
||||
#endif
|
@ -0,0 +1,128 @@
|
||||
//
|
||||
// UnityNotificationManager.h
|
||||
// iOS.notifications
|
||||
//
|
||||
// Copyright © 2018 Unity Technologies. All rights reserved.
|
||||
//
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
//
|
||||
#define SYSTEM_VERSION_10_OR_ABOVE ([[[UIDevice currentDevice] systemVersion] compare:@"10.0" options:NSNumericSearch] != NSOrderedAscending)
|
||||
|
||||
enum triggerType {
|
||||
TIME_TRIGGER = 0,
|
||||
CALENDAR_TRIGGER = 10,
|
||||
LOCATION_TRIGGER = 20,
|
||||
PUSH_TRIGGER = 3,
|
||||
};
|
||||
|
||||
typedef struct iOSNotificationData
|
||||
{
|
||||
char* identifier;
|
||||
char* title;
|
||||
char* body;
|
||||
int badge;
|
||||
char* subtitle;
|
||||
char* categoryIdentifier;
|
||||
char* threadIdentifier;
|
||||
|
||||
//Custom data
|
||||
char* data;
|
||||
BOOL showInForeground;
|
||||
int showInForegroundPresentationOptions;
|
||||
|
||||
// Trigger
|
||||
int triggerType; //0 - time, 1 - calendar, 2 - location, 3 - push.
|
||||
BOOL repeats;
|
||||
|
||||
//Time trigger
|
||||
int timeTriggerInterval;
|
||||
|
||||
//Calendar trigger
|
||||
int calendarTriggerYear;
|
||||
int calendarTriggerMonth;
|
||||
int calendarTriggerDay;
|
||||
int calendarTriggerHour;
|
||||
int calendarTriggerMinute;
|
||||
int calendarTriggerSecond;
|
||||
|
||||
//Location trigger
|
||||
float locationTriggerCenterX;
|
||||
float locationTriggerCenterY;
|
||||
float locationTriggerRadius;
|
||||
bool locationTriggerNotifyOnEntry;
|
||||
bool locationTriggerNotifyOnExit;
|
||||
|
||||
|
||||
} iOSNotificationData;
|
||||
|
||||
|
||||
typedef struct iOSNotificationAuthorizationData
|
||||
{
|
||||
bool granted;
|
||||
char* error;
|
||||
bool finished;
|
||||
const char* deviceToken;
|
||||
} iOSNotificationAuthorizationData;
|
||||
|
||||
|
||||
typedef void (*NotificationDataReceivedResponse)(struct iOSNotificationData* data);
|
||||
typedef void (*AuthorizationRequestResponse) (struct iOSNotificationAuthorizationData* data);
|
||||
|
||||
typedef struct NotificationSettingsData {
|
||||
int authorizationStatus;
|
||||
int notificationCenterSetting;
|
||||
int lockScreenSetting;
|
||||
int carPlaySetting;
|
||||
int alertSetting;
|
||||
int badgeSetting;
|
||||
int soundSetting;
|
||||
int alertStyle;
|
||||
int showPreviewsSetting;
|
||||
} NotificationSettingsData;
|
||||
|
||||
const int kDefaultPresentationOptions = -1;
|
||||
|
||||
@interface UnityNotificationManager : NSObject <UNUserNotificationCenterDelegate>
|
||||
|
||||
@property UNNotificationSettings* cachedNotificationSettings;
|
||||
@property struct iOSNotificationAuthorizationData* authData;
|
||||
|
||||
@property NotificationDataReceivedResponse onNotificationReceivedCallback;
|
||||
@property NotificationDataReceivedResponse onCatchReceivedRemoteNotificationCallback;
|
||||
@property AuthorizationRequestResponse onAuthorizationCompletionCallback;
|
||||
|
||||
@property NSArray<UNNotificationRequest *> * cachedPendingNotificationRequests;
|
||||
@property NSArray<UNNotification *> * cachedDeliveredNotifications;
|
||||
|
||||
@property (nonatomic) UNNotification* lastReceivedNotification;
|
||||
|
||||
@property BOOL authorized;
|
||||
@property BOOL authorizationRequestFinished;
|
||||
@property BOOL needRemoteNotifications;
|
||||
@property NSString* deviceToken;
|
||||
@property UNAuthorizationStatus remoteNotificationsRegistered;
|
||||
|
||||
@property UNNotificationPresentationOptions remoteNotificationForegroundPresentationOptions;
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
+ (struct iOSNotificationData*)UNNotificationRequestToiOSNotificationData : (UNNotificationRequest*) request;
|
||||
+ (struct iOSNotificationData*)UNNotificationToiOSNotificationData : (UNNotification*) notification;
|
||||
+ (struct NotificationSettingsData*)UNNotificationSettingsToNotificationSettingsData : (UNNotificationSettings*) settings;
|
||||
|
||||
+ (void)InitiOSNotificationData : (iOSNotificationData*) notificationData;
|
||||
|
||||
- (void)checkAuthorizationFinished;
|
||||
- (void)updateScheduledNotificationList;
|
||||
- (void)updateDeliveredNotificationList;
|
||||
- (void)updateNotificationSettings;
|
||||
- (void)requestAuthorization: (NSInteger)authorizationOptions : (BOOL) registerRemote;
|
||||
- (void)setDeviceTokenFromNSData:(NSData*)deviceToken;
|
||||
@end
|
||||
|
||||
#endif
|
@ -0,0 +1,327 @@
|
||||
//
|
||||
// UnityNotificationManager.m
|
||||
// iOS.notifications
|
||||
//
|
||||
// Created by Paulius on 24/07/2018.
|
||||
// Copyright © 2018 Unity Technologies. All rights reserved.
|
||||
//
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
#import "UnityNotificationManager.h"
|
||||
|
||||
#if defined(UNITY_USES_LOCATION) && UNITY_USES_LOCATION
|
||||
#import <CoreLocation/CoreLocation.h>
|
||||
#endif
|
||||
|
||||
|
||||
@implementation UnityNotificationManager
|
||||
|
||||
+ (instancetype)sharedInstance
|
||||
{
|
||||
static UnityNotificationManager *sharedInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[UnityNotificationManager alloc] init];
|
||||
});
|
||||
|
||||
[sharedInstance updateNotificationSettings];
|
||||
[sharedInstance updateScheduledNotificationList];
|
||||
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (void)checkAuthorizationFinished
|
||||
{
|
||||
bool requestRejected = self.authorizationRequestFinished && !self.authorized;
|
||||
|
||||
if (!requestRejected && self.needRemoteNotifications)
|
||||
if (!self.remoteNotificationsRegistered)
|
||||
return;
|
||||
|
||||
if (self.authorizationRequestFinished && self.onAuthorizationCompletionCallback != NULL && self.authData != NULL)
|
||||
{
|
||||
self.authData -> deviceToken = [self.deviceToken UTF8String];
|
||||
self.onAuthorizationCompletionCallback(self.authData);
|
||||
|
||||
free(self.authData);
|
||||
self.authData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)requestAuthorization: (NSInteger)authorizationOptions : (BOOL) registerRemote
|
||||
{
|
||||
if ( !SYSTEM_VERSION_10_OR_ABOVE)
|
||||
return;
|
||||
|
||||
registerRemote = true;
|
||||
|
||||
self.authorizationRequestFinished = NO;
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
|
||||
BOOL supportsPushNotification = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"UnityAddRemoteNotificationCapability"] boolValue] ;
|
||||
registerRemote = supportsPushNotification == YES ? registerRemote : NO ;
|
||||
|
||||
self.needRemoteNotifications = registerRemote;
|
||||
[center requestAuthorizationWithOptions: authorizationOptions completionHandler:^(BOOL granted, NSError * _Nullable error)
|
||||
{
|
||||
struct iOSNotificationAuthorizationData* authData = (struct iOSNotificationAuthorizationData*)malloc(sizeof(*authData));
|
||||
authData -> finished = YES;
|
||||
authData -> granted = granted;
|
||||
authData -> error = [[error localizedDescription]cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
authData -> deviceToken = "";
|
||||
|
||||
self.authData = authData;
|
||||
self.authorized = granted;
|
||||
if (self.authorized)
|
||||
{
|
||||
if (registerRemote)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[UIApplication sharedApplication] registerForRemoteNotifications];
|
||||
self.authorizationRequestFinished = YES;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
self.authorizationRequestFinished = YES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.authorizationRequestFinished = YES;
|
||||
NSLog(@"Requesting notification authorization failed with: %@", error);
|
||||
}
|
||||
|
||||
[self checkAuthorizationFinished];
|
||||
[self updateNotificationSettings];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setDeviceTokenFromNSData:(NSData *)deviceTokenData {
|
||||
|
||||
NSUInteger len = deviceTokenData.length;
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
const unsigned char *buffer = deviceTokenData.bytes;
|
||||
NSMutableString *str = [NSMutableString stringWithCapacity:(len * 2)];
|
||||
for (int i = 0; i < len; ++i) {
|
||||
[str appendFormat:@"%02x", buffer[i]];
|
||||
}
|
||||
self.deviceToken = [str copy];
|
||||
}
|
||||
|
||||
//Called when a notification is delivered to a foreground app.
|
||||
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
|
||||
|
||||
if (self.onNotificationReceivedCallback != NULL )
|
||||
self.onNotificationReceivedCallback([UnityNotificationManager UNNotificationToiOSNotificationData:notification]);
|
||||
|
||||
BOOL showInForeground;
|
||||
NSInteger presentationOptions;
|
||||
|
||||
if ( [notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]])
|
||||
{
|
||||
if (self.onCatchReceivedRemoteNotificationCallback != NULL)
|
||||
{
|
||||
showInForeground = NO;
|
||||
self.onCatchReceivedRemoteNotificationCallback([UnityNotificationManager UNNotificationToiOSNotificationData:notification]);
|
||||
}
|
||||
else
|
||||
{
|
||||
showInForeground = YES;
|
||||
presentationOptions = self.remoteNotificationForegroundPresentationOptions;
|
||||
if (presentationOptions == 0)
|
||||
presentationOptions = kDefaultPresentationOptions;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
presentationOptions = [[notification.request.content.userInfo objectForKey:@"showInForegroundPresentationOptions"] intValue];
|
||||
showInForeground = [[notification.request.content.userInfo objectForKey:@"showInForeground"] boolValue];
|
||||
|
||||
}
|
||||
if (showInForeground)
|
||||
{
|
||||
completionHandler(presentationOptions);
|
||||
}
|
||||
else
|
||||
completionHandler(UNNotificationPresentationOptionNone);
|
||||
|
||||
[[UnityNotificationManager sharedInstance] updateDeliveredNotificationList];
|
||||
}
|
||||
|
||||
//Called to let your app know which action was selected by the user for a given notification.
|
||||
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(nonnull void(^)(void))completionHandler
|
||||
{
|
||||
self.lastReceivedNotification = response.notification;
|
||||
completionHandler();
|
||||
[[UnityNotificationManager sharedInstance] updateDeliveredNotificationList];
|
||||
}
|
||||
|
||||
-(void)updateScheduledNotificationList
|
||||
{
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
[center getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> * _Nonnull requests) {
|
||||
self.cachedPendingNotificationRequests = requests;
|
||||
}];
|
||||
}
|
||||
|
||||
-(void)updateDeliveredNotificationList
|
||||
{
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
[center getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
|
||||
self.cachedDeliveredNotifications = notifications;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)updateNotificationSettings
|
||||
{
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
|
||||
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
|
||||
self.cachedNotificationSettings = settings;
|
||||
}];
|
||||
}
|
||||
|
||||
+ (struct NotificationSettingsData*)UNNotificationSettingsToNotificationSettingsData : (UNNotificationSettings*) settings
|
||||
{
|
||||
struct NotificationSettingsData* settingsData = (struct NotificationSettingsData*)malloc(sizeof(*settingsData));
|
||||
settingsData->alertSetting = (int) settings.alertSetting;
|
||||
settingsData->authorizationStatus = (int) settings.authorizationStatus;
|
||||
settingsData->badgeSetting = (int) settings.badgeSetting;
|
||||
settingsData->carPlaySetting = (int) settings.carPlaySetting;
|
||||
settingsData->lockScreenSetting = (int) settings.lockScreenSetting;
|
||||
settingsData->notificationCenterSetting = (int) settings.notificationCenterSetting;
|
||||
settingsData->soundSetting = (int) settings.soundSetting;
|
||||
settingsData->alertStyle = (int)settings.alertStyle;
|
||||
|
||||
if (@available(iOS 11.0, *)) {
|
||||
settingsData->showPreviewsSetting = (int)settings.showPreviewsSetting;
|
||||
} else {
|
||||
settingsData->showPreviewsSetting = 2;
|
||||
}
|
||||
return settingsData;
|
||||
}
|
||||
|
||||
+ (struct iOSNotificationData*)UNNotificationRequestToiOSNotificationData : (UNNotificationRequest*) request
|
||||
{
|
||||
struct iOSNotificationData* notificationData = (struct iOSNotificationData*)malloc(sizeof(*notificationData));
|
||||
[UnityNotificationManager InitiOSNotificationData : notificationData];
|
||||
|
||||
UNNotificationContent* content = request.content;
|
||||
|
||||
notificationData -> identifier = (char*) [request.identifier UTF8String];
|
||||
|
||||
if (content.title != nil && content.title.length > 0)
|
||||
notificationData -> title = (char*) [content.title UTF8String];
|
||||
|
||||
if (content.body != nil && content.body.length > 0)
|
||||
notificationData -> body = (char*) [content.body UTF8String];
|
||||
|
||||
notificationData -> badge = [content.badge intValue];
|
||||
|
||||
if (content.subtitle != nil && content.subtitle.length > 0)
|
||||
notificationData -> subtitle = (char*) [content.subtitle UTF8String];
|
||||
|
||||
if (content.categoryIdentifier != nil && content.categoryIdentifier.length > 0)
|
||||
notificationData -> categoryIdentifier = (char*) [content.categoryIdentifier UTF8String];
|
||||
|
||||
if (content.threadIdentifier != nil && content.threadIdentifier.length > 0)
|
||||
notificationData -> threadIdentifier = (char*) [content.threadIdentifier UTF8String];
|
||||
|
||||
if ([ request.trigger isKindOfClass:[UNTimeIntervalNotificationTrigger class]])
|
||||
{
|
||||
notificationData -> triggerType = TIME_TRIGGER;
|
||||
|
||||
UNTimeIntervalNotificationTrigger* timeTrigger = (UNTimeIntervalNotificationTrigger*) request.trigger;
|
||||
notificationData -> timeTriggerInterval = timeTrigger.timeInterval;
|
||||
notificationData -> repeats = timeTrigger.repeats;
|
||||
}
|
||||
else if ([ request.trigger isKindOfClass:[UNCalendarNotificationTrigger class]])
|
||||
{
|
||||
notificationData -> triggerType = CALENDAR_TRIGGER;
|
||||
|
||||
UNCalendarNotificationTrigger* calendarTrigger = (UNCalendarNotificationTrigger*) request.trigger;
|
||||
NSDateComponents* date = calendarTrigger.dateComponents;
|
||||
|
||||
notificationData->calendarTriggerYear = (int)date.year;
|
||||
notificationData->calendarTriggerMonth = (int)date.month;
|
||||
notificationData->calendarTriggerDay = (int)date.day;
|
||||
notificationData->calendarTriggerHour = (int)date.hour;
|
||||
notificationData->calendarTriggerMinute = (int)date.minute;
|
||||
notificationData->calendarTriggerSecond = (int)date.second;
|
||||
|
||||
}
|
||||
else if ([ request.trigger isKindOfClass:[UNLocationNotificationTrigger class]])
|
||||
{
|
||||
#if defined(UNITY_USES_LOCATION) && UNITY_USES_LOCATION
|
||||
notificationData -> triggerType = LOCATION_TRIGGER;
|
||||
|
||||
UNLocationNotificationTrigger* locationTrigger = (UNLocationNotificationTrigger*) request.trigger;
|
||||
CLCircularRegion *region = (CLCircularRegion*)locationTrigger.region;
|
||||
|
||||
notificationData -> locationTriggerCenterX = region.center.latitude ;
|
||||
notificationData -> locationTriggerCenterY = region.center.longitude;
|
||||
notificationData -> locationTriggerRadius = region.radius;
|
||||
notificationData -> locationTriggerNotifyOnExit = region.notifyOnEntry;
|
||||
notificationData -> locationTriggerNotifyOnEntry = region.notifyOnExit;
|
||||
#endif
|
||||
}
|
||||
else if ([ request.trigger isKindOfClass:[UNPushNotificationTrigger class]])
|
||||
{
|
||||
notificationData -> triggerType = PUSH_TRIGGER;
|
||||
}
|
||||
|
||||
if ([NSJSONSerialization isValidJSONObject: [request.content.userInfo objectForKey:@"data"]]) {
|
||||
NSError *error;
|
||||
NSData *data = [NSJSONSerialization dataWithJSONObject:[request.content.userInfo objectForKey:@"data"]
|
||||
options:NSJSONWritingPrettyPrinted
|
||||
error:&error];
|
||||
if (! data) {
|
||||
NSLog(@"Failed parsing notification userInfo[\"data\"]: %@", error);
|
||||
} else {
|
||||
notificationData -> data = (char*)[[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] UTF8String];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([[request.content.userInfo valueForKey:@"data"] isKindOfClass:[NSNumber class]] )
|
||||
{
|
||||
NSNumber *value = (NSNumber*)[request.content.userInfo valueForKey:@"data"];
|
||||
|
||||
if (CFBooleanGetTypeID() == CFGetTypeID((__bridge CFTypeRef)(value))) {
|
||||
notificationData -> data = (value == 1) ? "true" : "false";
|
||||
}
|
||||
else {
|
||||
notificationData -> data = (char*)[[value description] UTF8String];
|
||||
}
|
||||
}
|
||||
else {
|
||||
notificationData -> data = (char*) [[[request.content.userInfo objectForKey:@"data"]description] UTF8String];
|
||||
}
|
||||
}
|
||||
|
||||
return notificationData;
|
||||
}
|
||||
|
||||
+ (struct iOSNotificationData*)UNNotificationToiOSNotificationData : (UNNotification*) notification
|
||||
{
|
||||
UNNotificationRequest* request = notification.request;
|
||||
return [UnityNotificationManager UNNotificationRequestToiOSNotificationData : request];
|
||||
}
|
||||
|
||||
+ (void)InitiOSNotificationData : (iOSNotificationData*) notificationData;
|
||||
{
|
||||
notificationData -> title = " ";
|
||||
notificationData -> body = " ";
|
||||
notificationData -> badge = 0;
|
||||
notificationData -> subtitle = " ";
|
||||
notificationData -> categoryIdentifier = " ";
|
||||
notificationData -> threadIdentifier = " ";
|
||||
notificationData -> triggerType = PUSH_TRIGGER;
|
||||
notificationData -> data = " ";
|
||||
}
|
||||
|
||||
@end
|
||||
#endif
|
@ -0,0 +1,26 @@
|
||||
//
|
||||
// UnityNotificationWrapper.h
|
||||
// iOS.notifications
|
||||
//
|
||||
// Created by Paulius on 26/07/2018.
|
||||
// Copyright © 2018 Unity Technologies. All rights reserved.
|
||||
//
|
||||
#if TARGET_OS_IOS
|
||||
|
||||
#ifndef UnityNotificationWrapper_h
|
||||
#define UnityNotificationWrapper_h
|
||||
|
||||
typedef void (AUTHORIZATION_CALBACK)(struct iOSNotificationAuthorizationData* data);
|
||||
typedef void (*DATA_CALLBACK)(struct iOSNotificationData* data);
|
||||
|
||||
void _SetNotificationReceivedDelegate(DATA_CALLBACK callback);
|
||||
|
||||
void _ScheduleLocalNotification(struct iOSNotificationData* data);
|
||||
void _RequestAuthorization(int options, BOOL registerRemote);
|
||||
|
||||
int _GetScheduledNotificationDataCount();
|
||||
iOSNotificationData* _GetScheduledNotificationDataAt(int index);
|
||||
|
||||
|
||||
#endif /* UnityNotificationWrapper_h */
|
||||
#endif
|
@ -0,0 +1,296 @@
|
||||
//
|
||||
// UnityNotificationWrapper.m
|
||||
// iOS.notifications
|
||||
//
|
||||
// Copyright © 2018 Unity Technologies. All rights reserved.
|
||||
//
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if defined(UNITY_USES_LOCATION) && UNITY_USES_LOCATION
|
||||
#import <CoreLocation/CoreLocation.h>
|
||||
#endif
|
||||
|
||||
#import "UnityNotificationManager.h"
|
||||
#import "UnityNotificationWrapper.h"
|
||||
|
||||
AuthorizationRequestResponse req_callback;
|
||||
DATA_CALLBACK g_notificationReceivedCallback;
|
||||
DATA_CALLBACK g_remoteNotificationCallback;
|
||||
|
||||
void _FreeUnmanagedStruct(void* ptr)
|
||||
{
|
||||
if (ptr != NULL)
|
||||
{
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void onNotificationReceived(struct iOSNotificationData* data)
|
||||
{
|
||||
if (g_notificationReceivedCallback != NULL)
|
||||
{
|
||||
g_notificationReceivedCallback(data);
|
||||
_FreeUnmanagedStruct(data);
|
||||
}
|
||||
}
|
||||
|
||||
void onRemoteNotificationReceived(struct iOSNotificationData* data)
|
||||
{
|
||||
if (g_remoteNotificationCallback != NULL)
|
||||
{
|
||||
g_remoteNotificationCallback(data);
|
||||
_FreeUnmanagedStruct(data);
|
||||
}
|
||||
}
|
||||
|
||||
void _SetAuthorizationRequestReceivedDelegate(AUTHORIZATION_CALBACK callback)
|
||||
{
|
||||
req_callback = callback;
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
manager.onAuthorizationCompletionCallback = req_callback;
|
||||
}
|
||||
|
||||
void _SetNotificationReceivedDelegate(DATA_CALLBACK callback)
|
||||
{
|
||||
g_notificationReceivedCallback = callback;
|
||||
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
manager.onNotificationReceivedCallback = &onNotificationReceived;
|
||||
}
|
||||
|
||||
void _SetRemoteNotificationReceivedDelegate(DATA_CALLBACK callback)
|
||||
{
|
||||
g_remoteNotificationCallback = callback;
|
||||
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
manager.onCatchReceivedRemoteNotificationCallback = &onRemoteNotificationReceived;
|
||||
}
|
||||
|
||||
|
||||
void _RequestAuthorization(int options, BOOL registerRemote)
|
||||
{
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
[manager requestAuthorization:(options) : registerRemote];
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
center.delegate = manager;
|
||||
}
|
||||
|
||||
void _ScheduleLocalNotification(struct iOSNotificationData* data)
|
||||
{
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
|
||||
UNAuthorizationStatus authorizationStatus = manager.cachedNotificationSettings.authorizationStatus;
|
||||
|
||||
bool canSendNotifications = authorizationStatus != UNAuthorizationStatusAuthorized;
|
||||
if (@available(iOS 12.0, *)) {
|
||||
if (!canSendNotifications)
|
||||
canSendNotifications = authorizationStatus == UNAuthorizationStatusProvisional;
|
||||
}
|
||||
if (canSendNotifications)
|
||||
{
|
||||
NSLog(@"Attempting to schedule a local notification without authorization, please call RequestAuthorization before attempting to schedule any notifications.");
|
||||
return;
|
||||
}
|
||||
assert(manager.onNotificationReceivedCallback != NULL);
|
||||
|
||||
NSDictionary *userInfo = @{
|
||||
@"showInForeground" : @(data->showInForeground),
|
||||
@"showInForegroundPresentationOptions" : [NSNumber numberWithInteger:data->showInForegroundPresentationOptions],
|
||||
@"data" : @(data->data),
|
||||
};
|
||||
|
||||
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
|
||||
|
||||
NSString *title = [NSString localizedUserNotificationStringForKey: [NSString stringWithUTF8String: data->title] arguments:nil];
|
||||
NSString *body = [NSString localizedUserNotificationStringForKey: [NSString stringWithUTF8String: data->body] arguments:nil];
|
||||
|
||||
// iOS 10 does not show notifications with an empty body or title fields. Since this works fine on iOS 11+ we'll add assign a string
|
||||
// with a space to maintain consistent behaviour.
|
||||
if (@available(iOS 11.0, *)) {
|
||||
}
|
||||
else {
|
||||
if (title.length == 0)
|
||||
title = @" ";
|
||||
if (body.length == 0)
|
||||
body = @" ";
|
||||
}
|
||||
|
||||
content.title = title;
|
||||
content.body = body;
|
||||
|
||||
content.userInfo = userInfo;
|
||||
|
||||
if (data->badge >= 0)
|
||||
{
|
||||
content.badge = [NSNumber numberWithInt:data->badge];
|
||||
}
|
||||
|
||||
if (data->subtitle != NULL)
|
||||
content.subtitle = [NSString localizedUserNotificationStringForKey: [NSString stringWithUTF8String: data->subtitle] arguments:nil];
|
||||
|
||||
if (data->categoryIdentifier != NULL)
|
||||
content.categoryIdentifier = [NSString stringWithUTF8String:data->categoryIdentifier];
|
||||
|
||||
if (data->threadIdentifier != NULL)
|
||||
content.threadIdentifier = [NSString stringWithUTF8String:data->threadIdentifier];
|
||||
|
||||
// TODO add a way to specify custom sounds.
|
||||
content.sound = [UNNotificationSound defaultSound];
|
||||
|
||||
UNNotificationTrigger* trigger;
|
||||
|
||||
if ( data->triggerType == TIME_TRIGGER)
|
||||
{
|
||||
trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:data->timeTriggerInterval repeats: data -> repeats];
|
||||
}
|
||||
else if ( data->triggerType == CALENDAR_TRIGGER)
|
||||
{
|
||||
NSDateComponents* date = [[NSDateComponents alloc] init];
|
||||
if ( data->calendarTriggerYear >= 0)
|
||||
date.year = data->calendarTriggerYear;
|
||||
if (data->calendarTriggerMonth >= 0)
|
||||
date.month = data->calendarTriggerMonth;
|
||||
if (data->calendarTriggerDay >= 0)
|
||||
date.day = data->calendarTriggerDay;
|
||||
if (data->calendarTriggerHour >= 0)
|
||||
date.hour = data->calendarTriggerHour;
|
||||
if (data->calendarTriggerMinute >= 0)
|
||||
date.minute = data->calendarTriggerMinute;
|
||||
if (data->calendarTriggerSecond >= 0)
|
||||
date.second = data->calendarTriggerSecond;
|
||||
|
||||
trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:date repeats:data->repeats];
|
||||
}
|
||||
else if ( data->triggerType == LOCATION_TRIGGER)
|
||||
{
|
||||
#if defined(UNITY_USES_LOCATION) && UNITY_USES_LOCATION
|
||||
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(data->locationTriggerCenterX, data->locationTriggerCenterY);
|
||||
|
||||
CLCircularRegion* region = [[CLCircularRegion alloc] initWithCenter:center
|
||||
radius:data->locationTriggerRadius identifier:@"Headquarters"];
|
||||
region.notifyOnEntry = data->locationTriggerNotifyOnEntry;
|
||||
region.notifyOnExit = data->locationTriggerNotifyOnExit;
|
||||
|
||||
trigger = [UNLocationNotificationTrigger triggerWithRegion:region repeats:NO];
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:
|
||||
[NSString stringWithUTF8String:data->identifier] content:content trigger:trigger];
|
||||
|
||||
// Schedule the notification.
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
|
||||
|
||||
if (error != NULL)
|
||||
NSLog(@"%@",[error localizedDescription]);
|
||||
|
||||
[manager updateScheduledNotificationList];
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
NotificationSettingsData* _GetNotificationSettings()
|
||||
{
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
return [UnityNotificationManager UNNotificationSettingsToNotificationSettingsData:[manager cachedNotificationSettings]];
|
||||
}
|
||||
|
||||
int _GetScheduledNotificationDataCount()
|
||||
{
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
return (int)[manager.cachedPendingNotificationRequests count];
|
||||
}
|
||||
iOSNotificationData* _GetScheduledNotificationDataAt(int index)
|
||||
{
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
|
||||
if (index >= [manager.cachedPendingNotificationRequests count])
|
||||
return NULL;
|
||||
|
||||
UNNotificationRequest * request = manager.cachedPendingNotificationRequests[index];
|
||||
|
||||
|
||||
return [UnityNotificationManager UNNotificationRequestToiOSNotificationData : request];
|
||||
}
|
||||
|
||||
int _GetDeliveredNotificationDataCount()
|
||||
{
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
return [manager.cachedDeliveredNotifications count];
|
||||
}
|
||||
iOSNotificationData* _GetDeliveredNotificationDataAt(int index)
|
||||
{
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
|
||||
if (index >= [manager.cachedDeliveredNotifications count])
|
||||
return NULL;
|
||||
|
||||
UNNotification * notification = manager.cachedDeliveredNotifications[index];
|
||||
|
||||
return [UnityNotificationManager UNNotificationToiOSNotificationData: notification];
|
||||
}
|
||||
|
||||
|
||||
void _RemoveScheduledNotification(const char* identifier)
|
||||
{
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
[center removePendingNotificationRequestsWithIdentifiers:@[[NSString stringWithUTF8String:identifier]]];
|
||||
[[UnityNotificationManager sharedInstance] updateScheduledNotificationList];
|
||||
}
|
||||
|
||||
|
||||
void _RemoveAllScheduledNotifications()
|
||||
{
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
[center removeAllPendingNotificationRequests];
|
||||
[[UnityNotificationManager sharedInstance] updateScheduledNotificationList];
|
||||
}
|
||||
|
||||
void _RemoveDeliveredNotification(const char* identifier)
|
||||
{
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
[center removeDeliveredNotificationsWithIdentifiers:@[[NSString stringWithUTF8String:identifier]]];
|
||||
[[UnityNotificationManager sharedInstance] updateDeliveredNotificationList];
|
||||
}
|
||||
|
||||
void _RemoveAllDeliveredNotifications()
|
||||
{
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
[center removeAllDeliveredNotifications];
|
||||
[[UnityNotificationManager sharedInstance] updateDeliveredNotificationList];
|
||||
}
|
||||
|
||||
void _SetApplicationBadge(long badge)
|
||||
{
|
||||
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:badge];
|
||||
}
|
||||
|
||||
long _GetApplicationBadge()
|
||||
{
|
||||
return[UIApplication sharedApplication].applicationIconBadgeNumber;
|
||||
}
|
||||
|
||||
bool _GetAppOpenedUsingNotification()
|
||||
{
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
return manager.lastReceivedNotification != NULL;
|
||||
}
|
||||
|
||||
|
||||
iOSNotificationData* _GetLastNotificationData()
|
||||
{
|
||||
UnityNotificationManager* manager = [UnityNotificationManager sharedInstance];
|
||||
iOSNotificationData* data = [UnityNotificationManager UNNotificationRequestToiOSNotificationData : manager.lastReceivedNotification.request];
|
||||
return data;
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -516,5 +516,37 @@
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "E2A13FEA-03B1-44A2-A66B-EF0B840EBBDB"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "../../crypto/cocos_js/cocos/scripting/js-bindings/jswrapper/Value.cpp"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "539"
|
||||
endingLineNumber = "539"
|
||||
landmarkName = "Value::toObject()"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "8DEA81D0-F534-48B1-B519-461E07A17677"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Classes_cocos/AppDelegate.mm"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "69"
|
||||
endingLineNumber = "69"
|
||||
landmarkName = "AppDelegate::applicationDidFinishLaunching()"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
|
Loading…
x
Reference in New Issue
Block a user