SDL: [UIKit] handle app lifecycle events in a custom object instead of AppDelegate

From 5b13136471e36872741b35dca70ec6f6f0401a7a Mon Sep 17 00:00:00 2001
From: Andrey Filipenkov <[EMAIL REDACTED]>
Date: Sat, 6 Aug 2022 10:48:53 +0300
Subject: [PATCH] [UIKit] handle app lifecycle events in a custom object
 instead of AppDelegate

removes the need to call SDL counterparts manually when custom AppDelegate is used
---
 src/video/uikit/SDL_uikitappdelegate.m | 37 -------------
 src/video/uikit/SDL_uikitevents.m      | 74 ++++++++++++++++++++++++++
 2 files changed, 74 insertions(+), 37 deletions(-)

diff --git a/src/video/uikit/SDL_uikitappdelegate.m b/src/video/uikit/SDL_uikitappdelegate.m
index 635ed7615dc9..37bd4c78604e 100644
--- a/src/video/uikit/SDL_uikitappdelegate.m
+++ b/src/video/uikit/SDL_uikitappdelegate.m
@@ -434,43 +434,6 @@ - (void)setWindow:(UIWindow *)window
     /* Do nothing. */
 }
 
-#if !TARGET_OS_TV
-- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation
-{
-    SDL_OnApplicationDidChangeStatusBarOrientation();
-}
-#endif
-
-- (void)applicationWillTerminate:(UIApplication *)application
-{
-    SDL_OnApplicationWillTerminate();
-}
-
-- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
-{
-    SDL_OnApplicationDidReceiveMemoryWarning();
-}
-
-- (void)applicationWillResignActive:(UIApplication*)application
-{
-    SDL_OnApplicationWillResignActive();
-}
-
-- (void)applicationDidEnterBackground:(UIApplication*)application
-{
-    SDL_OnApplicationDidEnterBackground();
-}
-
-- (void)applicationWillEnterForeground:(UIApplication*)application
-{
-    SDL_OnApplicationWillEnterForeground();
-}
-
-- (void)applicationDidBecomeActive:(UIApplication*)application
-{
-    SDL_OnApplicationDidBecomeActive();
-}
-
 - (void)sendDropFileForURL:(NSURL *)url
 {
     NSURL *fileURL = url.filePathURL;
diff --git a/src/video/uikit/SDL_uikitevents.m b/src/video/uikit/SDL_uikitevents.m
index 286db8f33bb1..61c57b2539c3 100644
--- a/src/video/uikit/SDL_uikitevents.m
+++ b/src/video/uikit/SDL_uikitevents.m
@@ -41,10 +41,84 @@
 
 static BOOL UIKit_EventPumpEnabled = YES;
 
+
+@interface SDL_LifecycleObserver : NSObject
+@property (nonatomic, assign) BOOL isObservingNotifications;
+@end
+
+@implementation SDL_LifecycleObserver
+
+- (void)eventPumpChanged
+{
+    NSNotificationCenter *notificationCenter = NSNotificationCenter.defaultCenter;
+    if (UIKit_EventPumpEnabled && !self.isObservingNotifications) {
+        self.isObservingNotifications = YES;
+        [notificationCenter addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
+        [notificationCenter addObserver:self selector:@selector(applicationWillResignActive) name:UIApplicationWillResignActiveNotification object:nil];
+        [notificationCenter addObserver:self selector:@selector(applicationDidEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
+        [notificationCenter addObserver:self selector:@selector(applicationWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
+        [notificationCenter addObserver:self selector:@selector(applicationWillTerminate) name:UIApplicationWillTerminateNotification object:nil];
+        [notificationCenter addObserver:self selector:@selector(applicationDidReceiveMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
+#if !TARGET_OS_TV
+        [notificationCenter addObserver:self selector:@selector(applicationDidChangeStatusBarOrientation) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
+#endif
+    } else if (!UIKit_EventPumpEnabled && self.isObservingNotifications) {
+        self.isObservingNotifications = NO;
+        [notificationCenter removeObserver:self];
+    }
+}
+
+- (void)applicationDidBecomeActive
+{
+    SDL_OnApplicationDidBecomeActive();
+}
+
+- (void)applicationWillResignActive
+{
+    SDL_OnApplicationWillResignActive();
+}
+
+- (void)applicationDidEnterBackground
+{
+    SDL_OnApplicationDidEnterBackground();
+}
+
+- (void)applicationWillEnterForeground
+{
+    SDL_OnApplicationWillEnterForeground();
+}
+
+- (void)applicationWillTerminate
+{
+    SDL_OnApplicationWillTerminate();
+}
+
+- (void)applicationDidReceiveMemoryWarning
+{
+    SDL_OnApplicationDidReceiveMemoryWarning();
+}
+
+#if !TARGET_OS_TV
+- (void)applicationDidChangeStatusBarOrientation
+{
+    SDL_OnApplicationDidChangeStatusBarOrientation();
+}
+#endif
+
+@end
+
+
 void
 SDL_iPhoneSetEventPump(SDL_bool enabled)
 {
     UIKit_EventPumpEnabled = enabled;
+
+    static SDL_LifecycleObserver *lifecycleObserver;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        lifecycleObserver = [SDL_LifecycleObserver new];
+    });
+    [lifecycleObserver eventPumpChanged];
 }
 
 void