Skip to content

Instantly share code, notes, and snippets.

@hossamghareeb
Created January 3, 2021 11:10
Show Gist options
  • Save hossamghareeb/7317a064f30b28d395aad72565a8f355 to your computer and use it in GitHub Desktop.
Save hossamghareeb/7317a064f30b28d395aad72565a8f355 to your computer and use it in GitHub Desktop.
Bypassing AppDelegate and Scene delegate for Unit testing in iOS
Remove @main or @UIApplicationMain
// Add this file to the main target
import UIKit
let appDelegateClass: AnyClass = NSClassFromString("TestsAppDelegate") ?? AppDelegate.self
UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(appDelegateClass))
// Add this file to the unit test target
import UIKit
@objc(TestsAppDelegate)
class TestsAppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
print(">>> Launching with Tests app delegate.")
// Remove any cached scene configurations to ensure that TestingAppDelegate.application(_:configurationForConnecting:options:) is called and TestingSceneDelegate will be used when running unit tests. NOTE: THIS IS PRIVATE API AND MAY BREAK IN THE FUTURE!
for sceneSession in application.openSessions {
application.perform(Selector(("_removeSessionFromSessionSet:")), with: sceneSession)
}
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
let config = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
config.delegateClass = TestsSceneDelegate.self
return config
}
}
// Add this file to the unit test target
import UIKit
class TestsSceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.rootViewController = UIViewController()
window?.makeKeyAndVisible()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment