增加一些游戏中的插件

This commit is contained in:
CounterFire2023 2023-08-03 18:57:33 +08:00
parent 8a91dab9db
commit beedd5b8d7
22 changed files with 3609 additions and 648 deletions

View File

@ -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();
});

View 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;
}

View 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

View 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>
**/

View 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";

View 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

View 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 = @"";

View 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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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>