iOS 13中未调用应用程序委托方法

nev*_*ing 15 xcode uiapplicationdelegate ios ios13 uiscenedelegate

我正在使用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
Run Code Online (Sandbox Code Playgroud)

nev*_*ing 63

iOS 13具有一种发送应用程序生命周期事件的新方法。相反,通过未来的UIApplicationDelegate他们来过UIWindowSceneDelegate这是一个UISceneDelegate子协议。UISceneDelegate具有重要的委托方法。

此更改是为了在iOS 13中支持多个窗口。WWDC 2019会话212“ 在iPad上引入多个窗口”中有更多信息。技术信息的发布时间大约是14:30,由一位穿着高顶鞋的男人提供。较短的会议258“ 为多个Windows构筑您的应用程序”还对更改进行了很好的介绍。

它是这样工作的:如果Info.plist中有一个“ Application Scene Manifest ”,并且您的应用程序委托有一个configurationForConnectingSceneSession方法,UIApplication则不会将后台和前台生命周期消息发送给您的应用程序委托。这意味着这些方法中的代码将无法运行:

  • applicationDidBecomeActive
  • applicationWillResignActive
  • applicationDidEnterBackground
  • applicationWillEnterForeground

应用程序委托仍将接收willFinishLaunchingWithOptions:didFinishLaunchingWithOptions:方法调用,因此这些方法中的任何代码将像以前一样工作。

如果您希望恢复以前的行为,则需要

  1. 从应用程序的Info.plist中删除“ Application Scene Manifest”条目
  2. 注释或删除application:configurationForConnectingSceneSession:options:方法(或Swift application(_:configurationForConnecting:options:)函数)
  3. 将window属性添加回您的应用程序委托(@property (strong, nonatomic) UIWindow *window;

或者,打开Xcode创建的SceneDelegate文件,并在其中使用新的生命周期方法:

- (void)sceneDidBecomeActive:(UIScene *)scene {
}
- (void)sceneWillResignActive:(UIScene *)scene {
}
... etc
Run Code Online (Sandbox Code Playgroud)

UIScene通过在Info.plist中将“启用多个Windows”(“ UIApplicationSupportsMultipleScenes”)设置为“ NO”(这是新项目的默认设置),可以在不采用多窗口支持的情况下使用新的生命周期资料。这样,您可以在较小的步骤中开始采用新的API。

您可以看到场景委托方法名称与应用程序委托名称紧密匹配。一个令人困惑的事情是应用程序委托方法没有被弃用,因此,如果同时具有应用程序委托和场景委托方法,则不会收到警告,但只会调用一个。

其他的事情UISceneDelegate还包括用户活动(continueUserActivity:等),状态恢复(stateRestorationActivityForScene:等),状态栏问题和打开的URL。(我不确定它们是否代替了应用程序委托方法)。它还具有生命周期事件的类似通知(例如UISceneWillDeactivateNotification)。

在WWDC会议上,一些适合您的图像:

Swift的等效功能:

在此处输入图片说明

班级职责:

在此处输入图片说明

  • 谢谢,但根本没有。有趣的是,当我不调试我的应用程序时它运行得很好。 (2认同)
  • 是的,的确是,但是老实说,我只是创建一个新项目并将所有我的源代码文件添加到其中。我已经尝试修复它太长时间了,甚至在苹果论坛上都解释了这种情况,没人知道发生了什么。典型的XCode越野车行为。 (2认同)

DnV*_*DnV 7

应用程序和场景生命周期不是一回事!

在此输入图像描述

在我看来,禁用应用程序状态更改方法的调用(以及在更改每个场景的状态时发送应用程序状态更改通知)是一个错误,尽管强制程序员适应新场景生命周期的意图是可以理解的。

这是一个场景委托模板,用于恢复应用程序委托的应用程序状态更改方法的预期调用:

@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
    func sceneWillResignActive(_ scene: UIScene) {
        
        if !UIApplication.shared.connectedScenes.contains(where: { $0.activationState == .foregroundActive && $0 != scene }) {
            UIApplication.shared.delegate?.applicationWillResignActive?(.shared)
        }
    }
    
    
    func sceneDidEnterBackground(_ scene: UIScene) {
        
        if !UIApplication.shared.connectedScenes.contains(where: { $0.activationState == .foregroundActive || $0.activationState == .foregroundInactive }) {
            UIApplication.shared.delegate?.applicationDidEnterBackground?(.shared)
        }
    }
    
    
    func sceneWillEnterForeground(_ scene: UIScene) {
        
        if !UIApplication.shared.connectedScenes.contains(where: { $0.activationState == .foregroundActive || $0.activationState == .foregroundInactive }) {
            UIApplication.shared.delegate?.applicationWillEnterForeground?(.shared)
        }
    }
    
    
    func sceneDidBecomeActive(_ scene: UIScene) {
        
        if !UIApplication.shared.connectedScenes.contains(where: { $0.activationState == .foregroundActive && $0 != scene }) {
            UIApplication.shared.delegate?.applicationDidBecomeActive?(.shared)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

SceneDelegate.swift


bir*_*man 6

这个线程帮助了我:

视图控制器响应 iOS 12 中的应用程序委托通知,但不响应 iOS 13

目标 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];
}
Run Code Online (Sandbox Code Playgroud)