Skip to content

XCoordinator 3.0.0 & Modernization#16

Open
pauljohanneskraft wants to merge 4 commits into
masterfrom
feature/v3.0.0
Open

XCoordinator 3.0.0 & Modernization#16
pauljohanneskraft wants to merge 4 commits into
masterfrom
feature/v3.0.0

Conversation

@pauljohanneskraft

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings July 1, 2026 08:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR modernizes the sample app to XCoordinator 3-era APIs and iOS 16+/Swift 5.9 (goodbye, iOS 13), expands the example surface area with SwiftUI interop + deep linking, and replaces the old “unit tests copied from the library” approach with end-to-end UI tests. In other words: fewer historical artifacts, more “does the actual app work?”

Changes:

  • Migrates coordinators/view models to XCoordinator 3 conventions (any Router, @MainActor, XCoordinatorRx) and refactors coordinator transitions into helper-based factories.
  • Adds SceneDelegate + URL deep linking (including UI-test injection hooks) and introduces a SwiftUI-based home container (HomeSwiftUICoordinator / HomeSwiftUIView).
  • Revamps testing/CI: significantly expands UI tests and removes the duplicated unit-test suite previously copied from XCoordinator itself.

Reviewed changes

Copilot reviewed 53 out of 54 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
XCoordinator-ExampleUITests/XCoordinator_ExampleUITests.swift Adds comprehensive UI tests for picker flows, SwiftUI interop, deep links, and regressions.
XCoordinator-ExampleTests/XCText+Extras.swift Removes legacy unit-test helper (unit test suite deleted).
XCoordinator-ExampleTests/XCTestManifests.swift Removes Linux test manifest (unit test suite deleted).
XCoordinator-ExampleTests/XCoordinator-Example.xctestplan Updates the test plan to focus on UI tests (drops unit target from plan).
XCoordinator-ExampleTests/TransitionTests.swift Removes copied XCoordinator unit tests.
XCoordinator-ExampleTests/TestRoute.swift Removes unit-test-only route type.
XCoordinator-ExampleTests/TestAnimation.swift Removes unit-test-only animation helper.
XCoordinator-ExampleTests/AnimationTests.swift Removes copied XCoordinator unit tests.
XCoordinator-Example/Utils/NibIdentifiable.swift Documents nib instantiation convention used throughout coordinators.
XCoordinator-Example/Utils/BindableType.swift Documents MVVM-C binding contract and usage across scenes.
XCoordinator-Example/Services/UserService.swift Adds protocol documentation clarifying mock-only intent.
XCoordinator-Example/Services/NewsService.swift Adds protocol documentation and tightens swiftlint suppression scope.
XCoordinator-Example/Scenes/UserList/UsersViewModelImpl.swift Migrates router storage to any Router + @MainActor + XCoordinatorRx.
XCoordinator-Example/Scenes/UserList/UsersViewController.swift Adjusts section marker (“Initialization” → “Overrides”).
XCoordinator-Example/Scenes/User/UserViewModelImpl.swift Migrates router storage to any Router + @MainActor + XCoordinatorRx.
XCoordinator-Example/Scenes/User/UserViewController.swift Adjusts section marker (“Initialization” → “Overrides”).
XCoordinator-Example/Scenes/News/NewsViewModelImpl.swift Migrates router storage to any Router + @MainActor + XCoordinatorRx.
XCoordinator-Example/Scenes/Login/LoginViewModelImpl.swift Migrates router storage to any Router + @MainActor + XCoordinatorRx.
XCoordinator-Example/Scenes/Login/LoginViewController.swift Adds accessibility identifier for UI tests (login button).
XCoordinator-Example/Scenes/Home/HomeViewModelImpl.swift Migrates router storage to any Router, removes peek-registration path, adds @MainActor.
XCoordinator-Example/Scenes/Home/HomeViewModel.swift Documents the Input/Output/composite protocol pattern; removes peek API.
XCoordinator-Example/Scenes/Home/HomeViewController.swift Adds accessibility identifier for UI tests (users button) and removes peek wiring.
XCoordinator-Example/Scenes/Home/HomeSwiftUIView.swift Adds SwiftUI home container view embedding UIKit coordinators via WrappedRouter.
XCoordinator-Example/Scenes/About/AboutViewModelImpl.swift Migrates router storage to any Router + @MainActor + XCoordinatorRx.
XCoordinator-Example/PrivacyInfo.xcprivacy Adds privacy manifest stub for modern iOS requirements.
XCoordinator-Example/Info.plist Adds URL scheme + Scene configuration; removes armv7 requirement.
XCoordinator-Example/Extensions/Transitions.swift Documents custom transitions (presentFullScreen, dismissAll).
XCoordinator-Example/Extensions/TransitionAnimation+Defaults.swift Documents shared animation constants and CGFloat.verySmall.
XCoordinator-Example/Extensions/Presentable+Rx.swift Annotates dismissal observable with @MainActor.
XCoordinator-Example/Coordinators/UserListCoordinator.swift Refactors transitions into factories; removes peek route; adds documentation.
XCoordinator-Example/Coordinators/UserCoordinator.swift Refactors transitions into factories; documents routes + interactive wiring.
XCoordinator-Example/Coordinators/NewsCoordinator.swift Refactors transitions into factories; simplifies animation selection for iOS 16+.
XCoordinator-Example/Coordinators/HomeTabCoordinator.swift Switches to any Router storage and adds test identifiers for container visibility.
XCoordinator-Example/Coordinators/HomeSwiftUICoordinator.swift Adds SwiftUI container coordinator using ViewCoordinator + Transition.withAnimation.
XCoordinator-Example/Coordinators/HomeSplitCoordinator.swift Updates SplitCoordinator init API + adds test identifier for container visibility.
XCoordinator-Example/Coordinators/HomePageCoordinator.swift Updates PageCoordinator init API + adds test identifier and deep-link completion note.
XCoordinator-Example/Coordinators/AppCoordinator.swift Updates routing to XCoordinator 3 patterns, adds home picker + deterministic random selection, adds deep-link routes.
XCoordinator-Example/Coordinators/AboutCoordinator.swift Refactors into factories; extracts “open website” as a side-effect transition.
XCoordinator-Example/Common/UITestIdentifiers.swift Centralizes accessibility IDs and UI-test launch arguments (app target side).
XCoordinator-Example/Common/SceneDelegate.swift Adds SceneDelegate bootstrapping and URL handling (incl. UI-test env var hook).
XCoordinator-Example/Common/DeepLinkParser.swift Adds URL-to-route mapping for deep links.
XCoordinator-Example/Common/AppDelegate.swift Converts AppDelegate to scene-based lifecycle configuration.
XCoordinator-Example/Animations/Animation+Swirl.swift Ensures incoming view is framed properly (important for SwiftUI hosting).
XCoordinator-Example/Animations/Animation+Scale.swift Ensures incoming view is framed properly; removes dead code.
XCoordinator-Example/Animations/Animation+Navigation.swift Updates frame calculations to use finalFrame + autoresizing for SwiftUI safety.
XCoordinator-Example/Animations/Animation+Modal.swift Updates modal animation framing to respect finalFrame and autoresizing.
XCoordinator-Example/Animations/Animation+Fade.swift Ensures presented views get a real frame before fading (SwiftUI hosting fix).
XCoordinator-Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved Updates dependency pins (RxSwift 6.x / Action 5.x / XCoordinator revision).
XCoordinator-Example.xcodeproj/project.pbxproj Raises deployment target to iOS 16, updates Swift to 5.9, adds new sources/resources, adjusts SPM refs.
README.md Major rewrite with expanded docs (currently contains some outdated references).
CLAUDE.md Adds contributor guidance and architecture notes for agent workflows.
.swift-version Pins Swift toolchain version to 5.9.
.gitignore Cleans up and modernizes ignore rules (adds .swiftpm, workspace user data, .DS_Store).
.github/workflows/ci.yml Adds GitHub Actions CI to build + run the test plan on macOS.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md Outdated
# XCoordinator-Example

