简体   繁体   中英

App crashes when opening after building it with Xcode 11.3.1

After upgrading to Xcode 11.3.1 we noticed that our app started to crash on some devices when opening. It happens on different iOS versions and iPhone models. However on some devices with the same iOS version or iPhone model the app works fine.

When installing an earlier build of the app on these devices (that was build with an earlier Xcode version) the crash does not occur.

While debugging we found out that the crash occurs when trying to unwrap an Optional when using the presenter of our login module. This presenter has a value when created and is assigned but after setting our rootViewController in the AppDelegate window.rootViewController = navigationController the execution jumps to the viewDidLoad() function shown below at which point the presenter is nil .

class LoginViewController: LoginPasswordResetViewController {
    var presenter: LoginPresenterProtocol!

    override func viewDidLoad() {
        super.viewDidLoad()

        updateUI(model: presenter.loadViewModel())
        presenter.viewDidLoad()
    }
}

Relevant code in AppDelegate.swift:

class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?

func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    let env = Environment()

    if let app = UIApplication.shared.delegate as? AppDelegate,
        let window = app.window,
        let loginVC = LoginModule().createModule(moduleData: LoginModuleData(env: env),
                                                 service: LoginService(env: env),
                                                 storageService: LocalStorageService(env: env)) {

        let navigationController = UINavigationController(rootViewController: loginVC)

        window.rootViewController = navigationController
        window.makeKeyAndVisible()
    }
    return true
}

I tried using the SceneDelegate.swift mentioned here Set RootViewController iOS 13 to set the RootViewController with no luck.

Any ideas on what could be the cause of this issue?

Additional info:

The createModule function initializes and sets the presenter :

func createModule(moduleData: LoginModuleDataProtocol, service: LoginServiceProtocol, storageService: LocalStorageServiceProtocol) -> LoginViewController? {
    guard let viewController: LoginViewController = UIStoryboard.viewController(from: self) else {
        return nil
    }
    let presenter = LoginPresenter()
    let interactor = LoginInteractor()
    let router = LoginRouter()

    // VC
    viewController.presenter = presenter
    // Presenter
    presenter.viewController = viewController
    presenter.interactor = interactor
    presenter.router = router
    // Interactor
    interactor.presenter = presenter
    interactor.dataManager = LoginDataManager(data: moduleData, service: service, storageService: storageService)
    // Router
    router.viewController = viewController

    return viewController
}

After creating the module, the loginVC variable has the presenter value as it should but as soon as we assign window.rootViewController = navigationController the value of presenter is nil .

I managed to make it work. I had to use the SceneDelegate to load the components to launch my app for iOS 13 while still supporting iOS 12 but I only managed to make it work after reading how to configure it properly .

So here is the result that worked for me:

SceneDelegate.swift:

import UIKit
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        let env = Environment()

        if let windowScene = scene as? UIWindowScene,
            let loginVC = LoginModule().createModule(moduleData: LoginModuleData(env: env),
                                                     service: LoginService(env: env),
                                                     storageService: LocalStorageService(env: env)) {
            self.window = UIWindow(windowScene: windowScene)
            self.window!.rootViewController = UINavigationController(rootViewController: loginVC)
            self.window!.makeKeyAndVisible()
        }
    }
}

AppDelegate.swift:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        if #available(iOS 13.0, *) {} else {
            let env = Environment()

            if let app = UIApplication.shared.delegate as? AppDelegate,
                let window = app.window,
                let loginVC = LoginModule().createModule(moduleData: LoginModuleData(env: env),
                                                         service: LoginService(env: env),
                                                         storageService: LocalStorageService(env: env)) {
                window.rootViewController = UINavigationController(rootViewController: loginVC)
                window.makeKeyAndVisible()
            }
        }
        return true
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM