Search code examples
swiftxcodeunit-testinguiviewcontrollerviewcontroller

Xcode 11 : iOS 13 specifically no longer triggers `viewDidAppear` when unit testing


Specifically this used to pass when testing using iOS 12:

let viewController = ViewController()
let _ = viewController.view
let window = UIWindow(frame: UIScreen.main.bounds)
window.layer.speed = 10
viewController.modalPresentationStyle = .fullScreen
viewController.beginAppearanceTransition(true, animated: false)
window.rootViewController = viewController
window.makeKeyAndVisible()
viewController.endAppearanceTransition()
...
XCTAssert(vc.viewDidAppearCalled == true)

No longer passes. The ViewController's viewDidLoad and viewWillAppear still gets called.

Any ideas what's going on?

Full example found here: https://github.com/nickm01/Test13ViewWillAppear


Solution

  • In iOS13, there was a subtle change to the ViewController lifecycle. viewWillAppear etc now get loaded asynchronously so for testing some level of asynchronous testing (or waiting) is needed. Couldn't find any documentation on this and I'm sure there's subtleties but this fixed the issue.