Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is a preview of what I've been working on over the past few months.
It all started with #760, #742 and #973. I began by testing the proposed solution but soon realized it didn’t fully address my needs. There were, in fact, two key problems:
UIWindow
.wait
, there was no guarantee views were fully rendered before snapshots were taken.Solving the First Problem: Delay Support
Adding delays programmatically can be done in multiple ways, but the existing SnapshotTesting architecture made it difficult to inject delays mid-flow. To resolve this, I restructured the core logic of the
Snapshotting
API, inspired by Swift’s functional programming paradigms.I split the
Async
type into two distinct components:Sync
: For synchronous operations within the same execution context.Async
: For asynchronous workflows using Swift’sasync/await
.Building on functional pipelines (input → processing → output), I redesigned
Snapshotting
to enforce a clear transformation chain:Each step in this pipeline processes input and passes the result to the next, enabling modular and composable snapshot logic.
Solving the Second Problem: Reliable View Rendering
This challenge required deeper exploration of UIKit’s lifecycle. The existing
UIWindow
initialization (init()
) was outdated—though not officially deprecated—since the introduction ofUISceneDelegate
. To ensure compatibility with both UIKit and SwiftUI, I updated the implementation to useUIWindow(windowScene:)
.This change resolved rendering inconsistencies, particularly for
UINavigationController
andNavigationStack
. Additionally, I discovered that relying onkeyWindow
(now deprecated) was unnecessary, as the new approach works seamlessly with or without scene delegate support.Key Improvements & Learnings
async/await
,Sendable
, and Swift Package Manager (SPM) compatibility.SnapshotTesting
: Adapters for integrating with Swift’s new Testing framework.XCTSnapshot
: Core snapshot logic (e.g., rendering pipelines, environment configuration).XCT...
naming convention, this layer ensures compatibility with Swift Testing’s test runner.SnapshotEnvironment
andSnapshotEnvironmentKey
to pass contextual parameters (e.g., delays, platform-specific configs).@available
) to ease migration.Remaining Tasks
UIWindow
sizing requirements.Final Notes
This PR is a draft, and I welcome feedback or suggestions. Given the scope of the refactoring, I completely understand if the project maintainers decide not to merge it.
What began as an attempt to fix a delay issue evolved into a complete overhaul. Regardless of the outcome, I’m deeply grateful to the community for the foundation and the opportunity to contribute over these months.
Thank you for your time and consideration! 🙏
P.S. Contributions to address the remaining tasks are highly encouraged!