xcode 在 iOS 13 中未调用应用程序委托方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/56508764/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
App delegate methods aren't being called in iOS 13
提问by nevan king
I am using Xcode 11 and building an app for iOS 13. In a new project I created in Xcode some of the UIApplicationDelegate methods were missing so I added them back into the app delegate file. The new template for a "Single View App" project was missing the methods. The problem is that none of the delegate methods are getting called except -application:didFinishLaunchingWithOptions:
. Here is my app delegate:
我正在使用 Xcode 11 并为 iOS 13 构建应用程序。在我在 Xcode 中创建的新项目中,缺少一些 UIApplicationDelegate 方法,因此我将它们重新添加到应用程序委托文件中。“单一视图应用程序”项目的新模板缺少方法。问题是除了-application:didFinishLaunchingWithOptions:
. 这是我的应用程序委托:
@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
回答by nevan king
iOS 13 has a new way of sending app lifecycle events. Instead of coming through the UIApplicationDelegate
they come through the UIWindowSceneDelegate
which is a UISceneDelegate
sub-protocol. UISceneDelegate
has the important delegate methods.
iOS 13 有一种发送应用生命周期事件的新方式。而不是通过UIApplicationDelegate
他们通过UIWindowSceneDelegate
这是一个UISceneDelegate
子协议。UISceneDelegate
具有重要的委托方法。
This change is to support multiple windows in iOS 13. There's more information in WWDC 2019 session 212 "Introducing Multiple Windows on iPad". The technical information starts at around 14:30and is presented by a man with very sparkly high-tops. The shorter session 258 Architecting Your App for Multiple Windowsalso has a great introduction to what's changed.
此更改是为了在 iOS 13 中支持多个窗口。 WWDC 2019 session 212“ Introducing Multiple Windows on iPad”中有更多信息。技术信息从14:30 左右开始,由一位穿着闪亮高帮的男士提供。较短的会话 258为多个 Windows 构建您的应用程序也对更改的内容进行了很好的介绍。
Here's how it works:If you have an "Application Scene Manifest" in your Info.plist and your app delegate has a configurationForConnectingSceneSession
method, the UIApplication
won't send background and foreground lifecycle messages to your app delegate. That means the code in these methods won't run:
这是它的工作原理:如果您的 Info.plist 中有一个“应用程序场景清单”并且您的应用程序委托有一个configurationForConnectingSceneSession
方法,UIApplication
则不会向您的应用程序委托发送后台和前台生命周期消息。这意味着这些方法中的代码不会运行:
applicationDidBecomeActive
applicationWillResignActive
applicationDidEnterBackground
applicationWillEnterForeground
applicationDidBecomeActive
applicationWillResignActive
applicationDidEnterBackground
applicationWillEnterForeground
The app delegate will still receive the willFinishLaunchingWithOptions:
and didFinishLaunchingWithOptions:
method calls so any code in those methods will work as before.
应用程序委托仍将接收willFinishLaunchingWithOptions:
和didFinishLaunchingWithOptions:
方法调用,因此这些方法中的任何代码都将像以前一样工作。
If you want the old behaviour backyou need to
如果你想恢复旧的行为,你需要
- Delete the "Application Scene Manifest" entry from the app's Info.plist
- Comment or delete the
application:configurationForConnectingSceneSession:options:
method (or the Swiftapplication(_:configurationForConnecting:options:)
function) - Add the window property back to your app delegate (
@property (strong, nonatomic) UIWindow *window;
)
- 从应用程序的 Info.plist 中删除“应用程序场景清单”条目
- 注释或删除
application:configurationForConnectingSceneSession:options:
方法(或 Swiftapplication(_:configurationForConnecting:options:)
函数) - 将 window 属性添加回您的应用程序委托 (
@property (strong, nonatomic) UIWindow *window;
)
Alternatively, open the SceneDelegate file that Xcode made and use the new lifecycle methods in there:
或者,打开 Xcode 创建的 SceneDelegate 文件并使用其中的新生命周期方法:
- (void)sceneDidBecomeActive:(UIScene *)scene {
}
- (void)sceneWillResignActive:(UIScene *)scene {
}
... etc
It's possible to use the new UIScene
lifecycle stuff without adopting multiple window support by setting "Enable Multiple Windows" ("UIApplicationSupportsMultipleScenes") to "NO" in the Info.plist (this is the default for new projects). This way you can start adopting the new API in smaller steps.
UIScene
通过在 Info.plist 中将“启用多个窗口”(“UIApplicationSupportsMultipleScenes”)设置为“NO”(这是新项目的默认设置),可以在不采用多窗口支持的情况下使用新的生命周期内容。通过这种方式,您可以以较小的步骤开始采用新的 API。
You can see that the scene delegate method names are a close match for the app delegate ones. One confusing thing is that the app delegate methods aren't deprecated so you won't get a warning if you have both app delegate and scene delegate methods in place but only one will be called.
您可以看到场景委托方法名称与应用委托方法名称非常匹配。一件令人困惑的事情是应用程序委托方法并未被弃用,因此如果您同时拥有应用程序委托和场景委托方法,但只会调用一个方法,您将不会收到警告。
Other things that UISceneDelegate
takes over are user activities (continueUserActivity:
etc), state restoration (stateRestorationActivityForScene:
etc), status bar questions and opening URLs. (I'm not sure if these replace the app delegate methods). It also has analogous notifications for the lifecycle events (like UISceneWillDeactivateNotification
).
其他UISceneDelegate
接管的是用户活动(continueUserActivity:
等)、状态恢复(stateRestorationActivityForScene:
等)、状态栏问题和打开 URL。(我不确定这些是否替换了应用程序委托方法)。它也有类似的生命周期事件通知(如UISceneWillDeactivateNotification
)。
From the WWDC Session, some images for you:
来自 WWDC Session 的一些图片供您参考:
The function equivalents for Swift:
Swift 的等价函数:
The class responsibilities:
班级职责:
回答by birdman
This thread helped me:
这个线程帮助了我:
View controller responds to app delegate notifications in iOS 12 but not in iOS 13
视图控制器响应 iOS 12 中的应用程序委托通知,但不响应 iOS 13
Objective C:
目标 C:
if (@available(iOS 13.0, *)) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appWillResignActive:)
name:UISceneWillDeactivateNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appDidBecomeActive:)
name:UISceneDidActivateNotification object:nil];
}
else {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appWillResignActive:)
name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self
selector:@selector(appDidBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
}