@@ -63,6 +63,46 @@ static void oldFn (UIApplication* app)
6363 }
6464 };
6565
66+ /* Each successful call to beginBackgroundTask must be balanced
67+ by a call to endBackgroundTask.
68+ */
69+ class TaskHandle
70+ {
71+ public:
72+ TaskHandle () = default ;
73+
74+ explicit TaskHandle (UIBackgroundTaskIdentifier t)
75+ : task (t) {}
76+
77+ ~TaskHandle ()
78+ {
79+ if (task != UIBackgroundTaskInvalid)
80+ [[UIApplication sharedApplication ] endBackgroundTask: task];
81+ }
82+
83+ TaskHandle (TaskHandle&& other) noexcept
84+ {
85+ swap (other);
86+ }
87+
88+ TaskHandle& operator = (TaskHandle&& other) noexcept
89+ {
90+ TaskHandle { std::move (other) }.swap (*this );
91+ return *this ;
92+ }
93+
94+ TaskHandle (const TaskHandle&) = delete ;
95+ TaskHandle& operator = (const TaskHandle&) = delete ;
96+
97+ private:
98+ void swap (TaskHandle& other) noexcept
99+ {
100+ std::swap (other.task , task);
101+ }
102+
103+ UIBackgroundTaskIdentifier task = UIBackgroundTaskInvalid;
104+ };
105+
66106 struct SceneUtils
67107 {
68108 // This will need to become more sophisticated to enable support for multiple scenes
@@ -80,20 +120,20 @@ static void sceneWillResignActive()
80120 appBecomingInactiveCallbacks.getReference (i)->appBecomingInactive ();
81121 }
82122
83- static void sceneDidEnterBackground ()
123+ template <typename Self>
124+ static void sceneDidEnterBackground ([[maybe_unused]] Self* s)
84125 {
85126 if (auto * app = JUCEApplicationBase::getInstance ())
86127 {
87128 #if JUCE_EXECUTE_APP_SUSPEND_ON_BACKGROUND_TASK
88- appSuspendTask = [application beginBackgroundTaskWithName: @" JUCE Suspend Task" expirationHandler: ^{
89- if (appSuspendTask != UIBackgroundTaskInvalid)
90- {
91- [application endBackgroundTask: appSuspendTask];
92- appSuspendTask = UIBackgroundTaskInvalid;
93- }
94- }];
129+ s->appSuspendTask = TaskHandle { [[UIApplication sharedApplication ] beginBackgroundTaskWithName: @" JUCE Suspend Task"
130+ expirationHandler: ^{ s->appSuspendTask = {}; }] };
95131
96- MessageManager::callAsync ([app] { app->suspended (); });
132+ MessageManager::callAsync ([app, s]
133+ {
134+ app->suspended ();
135+ s->appSuspendTask = {};
136+ });
97137 #else
98138 app->suspended ();
99139 #endif
@@ -112,10 +152,17 @@ static void sceneWillEnterForeground()
112152
113153API_AVAILABLE (ios (13.0 ))
114154@interface JuceAppSceneDelegate : NSObject<UIWindowSceneDelegate>
155+ {
156+ @public
157+ TaskHandle appSuspendTask;
158+ }
115159@end
116160
117161@implementation JuceAppSceneDelegate
118- SharedResourcePointer<WindowSceneTracker> windowSceneTracker;
162+ {
163+ SharedResourcePointer<WindowSceneTracker> windowSceneTracker;
164+ }
165+
119166- (void ) scene : (UIScene*) scene
120167 willConnectToSession : (UISceneSession*) session
121168 options : (UISceneConnectionOptions*) connectionOptions
@@ -144,7 +191,7 @@ - (void) sceneWillResignActive: (UIScene*) scene
144191
145192- (void ) sceneDidEnterBackground : (UIScene*) scene
146193{
147- SceneUtils::sceneDidEnterBackground ( );
194+ SceneUtils::sceneDidEnterBackground (self );
148195}
149196
150197- (void ) sceneWillEnterForeground : (UIScene*) scene
@@ -167,7 +214,8 @@ @interface JuceAppStartupDelegate : NSObject <UIApplicationDelegate, UNUserNotif
167214@interface JuceAppStartupDelegate : NSObject <UIApplicationDelegate>
168215#endif
169216{
170- UIBackgroundTaskIdentifier appSuspendTask;
217+ @public
218+ TaskHandle appSuspendTask;
171219 std::optional<ScopedJuceInitialiser_GUI> initialiser;
172220}
173221
@@ -216,13 +264,13 @@ - (void) userNotificationCenter: (UNUserNotificationCenter*) center
216264@end
217265
218266@implementation JuceAppStartupDelegate
219-
267+ {
220268 NSObject * _pushNotificationsDelegate;
269+ }
221270
222271- (id ) init
223272{
224273 self = [super init ];
225- appSuspendTask = UIBackgroundTaskInvalid;
226274
227275 #if JUCE_PUSH_NOTIFICATIONS
228276 [UNUserNotificationCenter currentNotificationCenter ].delegate = self;
@@ -260,7 +308,7 @@ - (void) applicationWillTerminate: (UIApplication*) application
260308
261309- (void ) applicationDidEnterBackground : (UIApplication*) application
262310{
263- SceneUtils::sceneDidEnterBackground ( );
311+ SceneUtils::sceneDidEnterBackground (self );
264312}
265313
266314- (void ) applicationWillEnterForeground : (UIApplication*) application
0 commit comments