diff --git a/modules/juce_events/juce_events.h b/modules/juce_events/juce_events.h index a03319584d..114a7a2a59 100644 --- a/modules/juce_events/juce_events.h +++ b/modules/juce_events/juce_events.h @@ -57,6 +57,15 @@ #include +//============================================================================== +/** Config: JUCE_EXECUTE_APP_SUSPEND_ON_IOS_BACKGROUND_TASK + Will execute your application's suspend method on an iOS background task, giving + you extra time to save your applications state. +*/ +#ifndef JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK + #define JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK 0 +#endif + #if JUCE_EVENTS_INCLUDE_WINRT_WRAPPER && JUCE_WINDOWS #include #endif diff --git a/modules/juce_gui_basics/native/juce_ios_Windowing.mm b/modules/juce_gui_basics/native/juce_ios_Windowing.mm index 0e605f79c5..bcdac9ff8e 100644 --- a/modules/juce_gui_basics/native/juce_ios_Windowing.mm +++ b/modules/juce_gui_basics/native/juce_ios_Windowing.mm @@ -37,9 +37,11 @@ Array appBecomingInactiveCallbacks; @interface JuceAppStartupDelegate : NSObject { + UIBackgroundTaskIdentifier appSuspendTask; } @property (strong, nonatomic) UIWindow *window; +- (id)init; - (void) applicationDidFinishLaunching: (UIApplication*) application; - (void) applicationWillTerminate: (UIApplication*) application; - (void) applicationDidEnterBackground: (UIApplication*) application; @@ -52,6 +54,14 @@ Array appBecomingInactiveCallbacks; @implementation JuceAppStartupDelegate +- (id)init +{ + self = [super init]; + appSuspendTask = UIBackgroundTaskInvalid; + + return self; +} + - (void) applicationDidFinishLaunching: (UIApplication*) application { ignoreUnused (application); @@ -76,10 +86,31 @@ Array appBecomingInactiveCallbacks; - (void) applicationDidEnterBackground: (UIApplication*) application { - ignoreUnused (application); - if (JUCEApplicationBase* const app = JUCEApplicationBase::getInstance()) + { + #if JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK + appSuspendTask = [application beginBackgroundTaskWithName:@"JUCE Suspend Task" expirationHandler:^{ + if (appSuspendTask != UIBackgroundTaskInvalid) + { + [application endBackgroundTask:appSuspendTask]; + appSuspendTask = UIBackgroundTaskInvalid; + } + }]; + + MessageManager::callAsync ([self,application,app] () + { + app->suspended(); + if (appSuspendTask != UIBackgroundTaskInvalid) + { + [application endBackgroundTask:appSuspendTask]; + appSuspendTask = UIBackgroundTaskInvalid; + } + }); + #else + ignoreUnused (application); app->suspended(); + #endif + } } - (void) applicationWillEnterForeground: (UIApplication*) application