当所有场景都被关闭时,我如何选择在 iPadOS 上恢复哪个场景?

How can I choose which scene gets restored on iPadOS when all have been dismissed?

我有一个 iPad 应用程序,我开始在其中支持多个 windows / 场景。我有一种主要的 window 类型,比方说 MainScene,还有至少一种次要的 window 类型用于打开特定类型的内容,比如 DetailScene.

我还没有在 Info.plist 中声明我的场景类型。我已经实现了 application:configurationForConnectingSceneSession:options: 这样的:

-(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];
}

假设我执行这些步骤:

  1. 首次启动应用程序。我接到了 configurationForConnectingSceneSession 的电话,activity 类型是 nil 所以它 returns 是 MainScene.
  2. 为一些内容打开一个新的window。即使用细节场景activity类型,所以configurationForConnectingSceneSessionreturns一个DetailScene。创建新场景如下所示:
NSUserActivity *activity = [[NSUserActivity alloc] initWithActivityType:@"detailType"];
activity.userInfo = @{@"content_id": @(contentRowId)};
[[UIApplication sharedApplication] requestSceneSessionActivation:nil userActivity:activity options:nil errorHandler:nil];
  1. 暂停应用程序并打开应用程序切换器。首先丢弃(向上轻弹)主要 window,然后是细节 window。该应用程序现已被终止。
  2. 重新启动应用程序。

此时我没有接到configurationForConnectingSceneSession的电话。我从它的用户 activity 处恢复了细节场景,并直接调用 DetailSceneDelegate.

我的问题:我如何控制在这种情况下恢复哪些场景?我想让我的主场景回来。

消息、邮件和便签都可以做到这一点。如果您打开消息并将对话拖出到新的 window 中,您会得到该对话的 window,角落里有一个完成按钮,该按钮将关闭 window。如果您对 Messages 执行上述步骤,您将重新启动到完整的 Messages 视图。他们是否正在将详细视图转换为主视图?或者有没有办法告诉系统细节场景是次要,不应该先恢复,或者我应该通过configurationForConnectingSceneSession询问我要恢复什么?或者别的什么?

我 cross-posted 这个给 UIScene 上的 Apple Developer forums and got an answer from a Framework Engineer. The answer is UISceneActivationConditions, set as a property。将 canActivateForTargetContentIdentifierPredicate 设置为始终 return NO:

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

我在 UIWindowSceneDelegate 实现中的 scene:willConnectToSession:options: 实现中这样做。

截至目前,在 Xcode 13.2 和 iOS 15.2 模拟器上,如果第二次启动(上面的第 4 步)是通过点击应用程序图标,但不是通过构建时,它可以工作Xcode 中的 运行。我可能会对此提出反馈。