@@ -8,7 +8,7 @@ import { SDK_VERSION } from '../utils/constants';
88import { ios as iosUtils , dataSerialize , dataDeserialize } from '../utils/native-helper' ;
99import { ApplicationCommon } from './application-common' ;
1010import { ApplicationEventData , SceneContinueUserActivityEventData , SceneEventData , SceneOpenURLContextsEventData , ScenePerformActionForShortcutItemEventData } from './application-interfaces' ;
11- import { deliverShortcutItem , forwardContinueUserActivity , forwardOpenURLContexts , oneShotCompletion } from './scene-delegate-bridge' ;
11+ import { deliverShortcutItem , forwardContinueUserActivity , forwardOpenURLContexts , getLaunchUserActivities , oneShotCompletion } from './scene-delegate-bridge' ;
1212import { Observable } from '../data/observable' ;
1313import type { iOSApplication as IiOSApplication } from './application' ;
1414import { Trace } from '../trace' ;
@@ -255,6 +255,104 @@ function getSceneConnectionData(connectionOptions: UISceneConnectionOptions): Re
255255 return activity ?. userInfo ? ( dataDeserialize ( activity . userInfo ) as Record < string , any > ) : undefined ;
256256}
257257
258+ /**
259+ * The activity type `openWindow()` uses to hand its data to the scene it opens.
260+ */
261+ function getSceneActivityType ( ) : string {
262+ return `${ NSBundle . mainBundle . bundleIdentifier } .scene` ;
263+ }
264+
265+ function deliverOpenURLContexts ( windowScene : UIWindowScene , nativeWindow : IOSNativeWindow | undefined , URLContexts : NSSet < UIOpenURLContext > ) : void {
266+ if ( nativeWindow ) {
267+ nativeWindow . notify ( {
268+ eventName : NativeWindowEvents . sceneOpenURLContexts ,
269+ object : nativeWindow ,
270+ window : nativeWindow ,
271+ scene : windowScene ,
272+ urlContexts : URLContexts ,
273+ } as SceneOpenURLContextsEventData ) ;
274+ }
275+
276+ Application . ios . notify ( {
277+ eventName : NativeWindowEvents . sceneOpenURLContexts ,
278+ object : Application . ios ,
279+ window : nativeWindow ,
280+ scene : windowScene ,
281+ urlContexts : URLContexts ,
282+ } as SceneOpenURLContextsEventData ) ;
283+
284+ forwardOpenURLContexts ( Application . ios . delegate , UIApplication . sharedApplication , URLContexts ) ;
285+ }
286+
287+ function deliverUserActivity ( windowScene : UIWindowScene , nativeWindow : IOSNativeWindow | undefined , userActivity : NSUserActivity ) : void {
288+ if ( nativeWindow ) {
289+ nativeWindow . notify ( {
290+ eventName : NativeWindowEvents . sceneContinueUserActivity ,
291+ object : nativeWindow ,
292+ window : nativeWindow ,
293+ scene : windowScene ,
294+ userActivity,
295+ } as SceneContinueUserActivityEventData ) ;
296+ }
297+
298+ Application . ios . notify ( {
299+ eventName : NativeWindowEvents . sceneContinueUserActivity ,
300+ object : Application . ios ,
301+ window : nativeWindow ,
302+ scene : windowScene ,
303+ userActivity,
304+ } as SceneContinueUserActivityEventData ) ;
305+
306+ forwardContinueUserActivity ( Application . ios . delegate , UIApplication . sharedApplication , userActivity ) ;
307+ }
308+
309+ function deliverShortcutAction ( windowScene : UIWindowScene , nativeWindow : IOSNativeWindow | undefined , shortcutItem : UIApplicationShortcutItem , completionHandler : ( ( handled : boolean ) => void ) | undefined ) : void {
310+ // Shared by the listeners and the legacy handler, so it has to tolerate several callers.
311+ const deliver = oneShotCompletion ( completionHandler ) ;
312+
313+ if ( nativeWindow ) {
314+ nativeWindow . notify ( {
315+ eventName : NativeWindowEvents . scenePerformActionForShortcutItem ,
316+ object : nativeWindow ,
317+ window : nativeWindow ,
318+ scene : windowScene ,
319+ shortcutItem,
320+ completionHandler : deliver ,
321+ } as ScenePerformActionForShortcutItemEventData ) ;
322+ }
323+
324+ Application . ios . notify ( {
325+ eventName : NativeWindowEvents . scenePerformActionForShortcutItem ,
326+ object : Application . ios ,
327+ window : nativeWindow ,
328+ scene : windowScene ,
329+ shortcutItem,
330+ completionHandler : deliver ,
331+ } as ScenePerformActionForShortcutItemEventData ) ;
332+
333+ deliverShortcutItem ( Application . ios . delegate , UIApplication . sharedApplication , shortcutItem , deliver ) ;
334+ }
335+
336+ /**
337+ * UIKit hands the URLs, continuation activities and quick action that launched a scene only to
338+ * `scene:willConnectToSession:options:`; the scene callbacks that carry them later never fire for
339+ * the launch itself, so they are delivered here the same way.
340+ */
341+ function deliverLaunchPayloads ( windowScene : UIWindowScene , nativeWindow : IOSNativeWindow , connectionOptions : UISceneConnectionOptions ) : void {
342+ if ( connectionOptions ?. URLContexts ?. count ) {
343+ deliverOpenURLContexts ( windowScene , nativeWindow , connectionOptions . URLContexts ) ;
344+ }
345+
346+ for ( const userActivity of getLaunchUserActivities ( connectionOptions , getSceneActivityType ( ) ) ) {
347+ deliverUserActivity ( windowScene , nativeWindow , userActivity ) ;
348+ }
349+
350+ if ( connectionOptions ?. shortcutItem ) {
351+ // A launch has no completion handler to report back to.
352+ deliverShortcutAction ( windowScene , nativeWindow , connectionOptions . shortcutItem , undefined ) ;
353+ }
354+ }
355+
258356@NativeClass
259357class SceneDelegate extends UIResponder implements UIWindowSceneDelegate {
260358 static ObjCProtocols = [ UIWindowSceneDelegate ] ;
@@ -351,6 +449,10 @@ class SceneDelegate extends UIResponder implements UIWindowSceneDelegate {
351449 ios : { connectionOptions } ,
352450 } ) ;
353451 }
452+
453+ // After the content is resolved, matching the legacy order where `openURL` and friends
454+ // arrived once launch had finished and the root view existed.
455+ deliverLaunchPayloads ( windowScene , nativeWindow , connectionOptions ) ;
354456 }
355457
356458 sceneDidBecomeActive ( scene : UIScene ) : void {
@@ -505,80 +607,18 @@ class SceneDelegate extends UIResponder implements UIWindowSceneDelegate {
505607
506608 sceneOpenURLContexts ( scene : UIScene , URLContexts : NSSet < UIOpenURLContext > ) : void {
507609 const windowScene = scene as UIWindowScene ;
508- const nativeWindow = Application . ios . _getWindowForScene ( windowScene ) ;
509-
510- if ( nativeWindow ) {
511- nativeWindow . notify ( {
512- eventName : NativeWindowEvents . sceneOpenURLContexts ,
513- object : nativeWindow ,
514- window : nativeWindow ,
515- scene : windowScene ,
516- urlContexts : URLContexts ,
517- } as SceneOpenURLContextsEventData ) ;
518- }
519-
520- Application . ios . notify ( {
521- eventName : NativeWindowEvents . sceneOpenURLContexts ,
522- object : Application . ios ,
523- window : nativeWindow ,
524- scene : windowScene ,
525- urlContexts : URLContexts ,
526- } as SceneOpenURLContextsEventData ) ;
527610
528- forwardOpenURLContexts ( Application . ios . delegate , UIApplication . sharedApplication , URLContexts ) ;
611+ deliverOpenURLContexts ( windowScene , Application . ios . _getWindowForScene ( windowScene ) , URLContexts ) ;
529612 }
530613
531614 sceneContinueUserActivity ( scene : UIScene , userActivity : NSUserActivity ) : void {
532615 const windowScene = scene as UIWindowScene ;
533- const nativeWindow = Application . ios . _getWindowForScene ( windowScene ) ;
534616
535- if ( nativeWindow ) {
536- nativeWindow . notify ( {
537- eventName : NativeWindowEvents . sceneContinueUserActivity ,
538- object : nativeWindow ,
539- window : nativeWindow ,
540- scene : windowScene ,
541- userActivity,
542- } as SceneContinueUserActivityEventData ) ;
543- }
544-
545- Application . ios . notify ( {
546- eventName : NativeWindowEvents . sceneContinueUserActivity ,
547- object : Application . ios ,
548- window : nativeWindow ,
549- scene : windowScene ,
550- userActivity,
551- } as SceneContinueUserActivityEventData ) ;
552-
553- forwardContinueUserActivity ( Application . ios . delegate , UIApplication . sharedApplication , userActivity ) ;
617+ deliverUserActivity ( windowScene , Application . ios . _getWindowForScene ( windowScene ) , userActivity ) ;
554618 }
555619
556620 windowScenePerformActionForShortcutItemCompletionHandler ( windowScene : UIWindowScene , shortcutItem : UIApplicationShortcutItem , completionHandler : ( p1 : boolean ) => void ) : void {
557- const nativeWindow = Application . ios . _getWindowForScene ( windowScene ) ;
558- // Shared by the listeners and the legacy handler, so it has to tolerate several callers.
559- const deliver = oneShotCompletion ( completionHandler ) ;
560-
561- if ( nativeWindow ) {
562- nativeWindow . notify ( {
563- eventName : NativeWindowEvents . scenePerformActionForShortcutItem ,
564- object : nativeWindow ,
565- window : nativeWindow ,
566- scene : windowScene ,
567- shortcutItem,
568- completionHandler : deliver ,
569- } as ScenePerformActionForShortcutItemEventData ) ;
570- }
571-
572- Application . ios . notify ( {
573- eventName : NativeWindowEvents . scenePerformActionForShortcutItem ,
574- object : Application . ios ,
575- window : nativeWindow ,
576- scene : windowScene ,
577- shortcutItem,
578- completionHandler : deliver ,
579- } as ScenePerformActionForShortcutItemEventData ) ;
580-
581- deliverShortcutItem ( Application . ios . delegate , UIApplication . sharedApplication , shortcutItem , deliver ) ;
621+ deliverShortcutAction ( windowScene , Application . ios . _getWindowForScene ( windowScene ) , shortcutItem , completionHandler ) ;
582622 }
583623}
584624// ensure available globally
@@ -1550,7 +1590,7 @@ export class iOSApplication extends ApplicationCommon implements IiOSApplication
15501590 try {
15511591 request = UISceneSessionActivationRequest . requestWithRole ( UIWindowSceneSessionRoleApplication ) ;
15521592
1553- const activity = NSUserActivity . alloc ( ) . initWithActivityType ( ` ${ NSBundle . mainBundle . bundleIdentifier } .scene` ) ;
1593+ const activity = NSUserActivity . alloc ( ) . initWithActivityType ( getSceneActivityType ( ) ) ;
15541594 activity . userInfo = dataSerialize ( options ?. data ?? { } ) ;
15551595 request . userActivity = activity ;
15561596
@@ -1737,7 +1777,7 @@ export class iOSApplication extends ApplicationCommon implements IiOSApplication
17371777 }
17381778
17391779 // Create user activity for the new scene
1740- const userActivity = NSUserActivity . alloc ( ) . initWithActivityType ( ` ${ NSBundle . mainBundle . bundleIdentifier } .scene` ) ;
1780+ const userActivity = NSUserActivity . alloc ( ) . initWithActivityType ( getSceneActivityType ( ) ) ;
17411781 userActivity . userInfo = dataSerialize ( data ?? { } ) ;
17421782
17431783 // Use the legacy API
0 commit comments