Skip to content

Instantly share code, notes, and snippets.

@albertodebortoli
Created May 7, 2023 18:15
Show Gist options
  • Save albertodebortoli/ccf7590b48ea68dc2857c79938fa13f9 to your computer and use it in GitHub Desktop.
Save albertodebortoli/ccf7590b48ea68dc2857c79938fa13f9 to your computer and use it in GitHub Desktop.
Showcasing the ViewController's dismiss method being broken in packages
import XCTest
import UIKit
@testable import DismissTest
class TopLevelUIUtilities {
private var rootWindow: UIWindow!
func setupTopLevelUI(withViewController viewController: UIViewController) {
// let windowScene = UIApplication.shared.connectedScenes.first as! UIWindowScene
rootWindow = UIWindow()
rootWindow.rootViewController = viewController
rootWindow.makeKeyAndVisible()
rootWindow.isHidden = false
}
}
final class DismissTestTests: XCTestCase {
private var presentingViewController: UIViewController!
private var topLevelUIUtilities: TopLevelUIUtilities!
override func setUp() {
super.setUp()
// presentingViewController = UIViewController()
topLevelUIUtilities = TopLevelUIUtilities()
// topLevelUIUtilities.setupTopLevelUI(withViewController: presentingViewController)
}
func testExample() throws {
let expectation = XCTestExpectation(description: #function)
let v1 = UIViewController()
let v2 = UIViewController()
topLevelUIUtilities.setupTopLevelUI(withViewController: v1)
v1.present(v2, animated: true)
// after the above line,
//
// 1) if `makeKeyAndVisible` was executed in `setupTopLevelUI`, presentingViewController.presentedViewCOntroller is not nil
// but the closure in the `dismiss` call later never gets called
//
// 2) if `makeKeyAndVisible` is commented out in `setupTopLevelUI`, presentingViewController.presentedViewCOntroller is nil
// and the following is printed on the console, which makes sense
// [Presentation] Attempt to present <UnitTests.MyViewController: 0x15d704940> on <UIViewController: 0x15ef0b200> (from <UIViewController: 0x15ef0b200>) whose view is not in the window hierarchy.
// but in this case the closure in the `dismiss` call later gets called
//
// Case 1 is the correct code as we need to setup a window, but cannot understand why dismiss never gets called.
// DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
v1.dismiss(animated: false) {
expectation.fulfill()
}
// }
wait(for: [expectation], timeout: 300)
}
}
class MyViewController: UIViewController {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment