How can I choose what scene gets opened on iPad after all are closed?

I have an iPad app in which I'm starting to support multiple windows / scenes. I have one main window type, let's say MainScene, and at least one secondary window type for opening specific types of content, say DetailScene.

I have not declared my scene types in Info.plist. I have implemented application:configurationForConnectingSceneSession:options: like this:

-(UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options
{
  NSUserActivity *activity = options.userActivities.anyObject;
  NSString *activityType = activity.activityType;
  if ([activityType isEqualToString:@"detailType"])
    return [DetailSceneDelegate makeSceneConfiguration];

  return [MainSceneDelegate makeSceneConfiguration];
}

Say I perform these steps:

  1. Launch app for the first time. I get a call to configurationForConnectingSceneSession, and the activity type is nil so it returns a MainScene.
  2. Open a new window for some piece of content. That uses the detail scene activity type, so configurationForConnectingSceneSession returns a DetailScene. Creating the new scene looks like this:
NSUserActivity *activity = [[NSUserActivity alloc] initWithActivityType:@"detailType"];
activity.userInfo = @{@"content_id": @(contentRowId)};
[[UIApplication sharedApplication] requestSceneSessionActivation:nil userActivity:activity options:nil errorHandler:nil];
  1. Suspend the app and open the app switcher. Discard (by flicking up) first the main window and then the detail window. The app is now killed.
  2. Relaunch the app.

At this point I do not get a call to configurationForConnectingSceneSession. I get the detail scene back, restored from its user activity, with calls straight to DetailSceneDelegate.

My question: how do I control what scene gets restored in this situation? I want my main scene to come back.

Messages and Mail and Notes all do this. If you open Messages and drag a conversation out into a new window, you get a window for that conversation with a Done button in the corner that will dismiss the window. If you perform my steps above with Messages, you will relaunch to the full Messages view. Are they converting the detail view to a main view on the fly? Or is there a way to tell the system that the detail scene is secondary and should not be restored first, or that I should get asked what I want to restore via configurationForConnectingSceneSession? Or something else?

Are they converting the detail view to a main view on the fly?

No.

Or is there a way to tell the system that the detail scene is secondary and should not be restored first, or that I should get asked what I want to restore via configurationForConnectingSceneSession? 

Yes, you want UISceneActivationConditions: https://developer.apple.com/documentation/uikit/uisceneactivationconditions

Specifically, you want the detail scene to have a canActivateForTargetContentIdentifierPredicate to always return NO, like this:

windowScene.activationConditions.canActivateForTargetContentIdentifierPredicate = [NSPredicate predicateWithValue:NO];

I made a project with a main and detail configuration like yours and confirmed your behavior without the canActivateForTargetContentIdentifierPredicate. I then added that predicate for the detail scene in my delegate, and that ensured it was not activated after discarding my last session.

In addition to checking for the user activity in the options parameter, you must also check the user activity in the UISceneSession’s stateRestorationActivity property. The latter is set when your scenes are restored after your app is terminated.

Example code:


NSUserActivity *userActivity = options.userActivities.anyObject;
if (!userActivity) {
    userActivity = connectingSceneSession.stateRestorationActivity;
}

if ([userActivity.activityType isEqualToString:@"detailType"]) {
    // Return detail configuration
}

// Return main configuration
How can I choose what scene gets opened on iPad after all are closed?
 
 
Q