我正在使用 Xcode 11 并为 iOS 13 构建应用程序。在我在 Xcode 中创建的新项目中,缺少一些 UIApplicationDelegate 方法,因此我将它们添加回应用程序委托(delegate)文件中。 “单一 View 应用程序”项目的新模板缺少方法。问题是除了 -application:didFinishLaunchingWithOptions:
之外,没有任何委托(delegate)方法被调用。这是我的应用委托(delegate):
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(@"application:didFinishLaunchingWithOptions:");
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@"applicationDidEnterBackground:");
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(@"applicationWillEnterForeground:");
}
#pragma mark - UISceneSession lifecycle
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}
- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
}
@end
最佳答案
iOS 13 有一种发送应用生命周期事件的新方法。它们不是通过 UIApplicationDelegate
来的,而是通过 UIWindowSceneDelegate
来的这是一个 UISceneDelegate
子协议(protocol)。 UISceneDelegate
具有重要的委托(delegate)方法。
此更改是为了支持 iOS 13 中的多个窗口。在 WWDC 2019 session 212“Introducing Multiple Windows on iPad”中有更多信息。技术信息开始于 around 14:30由一位穿着非常 Shiny 的高帮鞋的男士呈现。较短的 session 258 Architecting Your App for Multiple Windows也很好地介绍了更改内容。
它是这样工作的:如果您的 Info.plist 中有一个“Application Scene Manifest”并且您的应用委托(delegate)有一个configurationForConnectingSceneSession
方法,UIApplication
不会向您的应用委托(delegate)发送后台和前台生命周期消息。这意味着这些方法中的代码将不会运行:
applicationDidBecomeActive
applicationWillResignActive
applicationDidEnterBackground
applicationWillEnterForeground
应用程序委托(delegate)仍会收到 willFinishLaunchingWithOptions:
和 didFinishLaunchingWithOptions:
方法调用,因此这些方法中的任何代码都将像以前一样工作。
如果您想要恢复旧行为,您需要
- 从应用程序的 Info.plist 中删除“Application Scene Manifest”条目
- 注释或删除
application:configurationForConnectingSceneSession:options:
方法(或 Swiftapplication(_:configurationForConnecting:options:)
函数) - 将窗口属性添加回您的应用委托(delegate) (
@property (strong, nonatomic) UIWindow *window;
)
或者,打开 Xcode 创建的 SceneDelegate 文件并使用其中的新生命周期方法:
- (void)sceneDidBecomeActive:(UIScene *)scene {
}
- (void)sceneWillResignActive:(UIScene *)scene {
}
... etc
通过在 Info.plist 中将“Enable Multiple Windows”(“UIApplicationSupportsMultipleScenes”)设置为“NO”(这是默认设置),可以在不采用多窗口支持的情况下使用新的 UIScene
生命周期内容用于新项目)。通过这种方式,您可以以更小的步骤开始采用新的 API。
您可以看到场景委托(delegate)方法名称与应用程序委托(delegate)方法名称非常匹配。一件令人困惑的事情是,应用程序委托(delegate)方法并未被弃用,因此如果您同时拥有应用程序委托(delegate)和场景委托(delegate)方法但只会调用一个方法,您将不会收到警告。
UISceneDelegate
接管的其他事情是用户事件(continueUserActivity:
等)、状态恢复(stateRestorationActivityForScene:
等)、状态栏问题和打开网址。 (我不确定这些是否取代了应用程序委托(delegate)方法)。它还具有生命周期事件的类似通知(如 UISceneWillDeactivateNotification
)。
来自 WWDC session 的一些图片:
Swift 的等效函数:
类职责:
关于ios - iOS 13 中未调用应用程序委托(delegate)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56508764/