为什么不可靠地调用 UIApplicationDelegate 方法`application(_:configurationForConnecting:options:)` [英] Why is UIApplicationDelegate method `application(_:configurationForConnecting:options:)` not called reliably

查看:37
本文介绍了为什么不可靠地调用 UIApplicationDelegate 方法`application(_:configurationForConnecting:options:)`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:

我发现一些关于 AppDelegate 方法的意外行为application(_:configurationForConnecting:options:).

I find some unexpected behavior regarding the AppDelegate method application(_:configurationForConnecting:options:).

文档说明:

UIKit 在创建新场景前不久调用此方法.

UIKit calls this method shortly before creating a new scene.

我希望每次启动应用程序时都是这种情况.
当我第一次启动我的应用程序时确实会调用该方法,但是对于所有后续启动,它不会.

I would expect that this is the case every time the app is launched.
The method is indeed called when I launch my app for the first time, however for all subsequent launches, it is not.

复制:

我有一个非常简单的测试用例来重现:

I have a very simple test case to reproduce:

  • Xcode 12 >创建新项目 >iOS >应用(UIKit/故事板)
  • AppDelegate 的方法中添加调试语句,如下所示:
  • Xcode 12 > Create new Project > iOS > App (UIKit/Storyboard)
  • add a debugging statement in the method in AppDelegate like so:
  // from Apple's sample project:
  func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
      // Called when a new scene session is being created.
      // Use this method to select a configuration to create the new scene with.
      print("I was called!").  // <--- debugging statement
      return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
  }

  • 运行应用程序 >我被召唤了!"在控制台打印
  • 再次运行应用程序 >什么也没有打印出来.
  • 问题:

    为什么 application(_:configurationForConnecting:options:) 在第二次启动时没有被调用?
    (这是预期的行为,如果是,为什么/这是 Apple 的错误)

    Why is application(_:configurationForConnecting:options:) not being called on second launch?
    (Is it expected behavior, if yes why / Is it a bug by Apple)

    推荐答案

    这似乎是预期的行为,一旦您了解正在发生的事情就有意义,但没有记录在案.我刚刚花了一些相当痛苦的时间来了解它的底部.哦,苹果.

    This seems to be expected behaviour, and makes sense once you understand what's going on, but it's not documented. I've just spent some fairly traumatic time getting to the bottom of it. Oh, Apple.

    要知道的关键是,当您重新启动应用程序时,会恢复上次运行的窗口.

    The key thing to know is that when you relaunch an app, the windows from the previous run are restored.

    (记住一个应用程序可以有多种类型的窗口——每种都由一个场景配置表示——这也是你可能首先实现这个委托方法的原因.)

    (It also helps to remember that an app can have multiple types of window – each represented by a scene configuration – which is why you might implement this delegate method in the first place.)

    案例 1:有史以来第一次启动应用

    应用程序不知道在窗口中放置什么类型的场景,并调用application(_:configurationForConnecting:options:) 来查找.到目前为止,事情正如我们所料.(如果您不实现此委托方法,它只会回退到 Info.plist 的场景清单中的第一个合适的条目,如果有的话.)

    The app doesn't know what type of scene to put in the window, and calls application(_:configurationForConnecting:options:) to find out. So far things are as we expect. (If you don't implement this delegate method, it just falls back to the first suitable entry in your Info.plist's scene manifest, if it has one.)

    案例 2:创建新窗口(适用于支持多个窗口的应用)

    (例如通过拖动 iPad 上的停靠栏图标).该应用程序也不知道该窗口中该放什么.与案例 1 相同.

    (e.g. by dragging the dock icon on iPad). The app doesn't know what to put in this window either. Same as case 1.

    案例 3:应用重新启动

    操作系统想要恢复您的 Windows.为此,它记住了您上次打开的窗口的场景配置.惊喜!它知道要在窗口中放置哪些场景,并且不会询问您的应用委托.它会继续使用记住的配置创建场景.

    The OS wants to restore your windows. To do this, it has remembered the scene configs of the windows you had open last time. Surprise! It knows what scenes to put in the windows, and doesn't ask your app delegate. It just goes ahead and creates the scenes using the remembered configs.

    对于那些在应用程序启动时创建一个窗口的可怜的开发人员来说,这是令人困惑的.但是,如果您认为 Windows 在启动时恢复而不是创建 - 即使只有一个 - 它开始变得有意义.

    For the poor developer thinking in terms of a window being created when the app starts up, this is confusing. But if you think in terms of windows being restored at startup, not created - even when there is only one - it starts to make sense.

    现在,如果您想重置一些东西以便忘记您的窗口并在下次启动时调用您的委托方法:

    Now, if you want to reset things so your windows are forgotten and your delegate method is called on next launch:

    • 对于 iOS,删除应用
    • 对于 Catalyst,删除应用的容器

    注意 1: 在 Catalyst 中,似乎只有第一个窗口在重新启动时恢复,但其他行为与上述相同. 现在观察到这一点不会是真实的.也许是不一致的.

    Note 1: In Catalyst, it seems that only the first window is restored on relaunch, but otherwise behaviour is the same as above. Have now observed this not to be true. Perhaps it's inconsistent.

    注意 2:您还可以使用 UIWindowSceneDelegate 恢复窗口的内容,而不仅仅是它们的类型UISceneSession.stateRestorationActivity,但那是另外一回事了.

    Note 2: You can also restore your windows' content, not just their type, using UIWindowSceneDelegate and UISceneSession.stateRestorationActivity, but that's another story.

    这篇关于为什么不可靠地调用 UIApplicationDelegate 方法`application(_:configurationForConnecting:options:)`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