Hot Reloading a SceneDelegate in Swift

Hot Reloading a SceneDelegate in Swift

I told you about Hot Reloading a SwiftUI App in my previous blog post.

In this blog post, I will tell you how to inject code that is not bound to a UI representation. Example: you need to change code in your scene delegate when testing the handling of custom URLs in a UIKit-based app.

You need the same tooling:

  • Inject, a Swift Package created by Krzysztof Zabłocki
  • InjectionIII, a macOS application for the heavy lifting (i.e. watching for modified source code and interposing the new function as if it had been compiled into the SwiftUI app)

I assume you made the necessary configurations in the Build Settings of your App (-Xlinker -interposable) and that you run the on your Mac.

The critical difference is that we don't use Inject.ViewControllerHost(...) or Inject.ViewHost(...). Instead we call the lazy property Inject.load in the AppDelegate so that will watch for file changes right from the application start.

import UIKit
import Inject

class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        Inject.load // connects running iOS simulator with
        return true
    // ...

That's it !

In my video, I also prove that changes to SceneDelegate.swift will be injected and eventually executed when called by the iOS lifecycle handling.

For my video I registered a URL scheme in the Info.plist.

I added the following function to the SceneDelegate class before running the app.

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    for context in URLContexts {
        print("url: \(context.url.absoluteURL)")
        print("scheme: \(String(describing: context.url.scheme))")
        print("host: \(String(describing:")
        print("path: \(context.url.path)")
        print("components: \(context.url.pathComponents)")

Once the app starts running in the iOS simulator, I change the implementation of scene(_:openURLContexts:)

Using the terminal command xcrun simctl openurl booted <myCustomURLScheme>, I invoke a custom URL in the running iOS simulator, and I witness that the injected code gets executed.

Did you find this article valuable?

Support Marco Eidinger by becoming a sponsor. Any amount is appreciated!