XCoordinator-Example is a MVVM-C example app for [XCoordinator](https://github.com/quickbirdstudios/XCoordinator). For a MVC example app, have a look at [a workshop](https://github.com/quickbirdstudios/Mobile-HackNight-XCoordinator) we did with a previous version of XCoordinator.
A sample iOS app showing **MVVM-C with [XCoordinator](https://github.com/quickbirdstudios/XCoordinator) v2** — built specifically to demonstrate the library's container coordinators side by side and to give you a worked example of MVVM-C scene wiring with RxSwift.
Comment thread README.md Outdated

## What this example teaches

A login → home → detail flow built end-to-end with XCoordinator v2 and MVVM-C. Use it as a reference for:
Comment thread README.md Outdated

A login → home → detail flow built end-to-end with XCoordinator v2 and MVVM-C. Use it as a reference for:

- **Four coordinator container types in one app** — `NavigationCoordinator`, `TabBarCoordinator`, `SplitCoordinator`, and `PageCoordinator`. The Home screen lets you pick which one drives the same `HomeRoute`, so you can compare them side-by-side.
Comment thread README.md Outdated
Comment on lines +29 to +31
## The three-home-coordinator picker

When you reach the Home screen, the app asks you to pick between `HomeTabCoordinator`, `HomeSplitCoordinator`, `HomePageCoordinator`, or a random one. This picker is the point of the example: all three coordinators expose the **same** `HomeRoute { case news; case userList }`, and `AppCoordinator` wraps whichever one you pick into `AppRoute.home(StrongRouter<HomeRoute>)`.
Comment thread README.md Outdated

`.multiple` chains the transitions sequentially, and `deepLink(...)` walks the coordinator hierarchy by triggering successive routes, so the app lands on the article from *any* current navigation state (modal stacks included). The users path (`AppRoute.userDetail`) takes the same shape and ends in a modal present.

One gotcha worth knowing if you deep-link through a `PageCoordinator`: `deepLink` chains the next route inside each transition's completion handler, but `UIPageViewController.setViewControllers(…, animated: true)` silently skips its completion when the requested page is *already* on-screen. A deep link whose page step targets the already-visible page would stall there. This example works around it with `Transition.setReliably(_:direction:)` in [`Extensions/Transitions.swift`](XCoordinator-Example/Extensions/Transitions.swift), a drop-in replacement for `.set` that always fires the completion — see [`HomePageCoordinator`](XCoordinator-Example/Coordinators/HomePageCoordinator.swift).
Comment thread README.md Outdated
- Xcode (current stable)
- Swift 5.9
- iOS 16+ (iPhone and iPad)
- Swift Package Manager — `XCoordinator` 2.2.1, `RxSwift` 6.10.2, `Action` 5.0.0
Comment on lines +16 to +17
/// Present the home flow. Pass `nil` to show the picker that lets the user choose one of `HomeTabCoordinator`,
/// `HomeSplitCoordinator`, or `HomePageCoordinator`; pass a concrete router to skip the picker.
Comment on lines +74 to +75
// three home-flow coordinators; the chosen coordinator is re-triggered through `.home(...)`,
// demonstrating that a `Transition` can present arbitrary decision UI.
Comment on lines +52 to +53
let alert = app.alerts.firstMatch
XCTAssertTrue(alert.waitForExistence(timeout: 5), "Picker alert never appeared")
- ci.yml: pick an available iPhone simulator dynamically instead of the
  hardcoded `iPhone 16` (the macOS runner image no longer ships it, which
  failed destination resolution with exit 70).
- README: update to XCoordinator 3 (versions, `any Router`, four home
  containers incl. the SwiftUI one, removed the obsolete `setReliably` note).
- AppCoordinator: doc/comment now mention all four home coordinators.
- UI tests: match the picker alert by its title instead of `firstMatch`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants