From 1bf462b6ca3a1ed62544751ac1ccf6b70ed8d483 Mon Sep 17 00:00:00 2001 From: irov Date: Sun, 27 Aug 2023 21:03:29 +0300 Subject: [PATCH] Add GDPR allow for iOS Sentry --- src/Environment/iOS/CMakeLists.txt | 1 + .../iOS/UIMainApplicationDelegateInterface.h | 7 +++- .../iOS/UIProxyApplicationDelegateInterface.h | 2 + src/Environment/iOS/iOSDetail.h | 4 ++ src/Environment/iOS/iOSDetail.mm | 35 ++++++++++++++++ ...aProtectionRegulationApplicationDelegate.h | 3 ++ ...ProtectionRegulationApplicationDelegate.mm | 16 ++++++- ...leGeneralDataProtectionRegulationService.h | 5 +-- ...eGeneralDataProtectionRegulationService.mm | 24 +++++++---- .../AppleMARSDKAdRewardedDelegate.mm | 18 ++++---- .../AppleSentryApplicationDelegate.h | 2 + .../AppleSentryApplicationDelegate.mm | 26 ++++++++++++ src/SDLApplication/SDLUIApplicationDelegate.h | 6 ++- .../SDLUIApplicationDelegate.mm | 42 +++++++++++++++---- src/SDLApplication/iOSMain.mm | 4 +- 15 files changed, 158 insertions(+), 37 deletions(-) diff --git a/src/Environment/iOS/CMakeLists.txt b/src/Environment/iOS/CMakeLists.txt index d87593e676..894f5ea5ab 100644 --- a/src/Environment/iOS/CMakeLists.txt +++ b/src/Environment/iOS/CMakeLists.txt @@ -8,6 +8,7 @@ src iOSDetail.h iOSDetail.mm + UIMainApplicationDelegateInterface.h UIProxyApplicationDelegateInterface.h ) diff --git a/src/Environment/iOS/UIMainApplicationDelegateInterface.h b/src/Environment/iOS/UIMainApplicationDelegateInterface.h index 7d2269a71c..9919d5b3ab 100644 --- a/src/Environment/iOS/UIMainApplicationDelegateInterface.h +++ b/src/Environment/iOS/UIMainApplicationDelegateInterface.h @@ -1,9 +1,14 @@ #include "Config/Config.h" +#import "Environment/iOS/UIProxyApplicationDelegateInterface.h" + #import @protocol UIMainApplicationDelegateInterface -- (void)notify:(NSString *)id args:(NSArray *)args; +- (NSArray *)getPluginDelegates; + +- (void)notify:(NSString *)name args:(id)firstArg, ... NS_REQUIRES_NIL_TERMINATION; +- (void)notify:(NSString *)name arrayArgs:(NSArray *)args; @end diff --git a/src/Environment/iOS/UIProxyApplicationDelegateInterface.h b/src/Environment/iOS/UIProxyApplicationDelegateInterface.h index 92be086556..84f14f246f 100644 --- a/src/Environment/iOS/UIProxyApplicationDelegateInterface.h +++ b/src/Environment/iOS/UIProxyApplicationDelegateInterface.h @@ -10,6 +10,8 @@ @optional +- (void)event:(NSString *)name args:(NSArray *)args; + #pragma mark - UISceneSession lifecycle - (void)applicationWillResignActive:(UIApplication *)application; diff --git a/src/Environment/iOS/iOSDetail.h b/src/Environment/iOS/iOSDetail.h index 64642e5cf8..0b71fe728b 100644 --- a/src/Environment/iOS/iOSDetail.h +++ b/src/Environment/iOS/iOSDetail.h @@ -2,6 +2,8 @@ #include "Config/Config.h" +#import "Environment/iOS/UIProxyApplicationDelegateInterface.h" + #import #import @@ -11,5 +13,7 @@ namespace Mengine { UIViewController * iOSGetRootViewController(); NSUUID * iOSGetAdIdentifier(); + id iOSGetUIProxyApplicationDelegate( Class delegateClass ); + void iOSPluginApplicationDelegateEventNotify( NSString * name, id firstArg, ... ); } } diff --git a/src/Environment/iOS/iOSDetail.mm b/src/Environment/iOS/iOSDetail.mm index b47e2db7fc..e8cb9ce1f4 100644 --- a/src/Environment/iOS/iOSDetail.mm +++ b/src/Environment/iOS/iOSDetail.mm @@ -1,5 +1,7 @@ #include "iOSDetail.h" +#import "Environment/iOS/UIMainApplicationDelegateInterface.h" + #import namespace Mengine @@ -23,5 +25,38 @@ return idfa_uuid; } ////////////////////////////////////////////////////////////////////////// + id iOSGetUIProxyApplicationDelegate( Class delegateClass ) + { + NSObject * delegate = (NSObject *)[[UIApplication sharedApplication] delegate]; + + NSArray * pluginDelegates = [delegate getPluginDelegates]; + + for( NSObject * delegate : pluginDelegates ) { + if( [delegate isMemberOfClass:delegateClass] == YES ) { + return delegate; + } + } + + return nil; + } + ////////////////////////////////////////////////////////////////////////// + void iOSPluginApplicationDelegateEventNotify( NSString * name, id firstArg, ... ) + { + NSObject * delegate = (NSObject *)[[UIApplication sharedApplication] delegate]; + + va_list args; + va_start(args, firstArg); + + NSMutableArray * send_args = [[NSMutableArray alloc] init]; + + for( NSString *arg = firstArg; arg != nil; arg = va_arg(args, NSString*) ) { + [send_args addObject:firstArg]; + } + + va_end(args); + + [delegate notify:name arrayArgs:send_args]; + } + ////////////////////////////////////////////////////////////////////////// } } diff --git a/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationApplicationDelegate.h b/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationApplicationDelegate.h index 5d15160fe6..406852d1bf 100644 --- a/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationApplicationDelegate.h +++ b/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationApplicationDelegate.h @@ -2,4 +2,7 @@ @interface AppleGeneralDataProtectionRegulationApplicationDelegate : NSObject +- (void) setGDPRPass:(BOOL) passGDPR; +- (BOOL) isGDPRPass; + @end diff --git a/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationApplicationDelegate.mm b/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationApplicationDelegate.mm index 653258aa85..b4485a3fc8 100644 --- a/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationApplicationDelegate.mm +++ b/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationApplicationDelegate.mm @@ -1,14 +1,28 @@ #import "AppleGeneralDataProtectionRegulationApplicationDelegate.h" -#include "Environment/Apple/AppleUserDefaults.h" +#import "Environment/iOS/iOSDetail.h" +#import "Environment/Apple/AppleUserDefaults.h" @implementation AppleGeneralDataProtectionRegulationApplicationDelegate +- (void)setGDPRPass:(BOOL)passGDPR { + Mengine::Helper::AppleSetUserDefaultsBoolean( "mengine.gdpr.pass", passGDPR ); + + Mengine::Helper::iOSPluginApplicationDelegateEventNotify( @"NOTIFICATION_GDPR_PASS", @(passGDPR), nil ); +} + +- (BOOL)isGDPRPass { + bool passGDPR = Mengine::Helper::AppleGetUserDefaultsBoolean( "mengine.gdpr.pass", false ); + + return passGDPR; +} + #pragma mark - UIProxyApplicationDelegateInterface - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { bool passGDPR = Mengine::Helper::AppleGetUserDefaultsBoolean( "mengine.gdpr.pass", false ); + Mengine::Helper::iOSPluginApplicationDelegateEventNotify( @"NOTIFICATION_GDPR_PASS", @(passGDPR), nil ); return YES; } diff --git a/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationService.h b/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationService.h index c3a2654f5b..5aea3a28d2 100644 --- a/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationService.h +++ b/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationService.h @@ -19,9 +19,6 @@ namespace Mengine public: void setGDPRPass( bool _passGDPR ) override; - bool isGDPRPass() const override; - - protected: - bool m_passGDPR; + bool isGDPRPass() const override; }; } diff --git a/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationService.mm b/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationService.mm index 088a1a7058..3d1ab784eb 100644 --- a/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationService.mm +++ b/src/Plugins/AppleGeneralDataProtectionRegulationPlugin/AppleGeneralDataProtectionRegulationService.mm @@ -1,9 +1,14 @@ #include "AppleGeneralDataProtectionRegulationService.h" -#include "Environment/Apple/AppleUserDefaults.h" +#import "AppleGeneralDataProtectionRegulationApplicationDelegate.h" + +#import "Environment/iOS/iOSDetail.h" +#import "Environment/Apple/AppleUserDefaults.h" #include "Kernel/Logger.h" +#import + //////////////////////////////////////////////////////////////////////////// SERVICE_FACTORY( AppleGeneralDataProtectionRegulationService, Mengine::AppleGeneralDataProtectionRegulationService ); ////////////////////////////////////////////////////////////////////////// @@ -11,7 +16,6 @@ { ////////////////////////////////////////////////////////////////////////// AppleGeneralDataProtectionRegulationService::AppleGeneralDataProtectionRegulationService() - : m_passGDPR(false) { } ////////////////////////////////////////////////////////////////////////// @@ -21,9 +25,7 @@ ///////////////////////////////////////////////////////////////////////////// bool AppleGeneralDataProtectionRegulationService::_initializeService() { - bool passGDPR = Helper::AppleGetUserDefaultsBoolean( "mengine.gdpr.pass", false ); - - m_passGDPR = passGDPR; + //Empty return true; } @@ -39,14 +41,18 @@ , _passGDPR ); - Helper::AppleSetUserDefaultsBoolean( "mengine.gdpr.pass", _passGDPR ); - - m_passGDPR = _passGDPR; + AppleGeneralDataProtectionRegulationApplicationDelegate * delegate = Helper::iOSGetUIProxyApplicationDelegate([AppleGeneralDataProtectionRegulationApplicationDelegate class]); + + [delegate setGDPRPass:(BOOL)_passGDPR]; } ////////////////////////////////////////////////////////////////////////// bool AppleGeneralDataProtectionRegulationService::isGDPRPass() const { - return m_passGDPR; + AppleGeneralDataProtectionRegulationApplicationDelegate * delegate = Helper::iOSGetUIProxyApplicationDelegate([AppleGeneralDataProtectionRegulationApplicationDelegate class]); + + BOOL passGDPR = [delegate isGDPRPass]; + + return passGDPR; } ////////////////////////////////////////////////////////////////////////// } diff --git a/src/Plugins/AppleMARSDKPlugin/AppleMARSDKAdRewardedDelegate.mm b/src/Plugins/AppleMARSDKPlugin/AppleMARSDKAdRewardedDelegate.mm index a22b177eea..53cd2fd9d2 100644 --- a/src/Plugins/AppleMARSDKPlugin/AppleMARSDKAdRewardedDelegate.mm +++ b/src/Plugins/AppleMARSDKPlugin/AppleMARSDKAdRewardedDelegate.mm @@ -11,7 +11,7 @@ @implementation AppleMARSDKAdRewardedDelegate @synthesize m_service; -- (instancetype _Nonnull)initWithService: (Mengine::AppleMARSDKServiceInterface* _Nonnull)service { +- (instancetype _Nonnull)initWithService:(Mengine::AppleMARSDKServiceInterface* _Nonnull)service { self = [super init]; self.m_service = service; @@ -21,7 +21,7 @@ - (instancetype _Nonnull)initWithService: (Mengine::AppleMARSDKServiceInterface* #pragma mark - MARAdRewardedDelegate -- (void) MARAdRewardedDidFailed: (MARAdErrorCode)code withMessage: (NSString *)message adDict:(NSDictionary *)adDict { +- (void) MARAdRewardedDidFailed:(MARAdErrorCode)code withMessage: (NSString *)message adDict:(NSDictionary *)adDict { LOGGER_MESSAGE( "MARAdRewardedDidFailed code: %d message: %s adDict: %s" , (int32_t)code , [message UTF8String] @@ -38,7 +38,7 @@ - (void) MARAdRewardedDidFailed: (MARAdErrorCode)code withMessage: (NSString *)m provider->onAdRewardedDidFailed(); } -- (void) MARAdRewardedDidLoaded :(NSDictionary *)adDict { +- (void) MARAdRewardedDidLoaded:(NSDictionary *)adDict { LOGGER_MESSAGE( "MARAdRewardedDidLoaded adDict: %s" , [[NSString stringWithFormat:@"%@", adDict] UTF8String] ); @@ -53,7 +53,7 @@ - (void) MARAdRewardedDidLoaded :(NSDictionary *)adDict { provider->onAdRewardedDidLoaded(); } -- (void) MARAdRewardedDidShow :(NSDictionary *)adDict { +- (void) MARAdRewardedDidShow:(NSDictionary *)adDict { LOGGER_MESSAGE( "MARAdRewardedDidShow adDict: %s" , [[NSString stringWithFormat:@"%@", adDict] UTF8String] ); @@ -68,7 +68,7 @@ - (void) MARAdRewardedDidShow :(NSDictionary *)adDict { provider->onAdRewardedDidShow(); } -- (void) MARAdRewardedDidShowFailed :(NSDictionary *)adDict { +- (void) MARAdRewardedDidShowFailed:(NSDictionary *)adDict { LOGGER_MESSAGE( "MARAdRewardedDidShowFailed adDict: %s" , [[NSString stringWithFormat:@"%@", adDict] UTF8String] ); @@ -83,7 +83,7 @@ - (void) MARAdRewardedDidShowFailed :(NSDictionary *)adDict { provider->onAdRewardedDidShowFailed(); } -- (void) MARAdRewardedDidClicked :(NSDictionary *)adDict { +- (void) MARAdRewardedDidClicked:(NSDictionary *)adDict { LOGGER_MESSAGE( "MARAdRewardedDidClicked adDict: %s" , [[NSString stringWithFormat:@"%@", adDict] UTF8String] ); @@ -98,7 +98,7 @@ - (void) MARAdRewardedDidClicked :(NSDictionary *)adDict { provider->onAdRewardedDidClicked(); } -- (void) MARAdRewardedDidClosed :(NSDictionary *)adDict { +- (void) MARAdRewardedDidClosed:(NSDictionary *)adDict { LOGGER_MESSAGE( "MARAdRewardedDidClosed adDict: %s" , [[NSString stringWithFormat:@"%@", adDict] UTF8String] ); @@ -113,7 +113,7 @@ - (void) MARAdRewardedDidClosed :(NSDictionary *)adDict { provider->onAdRewardedDidClosed(); } -- (void) MARAdRewardedDidSkipped :(NSDictionary *)adDict { +- (void) MARAdRewardedDidSkipped:(NSDictionary *)adDict { LOGGER_MESSAGE( "MARAdRewardedDidSkipped adDict: %s" , [[NSString stringWithFormat:@"%@", adDict] UTF8String] ); @@ -128,7 +128,7 @@ - (void) MARAdRewardedDidSkipped :(NSDictionary *)adDict { provider->onAdRewardedDidSkipped(); } -- (void) MARAdRewardedDidFinished: (NSString *)itemName itemNum:(int)itemNum adDict:(NSDictionary *)adDict { +- (void) MARAdRewardedDidFinished:(NSString *)itemName itemNum:(int)itemNum adDict:(NSDictionary *)adDict { LOGGER_MESSAGE( "MARAdRewardedDidFinished adDict: %s" , [[NSString stringWithFormat:@"%@", adDict] UTF8String] ); diff --git a/src/Plugins/AppleSentryPlugin/AppleSentryApplicationDelegate.h b/src/Plugins/AppleSentryPlugin/AppleSentryApplicationDelegate.h index 3bff8a36b4..9b8048e62c 100644 --- a/src/Plugins/AppleSentryPlugin/AppleSentryApplicationDelegate.h +++ b/src/Plugins/AppleSentryPlugin/AppleSentryApplicationDelegate.h @@ -2,4 +2,6 @@ @interface AppleSentryApplicationDelegate : NSObject +@property (assign) BOOL m_sendAllow; + @end diff --git a/src/Plugins/AppleSentryPlugin/AppleSentryApplicationDelegate.mm b/src/Plugins/AppleSentryPlugin/AppleSentryApplicationDelegate.mm index 7290618fd2..27d899151d 100644 --- a/src/Plugins/AppleSentryPlugin/AppleSentryApplicationDelegate.mm +++ b/src/Plugins/AppleSentryPlugin/AppleSentryApplicationDelegate.mm @@ -10,6 +10,26 @@ @implementation AppleSentryApplicationDelegate #pragma mark - UIProxyApplicationDelegateInterface +- (instancetype _Nonnull)init { + self = [super init]; + + self.m_sendAllow = NO; + + return self; +} + +- (void)event:(NSString *)name args:(NSArray *)args { + if( [name isEqualToString:@"NOTIFICATION_GDPR_PASS"] == true ) { + BOOL passGDPR = [args[0] boolValue]; + + if( passGDPR == YES ) { + self.m_sendAllow = YES; + } else { + self.m_sendAllow = NO; + } + } +} + - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSString * AppleSentryPlugin_DSN = Mengine::Helper::AppleGetBundlePluginConfigString( @("MengineAppleSentryPlugin"), @("DSN"), nil ); @@ -36,11 +56,17 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( options.environment = @(ENVIRONMENT); options.beforeSend = ^SentryEvent * _Nullable(SentryEvent * _Nonnull event) { + if( self.m_sendAllow == NO ) { + return nil; + } return event; }; options.beforeBreadcrumb = ^SentryBreadcrumb * _Nullable(SentryBreadcrumb * _Nonnull breadcrumb) { + if( self.m_sendAllow == NO ) { + return nil; + } return breadcrumb; }; diff --git a/src/SDLApplication/SDLUIApplicationDelegate.h b/src/SDLApplication/SDLUIApplicationDelegate.h index 14f5a724fe..b53d32b94b 100644 --- a/src/SDLApplication/SDLUIApplicationDelegate.h +++ b/src/SDLApplication/SDLUIApplicationDelegate.h @@ -1,7 +1,9 @@ #import -@interface SDLUIApplicationDelegate : NSObject +#import "Environment/iOS/UIMainApplicationDelegateInterface.h" -@property (nonatomic, strong) NSMutableArray * m_pluginDelegates; +@interface SDLUIApplicationDelegate : NSObject + +@property (nonatomic, strong) NSMutableArray * m_pluginDelegates; @end diff --git a/src/SDLApplication/SDLUIApplicationDelegate.mm b/src/SDLApplication/SDLUIApplicationDelegate.mm index a72110e7a6..3d90f7aee4 100644 --- a/src/SDLApplication/SDLUIApplicationDelegate.mm +++ b/src/SDLApplication/SDLUIApplicationDelegate.mm @@ -37,6 +37,35 @@ - (void)dealloc { [super dealloc]; } +#pragma mark - UIMainApplicationDelegateInterface Protocol + +- (NSArray *)getPluginDelegates { + return self.m_pluginDelegates; +} + +- (void)notify:(NSString *)name args:(id)firstArg, ... NS_REQUIRES_NIL_TERMINATION { + va_list args; + va_start(args, firstArg); + + NSMutableArray * send_args = [[NSMutableArray alloc] init]; + + for( NSString *arg = firstArg; arg != nil; arg = va_arg(args, NSString*) ) { + [send_args addObject:firstArg]; + } + + va_end(args); + + [self notify:name arrayArgs:send_args]; +} + +- (void)notify:(NSString *)name arrayArgs:(NSArray *)args { + for (id delegate in self.m_pluginDelegates) { + if ([delegate respondsToSelector:@selector(event: args:)] == YES) { + [delegate event:name args:args]; + } + } +} + #pragma mark - UIApplicationDelegate Protocol - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions API_AVAILABLE(ios(3.0)) { @@ -46,8 +75,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( } } - SDL_SetMainReady(); - [self performSelector:@selector(postFinishLaunch) withObject:nil afterDelay:0.0]; return YES; @@ -62,7 +89,6 @@ - (void)application:(UIApplication *)application didRegisterForRemoteNotificatio } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler API_AVAILABLE(ios(7.0)) { - for (id delegate in self.m_pluginDelegates) { if ([delegate respondsToSelector:@selector(application: didReceiveRemoteNotification: fetchCompletionHandler:)] == YES) { [delegate application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; @@ -134,19 +160,17 @@ - (void)setWindow:(UIWindow *)window { } - (void)postFinishLaunch { - /* run the user's application, passing argc and argv */ + SDL_SetMainReady(); + SDL_iPhoneSetEventPump(SDL_TRUE); Mengine::SDLApplication application; bool initialize = application.initialize( 0, nullptr ); - if( initialize == true ) - { + if( initialize == true ) { application.loop(); - } - else - { + } else { SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, "Mengine initialize", "Mengine invalid initialization", NULL ); } diff --git a/src/SDLApplication/iOSMain.mm b/src/SDLApplication/iOSMain.mm index 9f9a5cba0f..fa80daf1b0 100644 --- a/src/SDLApplication/iOSMain.mm +++ b/src/SDLApplication/iOSMain.mm @@ -1,10 +1,10 @@ -#import "MengineUIKitDelegate.h" +#import "SDLUIApplicationDelegate.h" #import int main( int argc, char * argv[] ) { @autoreleasepool { - int result = UIApplicationMain(argc, argv, nil, NSStringFromClass([MengineUIKitDelegate class])); + int result = UIApplicationMain(argc, argv, nil, NSStringFromClass([SDLUIApplicationDelegate class])); return result; }