Vincent Tourraine
Blog

Notes WWDC 2019 : Introducing Multiple Windows on iPad

#dev #iOS

Référence : Session 212 - Introducing Multiple Windows on iPad

Design intent

Where should I add scenes to my app?

The user should be allowed to do everything from just one window (apps cannot require multiple windows).

What interactions should create scenes?

Provided by system:

Or provided by the app:

App lifecycle changes

Migrating your code from:

application(_:didFinishLaunchingWithOptions:)
applicationWillEnterForeground(_:)
applicationDidBecomeActive(_:)
applicationWillResignActive(_:)
applicationDidEnterBackground(_:)
...
application(_:open:options:)
...
application(_:continue:restorationHandler:)

to:

scene(_:willConnectTo:options:)
sceneWillEnterForeground(_:)
sceneDidBecomeActive(_:)
sceneWillResignActive(_:)
sceneDidEnterBackground(_:)
...
scene(_:openURLContexts:)
...
scene(_:continue:)

UIScene state restoration:

Adding support to multiple windows:

Drag and drop

Next steps

Difference between “scene” and “window”: a “scene” can be present in the multitasking interface, even if the window is not loaded

Create new scenes:

requestSceneSessionActivation(_:userActivity:options:errorHandler:)

Update existing scenes:

requestSceneSessionRefresh(_:)

Close scenes:

requestSceneSessionDestruction(_:options:errorHandler:)

Examples:

 // Open a new window

@IBAction func handleLongPress(forDocumentAt url: URL) {
  if let existingSession = findSession(for: url) {
    UIApplication.shared.requestSceneSessionActivation(existingSession, userActivity: nil, options: nil)
  } else {
    let activity = NSUserActivity(activityType: "com.example.MyApp.EditDocument")
    activity.userInfo["url"] = url

    UIApplication.shared.requestSceneSessionActivation(nil, userActivity: activity, options: nil)
  }
}
// Close a window

func closeWindow(and action: DraftAction) {
  let options = UIWindowScene.DestructionRequestOptions()

  switch action {
  case .send: options.windowDismissalAnimation = .commit
  case .save: options.windowDismissalAnimation = .decline
  case .delete: options.windowDismissalAnimation = .standard
  }

  let session = view.window!.windowScene!.session
  UIApplication.shared.requestSceneSessionDestruction(session, options: options)
}

For state restoration:

Debugging tips: