### Observe Manual Injection with InjectListener in UIKit/AppKit Source: https://context7.com/krzysztofzablocki/inject/llms.txt Adopt InjectListener to observe injection events. Call enableInjection() to start listening and onInjection(callback:) to register a closure that executes on each injection. ```swift import UIKit import Inject class AnimatedHeaderView: UIView { private let titleLabel = UILabel() private let gradientLayer = CAGradientLayer() override init(frame: CGRect) { super.init(frame: frame) setupUI() enableInjection() // start listening for injection events onInjection { [weak self] _ in // Reconstruct gradient colours every time you tweak them in source self?.applyGradient() print("AnimatedHeaderView re-styled via injection") } } private func setupUI() { addSubview(titleLabel) titleLabel.font = .systemFont(ofSize: 28, weight: .bold) } private func applyGradient() { gradientLayer.colors = [UIColor.systemPurple.cgColor, UIColor.systemBlue.cgColor] gradientLayer.frame = bounds layer.insertSublayer(gradientLayer, at: 0) } required init?(coder: NSCoder) { fatalError() } } ``` -------------------------------- ### Configure Other Linker Flags Source: https://github.com/krzysztofzablocki/inject/blob/main/README.md For individual developer setup, add '-Xlinker -interposable' to the 'Other Linker Flags' for the Debug configuration. This is crucial for enabling injection and should be qualified by the simulator SDK. ```bash -Xlinker -interposable ``` -------------------------------- ### SwiftUI Injection Setup Source: https://github.com/krzysztofzablocki/inject/blob/main/README.md Enable hot reloading in SwiftUI views by calling `.enableInjection()` on the view's body and adding `@ObserveInjection var inject` to your view struct. This code is a no-op in production builds. ```swift import SwiftUI import Inject struct ContentView: View { @State private var name: String = "World" @ObserveInjection var inject var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, \(name)!") } .padding() .enableInjection() } } #Preview { ContentView() } ``` -------------------------------- ### Set onInjectionHook for UIKit View Controllers Source: https://github.com/krzysztofzablocki/inject/blob/main/README.md Use the `onInjectionHook` property to execute code every time a view controller is reloaded. This is useful for re-assigning controllers to presenters or performing other setup tasks. ```swift myView.onInjectionHook = { hostedViewController in //any thing here will be executed each time the controller is reloaded // for example, you might want to re-assign the controller to your presenter presenter.ui = hostedViewController } ``` -------------------------------- ### Use Inject.ViewHost for UIKit/AppKit Source: https://github.com/krzysztofzablocki/inject/blob/main/README.md Wrap your view or view controller with Inject.ViewHost or Inject.ViewControllerHost to enable hot-reloading. This is the only change needed at the call site. ```swift paneA = Inject.ViewHost( PaneAView(whatever: arguments, you: want) ) ``` -------------------------------- ### Configure Xcode Build Settings for InjectionIII Source: https://context7.com/krzysztofzablocki/inject/llms.txt Set 'Other Linker Flags' to '-Xlinker -interposable' and define 'EMIT_FRONTEND_COMMAND_LINES' as 'YES' in your Xcode project's build settings for debug builds on the simulator. This enables InjectionIII to work correctly. ```bash # In Xcode → Target → Build Settings → Other Linker Flags (Debug only, Simulator SDK) -Xlinker -interposable # In Xcode → Editor → Add Build Setting → Add User-Defined Setting (Debug only) EMIT_FRONTEND_COMMAND_LINES = YES ``` -------------------------------- ### Enable Animated SwiftUI Updates with InjectConfiguration Source: https://context7.com/krzysztofzablocki/inject/llms.txt Set `InjectConfiguration.animation` to a non-nil `SwiftUI.Animation` to animate all injected SwiftUI view updates. This should be set once at app startup. ```swift import Inject import SwiftUI @main struct MyApp: App { init() { // Set once at app startup; applies globally to all injected views InjectConfiguration.animation = .interactiveSpring( response: 0.4, dampingFraction: 0.7, blendDuration: 0.2 ) } var body: some Scene { WindowGroup { ContentView() } } } ``` -------------------------------- ### Enable Frontend Command Line Emission Source: https://github.com/krzysztofzablocki/inject/blob/main/README.md In newer Xcode versions, you need to add a user-defined setting 'EMIT_FRONTEND_COMMAND_LINES' and set its value to 'YES' in your project's Debug build settings to support injection. ```bash EMIT_FRONTEND_COMMAND_LINES = YES ``` -------------------------------- ### Hot Reload UIKit/AppKit View Controllers with ViewControllerHost Source: https://context7.com/krzysztofzablocki/inject/llms.txt Use `Inject.ViewControllerHost` to wrap a `UIViewController` or `NSViewController`. It automatically handles tearing down the old controller and creating a new instance on injection, forwarding navigation metadata. Ensure the child controller is created via an autoclosure for proper re-creation. ```swift import UIKit import Inject // In the parent split view controller – the only change needed: class SplitViewController: UISplitViewController { override func viewDidLoad() { super.viewDidLoad() // CORRECT – pass the constructor expression directly (autoclosure) let detail = Inject.ViewControllerHost( DetailViewController(itemID: selectedItemID, style: .insetGrouped) ) // detail forwards title, navigationItem, tabBarItem automatically showDetailViewController(detail, sender: nil) } } // WRONG – do not pre-instantiate before passing to the host: // let vc = DetailViewController(itemID: id) // let host = Inject.ViewControllerHost(vc) ← injection cannot recreate vc ``` -------------------------------- ### Hot Reload UIKit/AppKit Views with ViewHost Source: https://context7.com/krzysztofzablocki/inject/llms.txt Employ `Inject.ViewHost` as a `UIView` or `NSView` to wrap subviews created via `@autoclosure`. It pins the subview to fill the host and replaces the old subview with a new instance upon injection. ```swift import UIKit import Inject class DashboardViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Wrap PriceChartView so edits to it are reflected without restarting let chartHost = Inject.ViewHost( PriceChartView(data: viewModel.chartData, style: .candle) ) view.addSubview(chartHost) NSLayoutConstraint.activate([ chartHost.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), chartHost.leadingAnchor.constraint(equalTo: view.leadingAnchor), chartHost.trailingAnchor.constraint(equalTo: view.trailingAnchor), chartHost.heightAnchor.constraint(equalToConstant: 280) ]) } } ``` -------------------------------- ### Automatic Injection Script for SwiftUI Source: https://github.com/krzysztofzablocki/inject/blob/main/README.md This bash script automates the addition of `import Inject`, `@ObserveInjection var inject`, and `.enableInjection()` to SwiftUI views. Use with caution and review changes. ```bash #!/bin/bash # Function to modify a single Swift file modify_swift_file() { local filepath="$1" local filename=$(basename "$filepath") local tempfile="$filepath.tmp" # Check if the file should be processed if [[ $(grep -c ": View {" "$filepath") -eq 0 ]]; then echo "Skipping: $filename (No ': View {' found)" return fi # Create a temporary file for modifications cp "$filepath" "$tempfile" # 1. Add import Inject if needed if ! grep -q "import Inject" "$tempfile"; then sed -i '' -e '/^import SwiftUI/a\ import Inject' "$tempfile" fi # 2. Add @ObserveInjection var inject if needed if ! grep -q "@ObserveInjection var inject" "$tempfile"; then sed -i '' -e '/struct.*: View {/a\ @ObserveInjection var inject' "$tempfile" fi # 3. Add .enableInjection() just before the closing brace of the body # Find the start of var body: some View { local body_start_line=$(grep -n "var body: some View {" "$tempfile" | cut -d ':' -f 1) if [[ -n "$body_start_line" ]]; then # Get the line number of the closing brace of the body local body_end_line=$(awk -v start="$body_start_line" ' NR == start { count = 1 } NR > start { if ($0 ~ /{/) count++ if ($0 ~ /}/) { count-- if (count == 0) { print NR exit } } } ' "$tempfile") if [[ -n "$body_end_line" ]]; then # Check if .enableInjection() is already present if ! grep -q ".enableInjection()" "$tempfile"; then # Insert .enableInjection() before the closing brace of the body sed -i '' -e "${body_end_line}i\\ .enableInjection()" "$tempfile" fi fi fi # Check if modifications were made and overwrite the original file if ! cmp -s "$filepath" "$tempfile"; then mv "$tempfile" "$filepath" echo "Modified: $filename" else echo "No changes for: $filename" fi rm -f "$tempfile" } # Main script find "$SRCROOT" -name "*.swift" -print0 | while IFS= read -r -d $'\0' filepath; do modify_swift_file "$filepath" done echo "Inject modification script completed." ``` -------------------------------- ### Configure Injection Animation Source: https://github.com/krzysztofzablocki/inject/blob/main/README.md Optionally configure an animation that will be used whenever new source code is injected into your application by setting InjectConfiguration.animation. ```swift InjectConfiguration.animation = .interactiveSpring() ``` -------------------------------- ### Correct Usage of Inject.ViewControllerHost Source: https://github.com/krzysztofzablocki/inject/blob/main/README.md Ensure you instantiate Inject.ViewControllerHost with the view controller itself, not just the view controller instance. This is crucial for the injection mechanism to work correctly. ```swift let viewController = Inject.ViewControllerHost(YourViewController()) rootViewController.pushViewController(viewController, animated: true) ``` -------------------------------- ### Post-Reload Callback for View Controllers with onInjectionHook Source: https://context7.com/krzysztofzablocki/inject/llms.txt Utilize the `onInjectionHook` closure on `ViewControllerHost` to execute code after a view controller reload. This is useful for re-binding dependencies like presenters or coordinators to the newly created controller instance. ```swift import UIKit import Inject class AppCoordinator { var presenter: HomePresenter! func start(in window: UIWindow) { let host = Inject.ViewControllerHost(HomeViewController()) // Re-attach presenter reference each time HomeViewController is recreated host.onInjectionHook = { [weak self] freshVC in guard let self else { return } self.presenter.ui = freshVC print("Presenter re-bound to reloaded HomeViewController") } window.rootViewController = UINavigationController(rootViewController: host) window.makeKeyAndVisible() } } ``` -------------------------------- ### Add Inject as SPM Dependency Source: https://github.com/krzysztofzablocki/inject/blob/main/README.md Integrate Inject into your project by adding it as a Swift Package Manager dependency. Specify the repository URL and the desired version. ```swift dependencies: [ .package( url: "https://github.com/krzysztofzablocki/Inject.git", from: "1.2.4" ) ] ``` -------------------------------- ### Automatic SwiftUI Injection Script for Xcode Build Phase Source: https://context7.com/krzysztofzablocki/inject/llms.txt This shell script injects necessary code into SwiftUI view files during the build process. It adds 'import Inject', '@ObserveInjection var inject', and '.enableInjection()' to enable hot-reloading. ```shell #!/bin/bash # Add as an Xcode "Run Script" Build Phase (runs before Compile Sources) modify_swift_file() { local filepath="$1" local filename=$(basename "$filepath") local tempfile="$filepath.tmp" # Only process files that define a SwiftUI View if [[ $(grep -c ": View {" "$filepath") -eq 0 ]]; then return fi cp "$filepath" "$tempfile" # 1. Inject import if ! grep -q "import Inject" "$tempfile"; then sed -i '' -e '/^import SwiftUI/a\ import Inject' "$tempfile" fi # 2. Inject property wrapper if ! grep -q "@ObserveInjection var inject" "$tempfile"; then sed -i '' -e '/struct.*: View {/a\ @ObserveInjection var inject' "$tempfile" fi # 3. Add .enableInjection() before the closing brace of var body local body_start_line=$(grep -n "var body: some View {" "$tempfile" | cut -d ':' -f 1) if [[ -n "$body_start_line" ]]; then local body_end_line=$(awk -v start="$body_start_line" ' NR == start { count = 1 } NR > start { if ($0 ~ /{/) count++ if ($0 ~ /}/) { count-- if (count == 0) { print NR; exit } } } ' "$tempfile") if [[ -n "$body_end_line" ]] && ! grep -q ".enableInjection()" "$tempfile"; then sed -i '' -e "${body_end_line}i\\ .enableInjection()" "$tempfile" fi fi if ! cmp -s "$filepath" "$tempfile"; then mv "$tempfile" "$filepath" echo "Inject: modified $filename" fi rm -f "$tempfile" } find "$SRCROOT" -name "*.swift" -print0 | while IFS= read -r -d $' ' filepath; do modify_swift_file "$filepath" done echo "Inject modification script completed." ``` -------------------------------- ### Add Inject via Cocoapods Source: https://github.com/krzysztofzablocki/inject/blob/main/README.md To integrate Inject using Cocoapods, add the 'InjectHotReload' pod to your Podfile. ```ruby pod 'InjectHotReload' ``` -------------------------------- ### Add Inject as SPM Dependency Source: https://context7.com/krzysztofzablocki/inject/llms.txt Add Inject to your Swift Package Manager dependencies in Package.swift. Ensure the version is compatible with your project. ```swift // Package.swift let package = Package( name: "MyApp", dependencies: [ .package( url: "https://github.com/krzysztofzablocki/Inject.git", from: "1.2.4" ) ], targets: [ .target( name: "MyApp", dependencies: ["Inject"] // Ensure Inject is listed as a dependency ) ] ) ``` -------------------------------- ### Observe Injection in SwiftUI Views Source: https://context7.com/krzysztofzablocki/inject/llms.txt Use the @ObserveInjection property wrapper in SwiftUI views to trigger body re-evaluation when code is injected. This wrapper has no overhead in release builds. ```swift import SwiftUI import Inject struct ProductCardView: View { @ObserveInjection var inject // triggers body re-evaluation on each injection let product: Product var body: some View { VStack(alignment: .leading, spacing: 8) { AsyncImage(url: product.imageURL) .frame(width: 120, height: 120) .cornerRadius(12) Text(product.name) .font(.headline) Text(product.price, format: .currency(code: "USD")) .foregroundColor(.secondary) } .padding() .background(Color(.systemBackground)) .shadow(radius: 4) .enableInjection() // must be the last modifier in body } } ``` -------------------------------- ### Register Per-Injection Callbacks in SwiftUI Source: https://context7.com/krzysztofzablocki/inject/llms.txt Use the .onInjection() view modifier to register a closure that executes on each code injection. This is useful for triggering side-effects like analytics, logging, or state resets. ```swift import SwiftUI import Inject struct ChartView: View { @ObserveInjection var inject @State private var reloadCount = 0 var body: some View { VStack { Text("Reloaded \(reloadCount) times") MyCustomChart() // Placeholder for a custom chart view } .onInjection { _ in reloadCount += 1 print("ChartView injected, rebuilding data source") } .enableInjection() } } ``` -------------------------------- ### Enable Injection in SwiftUI Views Source: https://context7.com/krzysztofzablocki/inject/llms.txt Apply the .enableInjection() modifier to a SwiftUI view to load the InjectionIII bundle and allow structural view-tree changes during injection. This modifier is inlined and has no effect in release builds. ```swift import SwiftUI import Inject struct SettingsView: View { @ObserveInjection var inject var body: some View { Form { Section("Account") { Toggle("Notifications", isOn: .constant(true)) Toggle("Dark Mode", isOn: .constant(false)) } Section("Debug") { Button("Reset Onboarding") { } // Example button .foregroundColor(.red) } } .navigationTitle("Settings") .enableInjection() // ← single line enables live editing of this entire view } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.