Commit 787a54c84b3181785a51d29ebecb9dfb966b4465

Alex Szpakowski 2016-12-18T12:28:28

iOS bug #3377: work around bugs in some third party iOS libraries (e.g. Google admob) where they assume the optional UIApplicationDelegate ?window? property always exists and will crash if it doesn?t.

diff --git a/src/video/uikit/SDL_uikitappdelegate.h b/src/video/uikit/SDL_uikitappdelegate.h
index edf09f5..880cccc 100644
--- a/src/video/uikit/SDL_uikitappdelegate.h
+++ b/src/video/uikit/SDL_uikitappdelegate.h
@@ -36,6 +36,12 @@
 
 - (void)hideLaunchScreen;
 
+/* This property is marked as optional, and is only intended to be used when
+ * the app's UI is storyboard-based. SDL is not storyboard-based, however
+ * several major third-party ad APIs (e.g. Google admob) incorrectly assume this
+ * property always exists, and will crash if it doesn't. */
+@property (nonatomic) UIWindow *window;
+
 @end
 
 /* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/uikit/SDL_uikitappdelegate.m b/src/video/uikit/SDL_uikitappdelegate.m
index c94c78a..fa37faa 100644
--- a/src/video/uikit/SDL_uikitappdelegate.m
+++ b/src/video/uikit/SDL_uikitappdelegate.m
@@ -422,6 +422,26 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
     return YES;
 }
 
+- (UIWindow *)window
+{
+    SDL_VideoDevice *_this = SDL_GetVideoDevice();
+    if (_this) {
+        SDL_Window *window = NULL;
+        for (window = _this->windows; window != NULL; window = window->next) {
+            SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+            if (data != nil) {
+                return data.uiwindow;
+            }
+        }
+    }
+    return nil;
+}
+
+- (void)setWindow:(UIWindow *)window
+{
+    /* Do nothing. */
+}
+
 - (void)applicationWillTerminate:(UIApplication *)application
 {
     SDL_SendAppEvent(SDL_APP_TERMINATING);
@@ -467,7 +487,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
     SDL_VideoDevice *_this = SDL_GetVideoDevice();
     if (_this) {
         SDL_Window *window;
-        for (window = _this->windows; window != nil; window = window->next) {
+        for (window = _this->windows; window != NULL; window = window->next) {
             SDL_SendWindowEvent(window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
             SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
         }