@testable import Booking @MainActor struct BookingLandingViewTests { @Test( "Danish New Member with no GX, only PT trial", arguments: SnapshotVariant.fixedHeightVariants( height: 900, navigationTitle: "Danish New Member with no GX, only PT trial", backgroundColor: .backgroundSecondaryDefault ) ) func danishNewMemberNoGxOnlyPt(_ variant: SnapshotVariant) async throws { let view = BookingLandingView(viewData: .sampleDanishNewMemberWithoutGxOnlyPtTrial()) expectSnapshot(of: view, on: variant) } }
Type Large, Extra Large, … Region Norway, Chile, … Interface Style Light, Dark Orientation Portrait, Landscape, … Split screen Full screen, half screen, … Device Con fi guration View states Loading Error Empty Content Normal Content Content Situation #1 Content Situation #2 Content Situation #3
@testable import Booking @MainActor struct BookingLandingViewTests { @Test( "Danish New Member with no GX, only PT trial", arguments: SnapshotVariant.fixedHeightVariants( height: 900, navigationTitle: "Danish New Member with no GX, only PT trial", backgroundColor: .backgroundSecondaryDefault ) ) func danishNewMemberNoGxOnlyPt(_ variant: SnapshotVariant) async throws { let view = BookingLandingView(viewData: .sampleDanishNewMemberWithoutGxOnlyPtTrial()) expectSnapshot(of: view, on: variant) } }
modules appear depend on user, the same as the content of said modules Polymorphic data structures "Smartness" part of the backend, the clients just render that JSON
modules appear depend on user, the same as the content of said modules Polymorphic data structures "Smartness" part of the backend, the clients just render that JSON
let startTime: String let clubName: String let durationInMinutes: String let image: ImageViewData? let friendsJoining: FriendJoiningViewData? let tag: TagViewData? let destination: Destination }
let startTime: String let clubName: String let durationInMinutes: String let image: ImageViewData? let friendsJoining: FriendJoiningViewData? let tag: TagViewData? let destination: Destination } public enum ImageViewData: Equatable { case empty case remote(url: URL) case image(_ image: Image) }
fl ow Split between stateful and stateless views Mutations will trigger a new view data value that will update the view We don’t use this pattern when it doesn’t fi t the problem
Tracking Events • Networking • Design System • Navigation • Booking • Friends • Member Pro fi le • iOS • watchOS • Widgets Extracted from Figma Need dependency injection
components Snapshot testing drives you to build better UI SwiftUI is quite fl exible when it comes to the choice of architecture Dividing code in SPM packages has multiple bene fi ts
SwiftUI 17:30 Advanced Navigation for SwiftUI apps 12:24 Snapshot testing for iOS apps in Xcode Cloud 14:00 Recommended videos More details related to this talk