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

时间:2019-06-08 17:42:27

标签: ios uiapplicationdelegate ios13 uiscenedelegate

我正在使用Xcode 11并为iOS 13构建应用程序。在用Xcode创建的新项目中,我为UIApplicationDelegate添加了委托方法。 “单视图应用程序”项目的新模板缺少它们。问题是除#Custom Function: "ValueError: ('The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().', 'occurred at index PS_CD')" # Custom Function with For Loop: "SyntaxError: can't assign to function call" #np.Where: "ValueError: operands could not be broadcast together with shapes (152,7) (720,) (720,)" #Apply Lambda: "string indices must be integers" #Assign with a "Where": "TypeError: assign() takes 1 positional argument but 2 were given" 之外的所有委托方法都没有被调用。这是我的应用程序代表:

-application:didFinishLaunchingWithOptions:

3 个答案:

答案 0 :(得分:4)

iOS 13具有一种发送应用程序生命周期事件的新方式。它们不是通过UIApplicationDelegate子协议UIWindowSceneDelegate而是通过UISceneDelegate子协议。 The UISceneDelegate methods are listed in the API docs

这都是为了支持iOS 13中的多个窗口。WWDC 2019会话212“ Introducing Multiple Windows on iPad”中有更多信息。技术信息的发布时间大约是14:30,由一个穿着高顶鞋的男人提供。

如果您的Info.plist中有一个“ 应用场景清单”,并且您的应用程序委托有一种configurationForConnectingSceneSession方法,则UIApplication将不会发送后台和前台生命周期发送给应用程序委托的消息(applicationDidBecomeActiveapplicationWillResignActiveapplicationDidEnterBackgroundapplicationWillEnterForeground)。应用程序委托仍将收到willFinishLaunchingWithOptions:didFinishLaunchingWithOptions:

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

  1. 从应用程序的Info.plist中删除“应用程序场景清单”条目
  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

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

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

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

在WWDC会话中,有一些适合您的图像:

与Swift等效的功能:

enter image description here

班级职责:

enter image description here

答案 1 :(得分:1)

该线程帮助了我

View controller responds to app delegate notifications in iOS 12 but not in 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];
}

答案 2 :(得分:0)

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

enter image description here

我认为,即使有一种可以理解的意图迫使程序员适应新的情况,但禁用应用程序状态更改方法的调用(以及在更改每个场景的状态时发送应用程序状态更改通知)也是一个错误。场景生命周期。

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

@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)
        }
    }
}

SceneDelegate.swift