diff --git a/iphone/Classes/AppModule.m b/iphone/Classes/AppModule.m index 010b7bf3748..4c6ff86d0b6 100644 --- a/iphone/Classes/AppModule.m +++ b/iphone/Classes/AppModule.m @@ -48,9 +48,23 @@ - (void)_resumeRestart:(id)unused #ifndef TI_USE_AUTOLAYOUT [TiLayoutQueue resetQueue]; #endif + + // Get the currently active scene + UIScene *activeScene = nil; + for (UIScene *scene in UIApplication.sharedApplication.connectedScenes) { + if (scene.activationState == UISceneActivationStateForegroundActive) { + activeScene = scene; + break; + } + } + + if (activeScene == nil) { + NSLog(@"[ERROR] No active scene connected - this may lead to an undefined behavior"); + } + /* Begin backgrounding simulation */ - [appDelegate applicationWillResignActive:app]; - [appDelegate applicationDidEnterBackground:app]; + [appDelegate sceneWillResignActive:activeScene]; + [appDelegate sceneDidEnterBackground:activeScene]; [appDelegate endBackgrounding]; /* End backgrounding simulation */ @@ -76,8 +90,9 @@ - (void)_resumeRestart:(id)unused /* Begin foregrounding simulation */ [appDelegate application:app didFinishLaunchingWithOptions:[appDelegate launchOptions]]; - [appDelegate applicationWillEnterForeground:app]; - [appDelegate applicationDidBecomeActive:app]; + [appDelegate scene:activeScene willConnectToSession:activeScene.session options:TiApp.app.connectionOptions]; + [appDelegate sceneWillEnterForeground:activeScene]; + [appDelegate sceneDidBecomeActive:activeScene]; /* End foregrounding simulation */ } diff --git a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.h b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.h index a9fe584766f..909962df8c5 100644 --- a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.h +++ b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.h @@ -26,6 +26,7 @@ KrollBridge *kjsBridge; NSMutableDictionary *launchOptions; + UISceneConnectionOptions *_connectionOptions; NSTimeInterval started; int32_t networkActivityCount; @@ -112,6 +113,13 @@ */ @property (nonatomic, readonly) NSDictionary *localNotification; +/** + Returns details for the last remote notification. + + Dictionary containing details about remote notification, or _nil_. + */ +@property (nonatomic, readonly) UISceneConnectionOptions *connectionOptions; + /** Returns the application's root view controller. */ diff --git a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.m b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.m index ec6803de5a6..bf4558f7789 100644 --- a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.m +++ b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiApp.m @@ -48,6 +48,7 @@ @implementation TiApp @synthesize localNotification; @synthesize appBooted; @synthesize userAgent; +@synthesize connectionOptions; + (TiApp *)app { @@ -1062,6 +1063,7 @@ - (void)dealloc RELEASE_TO_NIL(queuedBootEvents); RELEASE_TO_NIL(_queuedApplicationSelectors); RELEASE_TO_NIL(_applicationDelegates); + RELEASE_TO_NIL(_connectionOptions); [super dealloc]; } @@ -1110,6 +1112,12 @@ - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session op // Initialize the launch options to be used by the client launchOptions = [[NSMutableDictionary alloc] init]; + // Retain connectionOptions for later use + if (_connectionOptions != connectionOptions) { + [_connectionOptions release]; // Release any existing object + _connectionOptions = [connectionOptions retain]; // Retain the new object + } + // If we have a APNS-UUID, assign it NSString *apnsUUID = [[NSUserDefaults standardUserDefaults] stringForKey:@"APNSRemoteDeviceUUID"]; if (apnsUUID != nil) { diff --git a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiRootViewController.m b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiRootViewController.m index 9f2ce2ff219..0d84e415f16 100644 --- a/iphone/TitaniumKit/TitaniumKit/Sources/API/TiRootViewController.m +++ b/iphone/TitaniumKit/TitaniumKit/Sources/API/TiRootViewController.m @@ -696,7 +696,8 @@ - (void)shutdownUi:(id)arg if (![TiSharedConfig defaultConfig].debugEnabled) { return; } - //FIRST DISMISS ALL MODAL WINDOWS + + // Dismiss all currently opened windows UIViewController *topVC = [self topPresentedController]; if (topVC != self) { UIViewController *presenter = [topVC presentingViewController]; @@ -706,7 +707,8 @@ - (void)shutdownUi:(id)arg }]; return; } - //At this point all modal stuff is done. Go ahead and clean up proxies. + + // Clean up proxies. NSArray *modalCopy = [modalWindows copy]; NSArray *windowCopy = [containedWindows copy]; @@ -725,7 +727,8 @@ - (void)shutdownUi:(id)arg [windowCopy release]; } - DebugLog(@"[INFO] UI SHUTDOWN COMPLETE. TRYING TO RESUME RESTART"); + DebugLog(@"[WARN] Calling the private `_restart()` API should not be done in production, as restarting an app is not a recommended native concept."); + if ([arg respondsToSelector:@selector(_resumeRestart:)]) { [arg performSelector:@selector(_resumeRestart:) withObject:nil]; } else {