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

查看:125
本文介绍了为什么不可靠地调用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/Storyboard)
  • 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 恢复Windows的内容,而不仅仅是它们的 type .和 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天全站免登陆