From 446d71f30520421d08d9bae7adfb0017d8b1131d Mon Sep 17 00:00:00 2001 From: shinhong-park Date: Thu, 29 Oct 2026 23:46:49 +0900 Subject: [PATCH 1/5] docs: overhaul CLAUDE.md to match current codebase --- CLAUDE.md | 660 +++++------------------------------------------------- 1 file changed, 57 insertions(+), 603 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index a089299d..0fcc4179 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,635 +1,89 @@ # CLAUDE.md -## Development Commands +SNUTT iOS — SNU course timetable app. Swift 6.1, SwiftUI, iOS 17+. Project generated with **Tuist**, tasks run with **just**. The Tuist version is pinned in `.mise.toml` (`mise exec -- tuist ...`). -This project uses **Tuist** for project generation and **Just** for task automation. +## Commands -### Essential Commands ```bash -# Project Generation -just generate # Generate Xcode project with proper certificates and open it -tuist generate --no-open # Generate without opening Xcode (useful when making file changes) - -# ⚠️ IMPORTANT: You must regenerate the project after: -# - Creating new files -# - Deleting files -# - Renaming or moving files -# - Adding new modules -# - Modifying Project.swift or Tuist configuration files -# - Updating resource keys that generate typed accessors (e.g. Localizable.strings, assets) -# Tip: Use --no-open when you plan to continue editing files before opening Xcode - -# Building -# ⚠️ WARNING: DO NOT use `tuist build` without specifying a scheme! -# It will build ALL schemes (app + all modules) and take a very long time. -# ALWAYS specify a scheme name: - -tuist build "SNUTT Dev" # Build development configuration (RECOMMENDED) -tuist build "SNUTT Prod" # Build production configuration -tuist build "SNUTT Widget" # Build app + widget extension - -# ⚠️ CRITICAL: ALWAYS run `tuist build` synchronously (NOT as a background job)! -# Never use run_in_background=true or append '&' to build commands. -# Wait for the build to complete before proceeding with other tasks. -# This ensures proper error detection and prevents build state corruption. - -# Module-Specific Builds -# Use these for faster builds when working on a single module: -tuist build Timetable # Build only Timetable module -tuist build Auth # Build only Auth module -tuist build Vacancy # Build only Vacancy module -tuist build Themes # Build only Themes module -# ... and more schemes for other modules - -# Testing -tuist test Timetable # Run tests for Timetable module -tuist test Auth # Run tests for Auth module -tuist test "ModuleTests" # Run all module tests - -# Code Quality -just format # Format Swift code using swift-format -just check # Run all checks (formatting, imports, etc.) - -# API Code Generation -just openapi-dev # Generate API client for dev server -just openapi-prod # Generate API client for prod server -``` - -### Available Schemes - -This project automatically generates the following schemes: - -#### Main App Schemes -- **SNUTT Dev**: Development build with dev API endpoint (`snutt-api-dev.wafflestudio.com`) -- **SNUTT Prod**: Production build with prod API endpoint (`snutt-api.wafflestudio.com`) -- **SNUTT Widget**: Build app with widget extension for testing widgets - -#### Module Schemes - -Each feature and shared UI module has its own scheme for faster, isolated builds and testing: - -**Feature Modules:** -- `Timetable`, `Auth`, `Notifications` -- `Vacancy`, `Themes`, `Settings` -- `Reviews`, `Friends`, `Popup` - -**Shared UI Modules:** -- `TimetableUIComponents` -- `SharedUIComponents`, `SharedUIWebKit`, `SharedUIMapKit` - -**Test Scheme:** -- `ModuleTests`: Runs all module tests across the project - -#### When to Use Module Schemes - -Module schemes are ideal for **localized development** when working on a single module: - -```bash -# Example: Working on Timetable feature only -tuist build Timetable # Much faster than full app build -tuist test Timetable # Run only Timetable tests - -# Example: Making changes to shared UI components -tuist build SharedUIComponents -tuist test SharedUIComponents -``` - -**Benefits:** -- **Faster build times**: Only builds the target module and its dependencies -- **Quick validation**: Immediately verify if your changes compile without full app rebuild -- **Focused testing**: Run tests for specific modules during development -- **Isolated development**: Work on specific modules without building the entire app - -**Note:** Some modules don't have schemes: -- `Analytics` (marked as `previewable: false`) -- `Configs` (marked as `previewable: false`) -- `APIClient` (marked as `previewable: false`) -- All `*Interface` modules (FeatureInterface modules don't have schemes) - -### Build Configurations -- **Dev**: Development configuration, API: `snutt-api-dev.wafflestudio.com` -- **Prod**: Production configuration, API: `snutt-api.wafflestudio.com` - -## Architecture Overview - -SNUTT follows a **strict modular architecture** with Clean Architecture principles: - -### Module Categories -1. **Feature Modules** (`Modules/Feature/`): Self-contained features with implementations -2. **Feature Interface Modules** (`Modules/Feature/*Interface/`): Public contracts for features -3. **Shared Modules** (`Modules/Shared/`): Reusable UI components and app-wide utilities -4. **Utility Modules** (`Modules/Utility/`): Low-level utilities and helpers - -### Critical Dependency Rules -- **Feature → FeatureInterface**: Features can ONLY depend on interfaces of other features -- **FeatureInterface → Feature**: **STRICTLY FORBIDDEN** - Interfaces cannot depend on implementations -- **Feature → Feature**: **FORBIDDEN** - Use UIProvider pattern instead (see "Core Architecture Patterns" below) -- **Feature/FeatureInterface → Utility/Shared**: Can depend on utilities and shared modules -- No circular dependencies between modules at the same level - -### Clean Architecture Layers (within each feature) -``` -UI Layer (SwiftUI Views) - ↓ -Presentation Layer (ViewModels with @Observable) - ↓ -Business Logic Layer (Use Cases, Domain Models, Repository Protocols) - ↓ -Infrastructure Layer (Repository Implementations) -``` - -**Layer Rules:** -- UI can ONLY depend on ViewModels (Presentation layer) -- UI CANNOT directly access repositories or use cases -- ViewModels use dependency injection to access business logic -- Business logic depends on repository interfaces, not implementations - -## Core Architecture Patterns - -### 1. UIProvider Pattern - Cross-Feature UI Composition - -Since features cannot directly depend on each other, SNUTT uses a **UIProvider pattern** to share UI components between features. - -**Problem:** Feature A needs to show UI from Feature B, but importing Feature B violates the architecture. - -**Solution:** Feature B defines a `UIProvidable` protocol in its interface module. Feature A uses this protocol via dependency injection. The app wires them together. - -**Example: TimetableUIProvidable** - -Interface definition in `TimetableInterface/Sources/UI/TimetableUIProvidable.swift`: -```swift -@MainActor -public protocol TimetableUIProvidable: Sendable { - func lectureDetailRow(type: DetailLabelType, lecture: Lecture) -> AnyView - func timetableView( - timetable: Timetable?, - configuration: TimetableConfiguration, - preferredTheme: Theme?, - availableThemes: [Theme] - ) -> AnyView -} - -public enum TimetableUIProviderKey: TestDependencyKey { - public static let testValue: any TimetableUIProvidable = EmptyTimetableUIProvider() -} - -extension DependencyValues { - public var timetableUIProvider: any TimetableUIProvidable { - withDependencies { - $0.context = .live - } operation: { - Dependency(\.timetableUIProvider).wrappedValue - } - } -} +tuist generate --no-open # Regenerate project (`just generate` also syncs certs and opens Xcode) +tuist build "SNUTT Dev" # Build the app (dev API) +tuist build Timetable # Build one module — much faster when only one module changed +tuist test Timetable # Test one module +tuist test ModuleTests # Test all modules +just check # tuist inspect implicit-imports + swift-format +just openapi-dev # Download OpenAPI spec and generate code ``` -Implementation in `Timetable/Sources/UI/TimetableUIProvider.swift`: -```swift -public struct TimetableUIProvider: TimetableUIProvidable { - public nonisolated init() {} - - public func lectureDetailRow(type: DetailLabelType, lecture: Lecture) -> AnyView { - AnyView(LectureDetailRow(type: type, lecture: lecture)) - } +- **Rerun `tuist generate --no-open`** after adding, deleting, or moving files, or changing `Project.swift`, Tuist config, or resources with generated accessors (Localizable.strings, assets). +- **Always pass a scheme to `tuist build`.** Without one it builds every scheme. +- **Run `tuist build` in the foreground, synchronously.** Never in the background. +- OpenAPI output (`**/Generated/`) is gitignored. On a fresh checkout, if the build fails on missing generated types, run `just openapi-dev` first. Output locations: `APIClientInterface/Sources/Generated` (types), `APIClient/Sources/Generated` (client). +- A pre-commit hook runs swift-format (120 columns, 4-space indent, `.swift-format`). - public func timetableView(...) -> AnyView { - AnyView(TimetableZStack(...)) - } -} -``` +### Schemes -Injection at app level in `SNUTT/Sources/Composition/LiveDependencies.swift`: -```swift -extension TimetableUIProviderKey: @retroactive DependencyKey { - public static let liveValue: any TimetableUIProvidable = TimetableUIProvider() -} -``` +- App: `SNUTT Dev`, `SNUTT Prod`, `SNUTT Widget` (includes the widget extension) +- Modules: every previewable Feature module and every UI Shared/Utility module gets a scheme with the module's name. `*Interface` modules and `previewable: false` modules (Analytics, Configs, APIClient) have none. -Usage in another feature: -```swift -@Environment(\.timetableUIProvider) private var timetableUIProvider +## Module Structure -var body: some View { - timetableUIProvider.lectureDetailRow(type: .lecturer, lecture: lecture) -} -``` +Three categories under `Modules/`. Modules and their dependencies are declared in `Project.swift`. -**Key Benefits:** -- Features remain independent (no direct imports) -- Dependency graph stays clean -- UI can be mocked in previews with test values -- App controls wiring, not individual features +- `Feature/` — feature modules and their `*Interface` contract modules +- `Shared/` — SNUTT-specific UI and app utilities (design system, `SharedAppMetadata`) +- `Utility/` — general-purpose helpers with no app context ---- +### Dependency Rules -### 2. EnvironmentValue with withDependencies - Preview Support +- A Feature may depend on other Features' **Interfaces only**. Importing another Feature directly is forbidden. +- An Interface must never depend on a Feature implementation. +- To show another Feature's UI, use the **UIProvider pattern** (below). +- Only the app module (`SNUTT/Sources/Composition/LiveDependencies.swift`) wires implementations together. -SNUTT bridges `DependencyValues` (swift-dependencies) with `EnvironmentValues` (SwiftUI) using `withDependencies`: +### Layers inside a Feature -```swift -extension EnvironmentValues { - public var timetableUIProvider: any TimetableUIProvidable { - withDependencies { - $0.context = .live // Switch to live context for previews - } operation: { - Dependency(\.timetableUIProvider).wrappedValue - } - } -} ``` - -**Why this pattern?** -- In app runtime: Dependencies uses `.live` context by default (production implementations) -- In previews: The `withDependencies { $0.context = .live }` explicitly switches to live context so preview values work seamlessly -- Ensures previews display actual UI, not test stubs -- Allows DependencyKey configuration to work in SwiftUI preview environment - -**@Entry Pattern - Simpler Alternative** - -For simpler environment values that don't need DependencyKey complexity: -```swift -extension EnvironmentValues { - @Entry public var timetableViewModel: any TimetableViewModelProtocol = DefaultTimetableViewModel() -} +Sources/ +├─ UI/ # SwiftUI views; depend only on ViewModels +├─ Presentation/ # @Observable @MainActor ViewModels; inject repositories/use cases via @Dependency +├─ BusinessLogic/ # Use cases (only when needed) +├─ Infra/ # Repository implementations (API, UserDefaults, Keychain, SDKs) +└─ Composition/ # This Feature's DependencyKey registrations (LiveDependencies.swift) ``` -The `@Entry` macro automatically provides a default value for previews without manual getter/setter. +Views never touch repositories or use cases. ViewModels may inject repositories directly (most do today). Add a use case only when there is real logic to hold, such as combining several repositories. Domain models and repository protocols live in `*Interface` modules. Infra maps DTOs to domain models. ---- +## Dependency Injection (swift-dependencies) -### 3. Three-Level Dependency Injection Strategy +**Where does the key go?** Does another Feature need to import this protocol? -SNUTT uses a sophisticated three-level DI system to maintain architecture integrity: +- **Yes** → define it in the `*Interface` module as a `TestDependencyKey` with only a `testValue` (usually a `@Spyable`-generated Spy). Add `liveValue`/`previewValue` via `@retroactive DependencyKey` in the implementing Feature's `Composition/` or in the app's `LiveDependencies.swift`. + - Example: `TimetableInterface/Sources/Repository/TimetableLocalRepository.swift` → `Timetable/Sources/Composition/LiveDependencies.swift` +- **No** → define a plain `DependencyKey` (internal) directly in the Feature's `Composition/LiveDependencies.swift`. + - Example: `LectureSearchRepositoryKey` in `Timetable/Sources/Composition/LiveDependencies.swift` -**Level 1: Interface Module - Define Contract with TestDependencyKey** - -In `TimetableInterface/Sources/Repository/TimetableLocalRepository.swift`: -```swift -@Spyable -public protocol TimetableLocalRepository: Sendable { - func loadSelectedTimetable() throws -> Timetable - func storeSelectedTimetable(_ timetable: Timetable) throws -} - -public enum TimetableLocalRepositoryKey: TestDependencyKey { - public static let testValue: any TimetableLocalRepository = { - let spy = TimetableLocalRepositorySpy() // Auto-generated by @Spyable - spy.loadSelectedTimetableReturnValue = PreviewHelpers.preview(id: "1") - return spy - }() -} - -extension DependencyValues { - public var timetableLocalRepository: any TimetableLocalRepository { - get { self[TimetableLocalRepositoryKey.self] } - set { self[TimetableLocalRepositoryKey.self] = newValue } - } -} -``` - -**Key Points:** -- Interface modules use `TestDependencyKey` (not `DependencyKey`) -- Only define `testValue` with pre-configured spy -- Interfaces don't know implementation details -- `@Spyable` automatically generates spy classes for testing - -**Level 2: Feature Module - Provide Implementation with DependencyKey** - -In `Timetable/Sources/Composition/LiveDependencies.swift`: -```swift -extension TimetableLocalRepositoryKey: @retroactive DependencyKey { - public static let liveValue: any TimetableLocalRepository = - TimetableUserDefaultsRepository() - - public static let previewValue: any TimetableLocalRepository = { - let spy = TimetableLocalRepositorySpy() - spy.loadSelectedTimetableReturnValue = PreviewHelpers.preview(id: "1") - return spy - }() -} -``` - -**Key Points:** -- Feature modules add `DependencyKey` conformance via `@retroactive` -- Define `liveValue` (production) and `previewValue` (Xcode previews) -- Feature-specific dependencies wired here (API repos, local storage, SDKs) -- Not exposed publicly - only used by app's LiveDependencies - -**Level 3: App Module - Wire Everything at Root** - -In `SNUTT/Sources/Composition/LiveDependencies.swift`: -```swift -// Imports all feature implementations -import Timetable -import Auth -import Vacancy -// ... more features - -// Wire all dependencies at app level -extension TimetableUIProviderKey: @retroactive DependencyKey { - public static let liveValue: any TimetableUIProvidable = TimetableUIProvider() -} - -extension AuthRepositoryKey: @retroactive DependencyKey { - public static let liveValue: any AuthRepository = AuthAPIRepository() -} - -extension VacancyRepositoryKey: @retroactive DependencyKey { - public static let liveValue: any VacancyRepository = VacancyAPIRepository() -} -``` +Repository protocols and implementations are all `Sendable`. -**Key Points:** -- Central place where all production implementations are wired -- Only the app module imports feature implementations -- Uses `@retroactive` to add conformances to interface types -- Features remain independent from each other -- Dependency graph is acyclic and clearly defined +### UIProvider Pattern ---- +Use it when Feature A needs to show a screen from Feature B: -### 4. Clean Architecture Layers - Detailed Responsibilities +1. In B's Interface, define `@MainActor protocol XxxUIProvidable: Sendable` (methods return `AnyView`) and a `TestDependencyKey` whose `testValue` is an empty implementation. +2. Keep the `DependencyValues` accessor `fileprivate`, and expose a `public` accessor on `EnvironmentValues`. Wrap that accessor in `withDependencies { $0.context = .live }` so previews read the live value too. +3. Implement the protocol in B, and wire it as `liveValue` in the app's `LiveDependencies.swift`. +4. Use it in A via `@Environment(\.xxxUIProvider)`. -**UI Layer** (`Sources/UI/`) -- SwiftUI Views and Scenes -- Pure UI presentation -- Responds to user interactions -- Accesses state only via ViewModels -- No business logic, no repository access +Reference: `TimetableInterface/Sources/UI/TimetableUIProvidable.swift`, `Timetable/Sources/UI/TimetableUIProvider.swift` -**Presentation Layer** (`Sources/Presentation/`) -- ViewModels marked with `@Observable` and `@MainActor` -- Orchestrates business logic operations -- Manages presentation state (loading, error, data) -- Performs side effects (navigation, analytics) -- Injects dependencies via `@Dependency` -- Never directly access repositories (go through use cases) - -**Business Logic Layer** (`Sources/BusinessLogic/`) -- **Use Cases**: Orchestrate repository calls, implement domain logic -- **Domain Models**: Value types representing core concepts (defined in interface) -- **Repository Protocols**: Contracts for data access (defined in interface) -- Business logic has **zero knowledge** of HTTP, storage, SDKs, or UI - -**Infrastructure Layer** (`Sources/Infra/`) -- **API Repositories**: HTTP communication via OpenAPI client, DTO-to-domain transformation -- **Local Storage Repositories**: UserDefaults, Keychain, CoreData access -- **SDK Wrappers**: Third-party SDKs (Auth services, ImageRenderer) -- Implementation details hidden from business logic -- Transforms external data formats to domain models - -**Example: API Repository** -```swift -public struct LectureAPIRepository: LectureRepository { - @Dependency(\.apiClient) private var apiClient // External dependency - - public func fetchBuildingList(places: [LectureBuilding]) async throws -> [Building] { - let response = try await apiClient.searchBuildings(query: .init(places: joinedPlaces)) - return response.content.compactMap { Building(dto: $0) } // DTO → Domain - } -} -``` - ---- - -### 5. TestDependencyKey vs DependencyKey - When to Use Each - -The choice depends on **whether the dependency is shared across features**: - -**TestDependencyKey - For Cross-Feature Dependencies** - -Use in Interface modules when a protocol is **used by multiple features**: -```swift -// TimetableInterface/Sources/Repository/TimetableLocalRepository.swift -// Used by: Timetable feature, Settings feature, potentially others - -@Spyable -public protocol TimetableLocalRepository: Sendable { - func loadSelectedTimetable() throws -> Timetable -} - -public enum TimetableLocalRepositoryKey: TestDependencyKey { - public static let testValue: any TimetableLocalRepository = { - let spy = TimetableLocalRepositorySpy() - spy.loadSelectedTimetableReturnValue = PreviewHelpers.preview(id: "1") - return spy - }() - // NOTE: No liveValue - interface module can't import implementations -} - -extension DependencyValues { - public var timetableLocalRepository: any TimetableLocalRepository { - get { self[TimetableLocalRepositoryKey.self] } - set { self[TimetableLocalRepositoryKey.self] = newValue } - } -} -``` - -**Why TestDependencyKey for cross-feature?** -- Other features import only the interface module (no feature implementation) -- Interface module can't define liveValue (would create circular dependency) -- Each feature provides its own implementation via `@retroactive DependencyKey` in Composition -- Only provides `testValue` - concrete implementations defined elsewhere - -**DependencyKey - For Feature-Internal Dependencies** - -Use directly in Feature Composition when a protocol is **used only within that feature**: -```swift -// Timetable/Sources/Composition/LiveDependencies.swift -// Used by: Only Timetable feature (not shared) - -struct LectureSearchRepositoryKey: DependencyKey { // Direct DependencyKey - static let liveValue: any LectureSearchRepository = LectureSearchAPIRepository() - - static let previewValue: any LectureSearchRepository = { - let spy = LectureSearchRepositorySpy() - spy.fetchSearchResultQueryQuarterPredicatesOffsetLimitReturnValue = [] - return spy - }() -} - -extension DependencyValues { - var lectureSearchRepository: any LectureSearchRepository { - get { self[LectureSearchRepositoryKey.self] } - set { self[LectureSearchRepositoryKey.self] = newValue } - } -} -``` - -**Why DependencyKey directly for internal?** -- Only this feature uses it (no circular dependency risk) -- Can safely define liveValue immediately (implementation is in same feature) -- Simpler and more direct - no need for @retroactive conformance -- Keeps internal dependencies private to the feature - -**Real-World Example:** - -``` -TimetableLocalRepository: - ✓ Shared by multiple features (Timetable, Settings, etc.) - → Defined as TestDependencyKey in TimetableInterface (testValue only) - → App's Composition adds @retroactive DependencyKey with liveValue - → All features: import TimetableInterface, use testValue in previews, - use app-injected liveValue at runtime - -LectureSearchRepository: - ✓ Used only by Timetable feature - → DependencyKey defined in Timetable/Composition/LiveDependencies.swift - → No interface module needed if truly feature-internal -``` - -**Decision Tree:** -``` -Does another feature need to import this protocol? -├─ YES → TestDependencyKey in *Interface module -│ (liveValue added by feature in Composition) -└─ NO → DependencyKey directly in feature's Composition - (liveValue defined immediately) -``` - ---- - -### 6. Shared vs Utility Modules - Clear Distinction - -| Aspect | Shared Modules | Utility Modules | -|--------|---|---| -| **Purpose** | SNUTT-specific UI & app utilities | General-purpose Swift helpers | -| **Reusability** | Only within SNUTT | Any Swift project | -| **App Context** | Contains design system decisions | Zero app context | -| **Examples** | `Popup` (12pt corner radius, SNUTT styling), `CommonTabView`, `Logo` | `Color+Hex` (generic extension), `@OnLoad` modifier | -| **Location** | `Modules/Shared/SharedUIComponents/`, `SharedAppMetadata/` | `Modules/Utility/SwiftUIUtility/`, `FoundationUtility/` | -| **Dependencies** | App-specific (assets, themes, configs) | Only Foundation/SwiftUI | -| **Used By** | Features, App | All modules | - -**Shared Example:** -```swift -// SharedUIComponents/Popup/Popup.swift - SNUTT-specific -private enum Layout { - static var cornerRadius: CGFloat { 12 } // Design decision - static var horizontalMargin: CGFloat { 40 } // Design decision - static var backgroundOpacity: CGFloat { 0.5 } -} -``` - -**Utility Example:** -```swift -// SwiftUIUtility/Color+Hex.swift - Generic, any app can use -extension Color { - public init(hex: String, alpha: Double = 1) { - // Pure hex parsing logic - no app context - } -} -``` - ---- - -### Key Features by Module - -- **Timetable**: Course timetable display, lecture search & edit, image export -- **Auth**: User authentication (local, Kakao, Google, Facebook, Apple), account management -- **Notifications**: Real-time notification display, FCM integration -- **Vacancy**: Course vacancy tracking, vacancy alerts -- **Themes**: Timetable color theme management & selection -- **Settings**: Account settings, app preferences, feature toggles -- **Reviews**: Lecture evaluation display (read-only) -- **Friends**: Friend list, timetable sharing -- **Popup**: App-wide popup/announcement system -- **Analytics**: Firebase analytics integration -- **Configs**: Server-side configuration & feature flags - -## Technology Stack - -- **Language**: Swift 6.1+ with modern Swift Concurrency (`async/await`) -- **UI Framework**: SwiftUI with Observation framework (`@Observable`, `@Bindable`) -- **Minimum iOS Version**: 17.0+ -- **Xcode Version**: 16.0+ -- **Project Management**: Tuist for modular project generation -- **Code Formatting**: swift-format with 120 character line length, 4-space indentation -- **API Integration**: OpenAPI-generated client with separate dev/prod configurations -- **Dependency Injection**: swift-dependencies package -- **Maps**: Kakao Maps SDK -- **Testing**: Swift Testing framework with Spyable for mock generation - -## Testing Strategy - -SNUTT uses **Swift Testing** framework (Apple's modern testing framework) instead of XCTest. - -### Swift Testing Basics - -**Import Statement:** -```swift -import Testing -``` - -**Test Function:** -```swift -@Test func testExample() { - #expect(1 + 1 == 2) -} -``` - -- Use `@Test` macro instead of `func testXxx()` or XCTestCase subclasses -- Use `#expect(condition)` instead of `XCTAssert*` methods - -**Test Suite (optional):** -```swift -@Suite struct TimetableTests { - @Test func loadsTimetable() { - #expect(true) - } - - @Test func savesTimetable() { - #expect(true) - } -} -``` - -### Test File Organization - -Test files are located in each module's `Tests/` directory: -``` -Modules/Feature/FeatureName/Tests/FeatureNameTests.swift -``` - -### Important: NO XCTest - -- **Do NOT use XCTest** in new test files -- **Do NOT use XCTAssert*** methods -- Always use Swift Testing framework with `@Test` and `#expect` - -## Code Style & Conventions - -- **Formatting**: Automatic formatting via swift-format (configured in `.swift-format`) -- **Pre-commit Hooks**: swift-format runs automatically on commit -- **Sendable**: All repository protocols and implementations must be `Sendable` -- **MainActor**: ViewModels should be annotated with `@MainActor` -- **Async/Await**: Use Swift Concurrency for all asynchronous operations -- **Observation**: Use `@Observable` macro for ViewModels instead of ObservableObject - -## File Structure Template - -Each feature should follow this structure: -``` -Modules/Feature/FeatureName/ -├─ Sources/ -│ ├─ UI/ # SwiftUI Views -│ ├─ Presentation/ # ViewModels -│ ├─ BusinessLogic/ # Use Cases, Domain Models -│ ├─ Infra/ # Repository Implementations -│ └─ Composition/ # Dependency Registration (LiveDependencies.swift) -└─ Tests/ - └─ UnitTests/ # Tests for all layers -``` +Use `@Entry` for simple environment values. -## OpenAPI Integration +## Testing -- API specs are automatically downloaded and generated -- Separate configurations for dev and prod environments -- Generated clients are located in `Modules/Feature/APIClientInterface/` -- Use `just openapi-dev` or `just openapi-prod` to regenerate API clients +- Use **Swift Testing** (`@Test`, `#expect`) only. No XCTest in new tests. +- Tests live in each module's `Tests/`. Use `@Spyable`-generated Spies as mocks. -## Widget Extension +## Misc -The project includes a widget extension (`SNUTTWidget`) with its own target and dependencies, primarily using timetable functionality. -- The app's Info.plist is stored in Tuist/ProjectDescriptionHelpers/InfoPlist.swift. +- The app's Info.plist is defined in `Tuist/ProjectDescriptionHelpers/InfoPlist.swift`. +- API hosts: Dev → `snutt-api-dev.wafflestudio.com`, Prod → `snutt-api.wafflestudio.com` +- The widget extension lives in `SNUTTWidget/` and mostly uses Timetable functionality. From 6368d6ab2a6a857bb2e0202fe3183715b087e89b Mon Sep 17 00:00:00 2001 From: Shinhong Park Date: Fri, 30 Oct 2026 01:43:48 +0900 Subject: [PATCH 2/5] docs: import personal instructions from outside the repo --- CLAUDE.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 0fcc4179..374e0c2a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -87,3 +87,7 @@ Use `@Entry` for simple environment values. - The app's Info.plist is defined in `Tuist/ProjectDescriptionHelpers/InfoPlist.swift`. - API hosts: Dev → `snutt-api-dev.wafflestudio.com`, Prod → `snutt-api.wafflestudio.com` - The widget extension lives in `SNUTTWidget/` and mostly uses Timetable functionality. + +## Additional Instructions + +@~/.claude/snutt-ios.local.md From af5b57a4a3caa92a9ff1323d0595485fb0f8568b Mon Sep 17 00:00:00 2001 From: Shinhong Park Date: Thu, 29 Oct 2026 23:56:59 +0900 Subject: [PATCH 3/5] chore: add sim-use agent skill --- .agents/skills/sim-use/SKILL.md | 189 ++++++++++++ .../sim-use/references/batch-reference.md | 104 +++++++ .../skills/sim-use/references/cheatsheet.md | 223 ++++++++++++++ .../sim-use/references/crash-awareness.md | 59 ++++ .agents/skills/sim-use/references/pitfalls.md | 141 +++++++++ .../__pycache__/preflight.cpython-314.pyc | Bin 0 -> 16279 bytes .agents/skills/sim-use/scripts/preflight.py | 281 ++++++++++++++++++ 7 files changed, 997 insertions(+) create mode 100644 .agents/skills/sim-use/SKILL.md create mode 100644 .agents/skills/sim-use/references/batch-reference.md create mode 100644 .agents/skills/sim-use/references/cheatsheet.md create mode 100644 .agents/skills/sim-use/references/crash-awareness.md create mode 100644 .agents/skills/sim-use/references/pitfalls.md create mode 100644 .agents/skills/sim-use/scripts/__pycache__/preflight.cpython-314.pyc create mode 100644 .agents/skills/sim-use/scripts/preflight.py diff --git a/.agents/skills/sim-use/SKILL.md b/.agents/skills/sim-use/SKILL.md new file mode 100644 index 00000000..5c14ad95 --- /dev/null +++ b/.agents/skills/sim-use/SKILL.md @@ -0,0 +1,189 @@ +--- +name: sim-use +description: Drive iOS Simulator, Android emulator/device, and physical iPhone/iPad screens for AI agents. Use when asked to automate a simulator or emulator, drive a real iOS device, tap/swipe/type on a device, describe UI, take a screenshot, or interact with a mobile app. +--- + +## 0. Preflight + +Before first interaction with a device, run the preflight check: + +```bash +python3 scripts/preflight.py --device +``` + +This verifies sim-use is installed and compatible with the skill, the device is reachable, and the daemon is healthy. If you don't have the script, do the checks manually: + +1. `sim-use --version` — confirm sim-use is on PATH and supports the skill's documented commands. +2. `sim-use devices` — confirm the target device is listed and booted/connected. +3. `sim-use ui --device ` — confirm you can read the screen. + +A `WARN UI content` line still passes preflight: the read works, but the outline can miss app controls. See the *Pitfalls* index. + +`--device` is optional when only one simulator is booted or one daemon is running. For Android, run `sim-use android init --device ` once to install the bridge APK. Attached physical iPhones/iPads appear in `sim-use devices` with kind `physical` and route through the top-level verbs too — but only `ui`, selector-based `tap` and `screenshot`; every other verb rejects on that target. See *Physical iOS devices* below before driving one. A Linux build of sim-use drives Android only: `sim-use ios …`, `record-video` / `stream-video`, `viewer` and `init` are absent there, every verb needs `--device `, and `sim-use devices` lists Android devices only. + +## 1. The observe-act loop + +Every interaction follows the same cycle: **observe → act → verify**. + +### Observe + +```bash +sim-use ui --device +``` + +Read the outline. Each element has an `@N` alias and optionally a `#` identifier. List cells carry `#N` (dominant list) or `#N@M` (scoped). + +Frames in the JSON output (`--json`: `entries[].frame`, `screen`) are in platform-native units — iOS **points**, Android **pixels**. Key off the envelope's `platform` field before doing math on coordinates across platforms. Always pair `--json` with `--no-raw` — see *Keeping output small* below. + +### Act + +Pick a selector, in order of preference: + +| Selector | When to use | +|---|---| +| `tap @N` | Right after `ui`. Fastest, cache-backed. | +| `tap #` | Stable across minor layout changes. Paste from the outline. | +| `tap --label 'X'` | Scripted flows. Combine with `--wait-timeout` for transitions. | +| `tap --label-regex '...'` | Dynamic labels with counters/timestamps. Anchor with `^...$`. | +| `tap --label-contains 'X'` | Substring match when exact label is unknown. | +| `tap -x N -y N` / `tap --point x,y` | Last resort for elements with no AX data. Takes the numbers the outline prints, in any orientation and on any display; `--coordinate-space native` is for device-native portrait points. | + +Disambiguate collisions with `--element-type` or `--frame minY=0.7r` (see `references/cheatsheet.md`). + +### Verify + +Always verify after acting — commands are fire-and-forget: + +```bash +sim-use ui --device # read the new screen state +sim-use screenshot --device --output after.png +``` + +### Keeping output small + +Every byte of command output you read costs context. Defaults that keep the loop cheap: + +- Prefer the default text outline over `--json`. The outline carries everything a tap needs (`@N` / `#` aliases, roles, frames, states); reach for `--json` when you need structured fields for coordinate math (`entries[].frame`, `screen`) or full untruncated text (the outline truncates labels at 60 graphemes, `value=` at 30). +- When you do use `--json`, add `--no-raw`. `data.raw` is the raw accessibility tree — typically the bulk of the envelope's bytes, and useful only for debugging sim-use itself. +- One `ui` per action: the Verify read of step N is the Observe read of step N+1. Don't run a second `ui` in between. +- Verify with the text outline, not a screenshot. Reading a screenshot costs several times more than a typical outline; take one only when the check is genuinely visual (colors, images, layout). +- On iOS, to wait out a transition, prefer `tap --label 'X' --wait-timeout 3` (polls for the element) over re-running `ui` in a loop. Android `tap` has no `--wait-timeout`; use `sleep` between commands instead. +- For a known multi-step sequence on iOS, use `sim-use ios batch` (see `references/batch-reference.md`) — one invocation, one output. + +### Common moves + +| Task | Command | +|---|---| +| Scroll down | `sim-use gesture scroll-up --device ` (scroll-up = content moves up = page down) | +| Type text | `sim-use type 'hello' --device ` | +| Paste Unicode | Focus the field, then `sim-use paste 'こんにちは 🎉' --device `; iOS works with Simulator.app or Device Hub, in either keyboard mode | +| Hardware button | `sim-use button home --device ` | +| Android back | `sim-use button back --device ` | +| Wait for animation | `sleep 0.4` between commands, or `--pre-delay 0.5` | +| Toggle/switch | `sim-use tap @N --duration 0.05 --device ` (UISwitch needs a brief hold) | +| Swipe | `sim-use swipe --from 50,500 --to 350,500 --device ` | +| Pinch zoom in | `sim-use gesture pinch-out --device ` (two-finger spread) | +| Rotate (two-finger gesture) | `sim-use gesture rotate-cw --angle 90 --device ` | +| Rotate the device (iOS) | `sim-use ios rotate landscape-left --device ` — interface names as the `App:` header prints them; re-run `ui` after | +| Fold / unfold (iPhone Duo) | `sim-use ios fold closed\|open --device `; `sim-use ios fold --device ` reports which display is active; re-run `ui` after | +| Record evidence GIF | `sim-use record-video --output demo.gif --device ` — stop with SIGINT/SIGTERM (never SIGKILL); transcodes after stop; auto-plays inline in PRs; add `--gif-markers` for START/END loop-boundary cards | + +### Paste on iOS simulators + +Prefer `paste` for Unicode and IME-safe text. The default preserves the focused field's caret and selection. `--replace` selects all first. Use `--via-menu --target-id ` or `--target-x/--target-y` to focus a target explicitly. Both paths use the native Paste action; no hardware-keyboard or sync-setting change is needed. + +For multiline or shell-sensitive text, use `printf '%s' "$TEXT" | sim-use paste --stdin --device ` or `paste --file `. The control's native rules still apply, including single-line normalization and smart-paste spaces. `--replace` fails before Paste if Select All is unavailable and the field is not confirmed empty through accessibility. Never treat that refusal as a successful replacement. Unknown or ambiguous menu provenance is also refused; do not bypass that refusal by tapping a same-label app button. Always verify the actual field. If the command reports that Paste may have been sent, check the field before retrying; it does not automatically resend Paste. + +Shared clipboard sync can also overwrite the Mac and other devices. Keep one clipboard writer active. sim-use serializes its own paste operations and checks for unexpected readback, but cannot prevent external writes. Never print unrelated clipboard data or restore an old backup over newer external content. + +Batch paste supports default, replacement, files and explicit menu targets; `paste --stdin` is not a batch step because stdin belongs to the batch. A failed batch is not automatically replayed after a transient boot-readiness error. Inspect the UI and completed steps before retrying, including with `--continue-on-error`. + +### Physical iOS devices (experimental) + +The top-level verbs route a physical UDID automatically, but only three of them: `ui`, `tap` (`#` / `--id` / `--label` / `--label-contains` / `--element-type` forms) and `screenshot`. **Never assume capability parity with the simulator** — every other verb or form (coordinates, `@N`/`#N` aliases, swipe/gesture/multi-touch, type/paste, recording, `--value`/`--label-regex`/`--frame`/`--duration`/`--wait-timeout`) rejects with the reason and the nearest alternative in the `hint`; read it instead of retrying. The `sim-use ios-device` namespace is the physical-only peer of `ios`/`android` (same verbs, plus ECID addressing and tree-tuning flags). + +**Hard requirement for `ui` / `tap`:** the device must be paired, trusted, unlocked and in Developer Mode, and the foreground target app must be development-signed with `get-task-allow=true`. A Release-configuration binary installed with a Development profile is supported. Distribution/Ad Hoc, TestFlight, App Store and system apps are unsupported; do not retry them or claim success. sim-use itself installs and signs no runner and needs no Developer Disk Image. `screenshot` is exempt from the signing rule — it runs over CoreDevice and captures any screen, system apps included. + +```bash +# Physical-device preflight — physical rows carry kind `physical` +sim-use devices + +# Observe → act → verify, same loop and verbs as the simulator +sim-use ui --device +sim-use tap --label "Friends" --element-type Button --device +sim-use ui --device + +# For dynamic labels +sim-use tap --label-contains "Reply" --element-type Button --device + +# By stable identifier (the #id shown in ui) — positional or --id +sim-use tap '#BackButton' --device + +# Screenshot — any screen, not limited to development-signed apps +sim-use screenshot --output shot.png --device +``` + +Rules for this experimental surface: + +1. **Treat hierarchy errors as capability failures.** If the command says the hierarchy is unavailable, confirm the screen is unlocked and inspect the installed app's final `get-task-allow` entitlement. Do not fall back to coordinates or focus walking. +2. **Tap by `#id` or label, not `@N`.** Element handles expire with the DTX connection, so there is no `@N` alias (nor coordinates — no geometry). Use the `#id` shown in the outline (positional `#` or `--id`) — it is stable and the best choice when a label is dynamic — or `--label` / `--label-contains`, with `--element-type` to disambiguate. The navigation-bar back button appears as a normal `Button "" #BackButton`; go back by tapping `#BackButton` (or the shown label) like any other element — no special "back" verb. +3. **Always verify.** Activate is fire-and-forget. Re-run `sim-use ui` and confirm the expected state before continuing. +4. **Respect the capability rejections.** A `not supported on physical iOS devices` error is a statement about the channel, not a transient failure — follow its hint (usually `ui` + `tap '#' / --label`) instead of retrying or substituting a lookalike form. `--json` works on every verb with the standard `{ok, data}` envelope; physical results carry `"kind":"physical"` and omit geometry fields (`screen`, `x`/`y`). +5. **Budget seconds, not milliseconds.** A full tree takes a few seconds. `sim-use ios-device ui --fast` is quicker but omits nested elements; do not poll in a tight loop. + +If `ui` succeeds with zero elements or `tap` prints success for a missing/ambiguous label, treat it as a sim-use bug; the command is expected to fail loudly instead. + +## 2. Pitfalls + +Quick symptom index — see `references/pitfalls.md` for detailed recipes. + +| Symptom | Cause | Fix | +|---|---|---| +| `tap --label` hits wrong element | Label collision (e.g. header and tab bar share text) | Add `--frame minY=0.7r` or `--element-type` to narrow | +| `tap @N` fails after navigation | Alias cache is stale | Re-run `ui` before tapping | +| `App:` line shows wrong app | System layer (alert, share sheet) is on top | Dismiss it first, then re-run `ui` | +| `multipleMatches` error | Several elements share the selector | Use `--frame`, `--element-type`, or a more specific selector | +| Tap lands but nothing happens | Animation in progress, or element not yet interactive | Add `--pre-delay 0.3` or `--wait-timeout 3` | +| iOS: `paste` fails or text is missing | No focused field, a custom edit menu, a paste prompt, or an external clipboard writer | Focus the field, or use `paste --via-menu --target-id `; inspect prompts and verify the actual field. Do not switch to `type` as a Unicode substitute | +| Android: `paste` denied | Background clipboard access blocked | Use `type` instead | +| Outline shows `U+FFFC` in label | iOS icon placeholder character | Match with `--label-regex` excluding the prefix | +| `[i] … covers ~N% of the screen` warning (text output, or `--json` top-level `advisory` key) | The selector resolved to a near-full-screen wrapper (common on Flutter/canvas UIs) and the tap hit its center, likely missing the intended control | Re-run `ui` and target the control via `@N`/`#`, or pass explicit `-x/-y`/`--point` | +| `[i] Screen orientation could not be confirmed…` / `…coordinates may be stale…` advisory | Device/app is rotated (the `App:` header shows a tag like `(landscape-right)`) and orientation self-calibration couldn't verify the mapping, or the `@N` snapshot predates a rotation | Re-run `ui` and tap again; selectors handle rotation automatically once calibration succeeds. Explicit `-x/-y`/`--point` take outline (visual-space) coordinates and ride the same calibration; `--coordinate-space native` is for device-native portrait points | +| Outline is empty or misses visible app controls, or `[i] … recovered from other processes …` advisory (`--json`: `advisory.kind: remote_content_recovery`) | The app exposed an empty accessibility tree. Normal for a system picker. Otherwise, on an iOS simulator, a likely cause is that app accessibility was off when the app launched | Compare the outline with the screen. If controls are missing, see [Missing app controls](references/pitfalls.md#missing-app-controls-in-the-outline) | +| iOS: `ui` fails with `No translation object returned for simulator for the frontmost application` on every screen, while `screenshot` and `ui --point` still work | The simulator's accessibility bridge (`CoreSimulatorBridge`) is stale | Follow the error's hint: run `xcrun simctl spawn launchctl stop com.apple.CoreSimulator.bridge` (launchd restarts it at once), then retry `ui`. Right after a boot, wait a few seconds and retry first | +| iOS: the `ui` header ends in `inner display`, `cover display` (older builds: `display LCD-1` for inner), or `display Resizable 560x874` | The app is on the named Duo screen or an Xcode 27 Resize Mode display. An active inner screen does not prove a fully open hinge. `--json` keeps raw names; `data.display` is absent on the main/cover screen. Touch, `ui`, `ui --point`, `screenshot` and `record-video` / `stream-video` (`h264`, `bgra`) route automatically | Work as usual — selectors and `@N` land on that display; the vertical bar of an iOS 27.1 SDK app (back button, tabs) is listed last as `[Trailing …]` / `[Leading …]`. Explicit `-x/-y` take the numbers `ui` prints there; `--coordinate-space native` means that display's native points. See [iPhone Duo](references/pitfalls.md#ios-iphone-duo-multi-display-simulator) and [Resize Mode](references/pitfalls.md#ios-resize-mode-resizable-app-session) | + +## 3. Crash awareness + +See `references/crash-awareness.md` for the full protocol. Summary: + +sim-use watches for the target process disappearing between commands. When it detects a crash: + +``` +================ PROCESS DISAPPEARED ================ +com.example.app (pid 12345) was alive at the previous command and is GONE now. +``` + +On Android, `ui` also detects the AOSP system crash dialog directly from the accessibility tree. + +**Mandatory response:** +1. **STOP.** Do not silently relaunch or continue. +2. Report the crash to the user with the banner text. +3. Wait for instructions before proceeding. + +After an intentional relaunch, call `sim-use app-state --reset` to clear the signal. + +## 4. Escalation + +Stop and ask the user when: +- A selector collision cannot be resolved with available disambiguators. +- Preflight fails and autofix does not recover. +- The task requires a destructive action (deleting data, uninstalling an app). +- You've retried the same action 3 times without progress. + +## 5. Exit checklist + +Before reporting a task as complete: +1. Run `sim-use ui` (or `screenshot`) to capture the final state. +2. Confirm the screen matches the intended outcome. +3. If the outcome is ambiguous, show the final `ui` output or screenshot to the user. diff --git a/.agents/skills/sim-use/references/batch-reference.md b/.agents/skills/sim-use/references/batch-reference.md new file mode 100644 index 00000000..b5f63ef8 --- /dev/null +++ b/.agents/skills/sim-use/references/batch-reference.md @@ -0,0 +1,104 @@ +# sim-use Batch Reference + +Use this reference when generating or reviewing `sim-use ios batch` commands. + +## Supported step commands +- `tap` +- `swipe` (`--from x,y --to x,y`, positional `x,y x,y`, or legacy `--start-x/--start-y/--end-x/--end-y`) +- `gesture` +- `touch` +- `type` +- `paste` (default, `--replace`, `--file`, or `--via-menu` with a target; not `--stdin`) +- `button` +- `key` +- `key-sequence` +- `key-combo` +- `sleep ` (batch pseudo-step) + +## Batch flags +- `--device `: required simulator target. +- `--step "..."`: repeatable inline step source. +- `--file `: read one step per line from file. +- `--stdin`: read one step per line from stdin. +- `--continue-on-error`: keep running after a failed step; report failures at end. +- `--ax-cache perBatch|perStep|none`: selector tap AX snapshot reuse policy. `perBatch` (default) resolves every selector against one snapshot fetched at first use; `perStep` refetches at each step; `none` never caches. `--wait-timeout` polling always refetches (and updates the cache). +- `--type-submission chunked|composite`: submission mode for `type` steps. +- `--type-chunk-size `: chunk size when using chunked submission. +- `--wait-timeout `: maximum seconds to poll for selector-based elements before failing (0 = no waiting, default). +- `--poll-interval `: seconds between accessibility tree polls when `--wait-timeout` is active (default 0.25). +- `--verbose`: enable detailed stderr logs for troubleshooting (default quiet output). + +## Input rules +- Use exactly one source: `--step` OR `--file` OR `--stdin`. +- Empty lines are ignored. +- `#` comment lines are ignored in file/stdin input. +- Do not pass `--device` or `--udid` inside step lines; keep the target at batch command level. +- A paste step runs after pending HID is flushed and uses the standalone verified clipboard and native menu path. Focus a field first, or use `--via-menu --target-id ` in the step. Clipboard sharing and native editing rules still apply. +- Use `paste -- 'text starting with -'` for dash-prefixed text. The option terminator does not hide the batch-level target. + +## Failure and retry + +- A transient boot-readiness error does not automatically replay the batch. +- Earlier steps may have completed before a later step failed. This also applies to errors collected by `--continue-on-error`. +- Inspect the current UI and completed steps before an explicit retry. Do not repeat the whole batch without checking its side effects. + +## Example: inline steps +```bash +sim-use ios batch --device SIMULATOR_UDID \ + --step "tap --id EmailField" \ + --step "type 'cam@example.com'" \ + --step "key 43" \ + --step "type 'super-secret'" \ + --step "key 40" +``` + +## Example: stdin steps +```bash +cat <<'EOF' | sim-use ios batch --device SIMULATOR_UDID --stdin +tap --id EmailField +type 'cam@example.com' +key 43 +type 'super-secret' +key 40 +EOF +``` + +## Example: file steps +`login.steps` +```text +# login flow +tap --id EmailField +type 'cam@example.com' +key 43 +type 'super-secret' +key 40 +``` + +Run: +```bash +sim-use ios batch --device SIMULATOR_UDID --file login.steps +``` + +## Example: explicit timing and policy +```bash +sim-use ios batch --device SIMULATOR_UDID \ + --ax-cache perStep \ + --type-submission chunked \ + --type-chunk-size 150 \ + --continue-on-error \ + --step "tap --label Settings" \ + --step "sleep 0.5" \ + --step "tap --id SaveButton" +``` + +## Example: multi-screen flow with element waiting +```bash +sim-use ios batch --device SIMULATOR_UDID \ + --wait-timeout 5 \ + --step "tap --id LoginButton" \ + --step "tap --id WelcomeMessage" +``` + +The second step polls for up to 5 seconds for `WelcomeMessage` to appear after the login tap triggers navigation. + +If label selectors are ambiguous and sim-use reports no `AXUniqueId` values for matches, switch that step to coordinates (`tap --point x,y` or `-x/-y`). diff --git a/.agents/skills/sim-use/references/cheatsheet.md b/.agents/skills/sim-use/references/cheatsheet.md new file mode 100644 index 00000000..bf967472 --- /dev/null +++ b/.agents/skills/sim-use/references/cheatsheet.md @@ -0,0 +1,223 @@ +# sim-use Command Cheatsheet + +## Command namespaces + +| Namespace | Scope | Examples | +|---|---|---| +| `sim-use ` | Cross-platform (iOS + Android) | `ui`, `tap`, `swipe`, `type`, `paste`, `button`, `gesture`, `screenshot`, `record-video`, `stream-video`, `app-state` | +| `sim-use ios ` | iOS Simulator only | `key`, `key-combo`, `key-sequence`, `batch` | +| `sim-use android ` | Android device only | `init`, `devices`, `ping` | + +## Device resolution + +`--device` is optional. Resolution order: `--device` flag → `$SIM_USE_DEVICE` env → only live daemon → only booted simulator. + +When multiple devices exist, pass `--device ` explicitly. Run `sim-use devices` to list all connected devices across platforms. + +## Selectors + +```bash +sim-use tap @5 # alias from last `ui` snapshot +sim-use tap '#3' # 3rd cell of dominant list +sim-use tap '#2@2' # 2nd cell of 2nd list (quote for shell) +sim-use tap '#settingsButton' # AXUniqueId (live AX lookup) +sim-use tap --id Safari # by accessibility identifier +sim-use tap --label "General" # by exact label +sim-use tap --label-contains "Order" # substring match +sim-use tap --label-regex '^Chat.*\d+$' # ICU regex +sim-use tap -x 100 -y 200 # outline coordinates (last resort; any orientation) +sim-use tap --point 100,200 # same, pair form +sim-use tap -x 100 -y 200 --coordinate-space native # device-native portrait points +``` + +## Disambiguating with --frame + +Narrow matches by screen region when selectors collide: + +```bash +sim-use tap --label 'Tab' --frame minY=0.7r # bottom 30% of screen +sim-use tap --label 'Tab' --frame maxY=0.2r # top 20% of screen +sim-use tap --label 'OK' --frame 'minX=200,maxX=400,minY=600,maxY=700' +``` + +- Values: absolute pixels (`700`) or fraction with `r` suffix (`0.7r`). +- Keys: `minX`, `maxX`, `minY`, `maxY`. Each appears at most once. +- Composes with all selectors and `--element-type`. + +## Text input + +```bash +sim-use type 'Hello World!' # HID keyboard (ASCII) +echo "complex text" | sim-use type --stdin # stdin for special chars +sim-use paste 'こんにちは 🎉' # focused caret/selection; either iOS host +sim-use paste 'text' --replace # Select All then native Paste +sim-use paste 'text' --via-menu --target-id # explicit iOS target +sim-use paste --file body.txt # UTF-8, including multiline text +``` + +- iOS: both modes work with software or hardware keyboards. Default paste preserves the focused field's caret and selection; explicit targeting can move them. Native editing rules apply. Verify the field and avoid concurrent shared-clipboard writers. +- Android: `paste` uses native `ACTION_PASTE`; `type` works for all unicode. + +## Gestures and timing + +```bash +sim-use gesture scroll-up # scroll-up = content moves up = page down +sim-use gesture scroll-down # page up +sim-use swipe --from 50,500 --to 350,500 +sim-use long-press @5 # default 0.8s hold +sim-use long-press --label "Photos" # selector targeting +sim-use long-press @5 --duration 1.2 # custom hold time +sim-use tap @5 --duration 0.05 # brief hold for toggles/switches +sim-use tap @5 --pre-delay 0.3 # wait before tapping +``` + +`long-press` is sugar over `tap --duration 0.8`. Same targeting surface as `tap`. Use for action menus, launcher popups, drag-handle activation. + +Note: some Android apps render long-press menus in a `PopupWindow` overlay that the bridge's `describe-ui` cannot walk — verify with a screenshot when this matters. + +**Naming gotcha:** `scroll-up` scrolls the *content* up (like swiping up), which shows content *below* — it's "page down" in reading order. + +## Pinch and rotate (two-finger gestures) + +```bash +sim-use gesture pinch-out # zoom in (default scale 2.0) +sim-use gesture pinch-in # zoom out (default scale 0.5) +sim-use gesture pinch-out --scale 3.0 --radius 60 # wider zoom, smaller start circle +sim-use gesture rotate-cw # clockwise 90° (default) +sim-use gesture rotate-ccw --angle 45 # counter-clockwise 45° +sim-use gesture pinch-out --center-x 200 --center-y 400 # off-center pivot +``` + +| Parameter | Default | Description | +|---|---|---| +| `--scale` | 2.0 (out) / 0.5 (in) | End radius / start radius ratio | +| `--angle` | 90 | Rotation sweep in degrees | +| `--center-x/y` | screen center | Pivot point (pixels) | +| `--radius` | 80 | Start radius (pixels) | +| `--steps` | 10 | Interpolated HID Move events (iOS only) | +| `--step-ms` | derived from duration/steps | Sleep between Move events (iOS only) | + +## Multi-touch (low-level) + +For gestures the presets don't cover, use `multi-touch` directly with two contact points: + +```bash +# Pinch-zoom in by moving two fingers apart vertically +sim-use multi-touch \ + --x1 195 --y1 472 --x1-end 195 --y1-end 322 \ + --x2 195 --y2 472 --x2-end 195 --y2-end 622 \ + --steps 10 --step-ms 30 +``` + +Also available: `tap --fingers 2` and `long-press --fingers 2` for two-finger tap/hold. + +## Touch (low-level, single finger) + +```bash +sim-use touch -x 150 -y 250 --down # touch down only +sim-use touch -x 150 -y 250 --up # touch up only +sim-use touch -x 150 -y 250 --down --up # tap +sim-use touch -x 150 -y 250 --down --up --delay 1.0 # long press +``` + +## Screenshots and video + +```bash +sim-use screenshot --output shot.png +sim-use record-video --output recording.mp4 # H.264, 30 fps default; Ctrl+C to stop +sim-use record-video --output smooth.mp4 --fps 60 # iOS: constant rate up to 60 fps (Android ignores --fps, native rate) +sim-use record-video --output demo.gif # animated GIF (inferred from extension, or --format gif); 10 fps + 0.5 scale defaults; add --gif-markers for START/END boundary cards; transcoded after Ctrl+C +sim-use stream-video --format h264 | ffplay -f mpegts -probesize 32768 -i - # live H.264 preview in MPEG-TS (both platforms); iOS constant --fps (default 30), Android native VFR (a still screen sends no new frames) +sim-use stream-video --fps 10 --format mjpeg > out.mjpeg # screenshot-loop JPEG stream; DEPRECATED on iOS (use h264), kept on Android for devices without screenrecord +``` + +### Stopping a backgrounded recording + +Send `SIGTERM` and `wait` — do **not** `SIGKILL`, which skips the MP4 trailer and produces an unplayable file. + +```bash +sim-use record-video --output recording.mp4 & +PID=$! +# ... drive the simulator ... +kill -TERM "$PID" +wait "$PID" # blocks ~50–150 ms while the trailer is written +``` + +## Batch (iOS only) + +```bash +sim-use ios batch --device \ + --step "tap --id SearchField" \ + --step "type 'query'" \ + --step "key 40" \ + --wait-timeout 5 +``` + +- One step source per run: `--step`, `--file`, or `--stdin`. +- `--wait-timeout` makes selector taps poll for the element. +- `--ax-cache perStep` refreshes the AX snapshot between steps. +- Do not put `--device` inside step lines. +- See `references/batch-reference.md` for full semantics, flags, and examples. + +## Daemon + +```bash +sim-use daemon status +sim-use daemon stop --device +sim-use daemon stop --all +SIM_USE_NO_DAEMON=1 sim-use ui # bypass daemon for one call +``` + +Daemon is iOS-only (auto-spawned, 600s idle TTL). Android commands go through adb directly. + +## iOS keyboard (HID keycodes) + +```bash +sim-use ios key 40 # Enter +sim-use ios key 42 --duration 1.0 # Hold Backspace +sim-use ios key-sequence --keycodes 11,8,15,15,18 # "hello" +sim-use ios key-combo --modifiers 227 --key 4 # Cmd+A +sim-use ios key-combo --modifiers 227 --key 6 # Cmd+C +sim-use ios key-combo --modifiers 227 --key 25 # Cmd+V +sim-use ios key-combo --modifiers 227,225 --key 4 # Cmd+Shift+A +``` + +### Common keycodes + +| Key | Code | Key | Code | Key | Code | +|---|---|---|---|---|---| +| Enter | 40 | Escape | 41 | Backspace | 42 | +| Tab | 43 | Space | 44 | a | 4 | +| LeftGUI (Cmd) | 227 | LeftShift | 225 | LeftCtrl | 224 | +| LeftAlt | 226 | F1 | 58 | F12 | 69 | + +## Timing parameters + +| Parameter | Range | Description | Available on | +|---|---|---|---| +| `--pre-delay` | 0–10s | Delay before action | tap, swipe, gesture | +| `--post-delay` | 0–10s | Delay after action | tap, swipe, gesture | +| `--duration` | 0–10s | Action duration | swipe, gesture, button, key, tap (opt-in for toggles) | +| `--delay` | 0–5s | Between-item delay | key-sequence, touch | + +## UDID auto-resolution + +`--device` is optional. Resolution order: + +1. Explicit `--device ` flag +2. `$SIM_USE_DEVICE` environment variable +3. The only live sim-use daemon under `/tmp/sim-use-/` (<1 ms) +4. The only simulator with `state == "Booted"` via `xcrun simctl list` (~150 ms) + +Edge cases: +- **Stale daemon**: if you shut down a simulator outside sim-use but its daemon is still alive, the next command fails loudly — run `sim-use daemon stop --all` then retry. +- **Multiple daemons + multiple booted**: falls through to step 4 and errors with a disambiguation message listing all booted devices. +- For CI fan-out (many simulators in parallel), keep `--device` explicit. + +## --json envelope + +Every command supports `--json`. Shape: `{ "ok": true/false, "data": {...}, "error": "...", "hint": "..." }`. + +The `hint` field on errors contains actionable guidance (e.g. each match as `'label' [Type] #id` on `multipleMatches`). Use it for self-correcting retries. + +For `ui --json`, prefer `data.outline` / `data.entries` / `data.lists`. The `data.raw` field is the full AX tree (~3x larger); pass `--no-raw` to omit it in agent loops (on older binaries without the flag, use `jq 'del(.data.raw)'`). diff --git a/.agents/skills/sim-use/references/crash-awareness.md b/.agents/skills/sim-use/references/crash-awareness.md new file mode 100644 index 00000000..4d5a60e7 --- /dev/null +++ b/.agents/skills/sim-use/references/crash-awareness.md @@ -0,0 +1,59 @@ +# Crash Awareness Protocol + +sim-use automatically tracks the target app's process liveness while the daemon is running. When the tracked process disappears between commands, sim-use surfaces a banner on the next `ui` call. + +## Signals + +### Process liveness (iOS + Android) + +``` +================ PROCESS DISAPPEARED ================ +com.example.app (pid 12345) was alive at the previous command and is GONE now. +Likely crash or termination, not a backgrounding. Verify before trusting subsequent actions. +===================================================== +App: SpringBoard 402x874 +``` + +The signal is process liveness — a PID that was alive and is now gone. Backgrounding (permission dialogs, share sheets, app switcher) does **not** trip it. + +### Crash dialog (Android only) + +``` +=============== CRASH DIALOG DETECTED =============== +An Android system app-crash dialog is on screen ("MyApp keeps stopping"). +===================================================== +``` + +Detected directly from the accessibility tree via the AOSP framework resource IDs (`android:id/aerr_close` / `aerr_app_info`). Works without the daemon, locale-independent, and fires while the dialog is visible — even before the process fully exits. + +Either signal alone is a sufficient crash hint. + +## Mandatory response + +1. **STOP** all automation. Do not silently relaunch or continue tapping. +2. **Report** the crash to the user, including the banner text and context (what action preceded the crash). +3. **Wait** for user instructions before proceeding. + +Never assume you can recover from a crash by relaunching the app — the user may need to inspect crash logs, capture state, or change strategy. + +## Confidence and idle gaps + +Deaths observed after a long idle gap (default 120s, tunable with `SIM_USE_CRASH_WINDOW`) are downgraded to a quiet `[i]` line and the baseline is reset. This prevents false alarms from out-of-band kills while the agent was idle. + +## Resetting the baseline + +After intentionally relaunching the app or accepting a known crash: + +```bash +sim-use app-state --reset --device +``` + +This clears pending signals so subsequent commands don't re-surface a stale death. + +## Disabling detection + +```bash +SIM_USE_NO_CRASH_DETECT=1 sim-use ui --device +``` + +Detection is on by default in daemon mode. diff --git a/.agents/skills/sim-use/references/pitfalls.md b/.agents/skills/sim-use/references/pitfalls.md new file mode 100644 index 00000000..613e99d3 --- /dev/null +++ b/.agents/skills/sim-use/references/pitfalls.md @@ -0,0 +1,141 @@ +# Pitfalls and Recipes + +Detailed solutions for common sim-use issues. The symptom index in SKILL.md points here. + +## Label collision + +**Symptom:** `tap --label 'X'` hits the wrong element, or returns `multipleMatches`. + +**Why:** Multiple elements share the same accessibility label (e.g. a segmented control at the top and a tab bar at the bottom both say "Chat"). + +**Recipes:** +1. Add `--element-type RadioButton` (or whatever the outline shows) to narrow by type. +2. Add `--frame minY=0.7r` to restrict to a screen region. Use `r`-suffixed fractions for device-independent targeting. +3. Combine both: `--label 'Chat' --element-type RadioButton --frame minY=0.7r`. +4. If the element has a `#` in the outline, use `tap '#'` instead — it bypasses label matching entirely. + +## Alias staleness + +**Symptom:** `tap @N` fails or taps the wrong element after navigating to a new screen. + +**Why:** `@N` aliases are cached from the last `ui` snapshot. Any screen change invalidates them. + +**Rule:** Always re-run `sim-use ui` after any action that changes the screen (navigation, dismissing a dialog, scrolling). Then use the fresh `@N` values. + +## iOS: rotated simulator + +**Symptom:** The `App:` header shows an orientation tag like `(landscape-right)` or `(portrait-upside-down)`, or a tap emits an `[i] Screen orientation could not be confirmed…` advisory. + +**Why:** iOS accessibility frames rotate with the app while HID taps target the fixed portrait framebuffer. sim-use bridges the two automatically: every AX-derived tap (`@N`, `#`, `--label` family, batch steps) self-calibrates the current orientation with 1–3 hit-test probes and transforms coordinates before dispatch. + +**Recipes:** +1. Normally nothing to do — selectors work in any orientation, and outline/tap coordinates always read in UI space (what you see). +2. The calibration-fallback advisory means the mapping could not be verified (empty or symmetric screen) and portrait was assumed; re-run `ui` and retry, or pass `-x/-y` with `--coordinate-space native` (device-native portrait points). +3. A "snapshot was captured at WxH…" advisory means the device rotated after the last `ui`; re-run `ui` to refresh the `@N` table. +4. Explicit `-x/-y`/`--point`, `swipe`/`touch`/`multi-touch` coordinates and the pinch/rotate centre take outline (UI-space) numbers and go through the same calibration. `--coordinate-space native` turns it off: the numbers are then device-native portrait points. +5. `batch` calibrates once per run. If a step rotates the device (or navigates to a screen that forces a different orientation), later selector steps may mis-target — split the flow into separate batches around the rotation. + +## iOS: Resize Mode (resizable app session) + +**Symptom:** The `ui` header ends in `display Resizable 560x874` (`--json`: a `data.display` object with `kind: virtual` and `resizableSession`), its size is not a real device size, and `screenshot` prints `[i] Captured the 'Resizable' display …`. + +**Why:** Xcode 27 can move the frontmost app of an iOS 27+ simulator onto a virtual display named `Resizable` and give it any size (Device Hub's resize button, or `xcrun devicectl device appResize start`). sim-use detects the session and routes touch input, hit-tests, screenshots and video to that display. Issue: https://github.com/lycorp-jp/sim-use/issues/143. + +**Recipes:** +1. Work as usual: `ui`, selectors, `@N`, `tap`, `swipe`, `gesture`, `type` and `screenshot` all act on the resized app. The `App:` header is the only place the scene's *actual* size shows — `appResize set` reports the size it asked for, which the scene may snap away from. +2. Explicit `-x/-y` are scene points (the scene is never rotated). +3. `record-video` and `stream-video --format h264|bgra` capture the scene (its size at the display scale, cut from the canvas). The screenshot-based `stream-video` formats (`mjpeg`, `raw`, `ffmpeg`) read the main display only and refuse. +4. The check costs one `devicectl` query per device per 5 s. A `ui` or selector tap whose root changed size re-reads it at once, so a session that just started or ended is noticed by the next `ui`. A raw `-x/-y` tap with no `ui` in between can see the previous answer for up to 5 s. `SIM_USE_RESIZE_SESSION_CHECK=0` disables the check; the per-device daemon reads it at spawn time. + +## iOS: iPhone Duo (multi-display simulator) + +**Symptom:** The `ui` header names `inner display` (for example `App: Settings 951x669 (landscape-left, inner display)`) or `cover display`. Older builds use `display LCD-1` for the inner screen. `--json` keeps raw names and ids; `data.display` is absent on the main/cover screen. + +**Why:** The iPhone Duo simulator (Xcode 27.1) has two integrated displays: the primary cover and the inner panel. sim-use uses inner/cover aliases only for a verified Duo device type and valid two-panel topology; unknown layouts keep system names. The active screen is not a hinge measurement: a half-open device can use the inner screen too. sim-use routes touch input, hit-tests, screenshots and video to the display that hosts the app and takes its orientation from CoreDevice. + +**Recipes:** +1. Check the posture: `sim-use ios fold --device ` names the active display and its orientation. +2. Fold and unfold with `sim-use ios fold closed|open --device `; rotate with `sim-use ios rotate ` (interface names, as the `ui` header prints them). Both clear the `ui` snapshot — re-run `ui` before `tap @N`. +3. An iOS 27.1 SDK app puts its back button, trailing toolbar items, tab bar and status bar in a **vertical bar** on the cover display (and on the inner display in landscape). The outline lists it last, as `[Trailing x>=N]` — `[Leading x<=N]` when the cover is in landscape-right; its `@N` aliases tap as usual. The back button there has **no label**: tap it with `#BackButton`, not by the previous screen's title. +4. Explicit `-x/-y` take the numbers `ui` prints on either display; `--coordinate-space native` means the inner panel's unrotated points. +5. `record-video` and `stream-video --format h264|bgra` capture the inner display in its native portrait orientation (2008x2854), like the main display. A fold during a recording keeps the display the recording started on and prints `[i] The app moved to … while \`record-video\` ran` at the end — start a new recording after a fold. + +## System layer detection + +**Symptom:** `ui` output shows unexpected content — the `App:` header names a system process like `SpringBoard` (iOS) or `com.android.systemui` (Android). + +**Why:** A system alert, permission dialog, or share sheet is covering the app. The accessibility tree reflects whatever is on top. + +**Recipe:** +1. Read the outline to identify the overlay (e.g. "Allow Paste", location permission, share sheet). +2. Dismiss it: tap the appropriate button (`Allow`, `Don't Allow`, `Cancel`), or `sim-use button home` to go home. +3. Re-run `ui` to confirm you're back in the app. + +## Missing app controls in the outline + +**Symptom:** Preflight passes with a content warning. Or `ui` succeeds, but the outline has no elements, or it shows the `[i] … recovered from other processes …` advisory (`--json`: `advisory.kind: remote_content_recovery`). + +**Why:** The app exposed an empty accessibility tree. On iOS, sim-use then recovers content from other processes. This can be normal for a system picker; the advisory alone does not mean the app is broken. If nothing can be recovered, the outline stays empty. + +**Recipe:** +1. Compare the outline with the visible screen. If it contains the expected controls (for example, the picker's), continue normally. +2. If visible app controls are missing on an iOS simulator, check whether app accessibility was enabled before the app launched. The current preference value alone does not establish the state at launch. See [idb's accessibility guidance](https://github.com/facebook/idb/blob/main/website/docs/idb/accessibility.mdx). +3. If needed, enable app accessibility for that simulator, then relaunch the target app and re-read `ui`: + + ```bash + xcrun simctl spawn defaults write com.apple.Accessibility ApplicationAccessibilityEnabled -bool true + ``` + +4. If controls are still missing, inspect the app with Accessibility Inspector or VoiceOver to check what it exposes. + +This setting applies to iOS simulators. Preflight only prints guidance; it does not apply the setting, relaunch the app, or restart the daemon for a content warning. + +## iOS: paste drops text + +**Symptom:** Paste errors, or a custom control does not show the expected text. + +**Why:** The current implementation verifies clipboard staging and invokes native menu Paste, without requiring a connected hardware keyboard. A field must be focused and expose the edit menu; app-specific editing rules, paste prompts and concurrent clipboard writes still apply. + +**Recipes:** +1. Focus the field with `tap '#'`, then `paste 'text'`. Use `--replace` to overwrite all content. +2. For explicit targeting, use `paste 'text' --via-menu --target-id ` or `--target-x/--target-y`. A missing menu is an error, not a reported success. +3. Inspect the UI for paste permission prompts; approve only with user authorization. Check the resulting field, not just the command exit status. +4. A readback mismatch means the clipboard changed or staging failed. Stop other clipboard writers, including on another shared device, before retrying. Do not log unexpected clipboard contents or restore an old backup over newer external content. +5. For controls that do not support native Paste, report the capability limit. Do not substitute US-keyboard `type` for arbitrary Unicode, change keyboard/sync settings, or fall back to overwriting the host clipboard. + +Simulator.app and Device Hub use different clipboard stacks. sim-use permits verified legacy staging only while the guest's CoreDevice ownership signal is inactive; otherwise it uses verified CoreDevice. Do not revive the old raw `simctl pbcopy` + Cmd+V workaround. + +## iOS: U+FFFC icon placeholder + +**Symptom:** An element's label in the outline contains a replacement character (often invisible or rendered as ``) before the actual text. + +**Why:** iOS uses U+FFFC as an object-replacement character for inline icons. The accessibility label includes it. + +**Recipe:** Use `--label-regex` with a pattern that skips the prefix: `--label-regex '.*Settings$'` or `--label-contains 'Settings'`. + +## Android: paste denied + +**Symptom:** `sim-use paste` succeeds but the field is empty, or the command errors. + +**Why:** Android 10+ blocks background processes from setting the clipboard on some devices/configurations. + +**Recipe:** Use `sim-use type 'text'` instead. On Android, `type` handles full unicode including CJK and emoji. + +## Android: button back unpredictability + +**Symptom:** `sim-use button back` navigates somewhere unexpected. + +**Why:** Android's back behavior is app-defined. It might close a dialog, pop a nav stack, minimize the app, or do nothing. + +**Recipe:** Always `ui` after `button back` to confirm where you ended up. If the result is wrong, use `tap` on a visible "Close" or "Cancel" button instead. + +## Tap lands but nothing happens + +**Symptom:** `tap` reports success but the UI doesn't change. + +**Why:** The element wasn't interactive yet (animation in progress, view still loading), or it's a toggle that needs a brief hold. + +**Recipes:** +1. For animation: add `--pre-delay 0.3` to wait before tapping, or `sleep 0.4` between commands. +2. For toggles/switches (shown as `CheckBox` in the outline): add `--duration 0.05`. +3. For elements that appear after navigation: use `--wait-timeout 3` to poll until the element exists. diff --git a/.agents/skills/sim-use/scripts/__pycache__/preflight.cpython-314.pyc b/.agents/skills/sim-use/scripts/__pycache__/preflight.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f0d74c1205688a089b81cb2c4189d9fc28a4beb0 GIT binary patch literal 16279 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 + python3 preflight.py # auto-resolve single device +""" + +import argparse +import json +import re +import shutil +import subprocess +import sys +from dataclasses import dataclass, field +from typing import Callable, Optional + + +MINIMUM_SIM_USE_VERSION = (0, 16, 0) + + +# --------------------------------------------------------------------------- +# Check framework +# --------------------------------------------------------------------------- + +@dataclass +class Check: + id: str + description: str + run: Callable[["Ctx"], bool] + on_fail: str = "abort" # abort | auto | prompt + autofix: Optional[Callable[["Ctx"], bool]] = None + fix_hint: str = "" + + +@dataclass +class Ctx: + device: Optional[str] = None + sim_use_bin: str = "sim-use" + platform: Optional[str] = None # "ios" or "android", detected + content_warning: Optional[str] = None # "remote_content_recovery" or "empty_outline" + ui_is_ios_simulator: bool = False + errors: list = field(default_factory=list) + + def run_sim_use(self, *args: str, check: bool = False) -> subprocess.CompletedProcess: + cmd = [self.sim_use_bin] + list(args) + if self.device: + cmd.extend(["--device", self.device]) + return subprocess.run(cmd, capture_output=True, text=True, check=check) + + def run_sim_use_json(self, *args: str) -> Optional[dict]: + result = self.run_sim_use(*args, "--json") + if result.returncode != 0: + return None + try: + return json.loads(result.stdout) + except json.JSONDecodeError: + return None + + +def run_checks(checks: list[Check], ctx: Ctx) -> bool: + all_passed = True + for c in checks: + passed = c.run(ctx) + if passed: + print(f" PASS {c.description}") + continue + + if c.on_fail == "auto" and c.autofix: + print(f" FIX {c.description} -- attempting autofix...") + if c.autofix(ctx) and c.run(ctx): + print(f" PASS {c.description} (after autofix)") + continue + + print(f" FAIL {c.description}") + if c.fix_hint: + print(f" hint: {c.fix_hint}") + ctx.errors.append(c.id) + all_passed = False + + if c.on_fail == "abort": + print("\n Aborting -- later checks depend on this one.") + break + + return all_passed + + +# --------------------------------------------------------------------------- +# Checks +# --------------------------------------------------------------------------- + +def check_sim_use_installed(ctx: Ctx) -> bool: + return shutil.which(ctx.sim_use_bin) is not None + + +def parse_version(value: str) -> Optional[tuple[int, ...]]: + match = re.fullmatch(r"v?(\d+)\.(\d+)\.(\d+)", value.strip()) + return tuple(int(part) for part in match.groups()) if match else None + + +def check_sim_use_compatible(ctx: Ctx) -> bool: + result = subprocess.run( + [ctx.sim_use_bin, "--version"], + capture_output=True, text=True, + ) + if result.returncode != 0: + return False + version = parse_version(result.stdout or result.stderr) + # Dev and dirty stamps are unparseable by design. Only release builds are + # gated, matching the Swift-side ReleaseVersion / BridgeClient behavior. + return version is None or version >= MINIMUM_SIM_USE_VERSION + + +def check_device_listed(ctx: Ctx) -> bool: + result = subprocess.run( + [ctx.sim_use_bin, "devices", "--json"], + capture_output=True, text=True, + ) + if result.returncode != 0: + return False + try: + data = json.loads(result.stdout) + devices = data.get("data", {}).get("devices", []) + except (json.JSONDecodeError, AttributeError): + return False + + if not ctx.device: + booted = [d for d in devices if d.get("state", "").lower() in ("booted", "device")] + if len(booted) == 1: + ctx.device = booted[0].get("deviceId") or booted[0].get("udid") + ctx.platform = booted[0].get("platform") + return True + if len(booted) > 1: + names = [f"{d.get('name')} ({d.get('deviceId') or d.get('udid')})" for d in booted] + print(f" Multiple devices found: {', '.join(names)}") + print(" Re-run with --device to pick one.") + return False + + for d in devices: + # `deviceId` is the canonical key; `udid` covers older sim-use + # binaries that predate the rename. + did = d.get("deviceId") or d.get("udid", "") + if did == ctx.device: + ctx.platform = d.get("platform") + return True + return False + + +def autofix_boot_simulator(ctx: Ctx) -> bool: + if not ctx.device: + return False + result = subprocess.run( + ["xcrun", "simctl", "boot", ctx.device], + capture_output=True, text=True, + ) + if result.returncode == 0: + import time + time.sleep(2) + return result.returncode == 0 + + +def check_ui_responds(ctx: Ctx) -> bool: + ctx.content_warning = None + envelope = ctx.run_sim_use_json("ui") + if envelope is None or envelope.get("ok") is not True: + return False + data = envelope.get("data") + if not isinstance(data, dict): + data = {} + is_ios = data.get("platform") == "ios" + is_physical_ios = is_ios and data.get("kind") == "physical" + ctx.ui_is_ios_simulator = is_ios and not is_physical_ios + advisory = envelope.get("advisory") + if isinstance(advisory, dict) and advisory.get("kind") == "remote_content_recovery": + ctx.content_warning = "remote_content_recovery" + # Physical iOS reads always carry an empty `entries` list; the outline + # text is their payload, so they are the only reads not checked. + elif not is_physical_ios and data.get("entries") == []: + ctx.content_warning = "empty_outline" + return True + + +def print_content_warning(ctx: Ctx) -> None: + if ctx.content_warning == "remote_content_recovery": + print(" WARN UI content: remote_content_recovery") + print(" The app tree was empty; content was recovered from other processes.") + print(" This can be normal for a system picker.") + else: + print(" WARN UI content: empty outline") + print(" The read succeeded, but the outline contains no elements.") + print(" Compare the outline with the visible screen.") + if ctx.ui_is_ios_simulator: + print(" If visible app controls are missing, check ApplicationAccessibilityEnabled") + print(" in com.apple.Accessibility before an app relaunch.") + print(" See 'Missing app controls in the outline' in references/pitfalls.md.") + + +def autofix_daemon_restart(ctx: Ctx) -> bool: + # `daemon stop --all` is mutually exclusive with `--device`, so bypass + # run_sim_use (which appends --device when a device is set and would make + # the command fail with "Specify either --device or --all"). + subprocess.run( + [ctx.sim_use_bin, "daemon", "stop", "--all"], + capture_output=True, text=True, + ) + return True + + +def shared_checks() -> list[Check]: + return [ + Check( + id="sim_use_installed", + description="sim-use is on PATH", + run=check_sim_use_installed, + on_fail="abort", + fix_hint="Install sim-use: brew tap lycorp-jp/tap && brew install lycorp-jp/tap/sim-use (run 'brew trust lycorp-jp/tap' first if you see an untrusted-tap error)", + ), + Check( + id="sim_use_compatible", + description="sim-use version is compatible with this skill", + run=check_sim_use_compatible, + on_fail="abort", + fix_hint=( + f"Upgrade sim-use to >= {'.'.join(map(str, MINIMUM_SIM_USE_VERSION))}: " + "brew update && brew upgrade lycorp-jp/tap/sim-use" + ), + ), + Check( + id="device_listed", + description="target device is listed and reachable", + run=check_device_listed, + on_fail="abort", + fix_hint="Boot a simulator, connect and unlock a physical iPhone/iPad, or connect an Android device, then retry.", + ), + Check( + id="ui_responds", + description="sim-use ui returns a valid response", + run=check_ui_responds, + on_fail="auto", + autofix=autofix_daemon_restart, + fix_hint="Try: sim-use daemon stop --all, then retry.", + ), + ] + + +# --------------------------------------------------------------------------- +# Main +# --------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description="sim-use preflight check") + parser.add_argument("--device", help="Device UDID or serial (auto-detected if omitted)") + parser.add_argument("--sim-use-bin", default="sim-use", help="Path to sim-use binary") + args = parser.parse_args() + + ctx = Ctx(device=args.device, sim_use_bin=args.sim_use_bin) + + print("sim-use preflight\n") + passed = run_checks(shared_checks(), ctx) + if passed and ctx.content_warning: + print_content_warning(ctx) + print() + + if passed: + device_label = ctx.device or "(auto-resolved)" + platform_label = ctx.platform or "unknown" + summary = "Preflight passed with a content warning" if ctx.content_warning else "All checks passed" + print(f"{summary}. Device: {device_label} ({platform_label})") + sys.exit(0) + else: + print(f"Preflight failed: {', '.join(ctx.errors)}") + sys.exit(1) + + +if __name__ == "__main__": + main() From 954fe0eb2dbf7cca4f519caf8292d2098c58579a Mon Sep 17 00:00:00 2001 From: Shinhong Park Date: Fri, 30 Oct 2026 19:21:11 +0900 Subject: [PATCH 4/5] chore: stop tracking Python bytecode --- .../__pycache__/preflight.cpython-314.pyc | Bin 16279 -> 0 bytes .gitignore | 3 +++ 2 files changed, 3 insertions(+) delete mode 100644 .agents/skills/sim-use/scripts/__pycache__/preflight.cpython-314.pyc diff --git a/.agents/skills/sim-use/scripts/__pycache__/preflight.cpython-314.pyc b/.agents/skills/sim-use/scripts/__pycache__/preflight.cpython-314.pyc deleted file mode 100644 index f0d74c1205688a089b81cb2c4189d9fc28a4beb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16279 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 Date: Thu, 29 Oct 2026 23:57:05 +0900 Subject: [PATCH 5/5] chore: update swiftui-expert-skill to latest --- .agents/skills/swiftui-expert-skill/SKILL.md | 71 ++-- .../swiftui-expert-skill/agents/openai.yaml | 6 + .../assets/logo-small.png | Bin 0 -> 29649 bytes .../swiftui-expert-skill/assets/logo.png | Bin 0 -> 398841 bytes .../swiftui-expert-skill/assets/logo.svg | 23 ++ .../references/animation-advanced.md | 28 +- .../references/animation-transitions.md | 8 +- .../references/document-apps.md | 209 ++++++++++++ .../references/environment-patterns.md | 162 +++++++++ .../references/focus-patterns.md | 2 +- .../references/image-optimization.md | 76 ++++- .../references/iphone-duo.md | 78 +++++ .../references/latest-apis.md | 199 ++++++++--- .../references/layout-best-practices.md | 166 ++++++++++ .../references/liquid-glass.md | 55 ++- .../references/list-patterns.md | 123 ++++++- .../references/localization.md | 194 +++++++++++ .../references/macos-scenes.md | 4 +- .../references/macos-views.md | 5 +- .../references/modifier-patterns.md | 64 ++++ .../references/performance-patterns.md | 2 +- .../references/previews.md | 313 ++++++++++++++++++ .../references/scroll-patterns.md | 167 +++++++--- .../references/sheet-navigation-patterns.md | 67 +++- .../references/soft-deprecation.md | 39 +++ .../references/state-management.md | 232 +++++++++---- .../references/styled-text-editing.md | 198 +++++++++++ .../references/text-patterns.md | 4 + .../references/toolbar-patterns.md | 215 ++++++++++++ .../references/trace-recording.md | 23 ++ .../references/view-structure.md | 206 ++++++------ .../references/webkit-integration.md | 242 ++++++++++++++ .../scripts/record_trace.py | 38 ++- skills-lock.json | 4 +- 34 files changed, 2863 insertions(+), 360 deletions(-) create mode 100644 .agents/skills/swiftui-expert-skill/agents/openai.yaml create mode 100644 .agents/skills/swiftui-expert-skill/assets/logo-small.png create mode 100644 .agents/skills/swiftui-expert-skill/assets/logo.png create mode 100644 .agents/skills/swiftui-expert-skill/assets/logo.svg create mode 100644 .agents/skills/swiftui-expert-skill/references/document-apps.md create mode 100644 .agents/skills/swiftui-expert-skill/references/environment-patterns.md create mode 100644 .agents/skills/swiftui-expert-skill/references/iphone-duo.md create mode 100644 .agents/skills/swiftui-expert-skill/references/localization.md create mode 100644 .agents/skills/swiftui-expert-skill/references/modifier-patterns.md create mode 100644 .agents/skills/swiftui-expert-skill/references/previews.md create mode 100644 .agents/skills/swiftui-expert-skill/references/soft-deprecation.md create mode 100644 .agents/skills/swiftui-expert-skill/references/styled-text-editing.md create mode 100644 .agents/skills/swiftui-expert-skill/references/toolbar-patterns.md create mode 100644 .agents/skills/swiftui-expert-skill/references/webkit-integration.md diff --git a/.agents/skills/swiftui-expert-skill/SKILL.md b/.agents/skills/swiftui-expert-skill/SKILL.md index 5f6712a4..534cf9ad 100644 --- a/.agents/skills/swiftui-expert-skill/SKILL.md +++ b/.agents/skills/swiftui-expert-skill/SKILL.md @@ -1,13 +1,15 @@ --- name: swiftui-expert-skill -description: Write, review, or improve SwiftUI code following best practices for state management, view composition, performance, macOS-specific APIs, and iOS 26+ Liquid Glass adoption. Use when building new SwiftUI features, refactoring existing views, reviewing code quality, or adopting modern SwiftUI patterns. Also triggers whenever an Xcode Instruments `.trace` file is referenced (to analyse it) or the user asks to **record** a new trace — attach to a running app, launch one fresh, or capture a manually-stopped session with the bundled `record_trace.py`. A target SwiftUI source file is optional; if provided it grounds recommendations in specific lines, but a trace alone is enough to diagnose hangs, hitches, CPU hotspots, and high-severity SwiftUI updates. +description: Use when writing, reviewing, or refactoring SwiftUI code for iOS or macOS, including state and `@Observable` data flow, view composition, resizable layouts, safe areas, display scale, performance, lists, environment, localization, animation, Liquid Glass, and API migration. Also use for iPhone Duo, foldable, or large-display layouts (`NavigationSplitView` on large displays, iPhone tab sidebar, two-column reflow, foldable grids, `ArrangementView`, `ReservedRegion`), hinge effects, vertical bars, `@State` initialization or synthesized-property diagnostics, `@ContentBuilder` ambiguity, `reorderable` drag/drop, custom `AsyncImage` `URLSession`, swipe actions outside List, item-bound `alert`/`confirmationDialog`, `ToolbarOverflowMenu`, `AnimatableValues`, Document APIs (`Document`/`DocumentReader`), and Instruments `.trace` capture or analysis. --- # SwiftUI Expert Skill ## Operating Rules -- Consult `references/latest-apis.md` at the start of every task to avoid deprecated APIs +- Treat each `View` type as an invalidation boundary: give it only the data it reads and keep frequently changing dependencies close to the smallest affected subtree +- Search `references/latest-apis.md` when writing, reviewing, or migrating API usage; look up only the APIs relevant to the task +- Replace hard-deprecated APIs with modern equivalents. During feature work, flag soft-deprecated APIs and leave them in place (see `references/soft-deprecation.md`) - Prefer native SwiftUI APIs over UIKit/AppKit bridging unless bridging is necessary - Focus on correctness and performance; do not enforce specific architectures (MVVM, VIPER, etc.) - Encourage separating business logic from views for testability without mandating how @@ -15,18 +17,20 @@ description: Write, review, or improve SwiftUI code following best practices for - Only adopt Liquid Glass when explicitly requested by the user (see `references/liquid-glass.md`) - Present performance optimizations as suggestions, not requirements - Use `#available` gating with sensible fallbacks for version-specific APIs +- For layout and rendering inputs, read the value nearest the SwiftUI view that consumes it; do not substitute process-global screen state ## Task Workflow ### Review existing SwiftUI code - Read the code under review and identify which topics apply -- Flag deprecated APIs (compare against `references/latest-apis.md`) +- Flag deprecated APIs (compare against `references/latest-apis.md`); replace hard-deprecated APIs, and flag soft-deprecated APIs without rewriting them unless the user asked to migrate - Run the Topic Router below for each relevant topic -- Validate `#available` gating and fallback paths for iOS 26+ features +- Validate `#available` gating and fallback paths for version-specific features +- For broad codebase reviews, first identify smaller focus areas and present them one at a time; if the user requests a whole-codebase review, divide it into a TODO list ### Improve existing SwiftUI code - Audit current implementation against the Topic Router topics -- Replace deprecated APIs with modern equivalents from `references/latest-apis.md` +- Replace hard-deprecated APIs with modern equivalents from `references/latest-apis.md`; flag soft-deprecated APIs and do not rewrite them during feature work - Refactor hot paths to reduce unnecessary state updates - Extract complex view bodies into separate subviews - Suggest image downsampling when `UIImage(data:)` is encountered (optional optimization, see `references/image-optimization.md`) @@ -94,12 +98,15 @@ Consult the reference file for each topic relevant to the current task: | Topic | Reference | |-------|-----------| | State management | `references/state-management.md` | +| Environment and `@Entry` | `references/environment-patterns.md` | | View composition | `references/view-structure.md` | +| View modifiers and identity | `references/modifier-patterns.md` | | Performance | `references/performance-patterns.md` | | Lists and ForEach | `references/list-patterns.md` | -| Layout | `references/layout-best-practices.md` | -| Sheets and navigation | `references/sheet-navigation-patterns.md` | -| ScrollView | `references/scroll-patterns.md` | +| Resizable layout, safe areas, two-column reflow, foldable grids, arrangements, and reserved regions | `references/layout-best-practices.md` | +| iPhone Duo, foldable, or large-display screens (read first to choose the technique) | `references/iphone-duo.md` | +| Sheets, navigation, `NavigationSplitView` on large displays, and tab bar/sidebar (`sidebarAdaptable`) | `references/sheet-navigation-patterns.md` | +| ScrollView, scroll position, and scroll geometry | `references/scroll-patterns.md` | | Focus management | `references/focus-patterns.md` | | Animations (basics) | `references/animation-basics.md` | | Animations (transitions) | `references/animation-transitions.md` | @@ -107,13 +114,20 @@ Consult the reference file for each topic relevant to the current task: | Accessibility | `references/accessibility-patterns.md` | | Swift Charts | `references/charts.md` | | Charts accessibility | `references/charts-accessibility.md` | -| Image optimization | `references/image-optimization.md` | +| Image optimization and display scale | `references/image-optimization.md` | +| Toolbars | `references/toolbar-patterns.md` | +| Document-based apps | `references/document-apps.md` | +| WebKit | `references/webkit-integration.md` | +| Styled text editing | `references/styled-text-editing.md` | | Liquid Glass (iOS 26+) | `references/liquid-glass.md` | | macOS scenes | `references/macos-scenes.md` | | macOS window styling | `references/macos-window-styling.md` | | macOS views | `references/macos-views.md` | | Text patterns | `references/text-patterns.md` | +| Localization | `references/localization.md` | | Deprecated API lookup | `references/latest-apis.md` | +| Handling soft-deprecated APIs | `references/soft-deprecation.md` | +| Previews | `references/previews.md` | | Instruments trace analysis | `references/trace-analysis.md` | | Instruments trace recording | `references/trace-recording.md` | @@ -123,39 +137,18 @@ These are hard rules -- violations are always bugs: - [ ] `@State` properties are `private` - [ ] `@Binding` only where a child modifies parent state -- [ ] Passed values never declared as `@State` or `@StateObject` (they ignore updates) +- [ ] Changing parent-owned inputs are not stored as `@State`/`@StateObject`; intentional state seeds are documented as one-time - [ ] `@StateObject` for view-owned objects; `@ObservedObject` for injected - [ ] iOS 17+: `@State` with `@Observable`; `@Bindable` for injected observables needing bindings -- [ ] `ForEach` uses stable identity (never `.indices` for dynamic content) -- [ ] Constant number of views per `ForEach` element +- [ ] `ForEach` uses stable identity (never `.indices`/`\.offset`; id outlives the view and isn't derived from mutable content) +- [ ] Constant number of views per `ForEach` element; `List` rows are unary +- [ ] No closures stored in custom `@Environment`/`@FocusedValue` keys +- [ ] Custom `@Entry` default values are stable (no `Model()`/`Date()`/`UUID()` expressions) +- [ ] SwiftUI display scale comes from `@Environment(\.displayScale)`, not global screen state +- [ ] Safe-area content does not double-apply `GeometryProxy.safeAreaInsets` - [ ] `.animation(_:value:)` always includes the `value` parameter - [ ] `@FocusState` properties are `private` - [ ] No redundant `@FocusState` writes inside tap gesture handlers on `.focusable()` views -- [ ] iOS 26+ APIs gated with `#available` and fallback provided +- [ ] Version-specific APIs are gated with `#available` and have sensible fallbacks - [ ] `import Charts` present in files using chart types - -## References - -- `references/latest-apis.md` -- **Read first for every task.** Deprecated-to-modern API transitions (iOS 15+ through iOS 26+) -- `references/state-management.md` -- Property wrappers, data flow, `@Observable` migration -- `references/view-structure.md` -- View extraction, container patterns, `@ViewBuilder` -- `references/performance-patterns.md` -- Hot-path optimization, update control, `_logChanges()` -- `references/list-patterns.md` -- ForEach identity, Table (iOS 16+), inline filtering pitfalls -- `references/layout-best-practices.md` -- Layout patterns, GeometryReader alternatives -- `references/accessibility-patterns.md` -- VoiceOver, Dynamic Type, grouping, traits -- `references/animation-basics.md` -- Implicit/explicit animations, timing, performance -- `references/animation-transitions.md` -- View transitions, `matchedGeometryEffect`, `Animatable` -- `references/animation-advanced.md` -- Phase/keyframe animations (iOS 17+), `@Animatable` macro (iOS 26+) -- `references/charts.md` -- Swift Charts marks, axes, selection, styling, Chart3D (iOS 26+) -- `references/charts-accessibility.md` -- Charts VoiceOver, Audio Graph, fallback strategies -- `references/sheet-navigation-patterns.md` -- Sheets, NavigationSplitView, Inspector -- `references/scroll-patterns.md` -- ScrollViewReader, programmatic scrolling -- `references/focus-patterns.md` -- Focus state, focusable views, focused values, default focus, common pitfalls -- `references/image-optimization.md` -- AsyncImage, downsampling, caching -- `references/liquid-glass.md` -- iOS 26+ Liquid Glass effects and fallback patterns -- `references/macos-scenes.md` -- Settings, MenuBarExtra, WindowGroup, multi-window -- `references/macos-window-styling.md` -- Toolbar styles, window sizing, Commands -- `references/macos-views.md` -- HSplitView, Table, PasteButton, AppKit interop -- `references/text-patterns.md` -- Text initializer selection, verbatim vs localized -- `references/trace-analysis.md` -- Parse Instruments `.trace` files via `scripts/analyze_trace.py`; interpret main-thread coverage, high-severity SwiftUI updates, hitch narratives, and map findings back to source files -- `references/trace-recording.md` -- Record a new trace via `scripts/record_trace.py`: attach to a running app, launch one fresh, or capture a manually-stopped session; supports stop-file for agent-driven flows +- [ ] Previews use self-contained mock data; no dependency on live services or network diff --git a/.agents/skills/swiftui-expert-skill/agents/openai.yaml b/.agents/skills/swiftui-expert-skill/agents/openai.yaml new file mode 100644 index 00000000..dc0a5c53 --- /dev/null +++ b/.agents/skills/swiftui-expert-skill/agents/openai.yaml @@ -0,0 +1,6 @@ +interface: + display_name: "SwiftUI Expert" + short_description: "Review SwiftUI invalidation, state flow, and modern SDK APIs." + icon_small: "./assets/logo-small.png" + icon_large: "./assets/logo.png" + brand_color: "#006BFF" diff --git a/.agents/skills/swiftui-expert-skill/assets/logo-small.png b/.agents/skills/swiftui-expert-skill/assets/logo-small.png new file mode 100644 index 0000000000000000000000000000000000000000..58c6eb6734ee6246ebfba0f551f955bd879578e7 GIT binary patch literal 29649 zcmb@tcU03sus@p6B1o~)n<64LK#<-+Q0aowq)Bg~_Yx2Vq&F#20wPU%?@a`R&?BAD zJE4SL67ulg`@8p^^UnL@z4LNT&dzssX7;=D-QDw<-Ptdi>dF*k^ke`4fa29l#Ww%| z@P-5eZjsy+?_CS6ZVDo6IW;)|pfdJ0){OY(nbrK|8#MsH_bC7n^a%jCykP}x0stQT z0Km2>03e^glNEG3$SbxZ6uT)>G4DRd8~(WEJM)=i`4YO~%T~D(Pxr zCH_WH>A%!(o}?bzxVt-xgTY>2UVL5Ncd5sZ|26dAzyEwsOK;o%X$k7~U){RtAoyPm zSb&co{NJ{3R3-m$#WiicEgkd}Z5=J4ZZ~a63-AjHN&bhz|E=nOn*3j?`v1?W|Euc1 zR3*Xxy70fc^q>Cv5AKb_q{$?~|LuHfvbP`2^#A}_z$-;L9dF=ntIx4xug9cMnWajd zrGA}-{t=IUva-+1WlvvY~wL9ZC zS!UE#^iz8yrIIZC)Eqd{+hq9hi}a``lKPRn~_ z;UDD{m24>}-6Nrd5Ts*SVal~ki;Bg>j8>`k^m_N&=s#UCZ!xdoNyG@u3m7E#ozw2q z@*@6UsQtcLjb;+NZ6(PGWcoB9@|i6TS@lsB{_EdsH98LLT5koTQ#e~r;Y;MEMg;~x z;ZW~ttnb29SmPU2$orH!ieVlnuv(Xgv_Xnh^p5vL9+TX~b3$2z!bZ)|2TxY`rh=pq zXVA)Wa!}xQBiY!|!1a!lIh=OrTB72*-ikD?l{fajQK1&I%5nC%5Lfpjy?ZRjiY3`lo{~Z8;UW95!;@`tQxrAqXLBI8pKR{w*w;uKO2YYmk?c-MgmntV zL2$Vh{<9N_bg*DOTrRyYKDd09qdOf4c>Lb;gPB23VqLHx@<08pf0~lJ0NcKo?Rid? z9NqBFN@jQXD|d#CjNX$P7DcOzgJE>L@8{In;i`7V&)3xlqL;c?3K?OuPCJ=mNd|w(igdhAo0@nZ;w_;q!7c`={J^S zegqQw>RiRD8oE0L44_&Jq(Y_%t3m2CR6^-N1uB&ru0zbJQbC{^qLGDD>xI?EU<|oo zMuY7pZI>FNrH5hz8wo-eqg9Yqln^`Yj3_cN{*e5IH{D z%wm!kw+&Ty^G^mdr{Ok|1wJ)qTCiA(-xK4t|Kp#=apO4@mScf81u$JSjp@mRHhkH0 zS3uA~ze}J-Ttm}0)kSJDmYy~tDR`~_|EqfBzGQiSM78->iG!~Gx%EY>w<9Oy%4sXI z)wG})zgjIwSivTlIWwMC?T?v4x3^MkyIqM1>?-eiG>~pa+;X!SH2ickJFd?UNSJOW zOEs3HcYGCH9d+|baP@tJc3^vwAUXS=Y*(RjW~_qY1BXj7(=hwl)$Bg<$2XRKoI)gT zJ*Z8jFWO;MaArV`S^M~yo|*^|Uay`mozDfvsN=OV$*loG#xf6tHdl+ZwBtY3xrT_| zd~)rs#YdHmxI*P8GK%<@uo!uKJcY-7&CqSUpefTQ@>d>=I^KUaH6C}>J`n}JbY|2! z=K(7ZTq6cQzN>QJfP&qw=q`zAm=y6#0e~e#9Iz+WSf3%!Hs-7%RokNT-!RUjOH%%@ zaa!#_bsW1L%Pg;*4SOLfhg0^kC)Jd|j(xL8-R*iq^PS$l@fndg0Ve?|1wrmOkBQL} zlTWap3x1Mu(=cz=#>b3;^(>7`cP`=Bj8lM392wz;1o9g-IUSWe4uS|{v%=>o3Dm>a zOr7c(ORuZ_sXI=Aw!f#gdK_NP2%9C#wBpYE>;TsMjeqx>7mVt19cL&dZ#)Ox`-j1|gr| z*Qx>L#KMCWrRA!_4Hv2qArwCnGM^ut*O|CQ2Vc9H1osuLy8jn%qaTK0M=kH;QDs*r zuvw4xGry(<9k>L-U;8}p=sz?}6t37iAx$zDDNuC`U8Yn8jH<%c>-xfgM6%Hk+tohF zyVp{^!`J+MC(AE~go1*^o__Tj0)LKP4qjX7Xnr}^QVkOJSxjF*H%;Q4Cj(ZyjLs(N z-6Q?>_F`~}XyO6IBsib*Q4(LM;-KDPEmSu<}@ z@B4U7-*4Ev)O-4yIT+{8^>x8=hM0NdFojN5m_ODbt&LY2@gHANdl0s8`OXV{hO?P$ zUClG%Xz`062`-1V8e;op_NehYH=a_Kk&tGfJsYyxE?RFNWM_6o>s^nt%a+S3#A5_( z=%*P#^c!!i{K>xwBdBnHuht%5SQtKP1V$tiz^Zn#uHC=Bb%EX&Wbj__Yw8|^b{0M>c~XXijap%sf)C#y?*U40@g_MhfTv|k$NjF zX+$(v!)}xCp%jt_W^kc#a=p9n-W#}F;4X0>m`RBps(PE@qO=%kf)_z8r@)GKq;Vsz zuj0~GoGs;%Lzh27+Xi0g4L@mF+DW9pWE8?V78TaX}eDn2(_>Tq;tMP9P&Fo;^U&U#Ui^}}Yk#+%V+xyh_ zU3iJ9_a_q;CFuF}?p3JL@{o?CxUYBC=@NZlR^S*qoEAaQ1>x?;biEQ2g{C46<|v2U z5p?S{)bKSGV$1d^r%g2HJ%RoTRYpB!sw_9snPbHm$1Wn%=C{-vX2dL`T}hQMfbS zOh60fv(Z^dId462zS`4wR z?I_-BRJm=%NERSHBymaTV8LSg)l@0AJ8`cdbSN8M7qM6)Fg0d%u^c=N8>eF14dcFw zy$<$v5H+S>7KV_d2^>6FD!)#IVl?pa!nZsaFt0{_&Nt#7mQPciF6EzcT#ugtOWb}! zY#z~BeeH9hwpPYwwpfo47SUueE@_oe-s7(wzax2bASKY38RGcuM(@&k04NkxY2 zPy?y&uEs%wA1?PqiL_~zv6|P#jK+M#O<79xIJ{S`&R7zkuM|Si#b8Qu^@r{l$J~Ou zLA}rvu!_b>D&)70oE(k$dEV=FuqUeZY*RRAdFSwHbllR@Yhm1juM2@BahWvpbC_YR zIBSxFk16gb$S|*N+%T+c4my+nOu6%V?pA%J*b(E~tLfX`C-zNy{r3Gc(z7j;8^Sp; z6yWO#@Ycmg!{mC>0*e^CivqOcR+t5Tn^`s;)6@|Ckz-}Y!u19od#~$H$no>`+f7Z&1o zQLU9mw-YP{+e+`>z;-I_tP^}Rc#ql%p9#ez;|n3%zA)7D$s#mY3zZO))wRACpIZ-P zSX}Z3$7ial-{AgX$(@56lOBR%6m-c1G+XT7S&%9Uq8Ih2!Y0(zl;y@Ub>|0HCqtc) zO?yA>z5E{f)QPRA2`7%;D7^}P`UqjsVwN6dl@_Hz_JasR1qw>?e4XolXq|B%{PTUw zk)ya@nHqaCNTluA=`BxYB6VA9rm$aHEE*CL;(N<%EYCbDRO-kH3|@b7AYUJzb<{9R zX;BxLUjk(N(q^#z`5Y}oLC4@zrTHuNn`D?4U!$t-9Y?bH?=-seE{65z0|n1-*~A9* zocp~VUMif1J3`tjp)t<5$_I;?K-IOz?s^1I&|z1(c(nfS#^JrD9jK-xFX#FtcYQ~? zu&dHp@7O(7`g=#=j`C}S*)>!g@sgR?%MGtcW#+%334v5nBfQYb+uSyi8z!1rFLw~* zj|*fkILEY#+Ec$uDU{zvB7^D!6{`WLqlM?rJqm=c$O(r1-xVp7B+FgZj5S^tUReR0 z?F)yt3JA4bGPZ0TwVxy2e5^8>m91T=4Yft`I7vt?=YWnf&m0x&yfV zXWHw!wTeO6UzoZDAEosI*=w#}ZhRvNXrnb@N5&b~>AFt>w-~ukE_eos$_639jn@%0 zDS;z^gWDo0(z;)mdAlwgtyNu=9CS6~&e*`yCAYa_b+6HqGAr+yUbWU3`Y)o`7o0Zp zzOwwi+NNbJn}lpl$@{Q1WPtPoQ*PpPIMO+W2iUSWj0O&EUKf%C-KsTHR)8>ndo9@i zt1?2#b-mAj#O)i#3zwYU7z*chz z;FmS7?4ns0i8S`zQ&b~Li@38Sxu7u3y=#m5k#fH*D*{!{l>kpZm0DQ)8hkBfH_UfL z{d##%q85Ag(n>-C9G_e^r~eCXe-qLY=!WY{N1QfG-uipr4fK#r>!aCliY>q1 z7W10N6L-uyY{3H_(7?E>$S$5)ZU&D{@H1E=CK|0nvks3NN%Zwzufny>8x0tO#B-Du z(H9)h@k(U-jE94|zkQ=bahS!83 zdX0l7_9A1qRXfT+A+B#}H>h*6aC-jB=9Xf;Z5^AcfM6s7&qf&3Iw8)6tnaRdi2UI{ zG2h4}WWt~Cd*05U)wMses!4Pl8RyuKYqu0-$=0?->1!bWYEi^--wIax0Ss1ZT$HX= zzvrnTt$o_J*H;mS1vRN_Uo^1VWCvgosO1$F)RmR#Df>w;>oq46u5Ih9Wp=?}DMdjW zet0u*j|Lhe=Y;AOFK`U0S4Sz4Fz+GUW|cs$)cDsd39DpS|I8tC?I9*d1|z@0g_A+x zz3IvkF}G8|rQg^9$$8OT-o5tvDbFE@$Mbj;5h7*ka9>#1IxEkj({)DpobwUbT6!f7 zwcP3i*0smBEp(`=r#D4{_I8_6+Fv8YNSqme#^DT}A=i*D;zBZhcOAd(p_`_ z>7KaOP+Wf^SUl@YUTw0**l*ad`7`B)yGV;>Y;=B%u;oJFk<;4q^WP6w+~B;3pb8Du zIc9&ou+Ro`=k9UKo{q&@mW9ty+;nWr#5Jdk+GuP-ixcU*hw{0vNqTT&3pv4iQ`$K? zB3eE4QLfIl!%^KiGn$1GFl*(W>L2yTUtzDR*uBmWvQAW1OO3(XD zdD_s880Dq`Kq2nJrp}UI=&I?7-9~Ap?{-9j{ zO)~dFOF}_yDN{-);a}ERgVBFN7UVTbZy?(IhL<+u>7(G zgF(*x;e-a_k0lQRFeCH$H(qGa!GUH5bqPeYz6kjnZ%Jjk50#XBC2Z4h8Mp_zi3O#$ z$;IdUNaj-7f3SZ%B_0~vZHP`61(`DMTyd9;nr4I4dW3(_-Z@9*7=DHaYK8;}gHHVY z+QH6%rx|rz4f2STN~?B_4FcNtR9t_9{avm~*UBgvMs^8JL0>2DPPn;)02w_2rl*9P z-tPXwgtbrK&lR0r3fvdfph7dovI7aDDG7K*OO6*?iz(uJ6j%H=+gyvkXj{{~7os8n zjUJ?3Le61}MqTVva+~?{ZF#dHURzTbwS|ICB`P+b>I>FmIFWciphHKyZL=VQcJKUw z5Y<7&YT9dUPBiFufDhA<*`1O6x#cbcKbf7DLoUv;2UyqCs#$mMPSV*a4TToD^pA5Y zf#^uYY{(0R3j}L+%@mEPolhPK!R)#}Mf?;y3_+L0cX+PB&=E;x2k>4lK1|~y1JUV` zXcGAHir+lsf-j|J+F`KV@q>8N~Fw40&TP)#Ip2L2u?XRTqoxia}~J zx69z@ns$A?9Ojrd1v@-c{4S4i27N_)#>Z99tNXQw@d)-H?EA8pd_Qtp|NeT4<6qm7 zM1%Y>N0;hz1+T-FO+ibE27U|0CyyA!25w!l%bA-jsl(Eb9nsd&-kqQOH?V?)a)w4K zPrDJpa`l2VaGyf-?ZUfMlc|1xV5xnq6T=@aZC~WV{*>w^wy9l!#A9+LnRMVpk-;gz zQ+@(peKP0zSCFAWKhfSwZ0?#=DmDxPpog&WMVo7x0XE|pXhXlOJL?^8DvMkJXB>9g z&Km{ahA6F^m+bAhA~c&%FyyeLr90?eFgby)9d(DuHgwW82-_<^m9LaXF+glRQr=`d z++=@nkn;#u%kK5N>(FGgRC?fq){`ada@Og3s)%hW@~oY0=p>f1Nh>)3+o=Q1?z6f+44iJZ!C;io*J zAwx{Wr@|z49S#z_Q!}$YXJ#-9mwSE4yR|em=c|sscE@rQO+WX$ZVhmW&0>fLg-kGn z&q0%jqAk1-;UD7XF;r1bNYeo)y58WcuPJ2W^A}AKu1=}k(!rxqnkht)5<{B8MopSLs zrlU7W#CP-zgrSR`f)^m!GWo&B!kKLu-#nH=aU|}r%Qk3^`5%|&X-Hi_{X#yDeEU|e zk#%qV_0VSEDGiiQ+mCLuNG|Kzx~rnp zZCaK#tS1FGH%(a?QuPNO9}wk2mHDK_UEgSy(Gl(IZ}R<;S4rL@$)pKSiM7-0>g`3q zKyL%n{IT06XFW4ek)|%Ddc{G zdiqC`3E(4=bjOK8G+oUV!N`Y@iqyZuKMiJQ&I5O4^jGPQee92TS*C`1Jy(n$r4KO5 ztq1404Qm@}r8De+I3n>%GiuX>Q^g_bHH^83FH$^E+RvZ2tl_r7KPxIZy&ZmyhbYXf zMY99F zKRIH?Jw7amL;O0|G?GzKA{fQQzzCwIGecNQ#DAcdkE5 z56PI6DIDtgnvM+L{v8>+gIVi6LH}x!AcPVK36d0ocG`l5Xvv3er#gk^;rn_csah16 zj_$+|$6lm1`K$t4OJ6&EY1;OY;34iwVv;hT14vRBTf=9zOfLz`ZFg2Ptc<%tk_%Q) z#o8Yo<}_{1ABm?Y6N$g9IUi|uZ_#5)er@SYtJM4-)hP7PWv4DhJ^oReS2k<8R_-8lPl>O3p%&%c>=j zI?mJ+L5A!u+rhSmU4?JUMnB65jf^E2dK~Un4bsI*5Kby>82QVCbnEoVL?x`)K1tkw zqKf=1astUuLc*dq5x%jI!*%+NRsAYwi?k?~e95-Ihg{p|-h+T=R3SmkwA;p_RgYd? zVz^{{#8xFCd&j(sMFND*a;==+r_&zVnwc3fZG6rTmv*aJ0Zm6HqWOX+!?cF-F4p_xJ)p$!jl z3%Tes9LLMyqUV4`MJobbd+oT0%cP+gCnSaz^?cBH?pkYid8dxbn&kNRLfihm5&cHU z!2xbHmz1mqVQxBqIycRq|02E(1^SDIwQykWf0v&Bl z-5aE)!8rw+^Cw46V}?=g8^Hy%UYT`cn+?mhGC3J`e-i+i1N;_;te>L4B&_&VnKWhe zY9;7im}~l@k1Xx7BK!-VIezL*NE>fGd|s??2}}I8qTB~7(@yhNItzm>SveR{e6fG7 zmBf~z9ww!bx#|PnqJ}r+tr#5`dP$0Jig;MbHlIg=Rrcr|@ARYvsI`O45Qj)D_-Ryw z-ER_hr`qY$p`fGOB~0^Cohvqt`_2`Uy+(nfE&NC?SXs~5>9$o}kAj5ZgnAY)!1!s~GFS~n32W!7-?x^KkVsHI%vx_v((6tpi5I`B2H#Io+ z9;F5Q9be1Q&vffG5K834e#r?aT`!-<<=>g%6_dkSwXAjRykG zS;hw@oP)=!NrFUBa~e*ZL?`OmofP!V%kT9=)Zg?Bn!F&2`6QWpu+W5Tu#q0RvMUEXimt!S^CwE4_E=z1zr1Z*GG<=>7Sr7IJ z>u3X%zuL&5-FszHs-|+>EIpz^yUOy3ol5HnR3_8NGZIrJDQ#Nhx#J>!FG|MMl=|Re z_&2a-Pkx+p7j1FKVp()j&fbv@O+G2|UUbZ`sO2G}qewZYjomW0<#?H;CRf(Nc)8@s zV(DyYwwK>Qk3ADwhAk_gK8g@PP9#z&uH9)IoKVxl7=RMz9FEBm$JDF>)5!woP z=t!r|ho1xjjyOLvsQ0Kr25b=@SZsYrg6&TXoMK}4EN5PFto`gdPERA+amoTb;ZIQd z6WG^)d-o`$qqa$^uvbkV>Ew~}eVrdLrMP09<~qFFL~r}_ju#&-(Zs6EO9cJRb|Ax5 z>_PT`Oycp!4nOk}?>vI)wyFv|R` z9E0m)9nN30zS+XL+D94ouJm`cnod$%`sP;?v0fH%ACBZIeGo9oPl^D+788V)Q_sqXVN zn&dVURl3Kk%}$w10b^}&mJApeBgq(`gJU`z9v&3ieqcif@cyjFNI6r^+p8OB0T8{L zC8_Q+hROQb>*(W&7j|To!hCHlePrwW-ltXWPar_sc>%tVFFNJAu8p7z*4T;y>_41C z1g*BvrjGbrDfe^tmcg_daiR?>rt8{(pCyrJwg6FM4dR%_D9?kFa*s%B>1G~ck}G+0 z0_E7`WPo5yr?O*VyA7?#?`ySly-Qlh*OUKF!pjfQpo%XAy}>J|tW+qpuS!e{sms@K z5yI#9^$wQ95#>nn_w`qETMqS)1nI(J-L5CMPOMn)*%P(mrXPn|Lupf=lv{Q$Q=-}| z;L9H)!x)mq@B;pZ^ukbtL{B}-#f+>uKomV0;#hLq<6F72%0aDVsMxy+ftkR54H>Ch zK3mTSWwpF6v6es9msn7bdFogH-aQkKK6Y5FZsI)=aJ=Jc6JAd#Q0V+({sAq~R7*4V z^22Qt#$~%Ucn4ZBEcF+2e!i};iTIB2DVk$ph23z6D~8Zb&%XV7CKk0isAAQ?1XA)Swqeg^{ei$56S}O5~`_a6&oIJ z27mAFt?lh#fHiVCudSt|=$*z}ZXKr>mxcu%4~E3Ho9LWNO+t_{cYFf9VDD9uG>S^V zBfJAg{n>xlW9^Uz4V;5kwXQKNp)DDW=ZpKvgLC(#0E;W-cGL$|lfQSi-fds<_rn94 zsqpYo+~0I)9oClA<%t(b1NT9Pk)@kcdyFYrS?+g69eqhmEnj{ZhVmChHIM|DpWu73 zCZFyz>O=M6P6so}Hhj9g2>~33F~0yE5N7g4-R*4J z6YqpiOXQ1B1TIYnb->v`7nMCZ3P7y1JAViO0xY}qC3EgXFE4Y~`+**%CpnO9|Iqg; zV78bU&J0FBJ1&gplb)F4lH@!i79y}QjbiW6q6HjOC;Q&s##+kgZA)EU-&(N*9DEIm z_aH9-s6&J(M4u*J4BR%!54o>iBYEZocYW8$u3Rv?&)fLsrz`QscCp9ya_&A4hTG{` zb2pDne!oURi(Kp-Na<=4i#X+DZ_OrLSJT_VV0A*Zxz7g=i%S_MZ~I6LjtFI6%m^U| zRa(}jBmF(*mT~QFLdk%nrB_^2lkSEWYdnNCccZi^i?I`tU{W#Z&@S_KhIcbDDu9jf zW8+_UlVb}&9x5^BP4LC!46Z~!afB-XtvJ|F$uQ)HVD=lI-v84w{jA}jU`YX8l> z5C$T>H~b7EekaTC9wC5^(q*-I_4|c?Sv)rxJFXU7g@l0^s=)EIpcvqFl|2X6M+ZBp zTL>ler3#8SH(g+@O4_V^iqna+?!A8Rq3SWx?Kl%XS#}*vL9piyZ#0oO+8@2b!*iPN z*gbP;)~pVmfDI5d94?$kKrvf>C#1(9O6Z+z%F$BL7rlE2MxXVXKbW^avDvOK_hM7? zwZ~To=s)Yk{h^Vd*}pD*))hRiRRz^}=0$k0wrF#Zl#fed$po>%ZqUn3@b2_MDClPf z)hAbJvG1ZSV<3zo!$>!*s{d$;FU;D##mi;K5Aia_gpz9nv+S7z9S)FV(DOBso8z+( z=09i`JRbWb7qqb;gFon`B*;p0o(wLhuY4kUWNR4`_n2kvvY@*4NThbUf2oM@ThVTF z%vy~TOgrqOae=Sz>s`p3Z#!QlFTEAdwdFNrjB(bTVV2G^QzDv1a!7MI2i=5^NSnkGMe|JJ*dHvNmqWd?mp z{sHKrjeC`4XEjBW5iR2Wd`^ees;PnNr){eAi;|gUA%MRE5^ANT{K%9B5k%8cHAlcK z`N;bdmZpshSI-CJ9|E>S_pZS{WmyUalKp|)+Dsn$cyw9sruoux*()x1x?|G4`5?E+ z=uZ}5SlG}TYZk@{t*ohEIp23qgjP5_exGsAFiLJ3noJ#b4<{o-HZ~n3dcR$DZibJ` zgcQW6^^ylACW4H>ex>H<4rb$fuDg+MW521L(x@k`pH@>kAt{IPwxpU$pPoq|y`rN1 z1$t!O*wg=b8KzX|KBE01>uyGfe1}E=+O)jo{LA9j4$60d#pl4{Q8{3vpM|O7GD|L4 zK~j96+EjMg9c~$!kHcGPE(y#U)+%=fI68*+pyE5Vp~~6Um5HFrRN!ya1AlkLk7)ga zyT}y0W>Nbln{qw=2e3n3mC1+y!*u7m+uX>p_A6t{-22iRpwHf}2lE~*(k5OH+{fZlA{dWZ?;vea=GL-J_?W6<)I#MS z5Bn90SaaM8w_^m~{Ml^Nl&Hz9%SW>Tg5&T*gh}yq#;NwDe$wu@s>x%tIg;l#W3J^T z^w1XI{8XDxG~mAE!?m~h8|^KI&U@HS2`cM59i{K5g=Y2q6AEsRU+^{NyPpTXVwKRN zbpEDM|Lp^8nU$H@t~g0amE&rz%aSb#xcFvT-h61c_-o|3OCijmS(n8Jw4qATdQC}+6+X?GS5(H=#QLe&QM%2FNGi=29XAcH02O&ys2DkquQL?#OyUSeUr$hFmG`xf4f(#|d38+wc#VZ9W zE4f`wM+{WYq@;+vB;)d;K#?Vc^i0M~=|$JeOMZwwNk2fP1lUN3Cx%95BSG+%qJqL1 zFs$jf-ke8d+pBC)L=AQ`%O`L^hf=g)cf3#JCiZ_Z3}sw)aPYH#C-z*kcO9eV!D9M# z<&UOPGC;YfF4y{2h-^!@G6JY3H~l=e$kly$Vs2&>)d?BMlp^_JrMU^BGzxB;7{{ z1S?SmCd`@T^m}1qV7ge?h?fH8Z>x()YcXR?S6*wzEfz=pm~r-wBv!}Im%^XGE59d+ zkLZ7;V?3(TL=YBO?>=PTX815N;KC1z1bzemO#`gO%Uy_Un$k9JZG8NdLI8<%vg0Zn zs$X29Nhb1difX=3PT-q%%Sp^&?plttD1nx!ib<+$6{tQZq;S_a%MR>9OGo6sAeBs% zk+6#Skd-rKl^GckVk48$xY1qWgsZK{BljK)NFuoYB?HDvx4N(Y66Z&Bggk4! z6=Bz(mtc?XnI^9EjM*OC93QBkt?mCUZEgUU58VY)O`7bzG+YXQE&O}yH|LPfdzNl= z4K`c?zysoI`?=aZzD|aEK9XHA5+Xf1cG*lgo~)VwL;9r&(HLnOcxg)E+iom(+1|Z5 zkK(<1{%=BJNpi3GyH3wT% z=M0b+@m8vGO~vjMkirc}*uA?*xcK_4B@fkY#h{Ye zZ*?-mO?&H)>4mb=77cxL?O%1YIyvbi@B-&U>}2QxG%V*DzN!Y+g0$q9f)j$r!jt|W z7YC=Ukuj$}(;m`iu0-7K{-iYL8xLjP?6ETGT%>H*_wu_u#_y5@?N*E9MCpk1HZVkw zIF6S|<=^@XJ((L7zOzh(>|Opo`fRB$8riTlKyo|;m{`S(v*oW?+o=tyW9r}3i zTs79RWEw9AC92z8C@oK$B#Qog!XQ)Z(IS7i(OH$!S~oEAq3Z!d%sX02K-9hS-;_Hm zkBOPT@JEGZwI80iRKoiY-}{JV?JF{PEU1#6Dql6MRC6&yp@ z*=js;_Q7AvV^ua;u_6huX+k~gzdH2&{C4F_I*HbI7Q5-2L|8%q>9Q^=d=lXiYBK(d zEbc2EY8X>Fl6N>W;f~@Cr+|9;ti$!Z2N_D*1z+S?y^}!VwtNHZLwng zH72&BQqqv#M{_-FpSzwN?hz~<8TgrAq7=nz+;j!lJ16;bi8pH3iZ!?Auds1yzZKwf zug#*w=j0(b<5o53;c&iuig|!}x)^<4xtHb?dX*5{yx{PpOkvA@By5 zNj7ATP2TN)uq9(q=-sv}_{BU)UUW$)$@)h@=gzau<-{3Ui#yJ}xm769Anx|<`s|R6 zg%Y&(Y#UWTbpAbfq})Y}_Ol)X)GE0v0z3?ZqH z0}37295p702mRHl!gF$n6g#~?YguXeIBziTYS>u)b$Jmb*RlJ@HHUTUj|)byaBJ&# zcQZcZ!B2;DG()Y(tTnD236C9>%XJm`G=BuXW#etV{m8_9*HBN%Q?O8Ie&0V2Dq(9-uJ1Df9B-BkR&22 zz10;Ln7#e1iD3j)svv>CGI@)Ag{l<6w$SH^YeT~~YaNEVE<{nbz`K>W#qm1oF<=8E zhbEmba4n^2j~DNxPlbF$@~A#7s_PSU*V1`Rz)I)->3U1`t`yT-b5G&pKY|#28s|eA z`RA?6NtraQ2Qz|)j*-NMEUq7V%nC2+R*k8ja9Cy3*!t9lbD_`LPbhN940Nfq-i6pc zOIwT7uEI|d`Bsty!!K@c{c$KIzvAZ#3*Tak>q$g14fE?AgADM+AJF|rWTh}XtOs)4 z3-yggyMP?rH~dLNg~jzk8!!}clz5|7x{E>lcSEcROiEoSlwvAkc%qiYThzJ($Px46 z{zB@0QYmkMqHghmiz&XEG>wE3B}4(3ySv;V8Y0lSMlSj6PRj9Ipys;tgo0pUXH9Fr zN;DranK0Lbd{wsieZfnV5}JVq(zf zlbR{$N}^XB28@k}Dd3-Y$a`*zDGhKc&4X#9{a8~UPlqeP84CK+p4-x93$SS^FD9>* zV?TJIpUpEP?*JvHW!I|s$r&M zOO?MeLJq}DAtOPh;7(#}8NG3w)!RaPYU`H*CIm#RJ9{&S%gI839(A-t4QjnYEsh?I z6qYUZQOR2O2@ZNoU+AVYmlLQzwtH8G^$*38-u=K3!yfcBSG)nT1up3gjU zvgq>Q69GaXgC7s+b(ah$(%)v&CH+IT|7x2cVR%4DPnLs9Z0=)BjuThggw>VdW&U}I zmmt;F;@=O_cRq{D@3Clmuc!ao!D~@>+{_i@d1MSbDJV0OcxcMc}J=oGNZGK;#}1=q{FhYGB88=P}tkoez0(^cr`B ze+&9CP@N`sif0t$Y(1=7mF5d@50!Qp(GWxrysVLu zPnPOEFc~k%DTlJhW2;mla8u#it}$l~mTJx|4_UJa9KvhRG4|PplGk~Av|gdA5XHf# zb6cUae=L}9(wT*pj_v`%7>7GhKqhjr(`t`9i@?Xw=@-P9UW$t6b`kRjX@etucNgT^ z^}G1Er%CGQ4D)j~o)Ln;2BTkHG5goCWyn|U<_lLOnHK(e;%)OX2beQHr`*p?JPtV7 z(Oz_DK!L03*09gpxsp&Tmkj-f;3P|uKd*YGRw2kQVUc?*{zm1xMWGfOa&8$GD|GVp z=m)XL>I@I~(Bb&02Y zVlHCWf{dTJqGPf3;^6X)t*h$gzp3_v-XDDi>HJ?u7I`5;=zrGdpY_F*2PgN9_?*Q3 zdW*}J6G20`>nyJfu9$}7xY=c-&hNwRt=qG8zo0BY8Rxud#YT@<=T7f=InNNeGf!+a zJUV6`z78#uEF>(u_RURfHeBfC?+mamiC%SIp`)*->@{pq5}_VmQuGOuTl`6rBqv*b z9Ik=;K z>&*b|Tosk!T-C@8QOjC~{PHfhnW85e`l2-196d3(IhaX)i{$!tDCh^qF`_w`L`b4) z@ogBgB(VWg0%PN=Tofqr74A0!eedvS{~36{{K!p=5&o&P)lpKAr%pd?*I^|eRMUFj zQa*W_Y5&VD!)}<)OuOpnLDEMF`X5me>cF1OckxI;X#`EX+C?nqa`$AC+~P-s(6ho$ z#g(7Y{SHl5g@XHYxG zQt&;Qj$CjS$)0KV?`Wr>Y4r^{VO>9YM#itagBYUvK@n9YTgu;Rka^kJMgRQe=&3PJ zc0H1CW`&K?+^H_WLd?y5Bn=~iKdH1*T*srPQD=n-NVPB$C+xEU9+vBwNW3$P{fn&R zD>ix}?=%ubh>h%_J+LNmXi|XrS27*t_e}&EE{N0xa>qIMFHhO;8b;Sk z2INOOe3xjSfA>hPI(&s;QO9Ru#w2p|=+oUHZ^jRXLy>{Mwlr)SSuzj)-TMQmIAmy+ zM5!}PP)q(vE6Y#q|j5n z2#9@+WZ{Ocj656}KZ@G)G|sK)r_#}3+H|nY&`2-XnnJETW7qTf!n=|$QZX)70rXhj zhovvS^(wBe|KcwHdEnsjGiIX=n`8LRlB*P|w&*z5BR}lTImU(OVaeLUr3EBoNb!}n z$2D$Edj-c2mZBF7tw?IkwrmMVd0`>m(5L_f>V1GRBfTzG*zvJ?;DJ@D!!6(6_HGd$ zf_2lV4RrHoscm{dcl<8&dC!T;(=z6J<98qGX?>nT44XxOM@tbGC9<>JX$^ysXzCM| z({Ht3#q=&XdcR8dM}4rQmW4@1M`QWFlbY$~47h!Wd;zY^d8-l-pOafL zD}?mjloafuzJ%Ovy7YcQV38RRn&$Irz=~CZeMZG1^qVy!F*WK{PC@=>M$!mSP(>I^-RvpQN%2vA269V~rPELB?)5iU){rBSyb`TA?-klcjYh3TO zyBE61+Uq7+OKdL^{QV4Uv}ZG_pk~qD?B?phtv*~7=X+tm5prxP{C0k3sjBUr{Hq=L ziphbBTAHv4<%CdyZwZMJrk*V+4kwnOc{0AIoWG~*`N{e3n(c)3fV;0KTKe~&{5Fs( z!+W%evR()R;>>Ef(HIs%x?BmAb27^rQto`%>E7iM9I3jvT!TEaAU#*f z&8I?#+?jd#y|-@9A5N;Oo8m|Bbtvgf5sXzzbR~y1oYdIr5BVBo=?AvrKMa*mcTiy! zy`nT=ttTek_uX5Z%7i#GTDl%O&WdmC*oItJdS=?v?R(J6iI_#>tSXs%?}j9=jC|B2 z`D6M0bBGx>R-b%uya&YO!|tZS{*2h8!??D#O06hZ{hIFSpj4Bxk4*5`4&95AIp-u> zic!~4dp+eu9&6G5not|DuIDAWuaY5*mIewpS4Qb4`ks&gDQ~r6&$?MhS}$~)U*G_w ziP$kEgh>^r-e}!D-48!>^Id@kt`w8UHLVnv>@yo2PkM@V;!5a-a;|w#pZutv1h?)I zyV=U5Sp}G5>{!T(&5);$orF_W^peB8)8QA~)v|L%OL|9dx&>Vr23-FO5#-m50|EKy z-QO(_#StuJ_y%6@m9y@n!`_=~gPxHbZ6%X~w(yQpmFxY$T(XqoE3metRjaVeT~!q@2E13bU-*tFX5X+co+1!RZTk ztOs_2%HimbZE&tilaG{y$Ht|bfahlrk4X%H`R~+a0Rv&t0_!dyDC?5rnTDr`bDuk5}Zg6ubHt_wyad$<=2sN*}_ng)c0x@+G9nm zZy>PfW;ZbuX6FCu?X7~^djBxaAjOJPC=M-9O7Vo^4h4$0Kyh~o?iSp&6!!w5E$$R| z3lQ9)xVu|m^ZW1Y%--z9?#15ZJM+%TndIc0_vAg_=XpNqDc1$450V<}Xij$Q)``l# z7kBRg0B(){vH%K)uFtv%gA{zCf12wJ;wU^UUPgLuwhz}dR4k15OHuoL1e}J_^HMnv zjK^eJ#%%K#DZ?AR`mB^oDpxQ{tGENXb-sN^niX=mGbRHBL^if53IxC@oK(S0pt067 zxGPdBX5_Tke90nyjc(*#Z-6AB#U0)@F{D^s;=y-H=^#?+p9mxek`Y* zH;gxY`c_qqP{jsb@ZrmYQ#kBCRZEe5-ye$ zGKu`^(SI^Pt$(FTkJmDicJj6!6wu@KbF3OW0uiFOz)NdgC%$+JKbL~g)<3V;P5w#K zd@jTYv~-JZcwXd(w2f&8>XoVM(^XvU%BUn0-Cq)GP~+Iz=RIQx(l!L)EV>)kvQd4B zCbGZSq>mE?-s)EZl)Q|6-FQU9nd~3&!cq*buFNj3 z(FfCbVJF*Scd;^EFzNDE7K}iCuFGCo6G|PCf6cRaJ_2~0pTSu=^ja%*Qr}knTGnBn zkmi!$4D!+(C?7i0tW`L*-v27$_1NRustt4#2@UV&Rxu*PK z7_ns@i@+q{8!X5SXp54~k$B~mVtDc_avOhxqvxqHi`axr(=;D?UE!mA6nCi?6&wM| zEVE6nv7C{0b;sxQ#yW%Rg*;}ZMQf6*`k0}U9JnrFmTnOH>sr>ku6ZZk zGjTV^?~NSyzwuT;%02Mwy0jy>t}AqgA$>BgXfDgXnt?_liKg>HfHN3eeXv2yII@~=N^5$ zIL*&0u_fz;67JG@fOui$vCLoD~rS8 zPOeI_$FggHX4@E=Jd(+DtK}-iOuN2W#Ty+@%;s-U@qpQ6I@0gfI|+qvgE|@W%;feq zB-l5s*P_{e;Oh;s{7DbOn7`nd(NCZK^r7}l9RC5^C)JXCN#s;(U#a4#3Fhfi=2(7D z?QZ09+VFHz{%~Z-4nyC?MPH0VYt{uS9PXnW6RJ8uPT~CxSe_(K*6WWWcynhH9e+(S zDpcjYS6$h@7Sz1T8YOd@*ms}^*FSoD{YH|Bd`Qf-EP9q_FptkAJe(p_V|m76>7iABS1-XwTt6T6(Re=>b{ z>dL-W?&UP=cXU?%@K`+k`nS-&IOLYDaf9cQNjW5pu4hQDU!w9vvB2pMZri}y%Bx2W z!y(RFHDR7BCsvN@3G8JF5c05+%INVo-B~^?crs3jDU^Rbeyizt5REZ3{rsqa^pv1C z%*W*Zy5^(`Lj%Zwspk0jb!i^HP8zj$7++3E?wRtZF;?4I?hw zLi_}(kl}@L|1ar9BF?$4(NJY6G=rOhs^*QZol(;2-;>%Sz}8>-eF~y}EjZFkUAwdG z-*Y!L*Lx?jL@k5_6=fl-q%zdP14Y6`Y!(bki{?t+dRtY@W~pd$n@pOtK7U4^A@Gxm z@BnH4AY%j|VC0qe2S+9WLtE+`6-$KSY*MRBqzh|QE2;$!k6@0$hVJR&A%WcxWQYTq z#By~d>o?}fIW2%9s{F@WM>Taycj}?q>9u4efnYm%YBoVRHM7i8=h^P(w;#$Mef+u} zJdf0g2&mmBreiRi2Kmm6g1%j$A-aP^#U>caH?ew5$Q7L~q=1kK%?s>o<8aS__Tr+m z-dVThXn$3lgXwmgWlHMs>*jk&LLb2HD&?>>wCbW_R^83;QE^t}l4XR&lUON#N5j;+ z+TRf2Jlnd%*L0jj_g&3DPf<*p%E>i3Y4G#yk$;NO!*e3Dsj4!ynM72b(_K6^q}SupG)#s5<{1)arAh zNu`ia&6rA1bCk3<{Ksu@v`9pe`&Sa%I_U1fo}}vX4ukMI>09-6D~_tO%dXjr=-;Q& zlC*w|^TT$xlp;TAUUv!t=D4~CYVJ08@`A5+cqWHU)4UWx4$399S0DiE9Qr&#OSYYN+#X>nPw4I2;?_0$_x-sRv-rN!y=HBS+b~ zB@P>n{&HrULF9OF3cA^|L7D_}yBDrotu+pC@#oNZra)J7`x*<>h01iTh7?m_%BCkJ z*Pg41su9W#1S6<2!fEFvP zNFL?0bGA_bW`We91t>_D4$tz70p7JNL8XDs(?RlV1OQ+7bP1#oxU$BtL3vN-gjnDI zDZi@R>DS=4Y@{A#jHTXH>QG4M&T5)>T9OV$TvY)il6sCzok*AZmT94zc)lT2lnd&n#unBySFp8;Hq%rv~cr1Sk_|5b6 z@^cqJ^~GBc@aFkQqTP`HW<&Ea_w?-C zFuMlq!+ujuJdNSjAxk+gmhJqa^sHrtwJf7$3-^UdX7pB;-B(+AIyf%z`VeG%TK^{O zxrHtEK?seE%N0Ywo_aUos#zG?X__9>aK2EpYYCV!Mu?YJa}#SNeA?kZvW#FqcUndGh2@3p)_fYq&o_a(2w`sdZB=p9||fdaxXQ`#b2j4C}+$f z-V7LQsAG%xxD8ZrvBz_gU$Ri|+u2uNOXjo56&FjvVH4p`lMaqyyA2Nf7*dvO(Trz2 z=oyg}bp9iHo&tXY1XyPNr)j@z(_Qf|A-3A#qW=k{96KG{+i$xm&s1(YXS#slqg$5l zH{lOb0uF4guLa#RJZt}jbp^Yoi)JhTP0Y+w`o#2k6WbI_=knr&^n1a{F(a*^RfcR;fOj>Utyv75$QLv075-tW`+cEyylIXG*z(LZury* zGRpfWx?&c)N(oyq#u|O{m@*LvR!1^}6u!KFW=RDzHpe+xhU_i8*?qas;s zi5L_emda&A<1T*ug|_l-GQPHqh+ICefRLKAYP|ig9o0OjTf()^?#oQ}9x2>iaQ>}s zrU?q`9Ex-EW2o4i+rNjtrdMeR+0~O8z&A5V4GD&>5C(RXgjzIQA216$G6={yOdz`f z`(M%W7QrLLMx{C~JpjSqM^_DIsRrQ2&Blzu?xR>~J@7bM{v2@ptzY`)doN%@oUM)K z`?z2vgzIuo&R!gx+0RuRKkj_*zd24rW3bhY1-*=i7-&BDG#^iT?5jpyo2D0Bd+Tqjpn~b z<7)OEcMQK;V8Z|E1$Wo%M^g^-RY#J`$L-VIg`)hZUXv>Spkh^U#VzuqH}DT!L=_|8 zNguCiq2lV}RxQI(M`X1nuer!H!M7s5U42q5sVbt%!(V(gDhm$K&tV_y!HGSeqSE){ zAAdVnQ8tr<^DWxhqK_+VF~lioblSITQ@^6AWGJ6@`Q998PzU4RVf9VE? zh>+(66cc)#hIY%q$AN*C%=`8zCW3l}R8f4#Hzvye-eyM_3gCa(VLYNAz4ifU1z((!h+>vRec-Cc)j zT{`_@i1ft#VsBi0CD~Vt1VV+HljptiW&_L>@{XgQrEt#~YY<-lL|$wW-z5-W_M#uH zSas=bivrabx~HQFqk<|6%vkd8FMntsHIgQNqv!53{^>ovGjKNfkzrLo3_fAh@eU7! zZm>Jxg5Bmvfrch{^-|Bu_uiao!#YR_;GGc7T7z}G%b1@VH(JJ!Q|Y_zlwETBQ?Nx) zpu!Y$XHXt`f7;X?&he@ir5QW1DsMxA`WX#2b2t+oaOPC!Q(%#;L_0rPx^&5wG3n#W zAO-&`Vv-$Ori}ttjW_aexCLFgyMyD?cM{G>K!8S7T+|lsT`3*>vAG5cbT%REnhj%{ zbyqSzn}di^Ht#GZ!oqG4)hZPhF1n>HC&~a@XRg=V>}IOc;)09(T8%?oVCkKwOxJ)4 z^LEtJNJTOqJ48P_yO?S3GAs8MTE2gJOU9g?B|HzOSNN?LC;&sj2XzK9)wj3v0@!ET zWlSyRhj0(zLAIACS+x@FHND@0Hdbwq{skp!cPKgRA{X?k=`Zpw_`|mPC29zq^J8|p zD!OZEajKPb+{UIkSrmc@Y)lhMXz&&V42O>0rVG4i{I#;|h!+#kkwRV=U7 za}u%Q67OBj(?$WIt=RQ+G7?~nkx#8g`r52fXf-Ny`WX%l=z6pj;Hwl9WHp{&1VRT? zs*PU@b|l{k;&KHW7tCH;&Q;v&XT7J2 zB&FRA?bne47deApUsw>;sF(?{Y0boU6pnF;neY~cqV;#C;k{i6;hjGV15A-xxgWryqk^v2IhdI#N; zo=Lf+E=(22hcorp)}o5=0aFEa?pX5+*f;NYQx38#U07OuOME(t2UH|;qd!OV1PC^4 z3+KEfnMD_Wk~e{qg#Jo1O0o6`fk=iV2*+~tqNQGTf<7u;55 z=mqUK9D446+h{(m1I^<~D$jA=H>Y8k8a#IVm6TEu1Ep;@zH!|UdBx%=by4dyNwwSZ z?#+Icrt{)s<%>34AKlCrZf?n|UPi+S>(=_BSXr{^c0YHG6(EIi%`3jBu9i0^_Jg%KL7u~M2`(%}C4&@|CZ>T2 z-l7bv<@PG7;T||@I6+{GUwdXm z`83GJYdMf;lAiACEL>&IlZoaB%mKj_vElRS*=CbU(T_?oa^}EMQrC{d5RKhK-8oAe zqJ!XZ838bQh9BeagldF#E?zp}@F0buF&u*@h8pI7_@y=cOtck>xGSQ&+^VAn&dUHR zX)nYX%nXXnb=Jo91EhyS}j(a!-fyM)f#f(sWN8rpTeKT3KJ zp~s`$?Tqy?uv66~dTECZHwB&i0>Lb)KsjEh4!*Bz855FpU8qmoGK}un?A{d%aHM@U z^@K821=U9?ExntoCB0MRa)Exl$LOtZI3{&&FX*s17}EVdE0KF0I(`aX-X?zsF8TH1n;OOsJIg*}n+=i9 zCv8(mX6vU?zW(mKZ}btF&vP=}pRq41sv44E*ZD&Ix+_mnO^HsslXfnBQV`n{obEB4 z#eVipxYaz2`}k$~`AUco}lF}*Dk#@#7 z_nmoTbPhM{^J^PvPO)+5}0FY1G|Z*VTY zkJVtWm12QbE^6P{`*=6L((d(UVj1M={-Hkp=_dML%Jj73tusZRqgBZ80baCX@DBaf zU$N1|x%hVd=As5xh(3`P@nsoymJynQ-A()aF8h^vV(h%-Hv83ydW75k7Q_Bfx%0Jq zfpP9X41MOV*;cS5mjhVK@>!>ooumeZb(B@G8r!1bndZc$1bu&3!&@exD8TT$!q?F* z&yI{V>)l$#zI>up4LJosZ0py}=j>O7ZL+ zv6!n7ciaY>ka%2MoVdljv3NJ)#dF`+0|c}C%sAwKM6I8PY88g3qpYXgyQEOaexh@5 zb&*{?CfNJ3X1k_?Q6s@kTls-<>`$7t_PaGTm%R^uJpih}SGyUh$+Lk@sjILBfowfu z#s?ou%?0|n36wY3ad{SS#}M#m;Kp}glsO3y--U|c1>v|7x%vCg;A^rft+;S$)=C+V z!TiUMna0XgtGf=fm$o6*ewACd;uQ?0_u0HCF4q(%^NTUM4?cbQe%iy{nuiX=R&Ybl zU(_)^$H^HlcGo@R@~P3g=&8)*!us$)>>Gud{gq10%4za^%Ul=rJTsqn^uIzsYqn_# z_7bY;3INL;`CXR@wgehcX9f#-b`sxsR+7s@I87)WHyg~@_5?&bswj#C2>C`l(ZI!S z=2UrCXMaAduOjDQq>`#h*0}yP^#fK1yZ=1?txHS8$C9A%TXF|Rvu$j>O{`NPGi@t@ zoYO3a`q@W6?-EJDtUk6?iDe@C+M{;WRM&|S)3mKVD~*0f3?rFt@DDqrMK$%x(l>^0 za`o!_DpPxfU7GJ#DrR9?*zRZjOO#GUM{1ptTAcLIU37)5QrsDb>^RQ9GbZd0^f|HC zSFECSP>(R%BY0%6BD)Cw$U>K6N@Ro%1R7g{`)8h6+i0MPEx|ge3l{SEx|9G)U9mp@ z-@Vmb883z6UF>@x8(4s(LoHv$2dX$8u$nL(v$i-<=)e!)N0WL5uAD3_IIY}jWo*QKBr`s(o{{z#wjz%B>mZ|A28;Dz?Ej z)4|@xX3G2hwlPK2vtE1O#|V9yW8|&(ob{v1AdU|;(Eok&G7F+Ti@Zc?1l5UbKTz%r691wJkI8)Z-(2Rdj_i(3V^eM7+D`CS8Wigw zC6^?X=C&JtpLADn!=RdJBY{l)n5CvKh6O=6=(^`-zHA#Qe-|*lhO>Tvm)5)$9ULvJ zVa2^Ixa6=tXQUgI#wsIUt^`e-jDOEDIc6TvA8z>caK*c%vTyzpnQjxO^MG@hRGz0x zDLir8$2c<6)fTEVz>X>7A1BlrNcBBcq{Er4@(t7>fZc~q){ySAe4mxP{XAItJN3_W zW62%Wyq@8OE>g6fQQ)dm>rK@%Ci!GD<^r;7D$m7{3cm!eMgFjC?MZ&FM$XWVe~*9f z$Fk}+9<8|e1Qeeu{Sz=Aw$waTVS{_6-dOJUR7#3NkhO|+Ft+=^2E(h{cf!@yf5tL z*HC{pDuqYR^$P>9d<#^MU7`(w*#`VQPp9VS6(L(0Wo3e?IFdd~;bbV2N}sJyaoLTq zNVWQ|XyO{s4L#V2EoOK7i>JZ!Xfxydlshfv)bl=ZKupP(`q;S6OVfleThYuv^Z-S(g6*TvsB`pDE10e=M_l%>75h>m+hVSMVMB!Qs6-AP^{ zHfaTZd%)IpS$$fNfVk`SWYck&W@=+ z@358e=a>t5*@D>HOhR0&CG+*SU9Zc%{Dd^kSM={f{Qr%WEF%0cFhXu`*%48O_+Vc~ zcDP)yKE%_BBN*_neAkUu@wr3+U>+oOKU|WZ7(U5G)&wdSPRP$yJbx7!xN4_y9c@rC z()HSn1`Xv#&+FdiGPLl^*d2WEIFMhn0>d%IzU1t9a7XX=j=XC`jQ;iQXfTf41AR{n zeS_Edk}N&QHqXUh3av}CPT8{NSb-olzMjiGzSHQ?CjOiT^^QwTB;+ae7dC9=3Uov*03L-H|U^S9Bt*iBct&u@FGuUYw|1$rx@bt3aR=^Hf_&@|pB?<7KMjX-B|-T^2%aUYHVFOP+9<_m+~4LcCSQXNQN_dUd{YcQ>+oZGUNgWIMF( z0244Yz4@9!PN4)^7LX*MkspC%b2OW6NpB*HS9filu@ZK)-d5ExKggX=ZD&~y0 zwif-D&hASt0kb6-#3ePxow8`5psuKx03Szr?N*{LAmAi06mL&u9MW9COEd zMP2v3{)Mf!HJ@xyYwhbh=>e5yh2hS4cVLQn;+(PSkX0Jr-aQPVB$6N15!Kqe8kYDf z>v@Zhyn?JNTw8EVt3Ur;n1@7_$GASuMH)Ki@{m6Ogmax?4k=PH1>jF;9jp-OQs?Qa zhxiLN5Mb}5_~nsf!sNgYSE~^2N7tm2soN3cOT47A!)_f zGMb3=c``gXDV&WWXN>5p1#U4cKwO|e?WMCKGAerw-u~zCuqGXc;ECitxCBfRm9*_R zQ7=Y{Y;An}SFyEGQKI+(6q|bvx`=e_I5OPNpb#I)vzVn?HHhF20j$6HU6{AHN<40O z06Jm&2gf}f(H4vzm3puEoQB~qb>hE~Pn?2l_Z~>kCAEseq$j&^&ADIbaXA>ciLWA% zHX|w}bho3Q|8J{kvW7)Q+cd*473Iq}B9*Ia*>rfT*3p{avdNP)astH!gh!kXN~9Xz z?*mkY-jBSeq>Qkpu)rY4E+nz>O{w4*^gqb{icp{YHFmN93BtvoHZ&KfkKO41HwKnb zehcKP^t}yJek*B7hmu1$ODFg$F<`168-GqFGlI26wR~H}--hL%fX$d)il~}qy(fJ* ztH|L#z$ue-k%gcKH{X)dX##tU73*tCjiSY`M_DCW63*%LFxe9}5Z$%-=!`)49Emjy z{lb3;{s36tLYZSvX{V$0W$*O8 zC~PBw`1(*xAhE=RUrn@kq@|@xZD;@b7o7#VFWc2(22G{iD!7{aJ>Zk+>MF(6$vKHb zX$b}6zBmzYkg0RI@cEU>X~2X@^C|n@9@yu&L`Lt_rc2hLjyyjo5jqLNwij^G@|) z`(t-AU^i}vgy;A%FH@%Nf2++J;g$FPG#At4c>a?fXLQLs^L@Ws1f5+iSebG|l1`vT zh)&spv6E);7dz=rCE?~DTBB5;1t+!NHI4t?K=u@1cAOYHQm2N$9_jRbJiYL1Ff9nE zu?ak7`fv{jgE_Eu(c{N-E90t%&kOA5Gx#4IY&BznIWbSs={iS`;a1O=#2q=qYW$Nx z>dcwCy`EwmZWyOulAkf%=o4p7+G4zJ58*a%l9NlBt(ZL3D4;J(Sfgs_CcwGNz3Q58#r`ovIEl11i+`r zl$j$^22s1LY9STC!sh>w)F|Dnjx>kuYZt2{OE(N7%VrzrrN(?Opxq?08mAyBF!yX(VaPcr^rt;ss$W$%xr(s|eYziJ_{0oIA5 z;;U5*`(GV)?pv&-=Cij-$NgVT+lpyGy4sh70OxcN2D-xjCFq`K#p{KKC3d#-B)(IRF9 zham#=MuSkUu1U>ZxrL}Eq8#luZ|feunrBLam|H7*v7{qQ3Oq6oH3+T_a}SjXT*D)V5VdISw;-dcDG*lhwp8 z!K1pdrNI;QWe`f-^r;R@FM;l4p$AT#utiyWDwl`f+1pr`xmH!rQog4xlpp_3q7^d% z8y|{F@mIKcwg{IGy>O*J;Pe&#w~eqxey$5jzN{@iANq%(#x;vQ^XyJrfo^U88qEKo zR`w|d_tXY33R0og-!Hj-{xWg@$3u{i zuoq{U;Uskd!2bVb2=@(yyhpk_gPeXchDwm(!t$PcWH0PL@K3d&#WN{^SuQzW)*`%Z z5#ECCD4V%<7&tkGW{%wvu@L`fDWbHqR#e{_+G*0F63!3X2*qN3N=M8#P*B&d(?z&E zbiO3|_UO`aB%6*aCNv=iRbWaGqWC7aMBp4^oXmX6rMdUnJ|!2y*O1HbA6+dVPFKp+ z>M6!`+uzll61Z9;oD;$Ipkj~Ystt}qJm~TgquB?+&9^f)9C9F@Ye@IWKvmYSSc$diyJw=LfhiB@Z} zYkIjl#LAo64yBMB`F{<=`~Sw!b807wh;HIMWViPNd&6d-49GlOcFSF!i+a}y?Ej4* z<27_g$E=ZG|Gocc+xw~c=Xqv(A@(CAiR}=4jM`ZL!evd7cf`pE8oOp%tL?uR$nu&WMBR;5q;ScS8d|kuPxjLVtK_Bkm6_E{1niV{CjRB0Eh`3 zsx#`yn%`q4(EX#9)JCAYEQB~|>;KIgi1N240~o7?te}!m3Y_>%xAw-gD>9(H=Rf-8=TFMg J<&s80{|DSKMvDLd literal 0 HcmV?d00001 diff --git a/.agents/skills/swiftui-expert-skill/assets/logo.png b/.agents/skills/swiftui-expert-skill/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7af7d764198eff72132f6da95e6ac213898cb288 GIT binary patch literal 398841 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

X+eLxg@4{pWELqPicvGhqFbpaoRt6o;kF*m9 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π@Pl!qoCc{Q<554nDkpIz(~QVPrs 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 j; z&rA-~B#i^hA~37ODhBF1fTKEBLBe2cl}(|651H1w?#(m5B~1+OMPxek+5l`fW<0## z#z1bo=M3>N6j~fhGr4mAv=(QpgTuLsnvX0jvr`vd`5$^b5c%;pe}CE`Rf#xB*})0X z@%>^>OTMKCW+!}C=E>Zm-Cxb0cU!i|6EJ739NvJzNTV$$DDR`!cxo5WWxN@9*#=ZA zl;WSS8tAraUiggivI3L%qFK?$cuga+e75MwM|G57y|5p>`E6SvfI@&b&Yhb7yz2A# z$C)y%1~0{@lgXd7G^4!ctaWcH#UX8 zx?-n?alkxH)U}GS8;b0sE9_tGW3x_iq_HyCjxIjI(slh>AkANBUR_#ui|qAfj%a`a zdMA%~J_!r3io9tejK74gPI$PJ?^Vmkk95kNx)oj}9H#%Zk!8vrWf4X?u zZ!&vBJKY|!1lHe;MJ=-~^~6spHlC{Gak9$NHU*35rnSSh#ni{UgZb@ZR0_<+{|fi1 z@y;+5uRbhxQYdO@nrrzc$0f-Lc^esvn5O8lK-7(>LsyNmUG6Ipv#fA}){E*N{K-2ZPTctkx3dWX z?!TI7vTs_gHTkbs_Cd7KKH|Tb&~&fN*!^>5FyDa1;GLUc2C1KA44h62H(Pa?9Q&ei z>T;qS|RI{vo7WnB4S9gZFErFu=EwY#x^54 z;i)N&AV|*no7fDvA@YWpFQAv?(+@Qpfz{o{d)-D$9Yj&dbe0x&#F8N)^;+2Qmuk*j z=EsSimffZ}EmMRRzhxrgN2+I4 z*P20vWf}{4pH}?j&nWvs^7Q+Wz6kJwiqezn;XO=tO00epOz(F%cB_~x-}|tp?$b-M ztdXk$gQHnv0buhB{9QLRrMnR0rwcOLJ!Zdd5EFYHziUq*{# z?@{5R=)v#%!fLoG(hx|9r&q;WF8`s@q^^(exwU;CWQ@1wlL|oL;4Xhp`o0CECw?Gk zpFLkUuT#O;w*WJkw0^;PWO_eL7_(m5DZ}kdj=O**2>~CH-cIhktwyX44f?xMSAV;= zR<8#0+>lEY8&LxSQZ&45tLlIFM=X-D%m#tP3$mMvaCC$hr1R1l*?~{AS@5GrQ%fOx2D62>tALahH7UQ&bFX5JJ1xg^z4mzYb zbi&0(WA-aci)_({%JR1>Qchf;=#ckpnaHp@B)m7JIY`-dHziIPx~G7fK56Z;Rd>Dik8 z!GlAtxrn&Kjw&*3mxJ3+gPl}CWxOY?-AkX--dA!SW zY^duOykMWxm5wZW{_VKunp|7zGNu#022=s?tjelgnzD9++AaWk8pC~u-R5|1MEZ|Z z8%7yh1;BRcz}uZHN|mjGUDPvL`l`P2RZS7+SzBk(HKF%OUVCRQ$O(Rx*}ITQd;{M3 z{E2${J}_$lhS_FWc>hz1f`ac*VB7JTeAUqlcB?z9ZD5d0$ETarFTxq(hdNs>&P#)T zCZCB{PqM5*P#JoJ4u1pCnU%8GQ5xJaM7vTcB<*Do@iV;660i z*gVkxXg>QK-RpcbuxzXX3T_6rQE&;$XDsD^ooNPn3pos)BYc9vBOSQkRw7isRbF_* z$Th+w^h3Jshn?QS{pF$V#R20#(;j%1bF+%kbnVFnzf}hKvU+?46WW8i#T_KrBqtnz z)yS+mVf>JGZW!1x(fn~hgQ{!slWwq!TsxXpHybcMN)Ifgk6zZgvrql5VpN^{^R=1{VXvf=$qUF&)1t!(CVgu6T8`8F5M5`ZH-ijt8vKwBi^F5I;wRJMS zLL7V0eCeRBV;|;3e#E|cIDlL6uf{Ae7OAJy%fMm-bAuc4SbAnZz3TwK*(w}Rs8kg@ zaO0RiIaU&d45W47VG=-jLWSRomF{FJPuqQUt#qF@r-44yEfk?3vY)<1#^^%Rxo$v2 z$vnuz=~HCn8@SGu>!NO9OyKOQgUJ?$r$m1#L__gG{0z7l;B+ z==FP=yfl4aDPCg97UT5T=Blr-ZlcWQTw`by2XSb+->iyotQ- zH*4TEH(%LX+SVYSOe6(yxeJVrk_$CY7KhI=yru>Zo;aIR1rQj2i;n|iYs&tbF3Mux z1|_m8asMITzCZUR0-NOZU?G3b-VmT;*8s-Z0S@~!a?j3Mo-<}Kei&z{K^+?>R{ord zYTq_O_B&fIuXd_sg6t{(gX|GE34P>y-J?VoT@u)rf^lln6r)~0>PF8Fk*;e6>n_3C z#4_T5ej5g%D?F{&D_j3B83K(!gU8!@BywD|uF-!n#2EXdYvliet`S0b*MapUJEHi% z3=qJwu!cuZcTLgcguUzlY5FJ`grqR<;P+L21n2DX0o%5b$KI-V2;EneR#D1!7BUc7 zZ{)=n7JxlTd=4~`mlPLx@n8$2VD92u4Xm)+vLQ_>p3ie9>_dEowquAskR?gt?ZP$i zZp2A4>HO&tw7xMRZLBKX+Q+)Y7b%Q(^~F+n!Qa@pzKNT4>4f-`yT3*gRl~JSEpF!r zgMp24B8Y(X=%uFmlh+PQr*h$4n0=o$##xqC6KEWXVHwQqBMG19#p`uK2)CL7QbF?b z7qAeBfP+YzHY9*e$M%)(K09poM``o@*8F=Da0ZKM!!@Qzcaxi2JUH=scpk`t^lmxR zDh~0!a1)Va7ov04`QZW_mD{AX8-%ijC4i3I5g)upEH}YHd3p8fXUQ6E&i4_XV3_YE z?Y*{48YX$5!0qNAp(kLBpt(!Y_Ct(iW9h&!IWxF69q?f7M${M7`@)!pCG2+o-FN99 zU3>r8yqDc*>aA!__gR&HHtqOxR=|G<@fc2x+CduR@}1u&`A?r1ZdNj39O0UX5o!~o zhyinklHfY7(6&&43IqYR<>qPS0;Ysxs+-C7D?*N9@L4!5nI#EKR?@xY7T3kD>JXk63qy#P%Vp661}%2w{)Bj%(+vTkkGIuf);1 zb822Ina<{;20N-R4Gp4+gL`d9q%m&KbbR-}el^(f_*GFM3|~k>oiGk12>G9OOl-G= z7AE6Q+FD~;t^X(~l3MF;kxW8gyQk1*R$U$%UomL#R)~_}IQ}Wl=r{~fYL}4a<3Shk zDny=D+N_DLyeSxYpAI|ziM%SdjuWsH*M_H~h& zYqnfRC`&n{C*wJ8%R>QfbjRmOIIULOUqXLv4wx*@RsKI{;5Srs)>I&TLcWShfrIM3 zL)D_fBdBe;9yJGJQrz~v`9H@@VZM8TkXwVlYK+D{}qO=VnWy;;Tz|qczHoWsB?5eS9pf@;x!P;Wnc~m1K2zTK68l=s_>jT& zNP8dqlV8q9PlGxicP62f{5F*(*GJh^^Ms^-HDt@*7!*29>v57c7u}CqbNb~*+LTQ6 zTZeykgw?u<_Iz=OJH>*kHofbZvvEEvUe`l1H%>k2M#Tdt_(};m$|$gG7I_$Ezfk(u zz#=6L|eaPooOa)2$Va)*+s_gko*A%~*2(_lf<^~O~xW=^v^}|Ra`QJ4- z5}3-trID?Q$NX^I#?l6R>&`hL)y?-*)k`?AI^5A!zla28#=e3bmoloZO|{oIjrCeY z$IXI8NZObsbWr@rNE%BU#Cr3+v#svoxRsg^fmh1SGO#|Q((jk{x zIqS6B=tfmo5zv*+lK(qoDMDz(KR`OBPSM=?fBO&?UGK*EvO^>-eD4jH9}v6ReXDr) z;?%FubH3-MjD>C5RbbqG&qn=uGK}E9#sjwcDjVa9rN)`0FBr6@5IYrY=~wvUTpZI; z$_d?lpirAO@ImF-B%U-p7?grN`Q5^n?3%m<^WIrhytjFahaHH&AUt^XQ!-r*XaQN8bii z?GkWPQl|`G=q_BnS=P-#Llos31m+5u({00a8})I3Y_v+i>B$$lOH3Z_u35{t9;s81 zKf=B-6~g3uXvS>DJzWx^T80!5r{uUE^h%-SW*yIm4m3|jqaW+-e4Wa9NvQ%xX)>FR{84IJNTYt{=IhW zNX!%KMJ-0et!`lceN)-1;X5D3?*xe^Xw~SmYI!p{EFo6UCXY-HM88PX@L4Q3Rm+4noNc)CyD_+| zj`Ho~Qz`QhE3iGxQmoJS0osz{CU_uIdTR%9Z0{!+{$s^&`3V(qTa->Sm_>u-R&j~z zy=g)DE{u7b<%b2M6Pp>!&b8A4OZ7>31!o?jvP$ph`{T~KGk0e0a*^da=Xv&d`m@Vt@BO&J{)9=V8nu5@*yk#; zo-wJ!8_2U6`L?;D|IbexRUr`c0kh%vBjjY&jN=(aoOdvoE(k6$$~M59t2C@!EoztgOB*0 z9&Z&!65$8(B#}o<@7VHYOryOxkibGzd_9NkhDXK6@vXiM*jGTYgsWZr$NC5REyg|U z@XbSjYa!+1wA203A5=c!CR|Cji+XL$5!aEBI1>)x1B0B?rKRqBnH+2`Z)wTi?`^0N)I4YWi9o4lHtp~cbmK3$ulV+HeJfbzQ082-#phYrUb(b0V%8xtMlN|0C9k&<^NcC-^h1ANrQ>&byW}kXK1IT%?Yua#$rI$ zTrcGy$XQqdpm@kw3zDAzA6xdLBZI??#UQx<_zZxM_CKqK^#e|aKOejWD*oUYpo;IB z|Ndv7o$udmlU+M@zN z6Wv1ZvDOkU|GY~0pI86c(Exx+n25@+r=kWGRV^WtQ*>`{qCLD(kbO`l$@JMBS#s)Y zPv0&!J_tMCp~Az&-k##%P74IXSmo80cYvz3#3FiCMS9VrT&TxkL_Tk8C!k0vIiRt+ zo+<->RDMks3hOjs6xl1Kac1jTkHHx~?o2sk?Ag#5 zp<|*FpanZ4>#ZDQKQmiFMteiL`2*Tq^G(FqVQ6|thPSDvgS$-BlYkzG=b3$WN6}E- z%?MtPjU#_Nwx-Vg-25IVt@Pb{ustv#@q!HJw^8i3ue)$8XQ>=>Q_p~K7v&QnKCs+jY&$WkfQM~_lCJC*={%Pn;GTVJR_QiY@9Sa=QQBY@@ zC0?)C;B%RO2(`U!jpWf$e9>+xIuR;VKI%YopgZ7D>!=sARR7;zdzbyg8-U5*HPi4< z_ubw0X2Xie@MeHOcOU}6K;3;z`Q(&ci0d2^i2-;M0fseGh0vS5N!_K=BLT7E-zM#xszI@DO+;G~_lb-Y0Mt=CE|FEz;WM}H6 zYexYci&vy-$Ex7ZYtf`hh7#dUNr&S0jNfxVbnzYJW@e4z`Sfk3F<5Y3#y)`KmnjW3 zlD&%}n_d}eq{_nh9GjimsuWJ$kRA45WsgeowxDA@&2Xq%fr&5cC~_u7^U>yV_mj^f z)!W5-SAwo~{cIEnd2HO`65O6Ae0fYXi24)8Z zHI+aD#&f#2elF0?k+t_aPDks`bZiszH(h8_JX zw&P8ACLNZE6%e*xVByfG}TM?C8Fza)&vO{g2peBBdAF*#?uyQ1{#AY%>*wX=h+3h zIGGwM&_}m9Xd-Icw|6?MCH$1cUq7J*T_rqY((~DacgYFeljQthzkDKh*t3*L*02YxxeK~}!&EQe4`=i2I62oGRpFyv z%1E5Jb)Uo+EZvqMx$w@loPn$>C&=ZvqDhQO( zA&vmqfyt1w%13buTct$ZTG2lmA-_}l;Ev0;iLspCbX(>1;>Z9OV zL@Ph_twJEsDZm~0yFuk+7%Ex|SaV?3aoTK?>^s7v$?hIvhLK&<_qbhD_ReYGqy;7K zE#K4;3raSTt2bez8(G?Bo1ncxBp80%cB8CD-fZoyA8Oxc7M{NVA(^%WtzjMzd@P;B z?pY5`0QSh+6G_dX!?YrT_C!<N02>P?r4HurqCmsQxZ#?a8Ow7JAuvC>R}6t_>G zZV+hqByu8DVk4u(N5I6q-yrxLO+qQGY=3|_^y`$%(n}a;@J__BC#^5UErL=PB?BEy zCJwZ-w3fca*qk93G(Cv;=Dt_UrCs?m|&B zzU0t9bU`?a4&y|4lg|4?3IauI7u zw+?nFM_V)G>CkqX2c-;;8l(k>wtzDY7oLXx4zL7LrZI$Va1w!`jWFAmVruzLi#@V@ z-PPTag$1l;Ey2p9nhu1j2%7NR$C zX{QC2^yjSj3GN)HzFGI|N) zcU(0a(959U0zdSw>xyR1M6y^S{ixvnANF${5d5s-u#yKgVdGLoV1gPCC-dL1XdG2G z{0J8|ua;3DO&*i`WRCX)?)&HM`bDUv3i`Xkt%-Zubs>*!=@O(ziLe#L{4y%avU}1m z2njP4bM({~(9*7Gm*kC|Wf%oBuD~;_06neodA(b?2j$#6A%cNXL8jKb0i*v@wz1I6Ra0KOa&H0qa`>iOTDxQ4}>zfR1FoDJ>Ci88si` z^v;;`!IchttJ{8{q81S86f0Ptd!agAVklUBSAkve)352#cK;+}N@{Z(8WL{X`nii$ zAZHXMc4pY6NX^wmoJ*eQFh)+UY+X_wpA373HOLR?ou2UmOs}3i)p;6AKAXR}JcNf6 z@(ZyhKV(kQj-4NQPvUATa8s1c(Rte_R(Dtq1s95W-XkrLeCm0|@en3S{g7bo-nT13 zAxav7ltw^OK}OsBsaWI9G5Q8p7|;HE{RB4xFQ~^ zJ_3*Bc&+$IJAC+k;Ax?QDl97NFAR^#l|$y=8B<kNKH1aNR#@cUd!v)^^$r1otfH}67A3khv=z8&$hIXpSyCP`Bdm8 z)3L5zj(6(E6%PGVC97*HLH7D0$xU=n7HMMgXyD164d!sk%@vBGS{`om4R`GOvNrxQ zgF3gl&gV01NtchR4lS7F?=ttMDmsdq;csg{LS|9J&qnDOx8Rb70(Vv{09kR#AE^{3 zGrhTJ$A78}f1gykRnWwUzoEX!f3%0I!RUxK6W=*)Es3SB9Zl^@U8O;lz#l3ryM|4v zJWY;fx7!}2Kfn)bho9nSkH2we>Sy;VzlDVFL%yHC$RW>!6SXt(kWSW{Ldp_4c>N|m zu7fHO!T}n2hf^@fr~3IJ*LBl$>tx$Fm?As!aqWLo5#7?NGPfJpq2HyZ5N`yBA_NV4 zWX24W?q*JKD7yRzf2v<7LP-sc#Iq)Fv0S4dpvLom^3Cb_f#HW;mRR-0-UvoUkcp@; zHJ9L2wxc|RT%9w}Lq8vaCmi+V@zr12T(>VB52&yjaEW+WeEjc~bpO}te zB&NqB_#au8r)Xyv0eZLcgQFkq%vBtJ)jWyz%LJ?xhMCX)j#B=c_iLDr;fzYpGG0Ah zktv}SGx0|Jl6rwgwZjU3G4aISFGST9%|J!90ih9~^cDCgQKg07$Ivkor+M`DA;hL8 z#kn?(LyvLjb>$!L%D|R&6w(qGKNBRRl97!YwssShyo^&F#ckb)n# zq4H=wCU-!#{M$@DF}DmVax6H^r1^(LpE(U%bdQcAY05csuhU)eR_%h&-828RZ&$03 zpyWn~B=5_xYKcCVDy3t0McJykcd6;riVnF2`=smnO%sv0mZS#lCpVWVx}>A_i#U$;hp@HAtj<+S^0itQf*iyx&HI)S?B~)hUS`eFxst(mv!k7s0(t<-X{E2*V9OR~u?ysAjS zB}#m}e5cO~X1ts2Y+P{$+kSC-@*VU$Q_qBd>j5c$MgaYLQ6jPDp#qF&vXM5wH`D~K zI)_V5jdT@~S0=~@H<|l7_=^k7@6xV>j3sSIV`o1GZUkLpDVT~WKv~W8CJ~Bx*(G0qxevd^{NLprHSi<8Ai#e zs-acA_nMPcK^noE%*{m#uu)Y6)XnI^+1s`h*7hoYRvu#p?LYoo4uaPsas7W?` zXXbGXPJdsvsnu3&?Dl9;^N^6y<*|lZ(r<9$pKq#kAvr$6r_F zcW>%{q`S~Zb+*RG!UW^P&c7%R0CzgS=jnhYtL8KpF$1?at>I_DV~8h^^QGj-Sbvmr zmUgnrua@b)*XfTE$Hx?$1Df!F43DQNJyF$$XZP63`>2l}nu8}$qls_s+Jr06+i%ai zYM*gLMP*C7V(cy8|>k zz8K*j=qz>yCitv_oQneQMbFM=Da$m>Wn8Gl0Rv-&`$I!};nxr%*QJG$i2e?pej$G4 z4DjE!L`)>acVqf&C&hFc%}>-C90}Ul#s$8E8 zH6jDVWOI9b)C_P`Eeo}y^J3W#crz=14Am#_NK zFHU*!}IASX+aJGbf^0N_8se-zyL5XtndPCn{q6oW@RyBnY zM!5OLtLWc>w2}DcGEi2RI8lIv<8cxULr3dd8J84fwr$5Vrt|!PTi0xoN>8FM8wqDHzlNa;DUS~_-9nDk^*%|2Mdz3K2U~0TiN+oX1+#61O6!pwO zzdopWz`VKrlB@JCA3uu{Lo6~mb1bpXCF_W!jtpV!O`M*@^FG-p=(#^{l3(N+wnQDz z5U4)~cji^vxgloQ^D0aJ$nur9Cmel^29UC{Y+1=kE_G%9}YXeJCoIc&(C}nlg+66PZ9_3UWOa=^UiN~d)0|y zoj*5|Nz*+oKXP~*mXg1@Z7$!uqhY4%!*O0!_L%{rL)>{eMm;r|Ti5#dfQPVr>-2Qr z4UId8!-nw}?1g_t9dwc-eJhq@YRD+_;+)bk*0G3p7a+#ki->3mT zxKz{}Tpdu0OR>Jc;hi{^EVgob$Y~d3@;?_Ckl;SYM_EE6XKM_|(1{1N);_ysyG>i3 zoYQN^GOEsMJyh>)p+aK$RSFqIqaU_eP{q%xg&@x6n9i6NL@NBSi97wQ>;gp()Uj_E zIv=)ItU0fB*;0&RoWK9WVbF)|Sepy&_1*X!3-c~fDECd>`(~!xR{jebu9vce_r9mO7vsTyY7{e4eYoP2lYSdQiX%s6aYM>)>@ zuKN9-&eshZjnnRu;PRq9W^`2T8x$W{OdwTAuQdJg?s8#-jQd@=qPC)cXn{fwr)wd2 zuHcjkw^0zjL}HxG1*Ixn`npy^#&UVUKdiK0+}Do zv~{etq<=s4B%hSw<(6^oS3-nJkSJS}PxzBmqkQ`PDK&XGuLI48 z`itl&sitYpvA0rlvCix?=e47A5q?yRUT5MhX8;$>hGB|Y8hBxLj$pkLRH$| zg-qhl+bfHpQ&5B$7dK6DjBYRnyNTmD9A^v2Bw;XQ7a@eAJRGAD-#y=wG))TFp8yID zE1W->PerB(eY!^FYNu5ippnzabz-pIGuW=yiXFTg+=j6h0C75q#F#XGgH(VdW-Kbz zZ3Q&v1ZpB+gN=*?2OLBW)MNLf_Iu6A*cW&A=yT*hkAiwj_w9%>;)!JO12O=|G<*%h z@}1z8R^gi)M2>C&LK^K}*)eIHOat>M;O@M+kNE}M+PKrC4YS)L?*b(PmhPX1hx+AikhLYlKEU=3u%eY5#=-#X8AGX`=89nhi|{W zv%SBS+al3UxnMstXnmdQTjSfX$crwmuQk^mK*H6{X$~}`)}Y8MO?RH05x}3Zov^aT zd^z}5V9&mG5smj&EP6aBNtj*Z?fPx<3Vof_zbz{BmzSdijC(@Ig1qh??(DONol*1s z&y@_kb(Xu>2g-*Q+4&00cX^!tN<3<`=yj^%)p|%ny2BJBkFkzrmXpZBl`k5<_>hX} zK6Fbu7RG|($T5c`nxn1|HWy6K#nak-F|kXagwxUw7kJBdi#erk+m7tu1um>VGD;vS?>(z|8}{uXl=3jRwk5 z3^IzL)gPCc`1r$AJGbw58P3tX8*KdXDJ?cn&|kG&$V_3g#)3u66VH1Be&_m~L<`pZ zxWA$`JvhBpNb*rI9j@Ai^gp;_$}kC!ymw=~hU#$ViD}=~6OSYSuo=*#gwn zR7+Q#F3Emu3pTzZ{bBRI6AqliD!+Cf!y?ao~Ah=h(Fjy_jTIvO?{7lMguMM3lFrQi~(!aP(u4Lb+RdcMg=mh`a6qPb#OC zXAS`2GzG@l@Oxg6WBX1<3ShjBZ#3pF5_$XCx$R6oqKX?zvk~V;TX~zel%}|63>~1D|hiwp)}!eye$E;G@zzbA7rCzOL7Aal67; z^m-tHb5A~I<~&s^09zlY?szY#>V37va6nY0^q7WvG<;o8vmuBCFTa%uJT6xUo^_eL z*Hr&=HmFOHynX9bJTH5HnkcG`-{)C2NP<>A(zK2ml^qrL2eu#2Wp$?ZOYdB;UEbF0 z%E`dc$}wN2;p5sQM*Ar|?$8MX?chTKQEsvx{3Ur%d{=njAlO+L3>KX>oi_v!8X z3-e1uf9X@L^Nr0bPt-349RKgtY&D#V15+>iq{1xEEjbf|dsAC!zG@l!^qR#fEoM}0wHN&CvMGbmf^9e^KG za_yj`{3vw6ns9#wK9{b714{;XQs3-@r0LKH)k{ra$?|)U_YNRw;EmVlXB>&%3^)Lr z+$`(`VHr$%A&UAbfO#m3H!tH4pUGkjn+vj2kHzGVOcytAhJh<;lS*+m-NI=kRA!xq6!xc_EPq(YI^d#p`FV{F^=U*^7aU-aG z7R(a#tJ_xJ3xK6mphOpRH+A0{B;rdiFTTmYyjZBFzGl5Fd)K`4KYSiEADv%S;0Q7a zF>x8p2`)AankzI6!oM}9oe1t3v`|V`6E$ApOb;oEuGvLdAEEu$6&H{gPTeV(mNQ2L zf`7p|Lt)XNGSHH1kvqnm8Yv~=b-I*JwEXd3(9{w$nl)36<35c4-FqDNbkU@7^T5 zp4y(GQ@xw)s;s3Rc#+`6RtJh3O@0m>ZVE@53gnPQodgYf48nd6i$5?z@79=|SqdbF z{)^IRc_T0fW$MsriWlQZNJiaE%A1{wU~vwY!{)-q-)r+~#y{Nvt$o~9p{)dk{obT2 zp@NAB?^21{x6sjQ^U?RuO?xb83?2Qnt#_uzV1{181W-z};V(Q-_(U5)gZhsvg!(`W zppGS*XYZkwhO3xC#v(x)mPTXs>PdzSB{qTv3@Q?bun2xbPojhO8~P$zRFQ{PXs|6l9Mi>?@z(! z6I}X|%kcT%^qPq1qlqw(1u1?s1@{Lw4If-{@UGVMIT&%lPh9IOIhAk8F zX1Y=@ugQxw2+eaCu;N5)7|yV%kpzf6!icfJknSx(i&8l4>#!Vk#Vn#y&?FRup|APntqo%pa{74IrQ-V02q%)DuEr=)Iqd zx*b{w2?4FY@8`^M5^Ggp^1z~X)CEjRH}T4k&g6DE z_o02MmoX=I!6E6|i9FoM^>z10()mu5!chd!@7|TQCFxjpb_d>ocsdpwA20S)=$U^6 z>`pDC1%82RmtB+7Q?oO-78n7Rqt$_{GNBv3zL#p&Q8KrO^Vi`kCt6leB z&45X=eSz^q^^xK*#(1zyj|%rF&lQe-DWT@}m(q7_4`3}hf_OSIKVK{G>dl+qrUBD8 z1<+;yrnfNbp%T%NS1?4}Z6O#fLiiTi;zTky6deMYzJ%g}+F;?Em)F=CKVGJ4w|%RN zIvVL_o?TyOgOEhVJX_C==SRI&yFbD#wZj*OIZ-6L+l7$E5 zeA|YtU%*MNEJ;-ng%$V1t=!ZTld=wAAeuKyU3Z~)9hW_d=Z}!3_TKI(m3|i?K2{!p z83NRR@!|+-b~E-BrO9u%Ik9WjROo!DF#O;;8KV3@`yabjpfR+4_#)*Nll#`DzYVfi(A_$!WUF5w^mExUan^;dV)^Zdt4zi}_6m1cVX>ePFik)kiYS}F+{ z>JNOU%>M7Re)%V@C-;R=K5v|3|C}ZwgE1;TaiuYL;Q@M7}jhJkudhfx^ zsx$>8KcXXC*^hOx!C*x2n^1c7mXXH1ZokmXh+fdL;uR^3QG>ba_M+d9Bq85N-dPXS z3aLL%-te<(@o>}pd5X1(dSK=5T4*o`=y}u#DMv zNm+(Ps8d|_HF<1}viL$gvwdiC49^W0u(pP)vV*p?<{M_WCH5Zwq#}jKN>|(#GhTE> zeO78MPTU%BayKl?`2YH#4N>;2nHZfWv~z>mtdCE=>j{rMb;Gbluhv5<3*O=Eq3|vo z*h$@b8=frIRR-cfI-DcADm>QUJ9kOIi(^4ihV(O9$=syb?zKICM%|5s=1P`{ntss2 z&;ZPtY;aUA2E9K^nk`nC&EIZ_bpWM)Ty~_DPR1zR`atgT2SW3~1D;K%h0R+tkJEU) zRYVb&7bn)E%Pu@j<(X=za_9E8*fBPs81q5DED- zF0Cf90ak6E4X)Oq&F9E$34v20XD9)3bM$&671{4hS9;_%(hnvkA?iUpH) zz(?Rt`R{rZ{+1Q{_w_j38pusX;ZYUl`ip|zn30A@i{)qB&3YV24r8*pTby+SPf%xS zee8Opoj7Md6?q8*2C zQp%C?v7jo`yDPOithr_L++@;E(myt7OP4VioQ;{4Ny+1*-(Rni22ha+HSp9Lkt!m{!WgMP|LM^AI0A0Z~a_0uNB z``&P;BLlgPvTqqDK@IATfC{8yPznb*W^yjQVD)gK8A9pW-7B^$9(q01HaK`={yqND z%2tb$U-5 zo{sJTrZz>(M*%9Qa``8;HH~ZmtOq7ogZf0YIBEL(<$MJh5PoJJdSePf?Ai{g)5mcHwL;#+w?YNT@@L~BHCc#Yz%i4KT+{uTxj$5!71?b`>i+HEvq z^M6H-m4@|TWqYNt+&a4`$j-gEzp{t>*e$$dfDc3vj~xxoJ_~ICm2!!5g}rpkfM_>F zZUUI!)h%!*8lfp0s;eaG^VP>52PH%5G)EPoW?&qpM3ZGsFjmxw={s-%sOx%pgS_VU zIe*QcvKsCGN{u@kC?C454sQVJ7b{-{eNac>U@xybEdNX@+pq$?#O3_pBX+ZC(uD_^ zaZibdW=liwIGAvC-(ShVP=@H}i-{_|NyD3(*t7qZPdB=5P@>a3jaIyV6s>6>#`~PXa3@q zp2PC5q(MP}_Dw75l0V});P=~w`=Ie?^5N)~f%npOv!y$r1i!>6YW$%L_BQHsmGZwb z_X;J{4XTxI=hKk)#l2F&#s{_N$?QZYXs#Uf`3i~6zf88CI)MOt3uXzW zmVKL2T7ohmQ^4P?d+lK3(c4QM&>*)O@--qyX=KtYwvc~qA=!gXG>XjAD#xBR4rJYTiOOif6`cJbz<@`+(lzp7m{+|Bc zaPwEvae^E}dNu90>3VORz_;GnpA7vxFc$n9{}TZJZttQ@!2g}i_Nf5qTY}zFxAB~| z=VyY+9G9MCxqv7%9i_ivR|BFPrX*J)w4NGR@70{`JGW2?>IT0{aXy&P0S(i`5n$Li z-*xs{hK$+pmtDxDD_(H-#7Ys$U2npq4%dSvW#C|2#f(ICXFn77cm38tU2w&fRfqg( zq&)3agO)X;46BJvav;Hn-)De+83*ck$*-F&xWBZduesA6I_q5^4Gmms$y_~Z(i*sX zEUJ{DcMQY}fMI(1+KHSfv=uoH#LukNZw1ho#=#?`d6wY?S~sPZj=&;oXtF!&!Rr%n zvie^;v>nYBAeXgH(VM)0W@{vbGyW6PGrK9bT1M$@YrG{5XqNY_LlP(8#1RYy)rbsO z^8!!-Z2#c5iOp1XAb`AG7P@voBbvSst7D;e-JoRtiTkB+GoHC9B&iIE&)J{Y9=ndo z+OPDd%?hfI*;fXL_Spp0X=H#rxZAFLeVHyr8FFybPcMQ3#=l%@te@FMZMlVc=Ip06 z|5kBZoLYZerrm=aFJEY2UqtU8uoSRQUj03dQ{xXpL9WB$mp^w8l2UkZzhA<9PWhJy z4(bCzI2p2Se!vvim0go3zHsv+fgcMyk5Q37`@N~ zP9~s!spQ`sc9dx;55PX8ArH6?;9UW%)DA*;h$DqP} z*28F>8D3>145L~wY?(J}1W=PVApDGpfDrDlVN?!U1=b7(Yxr6})=Kb5>x z08S(F<2F<(Tn;if7w#A?hx|boE-TS{l1%hE6YFRK=jW#MEAMpwbxtw+1A<{-;{mKpq+(gD}OhT82X$!gUK8Tj;r z@1>^@*}-KQgHrO$X-W$nw*WbJeH~0mh}wXP3}pYUsmNmA>hC;I5YS@*e;OmeH9zYU zKOy7u$U${PMILf|K;^%-$paKrH}RK8j&U2V#@teAhIwZ1%gkYgHP*uxp>Nba=vG99 z%bA7k$rphA3k7>E$EBU0Sroe~d_4#s;B`2>W@RTfbWYLN@Mk1AA+rCc#SGYWCY}d( zYCjdaD)mq|MPgIH0vvE{a2igqBZrJFZ^5{;HA#)h=Y%5K4L|JyD0yA2XMv);2TYZ95!9wl=ajw*{A!FCUF||=Hfel z01TxQyPjs*ygrJWhL=+CbPTm*8h)T5cW4HDc^$!QBa^`Xb|cY3nlAlvN@3L~1--)Y znlG0tQHY|Yvti(ZXfQ6!=knv4_%_b?_4}p5JtisMcR5ZFW-8~AOB&YIX#bd!QMkq5 zD0;l}7etBmy6fQ&ySCLGI_IETu336HyAXU_aFyeN=}wLlTb_c#!|$sP`apouQ2`Yv z2<(li#z!vov9Be9C)5vrP<`Q}a5>d^;9K7=8h;>|&8~9od{mujv9ncny`jn$3QB#^ zc)i*q_kM>R1`V}UH!p%tV$@sL#4qle94P*OBbK?}WAr!Z>K+i0o2+lcRy0Y=7Z;T< zrU$CwZ81b>#Ps#{itHMjR&z{7Y>UD)fXaY!?7Z@0YDWtH-EIr{RLp!~v(nK~=Jf_U zCd}qIj2bEaHeTZB9EN)TV%4u;yLQsfJuY)TcnjzIK zW&<9O>z}H;Zy*9&APMLPAn5VyNBTJV&bN-c56DQX4&fIz4g}oG56&VFrT{C@noAGO z(~=39g73Dxel?qRGwo-Tvmwstp@;9ryLol6F{Ma;dnV8+q6M^jKwzs`3a7t#?*x#5 ztJ^u+%~GjQuY_q8&99S{WitC%_w`jM0pX-sq4EhJX8H&e(CbSTsFiy-K_qX))e zh)so_VqnWNFJdioNG z%jCr(pi^+utb$vh-yysS(u5tjJ07;hm?BxnoGzq6)jwaX#8U2!izo^di21s_`6i=L=Ns=42^l%2+6Nm9YsbK%K0#Uo1*j2m@2Q&QwPqZ9x|A_hXemmMP z!htk^Jsh~*_g2z1Nj$$UG${P0-@UHZ+3Xm^_goL2jHR`eUglL1CeRQX&r>h`5y^3m zXXPk*wyO>l5?c#NXj(t@5#1B?wWG<_&fDRz3PSRH=wmDRmMvQ0I;ud(OY{OkzoAIl zPS-D$>8d|~_IC}fe&7#a=-9+WJDRMm zHy=GmM(ohdoAMdtDlj^6J|(y*p8_F~L#(y~x?!>8VR)@Q2Bk55P@<(}WPfTCF{edx zD8-P731k6cA*$R*1s>3p9|)ye6a49o^IDxSJdtp}4=YBLoi+zXg6%+|9=eI3(y0Ge zNJd}mx^!^e4;TK7ryj@lFQx$icPYB&(I(Mt9{l^lB>);8v)+=#xf9p?ZoYR5I$)7RFTN=|{2|7VDLTnHAj;47G$NI(c z+TW5S2CW+ftkcz)1~Pc`PpKrg4m zNvsRQ3V)Q7U0F-T189^ox?Iaj8VtmY8vgqT!W5w|?f6v1AR2S&4OiBu-2&DW&R3o? zBD?`X_q9ME??MH8r3VPUeWS8+0%o+1z%}lc=Rj?jcw#rXrvbRz8GV_gSdNu~D~DtZ zL1$KvtsTyE))zukVH>}$Y#NJ6uCOSED4yol_Ro}qzv8v#`VnC;&iCBa)_+PKb|_lG zJ>+=t&_biSzDPy;@@^C~uUv10`NJiqb`Ji*8FNhGmfN0hr=;jV809=mOmmf<$zEia zbfvmcOL0^Uvqro(WbYw0*y4Xa^gl!Q|N6y%5337&BOa-^Pk zfVvDnd(byU^hx@Zm@=d^8Q7{iCHgzPYUTKLN}=m?m%J=mk%{{WGBDXROqcHazY7WB+!V={eznB6BS z%xjM&J z6R`ln@d9_MOOPtL7;Fzs=%At%;8xho_)V|oE@EJ9kAAfoMGFrSd=^9F-DbZ%EC#BF z?SVzcIJ+g_b1`~QbXb9Lh^eSU7jb2w2q~<((`?P}Bo}ztOe%2xH+!JajAy$YBvMLQ zK@n9SFSO6DOmDZs)clSK`jB4wHNzCNF6|XqhTJ==PluZ5d@ELa3p*AHZ+5aH26{Wt zBu>OmfX&ITQGgCaK5Ge}>t8Dzw{4Vi_nBHaP`6a;4e!{swrq<1#)Z>mD##+pd>sd}5x^=kg22-H>uXWcU z3&%fFc~SXq3Cd+1$Q`C2C84;z2OKNM>`NVv+JZq=6mW^S*TZP^^XV@s?r~+d3M-=d1TX?Wy{Cq%WY)=?e_}cU#?l}#Zu~L1Y2j1mkc5Eb)AvA* zp2nh+fe)b&B8}M8nTGC7XX!DZtGqvmH#KIrxvqu@t+ z^|-tLQ{jI#N~|zInknzl-V*~rSUKs4eUjP6NTgM;qwMZO32L%|N!StAKMy7D^ek^3 z$F6zN*CwkbfXCp0BU(j2wOG%xXv5m6(=5~ec|Q%Ioh6i{0(b$dZ>RdUtq8uCOr5YU$` z-hk~p{hMB(x2P!x*KmxALBty9fNBw~vO>C^ITq9J!g$7a7hjI!Zy8+YzH=!4u6l?D zqT9G};12?3N5kH|4@Mqx=j0_ z&cZ1y>9DVhqM+G#If$;(rIm*jg6FKp*}Xg+1{M^2HM%D)gN`7 zC()xnU%r}DPS;cM=3Qr#WlBae)hpyCwb{SB=Tw~9Lo9W<{lENAsBA%qvZk?(C7s{TRp^+RkfX}k3nA>4lEG#XtTa5{n9&+qUj@;1`7jUuh z32^tG^s7V_bNlYOYTsYzIu&kYJ?llUgn!>KCAZJA`R9NVmPxj%efh0WsqK-lKst9T z7;mELe9UBZQJvs00X2plVZRD$K;mdW2|jE!D@FVMpa%nnrody=4A7ld{7@!;OV)uk zH}T;vLTv&1VM{||6NBAx2pI?f{kiqV4Bvhq*Cs^Eb-;~1E1xTMqg&F*UOGTN)m=?I zeni%99uoJCa`-_h%B~-Dz>*zMef%dm)e)aRV9rjPei4-yf8FpfPps2kQj3ip{IXSk zZz&ZnfBNnrg9D*q|Emyvruz@uP|#71p5^i@6uWi=nmRVF`inP!33}vFrcV-kFC(`Tl!cmK36I z8)d8Xqn#G}GDRgtLn8H|}R zW_iv%_5EJI-}(M?u5+F1T<2WZIsO~Z{oMEMnaA^d?$7;xy+6vfbC#!^M`hX=Q3ga= zvv?(i2rs>|Q~tstF?Fw=!)=RJnN%(Pp*ioCp-XxgQkQFpll3V{LIHJ%@HpeFplu&m z$@Z>}cLxb4vAfcnUDJZG;z{J{ol#*@)-haJ9u_kV$Oj)g^x+3gefj<0$TEfe@IN%u zSv#?l?{Pmle*g5dT+J$d^hV-o8jK!+?gASlFy?}pX2;q-&1_q9jeVE;^Btl0o+b$4 zkBlMfJZ?nXoYifM*87lL?Gtsi#b^nPjYNdmT3hF>6|&hj_cw<({Mi4+D7P?b-`*XP zJD8D9C_JpE9;237c6^XJRx%N9Rn?ptWMd9Xs;FlP{DlsOIX84C9E#%N-yMd0u2F5A z_>J##Zx>Y4O6yhqXLulhlBvumK5_Aw&;9U@Lv>|#JPU_cO*?gGtULUWo3+b~N}7gV zc(QT)r+J1c9Ocjshe8twyRf$HwHdG z9#uht>B@sNqIFeO$$8{yX$OnE8MuVR3aMJ@zz5n|uxeAez$w@dlQGl^sh%>(r*$;W zOu3)Ec^Wo?p5v1qwa`Nd znqlFUxWv>wWITDL#=fc_H>(+xiZIvX;3f#emP5|$-Bv)fYcQl+!7p3FRkK*>iA#{FptX=#(lgqA{-N5Cuq)88)11EvKANv(RlJ{a>kTQF)uRtg zEaa`^Oew&xmAxEh$6Pv~+u>X7f-5wp4;x0zte~HmW{=lAs82MA*a|1s!8-|}ulH_j zOrmQSv6+ZN{l9fT>Y{%M|3{2^pu|x;Iyy5CDSWCtwO@mq0o3^%P2%jROp>-aU6-Rj zH7H_BUF*pVy$|g5h@)6kxKO!xi6`5lo;eK_oZUQJxs}aow9o=w4a4#1CijFt#{$4P z8afO0@NhH`wo69D?K)+mq+O6{*p1(7ExY(_e1vn`YUAEb^L{EP!%phW_`20-G`wQ_ zt#{e6^s!r1k%l6j4^!vRotcvD{IEXqo`ksz6xXP4&`hxzowhrG89Mt`3(!eDTGJ6; zGy3cU0l?`jW()*>8T&ZLhv4lO#;QZ`=#tTnp-l&8qla%cEy>O>ec4gfAyJ`@%p9o{qdG;^Jg#r_J}~1Z~EA$SJKH*^QFW zJAT#P?0Slf3R-bK_pSO|{pz-^e2=8^u^rLbMr}#!Oj=Sg9nu4^{h8M^csH=Usv1_& z-kbOKJdD~KjOVrAY=|cDaw8-Zj-)L!lpTH04djS@tV>(wb29s!GJc00W5r{C2uhP` zw3c7!EhOB$l`yO^_Yk-uxFn!Y+F7r3zObSx<$3aO*kNa<4ikuv^<^evkJ0HT{|{jn?P2FJ&}wNnzwYl9E1R+F61oj7y>IWi;|mP z9*`Rf)mX71@djn{8%;vU>n&5%@KW4uE9cg^+jXe5N(1&H*Vz=NVuR!#2&C~kTh2X9 zheh)8n!cW;9HUGvwKVG^0?E^#Oj3SNc+)XcM=TaG zkKVB?(@wT!$LzMq!FwJ7ASM2FsTy_xuD%)E#K0-5TQ{cy+scDLK7JF7_#MyCyy?kl zeln*QRF@LDQVlVV;FvudlQ-@02MsK`46C$lsEvI)#|s*k75vaph8@WHZaozFW1eWWCtV zMh8|OyWavoOV~f>Q}BEf33s^KLeGQK8XwFPrFK_7;~6+ zvt;JZt?nHRdF8~ZD20C8r^Y50>NcH5+HdopEgUa-mx%L$ztXCjEn!=?KhGRc0LAIAkmp37Eom@Y`UL$QYbOm5{%KNAtSpB8tfeicx zG1w7D@DfC=MjmyqLwPO=DY^Xz5-y(L+jYLzB2r95_lXy$F(bfsWZkYSE?lVl;H8a; zRnS!`?jCGeZ8N^TF*0L-L4ixi*X7Td3kFfh8S|klqRW^hoZ*mLSW-nAZWDEknt<#X z8Y`N}{K#EIjt!P`QH4CvT=YNMoIA(Qlo+l+DGo0as+up|uOjuE;>j)4yfG$iR<(6X zwIv7jbyb=6q5EQ+f|11rZMTtK-M=A321RV^47Ms`9Q*v^fa#x*O7vPO>Y6a$3dN`VbL+ ze4pFuE&1_Wd8YPP&__h#{;!`MfsaCkjzIyRK=f9hn?Q6{LC^8xuMDWPNkEvr_4~s) z?8x9PyX`B+QdD~`)(K9u8RIh0a^%v$%fj@I!0I#dO@ z+!x=)w5N+X7b}bqxLdr2%lDOfTxigO0Ls|3?)K5GF;Rjxu16Lt-EkxiZ`7*-(7gTt z?z34h>?il@P0u1U_A6dMsbn=9PHpi2t|^xQ$4>5XpC;_)HD%m*#cxILwqR|u`*Ag= ztWxuGPmh8-kYrFAFV?T!7@!>vLKJEJ$1Yi?oOflHLzCj&jv_@_@)Rcf0uuPT8Zm%t zyC!<#Q9i!x&?DG4*Xo6-*Wd3%>t9pPm0tgH-y`J|^+JQst`?Us&^7ft&7JVe9nGzN z)|1snu+KTqzx{v@rrIpKq!n(t{AKmigaXPo1TWWX26~YSxY&bFrZ@hqReLbBu%h`v zzB)%uQ=!A4-@H>+dx0)!J+7TX98UrNkvZN~wB}CFmwwyDRd(CH7Y*$^iNDz!{OeNK zYCdTzVVP<@wdFj9r*#8Fe+s_~9$kRX&QdV=emJE9UAQ}x;zb6)THu?(1L2;Qq*i9U z&;C9zZx^sbnHN@Uw(2>4&Pl@C{*Gj{U-oCml6TF_1^db5RY901`yN*bb}$#MdAkf) z+Qd<~>u|D;-P7fIkz-bFbZ(T8H$cA^p8aFRBmS`yu8hz3VS$m>_=CP0FP3m;8tC#e z{^s!-dWpEVI5~2-)_>;wR_Mj;9%Z?1w2HZ>8gvO-hvy$dH)g)8-2zYBzsghcQ(RRy zQ-;r~>`~@h_Wib#3yRkcq-fzNl1XNlo6YPqAcx;dbl1IN>!E9nMD3y-X555@yI^`& zV0xQsr4yAxim37&T5yRjC+4-*8HVbPz)Br!(OVgf(2j?pSX@}?5?)gka2V2}JP+Cq0`;AmY1T*O|u@z#N6P_Q0d-;E6G|YqzY$T%Eyp6brlhrv36lKBUDK)ru;>^LEuj?54p^ z!-H#AT(no9=l`x@!hk$uJz3^#rA9p+E4h3v(Q)m(GhsCmoep#aKicH`p^@`%Jpq4e zjJ7H}NVp!8C^UGo<&u6tm z|G;>vzi;cFZ!Wm5$LwbG^VrjfZli`kYA#rroKEp9gdA?U$9WQA(}I(BQANO1<$gfw zq&f+KqB+7C*SeIDPFx#vpSimAkEG(|s=}KsAKgsWr^m`FFE(s8pc+aQ(upL%o?e=R zbl7uCb@8q@&M|>~K>UIhigOX*s*Oe^#4~2(oXYKK- zJsfGDq4J$j!yuhY0T;$JPt;W7MZUF?ay&1NR>XkZw|Bi%rYCSAX3%3P9C4W*I>gH| z+)C-aX>{*ceNt4eLQLJEfT`^j`F0)AvKWsM-zTbc*5cE&Ma|sV(+5ZP%!lx$lNSAQ zetK-5a81SZrXx;15=qqJ-4J7{L~f|0ueDDp~Tm1Ay6jAl?Y7>Q~k7cmo9-h zAz^R;;d76W4hyhF;PnFA+nt~8rtL_i3!w#}CbTL-kibJJ&AzcTV3(mM=e;9VCG5Bs z5rg%uX@GrZ!5i^OV~f`x^D3idN~fd^R}R#z#Ta?i@&EN#BO~a+a2e(o=LwqPhT6Qf z1KY02dena4$ql8x`ASyb9bu>Q-ey=)sfW(kh4N_K4?~tp7-S4yIPI>lPO%!*0H!E0H-m`P%)iv)wd|+4c|JHv^L>y~8Gxx)T(O~_YD56|5+KcXC=eo#$N;jb&|a|qSB=qv)71>zx5xjJ3NB<_kU7c z96f~lxBfB9=%M^1iP7}d4ac3oZU<)1-w7CGW)op(4KEVL8 zxIN^Fqb&NM*|Il5Y`NBf{DlGB9j0QTL@{oX^p!l;CpNi-4U+OjUjzX}3pe0s3uob` z!6D^||%Au=tHb!h6P5i{a$|BG! z{h`5bI!`Qa4ol(=PW-f=CKUCsDhYT3M}tXdVS>g&q-zN+7-=pJGLh+2u@aj3&YesX zOQXZ8nFb_rV`?A~PZp2CMNtE>;>M(Yw0Wj@4CY)-zd+oW>cOP8$V38D-@rG*l&V5b z7*k++c1OLgXwfqnD9UUG&+-Ypa0-@`7Fgue<48xWuXZVcGih!D3KTBG;IQ2I1U~CB zUpP${P{q6bnL}j4VmZW@8xVg&a%r6${$J{A7%>w$=MQn$zZYwHTw&)p|TXlZ#_lek9n6AW2vyo?je7b5lk(M*j%C1c|R?_i$kwf&} zZs0Z`uArfHrYEcV$&d5p4p_h3wJi?8G_)swD=GVDlZ$KaapW;TB6}c0Jq*Lb7PCor0+R>q{p)R5a(#P?I6213Bc z?=F{>jD6q!_R`{cb%36mSB@ zn7H4&E)q;*YD|WB&FK?`EZ#JrhI-a7P74>OQ6)~K!H_2Tu}-c-5w38~sms)m-8fdr z9V;9oo=3l|G07|e@DR=|vScW!B$10|hd?+s786oUf&SSAv5nWj@Fu5U559tZBs#I9`s5O~YQ z0N#^4b1hOmSK?z?xyefmrF!=?3R&w?BK7Pozm1`~HbK%K~s1yGC`L=3=t@ zoRjJ}?YP}@<6ZDDvh4NdKVf1;z%vWB8Gw=LAX-9(3;W>Dv?++t?QQB$` z5fq+HfIVi|3f<@t_%KsT|Bm>=nEzk7Ff$^uNcxcE@~tT&q-;6#K?X(BtNKCqrOMi? zM?~8)oa|F?{Cr-YUgLcRl!x#m=j>^6g1&4C)e7U9QOil`SH$e317RBCSOH3rpfi;w z9Asg7L@pcB&t?EQSJy|Lp(eG*=Vwa1;WiT+{f$L1tlLU+LGG^6| zdN|wg@C>fY;L7VlWEb!4P`Fa5vdX#E%eV{F>Ua4}9oA+$NYA7tF3e8u(n$WIwpg_# zcK;+15TkO&L zP!&`WoJuRoOgBrq9;^4ME$7{9WVlr?K12is0mG_5q>>SJmauA+<1{<`;l47~b}=gQ zLMSD}!F@xP@z%)i_nTsZ{^1eh47k8r@0Y{=LSgM^>^D))f#QT|2pfxf@jMAQcQKnn z(cf&G7`xaW;)bK=fFD{31GW$io+3Hc?g`@6`xnz&sV6QR3V}Y|sXL1Cx=>lN{&!ze zhtxe+nHupt=^|*7&qNN%nBC}HwkpOw3lzY(9&9pxp@8*-87p;O5~RE3R51 zPS()UXMqux*8441c#+f*@Hn#R*3ocwwDm4!CXDf~P5JNkENgrmDoS;d|M6)no|dXI0kN)M@F;BHvc_bjX-r#n(2G!%`tON6$m ztR0FB2Ljy}Z_qJj{=MwYP@;8a;+s~Jd~9?fOEYHVY0_&2plf*9j=pF9q4G3sA2lJG zWtO&Ip)WPp%KET0@NA8lmQC~B5@W_ImMvhxnnT0`TNGvD-kB<~hus#zQUf@xz!p2z z&%IX(ji}Gd%x~Xqc5RnX(jqAGD5fHxaRum0Q360lGEo*tTn|uLBY-b+>nygiUvtO< zWUt1IYd|Cto=6iVlF~{53`tnLD#l)m7XJC!gI>ZgtgHogGr1ir}ryAK~2q@#H<;8nW`R zVl49t5@ZtV&Ts1iRdQoSCLF_cJzsoYLza3U9VH_^C`{d&ebZg9$z8!PbDCezJzn0x zl3;jd72o7ipzSL6Zc*;b67>c!FPSn5`p%=F5=i^fVYe9uSbJ^jYL#E!cTe1@$D&5T zW0Xd%x&t1&-y2rt=vIWh4PKgkwI|1m=o8p{+Bv4 zoTcETSCbZlx5N98*!^!j~RcG!j&yVsqBE@HE|^*b;shDUMj5>P&TF?pQ6YV~V5I1MrS~-kP|D9Yf-<7J$8Q);|=d9IM44 zEx>3qCr+w$ + + SwiftUI SVG Cursor Logo + + + + + + + + + + + + + diff --git a/.agents/skills/swiftui-expert-skill/references/animation-advanced.md b/.agents/skills/swiftui-expert-skill/references/animation-advanced.md index 561e111f..94256396 100644 --- a/.agents/skills/swiftui-expert-skill/references/animation-advanced.md +++ b/.agents/skills/swiftui-expert-skill/references/animation-advanced.md @@ -361,12 +361,38 @@ struct Wedge: Shape { ``` ### When to Use -- **Prefer `@Animatable`** for any custom `Shape`, `AnimatableModifier`, or type conforming to `Animatable` with multiple properties +- **Prefer `@Animatable`** for any custom `Shape` or type conforming to `Animatable` with multiple properties +- **Conform `ViewModifier` types to `Animatable` directly** — not `AnimatableModifier` (soft-deprecated in SDK 27) - **Use `@AnimatableIgnored`** for properties that control behavior but should not interpolate (e.g., directions, flags, identifiers) - The macro works with any type conforming to `Animatable`, not just `Shape` > Source: "What's new in SwiftUI" (WWDC25, session 256) +### When to Implement `animatableData` Manually + +Reach for an explicit `animatableData` (instead of the macro) when the interpolated value needs custom logic that doesn't map 1:1 to a stored property — normalization, clamping, or driving a derived value. For a deployment target of iOS 26+, use `AnimatableValues`; for earlier targets, use `AnimatablePair`. + +```swift +// iOS 26+: keep phase in 0..<2π and clamp amplitude during interpolation +struct WaveShape: Shape { + var amplitude: CGFloat + var phase: CGFloat + var maxAmplitude: CGFloat + + var animatableData: AnimatableValues { + get { AnimatableValues(amplitude, phase) } + set { + amplitude = min(max(newValue.value.0, 0), maxAmplitude) + phase = newValue.value.1.truncatingRemainder(dividingBy: 2 * .pi) + } + } + + func path(in rect: CGRect) -> Path { /* ... */ } +} +``` + +On earlier deployment targets, the same logic uses `AnimatablePair` with `newValue.first` / `newValue.second`. + --- ## Quick Reference diff --git a/.agents/skills/swiftui-expert-skill/references/animation-transitions.md b/.agents/skills/swiftui-expert-skill/references/animation-transitions.md index 29b3f984..e5224661 100644 --- a/.agents/skills/swiftui-expert-skill/references/animation-transitions.md +++ b/.agents/skills/swiftui-expert-skill/references/animation-transitions.md @@ -264,8 +264,10 @@ struct BadShakeModifier: ViewModifier { ### Multiple Properties with AnimatablePair +For deployment targets below iOS 26, use `AnimatablePair` to combine multiple animated properties. For iOS 26+ targets, prefer `@Animatable` or `AnimatableValues` — see [@Animatable Macro (iOS 26+)](animation-advanced.md#animatable-macro-ios-26) in `animation-advanced.md`. + ```swift -// GOOD - AnimatablePair for two properties +// GOOD (below iOS 26) - AnimatablePair for two properties struct ComplexModifier: ViewModifier, Animatable { var scale: CGFloat var rotation: Double @@ -285,7 +287,7 @@ struct ComplexModifier: ViewModifier, Animatable { } } -// GOOD - nested AnimatablePair for 3+ properties +// GOOD (below iOS 26) - nested AnimatablePair for 3+ properties struct ThreePropertyModifier: ViewModifier, Animatable { var x: CGFloat var y: CGFloat @@ -316,7 +318,7 @@ struct ThreePropertyModifier: ViewModifier, Animatable { - Place transitions outside conditional structures - Use `withAnimation` or `.animation` outside the `if` - Implement `animatableData` explicitly for custom Animatable -- Use `AnimatablePair` for multiple animated properties +- Use `AnimatablePair` for multiple animated properties on deployment targets below iOS 26; for iOS 26+, use `@Animatable` or `AnimatableValues` (see `animation-advanced.md`) - Use asymmetric transitions when insert/remove need different effects ### Don't diff --git a/.agents/skills/swiftui-expert-skill/references/document-apps.md b/.agents/skills/swiftui-expert-skill/references/document-apps.md new file mode 100644 index 00000000..5e7bd695 --- /dev/null +++ b/.agents/skills/swiftui-expert-skill/references/document-apps.md @@ -0,0 +1,209 @@ +# Document-Based Apps (SDK 27+) + +> The `Document` protocol family replaces `FileDocument` / `ReferenceFileDocument` for new code on iOS 27, macOS 27, and visionOS 27. **Unavailable on watchOS and tvOS.** For older deployment targets, see the `FileDocument` section in `references/macos-scenes.md`. + +## Table of Contents + +- [Protocol Map](#protocol-map) +- [Read and Write Flow](#read-and-write-flow) +- [Flat-File Document](#flat-file-document) +- [Undo Registration Is Required for Autosave](#undo-registration-is-required-for-autosave) +- [DocumentGroup and Launch Scenes](#documentgroup-and-launch-scenes) +- [Custom Readers and Writers](#custom-readers-and-writers-direct-url-access) +- [Package Documents](#package-documents) +- [Progress Reporting](#progress-reporting-with-subprogress) +- [Coordinated Access Outside Read/Write](#coordinated-access-outside-readwrite) +- [Export](#export) +- [Migrating from FileDocument](#migrating-from-filedocument) +- [Content Types](#content-types) + +--- + +## Protocol Map + +| Symbol | Role | +|---|---| +| `ReadableDocument` | Read-only. Requires `readableContentTypes`, `reader(configuration:)`, `apply(snapshot:previous:)`. | +| `WritableDocument` | Saving. Requires `writer(configuration:)` and `snapshot(contentType:)`; `writableContentTypes` defaults to `readableContentTypes` when both protocols are adopted. | +| `Document` | `ReadableDocument & WritableDocument`, no requirements of its own. | +| `DocumentReader` | `@concurrent func read(from:progress:) async throws -> sending Snapshot` | +| `DocumentWriter` | `@concurrent func write(snapshot:to:previous:progress:) async throws` | +| `FileWrapperDocumentReader` | Convenience reader; closure `(FileWrapper) async throws -> sending Snapshot`. | +| `FileWrapperDocumentWriter` | Convenience writer; closure `(Snapshot, FileWrapper?) async throws -> FileWrapper`. | +| `URLDocumentConfiguration` | `@MainActor @Observable`. `fileURL`, `lastContentModificationDate`, `makeFileCoordinator()`. | +| `DocumentCreationContext` | `creationSource: DocumentCreationSource?`. | + +Documents are `AnyObject`-constrained, so a document is a class. Mark it `@Observable` so SwiftUI tracks individual property changes instead of recreating the model. + +A **snapshot** is the document's state at one moment. It can be any type — `String`, a struct, or the document itself — and reading and writing may use different snapshot types. Keep snapshot, reader, and writer types at `internal` access; protocol requirements expose them in signatures, so `private` or `fileprivate` fails to compile. + +## Read and Write Flow + +**Open:** `reader(configuration:)` → `read(from:progress:)` in the background → `apply(snapshot:previous:)` on the main actor. + +**Save:** `snapshot(contentType:)` on the main actor → `writer(configuration:)` → `write(snapshot:to:previous:progress:)` in the background with coordinated file access. + +`snapshot(contentType:)` and `apply(snapshot:previous:)` are `@MainActor async throws` — keep them cheap and serialize inside `read(…)` / `write(…)`. Inside those methods, use the `source` / `destination` parameter rather than `configuration.fileURL`; the framework hands you the URL for *this* operation, which is not necessarily the document's URL. + +## Flat-File Document + +`FileWrapperDocumentReader` and `FileWrapperDocumentWriter` handle file coordination for you. `readableContentTypes` drives the document browser; `writableContentTypes` drives the save panel. + +```swift +@Observable +final class TextDocument: Document { + static let readableContentTypes = [UTType.plainText] + + var text: String = "" + + func reader(configuration: sending ReadConfiguration) -> sending FileWrapperDocumentReader { + FileWrapperDocumentReader(configuration) { fileWrapper in + guard let data = fileWrapper.regularFileContents else { + throw CocoaError(.fileReadCorruptFile) + } + return String(decoding: data, as: UTF8.self) + } + } + + func writer(configuration: sending WriteConfiguration) -> sending FileWrapperDocumentWriter { + FileWrapperDocumentWriter(configuration) { snapshot, previous in + FileWrapper(regularFileWithContents: Data(snapshot.utf8)) + } + } + + @MainActor + func snapshot(contentType: UTType) async throws -> sending String { text } + + @MainActor + func apply(snapshot: sending String, previous: sending String?) async throws { + text = snapshot + } +} +``` + +## Undo Registration Is Required for Autosave + +SwiftUI detects unsaved changes through the undo stack. **Without registered undo actions, autosave never runs.** Read `\.undoManager` from the environment and register an undo action for every change: + +```swift +struct TextDocumentView: View { + @Bindable var document: TextDocument + @Environment(\.undoManager) private var undoManager + + var body: some View { + TextEditor(text: $document.text) + .onChange(of: document.text) { oldValue, _ in + undoManager?.registerUndo(withTarget: document) { document in + document.text = oldValue + } + } + } +} +``` + +Registering with `withTarget: document` gives redo for free — SwiftUI replays the same closure with the restored value. + +## DocumentGroup and Launch Scenes + +`DocumentGroup` (or `DocumentGroupLaunchScene`) must be the app's first scene to opt into autosave, file coordination, file dialogs, undo management, and conflict resolution. On iOS, set `UISupportsDocumentBrowser` to `YES` to present a document browser. + +```swift +DocumentGroup { document in + TextDocumentView(document: document) +} makeDocument: { configuration, context in + TextDocument() +} +``` + +Read-only apps conform only to `ReadableDocument` and use `viewer:` / `makeReadableDocument:`, with `CFBundleTypeRole` set to `Viewer` instead of `Editor`. + +`makeDocument` is `async` and runs on the main actor, so you can suspend it to show a template picker or import preview before the document appears; throw `CancellationError` to cancel. On macOS and visionOS, drive that from a separate `Window` scene via a stored `CheckedContinuation`; on iOS, present a `.sheet` from a `NewDocumentButton`. + +`DocumentGroupLaunchScene` (iOS/visionOS) hosts `NewDocumentButton`s, each carrying a `DocumentCreationSource`. Read `context.creationSource` in `makeDocument` to configure the new document: + +```swift +DocumentGroupLaunchScene("My Notes") { + NewDocumentButton("New Note", source: .note) + NewDocumentButton("New List", source: .list) +} background: { + Color.accentColor.gradient +} + +extension DocumentCreationSource { + static let note = DocumentCreationSource(id: "note") +} +``` + +## Custom Readers and Writers (Direct URL Access) + +Implement `DocumentReader` / `DocumentWriter` directly when you need streaming, custom write logic, or a file URL for frameworks such as Core Graphics, AVFoundation, or PDFKit. Their `Source` and `Destination` associated types default to `URL`; specialize them only when the backing store requires another type. + +```swift +struct Reader: DocumentReader { + @concurrent + func read(from source: URL, progress: consuming Subprogress) async throws -> sending ImageSnapshot { + guard let imageSource = CGImageSourceCreateWithURL(source as CFURL, nil), + let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) else { + throw CocoaError(.fileReadCorruptFile) + } + return ImageSnapshot(image: image) + } +} +``` + +The writer's `previous` parameter holds the last successfully written snapshot; ignoring it and rewriting everything is the simplest correct behavior. + +## Package Documents + +A package is a directory the system presents as one item. `FileWrapperDocumentReader` / `FileWrapperDocumentWriter` work here too: read children from `directory.fileWrappers`, and build a fresh `FileWrapper(directoryWithFileWrappers:)` with `preferredFilename` set on each child when writing. + +Rewriting the whole package on every save is the default recommendation. `FileWrapper` loads contents **on demand**, so a child can be gone by the time you call `regularFileContents` — always handle errors when reading children. + +Incremental writes are worth it only against a measured problem. The pattern: carry a per-child `isChanged` flag, reuse the previous `FileWrapper` from the writer closure's second parameter, replace only changed children, remove children no longer listed in your metadata, and clear the flags in `snapshot(contentType:)`. + +## Progress Reporting with `Subprogress` + +Custom readers and writers receive a `Subprogress` (Foundation). The `FileWrapper` convenience closures do **not**. `Subprogress` is `~Copyable`, so the compiler enforces single use; unconsumed units auto-complete. + +```swift +let progressManager = progress.start(totalCount: 2) +let data = try Data(contentsOf: source) +progressManager.complete(count: 1) +let image = try decodeImage(from: data) +progressManager.complete(count: 1) +``` + +Pick a coarse `totalCount` — chunks or files, not bytes. SwiftUI decides case by case whether to show an indicator. + +## Coordinated Access Outside Read/Write + +SwiftUI coordinates `read` and `write` for you. For any other disk access — loading one file from a package on tap, for instance — retain the `URLDocumentConfiguration` passed to `makeDocument`, call `makeFileCoordinator()` on it for each operation, then use `coordinate(readingItemAt:options:error:)` (or the writing variant) and check the `NSError` out-parameter. Skipping coordination risks corruption when another process edits the same document. + +## Export + +Export to another location or format with `fileExporter(isPresented:document:contentType:defaultFilename:onCompletion:)`, passing the `WritableDocument` itself. + +## Migrating from FileDocument + +| Before | After | +|---|---| +| `FileDocument` struct / `ReferenceFileDocument` class | `@Observable final class` conforming to `Document` | +| `init(configuration:)` | `DocumentReader` + `apply(snapshot:previous:)` | +| `fileWrapper(configuration:)` | `DocumentWriter` + `snapshot(contentType:)` | +| `DocumentGroup(newDocument:editor:)` | `DocumentGroup { editor } makeDocument: { configuration, context in }` | +| Single `Snapshot` type | Separate read and write snapshot types | +| Change tracked by value comparison | Undo registration required | + +`FileDocument`, `ReferenceFileDocument`, and their `DocumentGroup(newDocument:)` APIs are soft-deprecated in the SDK 27 toolchain. They remain the compatible option for deployment targets below the aligned 27 releases; follow `references/soft-deprecation.md` when deciding whether migration belongs in the current task. When migrating a `ReferenceFileDocument`, drop `ObservableObject` and `@Published` rather than layering `@Observable` on top. + +## Content Types + +Built-in formats need no custom type (`UTType.plainText`, `.jpeg`, `.pdf`). Mirror a custom document type in code: + +```swift +extension UTType { + static let notebook = UTType(exportedAs: "com.mycompany.notebook") +} +``` + +Use `static let` for exported types and `static var` for `UTType(importedAs:)` types. Custom identifiers use lowercase reverse-DNS syntax. Flat files conform to `public.data`; packages conform to `com.apple.package`. diff --git a/.agents/skills/swiftui-expert-skill/references/environment-patterns.md b/.agents/skills/swiftui-expert-skill/references/environment-patterns.md new file mode 100644 index 00000000..85e2e2b4 --- /dev/null +++ b/.agents/skills/swiftui-expert-skill/references/environment-patterns.md @@ -0,0 +1,162 @@ +# SwiftUI Environment Patterns + +Use this reference for `@Environment`, `EnvironmentValues`, `@Entry`, `@FocusedValue`, and values propagated through the environment. + +## Read Framework Values + +Use `@Environment` to read framework-provided values and actions from the nearest ancestor: + +```swift +struct DetailView: View { + @Environment(\.dismiss) private var dismiss + @Environment(\.colorScheme) private var colorScheme + + var body: some View { + Button("Done") { dismiss() } + } +} +``` + +Keep the declaration in the smallest view that uses it so environment changes do not invalidate a broader parent. + +## Share Observable Models + +On iOS 17+ and aligned platforms, inject an `@Observable` model by type and read it with type-based `@Environment`: + +```swift +@MainActor +@Observable +final class AppState { + var isLoggedIn = false +} + +RootView() + .environment(AppState()) + +struct AccountView: View { + @Environment(AppState.self) private var appState + + var body: some View { + Text(appState.isLoggedIn ? "Signed in" : "Signed out") + } +} +``` + +Observation tracks the model properties read during `body`, so unrelated properties do not invalidate the view. Use `@Bindable` locally when a control needs bindings to the injected model. + +For older deployment targets, `@EnvironmentObject` with `.environmentObject(...)` remains the corresponding `ObservableObject` pattern. Do not create the shared model inline at multiple reader sites. + +## Prefer `@Entry` for Custom Values + +Use `@Entry` instead of manual key conformances when defining custom environment, transaction, container, or focused values: + +```swift +extension EnvironmentValues { + @Entry var accentTheme: Theme = .default +} + +extension FocusedValues { + @Entry var selectedDocument: Document? +} +``` + +Focused-value entries are optional and do not specify a non-`nil` default. + +When reviewing existing manual `EnvironmentKey` / `FocusedValueKey` boilerplate, surface an `@Entry` refactor as a top-line finding. Do not rewrite it unprompted. + +`@FocusedValue` uses the same comparison model as `@Environment`. Rules below for closures, defaults, unused reads, and high-frequency updates apply to both. + +## Never Store Closures in Custom Keys + +SwiftUI cannot reliably compare functions. A closure in a custom environment or focused-value key can therefore make every reader invalidate whenever the environment propagates. Wrapping the closure in a struct or storing it on a `View` does not fix comparison; the closure is still present. + +Framework action values such as `\.dismiss`, `\.openURL`, and `\.refresh` are designed for this purpose and are not affected by this rule. + +Represent custom behavior with a value that stores comparable inputs and exposes a method or `callAsFunction`, or share an `@Observable` model when the behavior belongs with shared state: + +```swift +// AVOID +extension EnvironmentValues { + @Entry var submit: (String) -> Void = { _ in } +} + +// PREFER +struct SubmitAction { + func callAsFunction(_ draft: String) { /* submit */ } +} + +extension EnvironmentValues { + @Entry var submit = SubmitAction() +} +``` + +When injected handlers differ by context (form vs cart, independent implementations), one option is a protocol plus concrete handler types stored as the `@Entry` value. When handlers share state and the set is closed, a single `@Observable` model can be simpler. + +## Keep Default Values Stable + +An `@Entry` default expression is evaluated when a reader falls back to it. The default is unstable when repeated evaluation produces a different value, such as a fresh class instance, `Date()`, `UUID()`, or a struct containing a newly allocated reference. Any unrelated environment write can then make fallback readers appear changed. + +```swift +// AVOID: creates a different instance on each fallback read +extension EnvironmentValues { + @Entry var model = Model() +} + +// PREFER: resolves to the same instance +extension EnvironmentValues { + @Entry var model = defaultModel + private static let defaultModel = Model() +} +``` + +Use an optional with a `nil` default when absence is meaningful. This is preferable when readers currently test a sentinel such as an empty identifier: + +```swift +extension EnvironmentValues { + @Entry var editingSession: EditingSession? +} +``` + +`Equatable` conformance does not repair an unstable default: the expression still allocates or changes on every read. Conversely, do not rewrite already-stable defaults. Literals, enum cases without associated values, `nil`, and structs built only from deterministic values or stable references are stable even without `Equatable`. + +A live unstable default has readers falling back and paying invalidation now. A latent one is currently covered by an upstream `.environment` injection; fixing it is still correct but is a regression guard, not a current-cost recovery. + +A manual `EnvironmentKey` with `static let defaultValue` is a deliberate stability fix (evaluated once). Do not use `static var defaultValue: T { Model() }` — that re-evaluates on every fallback read, the same problem `@Entry` has with an inline allocation. + +## Avoid High-Frequency Environment Updates + +Every environment write propagates through the subtree and makes environment readers check their values. Do not put per-frame or rapidly changing measurements such as scroll offsets, drag positions, geometry, timer ticks, or animation progress in custom environment keys. + +For visual scroll effects, prefer `scrollTransition` or `visualEffect(in:)`. When the value drives logic, consider an `@Observable` model that exposes a coarsened property such as `isWide` instead of raw width: + +```swift +@MainActor +@Observable +final class ViewportModel { + var width: CGFloat = 0 { + didSet { isWide = width > 600 } + } + + private(set) var isWide = false +} +``` + +The model alone is not the optimization: readers must observe a value that changes less often than the raw input. + +A shared `Set` of visible indices on one `@Observable` fires only on boundary crosses, which is better than a raw offset. Observation still tracks the whole `Set` property, so every row that read it invalidates. Persist a per-item `@Observable` whose own properties (for example `isVisible`) each row reads. + +## Remove Unused Reads + +An unused key-path declaration such as `@Environment(\.theme)` still subscribes the view to that key. Remove it when neither `body` nor anything called from `body` reads the value. + +Type-based `@Environment(Model.self)` uses Observation's property-level tracking. Merely declaring the model without reading one of its properties does not establish the same live dependency, though removing dead declarations still improves clarity. + +## Checklist + +- [ ] Custom values use `@Entry`; flag leftover manual keys without rewriting them unprompted +- [ ] Custom environment and focused-value keys do not store closures +- [ ] Default expressions return the same result on every fallback read (live or latent) +- [ ] `@FocusedValue` follows the same comparison and unused-read rules as `@Environment` +- [ ] Optional defaults represent semantic absence instead of sentinel instances +- [ ] High-frequency raw values do not flow through the environment +- [ ] Key-path environment declarations are actually read diff --git a/.agents/skills/swiftui-expert-skill/references/focus-patterns.md b/.agents/skills/swiftui-expert-skill/references/focus-patterns.md index fbc01dd2..74b3d010 100644 --- a/.agents/skills/swiftui-expert-skill/references/focus-patterns.md +++ b/.agents/skills/swiftui-expert-skill/references/focus-patterns.md @@ -118,7 +118,7 @@ extension FocusedValues { } ``` -Focused values are typically optional (default is `nil` when no view publishes them), but you can also use non-optional entries when you have a sensible default value. +Focused `@Entry` values must be optional and use the implicit `nil` default, representing that no focused view currently publishes the value. ### Publish from views diff --git a/.agents/skills/swiftui-expert-skill/references/image-optimization.md b/.agents/skills/swiftui-expert-skill/references/image-optimization.md index b55f4a68..73d6c14e 100644 --- a/.agents/skills/swiftui-expert-skill/references/image-optimization.md +++ b/.agents/skills/swiftui-expert-skill/references/image-optimization.md @@ -3,6 +3,7 @@ ## Table of Contents - [AsyncImage Best Practices](#asyncimage-best-practices) +- [SDK 27 Caching and Request Control](#sdk-27-caching-and-request-control) - [Image Decoding and Downsampling (Optional Optimization)](#image-decoding-and-downsampling-optional-optimization) - [UIImage Loading and Memory](#uiimage-loading-and-memory) - [SF Symbols](#sf-symbols) @@ -34,6 +35,44 @@ AsyncImage(url: imageURL) { phase in For custom placeholders, replace `ProgressView()` in the `.empty` case with your placeholder view. Add `.transition(.opacity)` to the success case and `.animation(.easeInOut, value: imageURL)` to the container for fade-in transitions. +## SDK 27 Caching and Request Control + +On aligned 27 runtimes, `AsyncImage(url:)` uses standard HTTP caching according to response headers, with no code change. The runtime behavior also benefits apps built with an older SDK. Do not add custom caching merely to obtain that default. If images still reload, first check the server's cache headers. + +SDK 27 adds three `AsyncImage(request:)` initializer shapes (remaining labels match the `URL` initializers): + +- Bare `AsyncImage(request:)` — renders the loaded image directly, like `AsyncImage(url:)` +- `content:` / `placeholder:` pair +- `transaction:` plus a `content:` closure that receives `AsyncImagePhase` + +The request carries a per-image `URLRequest`, including `cachePolicy` (`.returnCacheDataElseLoad`, `.returnCacheDataDontLoad`, `.reloadIgnoringLocalCacheData`, `.reloadRevalidatingCacheData`, `.useProtocolCachePolicy`). `asyncImageURLSession(_:)` supplies a configured `URLSession` and `URLCache` to a subtree. + +```swift +struct GalleryView: View { + private static let imageSession: URLSession = { + let configuration = URLSessionConfiguration.default + configuration.urlCache = URLCache( + memoryCapacity: 64 * 1024 * 1024, + diskCapacity: 256 * 1024 * 1024 + ) + return URLSession(configuration: configuration) + }() + + var body: some View { + AsyncImage( + request: URLRequest(url: imageURL, cachePolicy: .returnCacheDataElseLoad) + ) { image in + image.resizable().scaledToFit() + } placeholder: { + ProgressView() + } + .asyncImageURLSession(Self.imageSession) + } +} +``` + +The request initializers and `asyncImageURLSession(_:)` require the aligned OS 27 releases (iOS, macOS, watchOS, tvOS, visionOS 27). Gate them for older deployment targets and retain `AsyncImage(url:)` as the fallback. + ## Image Decoding and Downsampling (Optional Optimization) **When you encounter `UIImage(data:)` usage, consider suggesting image downsampling as a potential performance improvement**, especially for large images in lists or grids. @@ -103,12 +142,11 @@ OptimizedImageView( ### Reusable Downsampling Actor -For production use, wrap the logic in an `actor` with scale-aware sizing and cache-disabled source options: +For production use, wrap the logic in an `actor` with scale-aware sizing and cache-disabled source options. Apply this pattern when the processor converts a target measured in SwiftUI points into pixels. Display scale belongs to the view's environment because it can differ by scene and display. Read it in the SwiftUI view and pass it into the processor; the actor should not consult global screen state. If the caller already supplies pixel dimensions, do not multiply by display scale again. ```swift actor ImageProcessor { - func downsample(data: Data, targetSize: CGSize) -> UIImage? { - let scale = await UIScreen.main.scale + func downsample(data: Data, targetSize: CGSize, scale: CGFloat) -> UIImage? { let maxPixel = max(targetSize.width, targetSize.height) * scale let sourceOptions: [CFString: Any] = [kCGImageSourceShouldCache: false] guard let source = CGImageSourceCreateWithData(data as CFData, sourceOptions as CFDictionary) else { return nil } @@ -122,9 +160,35 @@ actor ImageProcessor { return UIImage(cgImage: cgImage) } } + +struct ProcessedImageView: View { + let data: Data + let targetSize: CGSize + let processor: ImageProcessor + + @Environment(\.displayScale) private var displayScale + @State private var image: UIImage? + + var body: some View { + Group { + if let image { + Image(uiImage: image).resizable().scaledToFit() + } else { + ProgressView() + } + } + .task(id: displayScale) { + image = await processor.downsample( + data: data, + targetSize: targetSize, + scale: displayScale + ) + } + } +} ``` -Key details: `kCGImageSourceShouldCache: false` on the source prevents the full-resolution image from being cached in memory. Multiplying `targetSize` by `UIScreen.main.scale` ensures the thumbnail is sharp on Retina displays. `kCGImageSourceShouldCacheImmediately: true` on the thumbnail forces decoding at creation time rather than at first render. +Key details: `kCGImageSourceShouldCache: false` on the source prevents the full-resolution image from being cached in memory. Multiplying the point target size by the view's `displayScale` produces the required pixel size and updates correctly if the scene moves to a display with a different scale. `kCGImageSourceShouldCacheImmediately: true` on the thumbnail forces decoding at creation time rather than at first render. ### When to Suggest This Optimization @@ -194,9 +258,11 @@ Variants are available via naming convention: `star.circle.fill`, `star.square.f - [ ] Use `AsyncImage` with proper phase handling - [ ] Handle empty, success, and failure states +- [ ] On OS 27, rely on default HTTP caching unless a custom cache policy or `URLSession` is needed - [ ] Consider downsampling for `UIImage(data:)` in performance-sensitive scenarios - [ ] Decode and downsample images off the main thread -- [ ] Use appropriate target sizes for downsampling +- [ ] Convert point target sizes to pixels with the view's `@Environment(\.displayScale)` +- [ ] Pass display scale into processors; do not read global screen state from an actor - [ ] Consider image caching for frequently accessed images - [ ] Use SF Symbols with appropriate rendering modes diff --git a/.agents/skills/swiftui-expert-skill/references/iphone-duo.md b/.agents/skills/swiftui-expert-skill/references/iphone-duo.md new file mode 100644 index 00000000..6b418714 --- /dev/null +++ b/.agents/skills/swiftui-expert-skill/references/iphone-duo.md @@ -0,0 +1,78 @@ +# iPhone Duo SwiftUI Guidance + +> iPhone Duo support in Xcode 27.1 and the iOS 27.1 SDK is beta. Confirm behavior against the shipping SDK. + +## Displays and Continuity + +iPhone Duo has an outer display and a larger inner display. The outer display uses the familiar compact-horizontal, regular-vertical iPhone context in portrait; the inner display can provide regular width and height, including sidebar and multi-column presentations. Use the current proposal and size classes, not a device check, orientation, fixed breakpoint, or global screen. + +Opening, closing, rotating, partially folding, Split View multitasking, and pinned video all resize the same app experience. Preserve navigation state, content hierarchy, and functionality across those transitions. Do not make a feature available only in one pose or prescribe a bespoke layout for every pose. Generic resizability, safe-area, and display-scale rules remain canonical in [layout-best-practices.md](layout-best-practices.md) and [image-optimization.md](image-optimization.md). + +Hardware placement is asymmetric. The outer and inner cameras occupy different positions, and system controls can use a vertical bar on a hardware-aligned side. Never assume opposite safe-area or margin values are equal. Let standard SwiftUI containers and directional safe areas place foreground controls; full-bleed visual backgrounds can extend behind them. See [toolbar-patterns.md](toolbar-patterns.md) for vertical-bar APIs. + +## Choose the Technique by Screen Structure + +Classify the screen by structure before choosing a fold technique; starting from `ArrangementView` or `reservedRegions` tends to misread the screen. Check in this order: + +1. **Rows push further screens** (settings, mailboxes, folders, even a short list): `NavigationSplitView` needs no Duo-specific code; it collapses on compact width and scales to iPad and resizable windows. See [sheet-navigation-patterns.md](sheet-navigation-patterns.md#large-displays). +2. **Cards or a feed in one `ScrollView`** (dashboards, collection grids): [reflow into two columns](layout-best-practices.md#two-column-reflow-for-card-screens) with the gutter over a vertical fold; don't split at a horizontal fold. +3. **Two peer regions without navigation** (media and controls, visual and copy): `ArrangementView` with `.split`, outside any scroll view. +4. **Content plus a supplementary queue or panel**: consider keeping the compact pattern, a persistent bar that pushes the full view (like the Music mini player). If you use `.inspector`, attach it around the `NavigationStack`, not on a pushed screen; in Xcode 27.1 that broke pushes and put full-bleed content under the inspector column. +5. **Custom edge-to-edge chrome only**: read `reservedRegions` directly. + +In a portrait-only iPhone app, regular width effectively means the inner display, which ignores supported orientations and can still be landscape. + +## Fold and Camera Regions + +The outer camera always shapes the outer-display area; standard safe areas and bars account for it. On the inner display, an active fold is represented as a `.division` reserved region because it separates the available area. The active FaceTime camera is an `.occlusion` region because it covers a smaller frame. Inner regions can change activity as the device pose and camera use change. + +System components (`NavigationStack`, `NavigationSplitView`, `TabView`, sheets, alerts, menus, `List`, `ScrollView`) already adapt around the fold and system UI. Do not displace continuously scrolling articles, feeds, documents, or lists merely because a fold exists. Pick the technique with the list above, then see [`ArrangementView`](layout-best-practices.md#two-region-arrangements-ios-271) and [reserved regions](layout-best-practices.md#reserved-regions-ios-271). + +## Duo Displacement Heuristics + +Displacement means moving or resizing the same element around a reserved region, not creating a pose-specific feature. Keep related elements together, move the smallest coherent group, and avoid large jumps that weaken their visual relationship. + +When a partially folded book-like pose requires displacement, a trailing region supports continuity as the device closes toward the outer display. In a table-like pose, the upper region suits content viewed at a distance and the lower stable region suits touch controls. Treat these as heuristics after purpose, reachability, and context, not as pose detection rules. Keep the same controls and general hierarchy everywhere. + +## Hinge Effects, Not Layout + +`onHingeChange` provides live hinge state and angle for optional interactions or effects. Do not use it to drive layout; use size classes, `ArrangementView`, and reserved regions instead. `DeviceHingeContext.hinge` is optional, so reset effect state when there is no hinge or when the relevant hinge status ends. + +```swift +@available(iOS 27.1, *) +struct HingeReactiveArtwork: View { + @State private var foldEffect = 0.0 + + var body: some View { + Artwork() + .scaleEffect(1 + foldEffect * 0.04) + .onHingeChange { _, context in + if let hinge = context.hinge, + hinge.status == .partiallyOpen { + foldEffect = min(max(hinge.angle.degrees / 180, 0), 1) + } else { + foldEffect = 0 + } + } + } +} +``` + +Select this view behind `#available(iOS 27.1, *)`; the fallback omits the optional effect. + +## Scene Accessories + +Scene accessories can pair supplementary content with the main scene on another display, but the system controls their availability and it can change at runtime. Keep enablement state synchronized with `onAvailabilityChange`, disable unavailable controls, and handle failed scene requests rather than inferring availability from pose. For camera accessories, register the accessory with the relevant camera view, but defer capture session, camera selection, preview, and rotation behavior to AVFoundation guidance. + +## Verifying Layouts + +Before claiming a fold or landscape layout works, check whether your environment can pose the iPhone Duo simulator. `simctl` cannot fold or rotate it, but the [RocketSim](https://www.rocketsim.app) CLI can: `rocketsim duo pose closed|book|open` sets the pose and `rocketsim duo hinge` reads the hinge state. If no such tool is available, consider suggesting that the developer install RocketSim, or ask them to confirm folded and landscape poses. Xcode Previews are another way to iterate on layout. + +Resizing is continuous, so also check the extremes, not just named poses: narrowest, widest, shortest, tallest, and roughly square. Look for clipped content, overlapping controls, and text that sprawls at wide sizes. If the root is a `TabView`, see [Tab Bar and Sidebar](sheet-navigation-patterns.md#tab-bar-and-sidebar-ios-27) for the iPhone sidebar presentation. + +## Official Sources + +- [Get ready for iPhone Duo](https://developer.apple.com/iphone-duo/) +- [Preparing your app for iPhone Duo](https://developer.apple.com/documentation/technologyoverviews/preparing-your-app-for-iphone-duo) +- [Designing for iPhone Duo](https://developer.apple.com/design/human-interface-guidelines/designing-for-iphone-duo) +- Apple Tech Talks 111461–111466, especially [Prepare your app](https://developer.apple.com/videos/play/tech-talks/111461/), [Raise the bar](https://developer.apple.com/videos/play/tech-talks/111462/), [Strike a pose](https://developer.apple.com/videos/play/tech-talks/111463/), and [Leverage multiple displays and scenes](https://developer.apple.com/videos/play/tech-talks/111464/) diff --git a/.agents/skills/swiftui-expert-skill/references/latest-apis.md b/.agents/skills/swiftui-expert-skill/references/latest-apis.md index 556c6481..1f5b1d55 100644 --- a/.agents/skills/swiftui-expert-skill/references/latest-apis.md +++ b/.agents/skills/swiftui-expert-skill/references/latest-apis.md @@ -2,12 +2,16 @@ > Based on a comparison of Apple's documentation using the Sosumi MCP, we found the latest recommended APIs to use. +> This file lists *what* the modern replacements are. For *how to behave* when you find a soft-deprecated API — when to migrate, when to leave it alone, and the scoping rule for unrelated edits — see `references/soft-deprecation.md`. To refresh this list after a new SDK release, run the maintenance skill at `.agents/skills/update-swiftui-apis/SKILL.md`. + ## Table of Contents - [Always Use (iOS 15+)](#always-use-ios-15) - [When Targeting iOS 16+](#when-targeting-ios-16) - [When Targeting iOS 17+](#when-targeting-ios-17) - [When Targeting iOS 18+](#when-targeting-ios-18) - [When Targeting iOS 26+](#when-targeting-ios-26) +- [When Targeting iOS 27+](#when-targeting-ios-27) +- [When Targeting iOS 27.1+](#when-targeting-ios-271) --- @@ -21,14 +25,51 @@ These replacements have minimal API shape changes. Most are near-direct swaps; a - **`navigationTitle(_:)`** instead of `navigationBarTitle(_:)` - **`toolbar { ToolbarItem(...) }`** instead of `navigationBarItems(...)` (structural change) -- **`toolbarVisibility(.hidden, for: .navigationBar)`** instead of `navigationBarHidden(_:)` -- **`statusBarHidden(_:)`** instead of `statusBar(hidden:)` - **`ignoresSafeArea(_:edges:)`** instead of `edgesIgnoringSafeArea(_:)` - **`preferredColorScheme(_:)`** instead of `colorScheme(_:)` - **`foregroundStyle(_:)`** instead of `foregroundColor(_:)` (e.g., `.foregroundStyle(.primary)`) - **`clipShape(.rect(cornerRadius:))`** instead of `cornerRadius()` - **`textInputAutocapitalization(_:)`** instead of `autocapitalization(_:)` (note: `.never` replaces `.none`) - **`animation(_:value:)`** instead of `animation(_:)` (adds required `value:` parameter; back-deploys to iOS 13+) +- **`dismiss` or `isPresented` environment values** instead of `PresentationMode` / `presentationMode` +- **`DynamicTypeSize` / `dynamicTypeSize`** instead of `ContentSizeCategory` / `sizeCategory` +- **Closure-based `NavigationLink` destinations** instead of eager `destination:` values +- **Direct `Animatable` conformance** instead of `AnimatableModifier` (use `@Animatable` only when its newer availability fits) + +### Lists and Forms + +**Use trailing-closure `Section` initializers instead of the positional header/footer View initializers.** + +The single-title form is still current and should not be treated as deprecated: + +```swift +// Current - single-title LocalizedStringKey initializer +Section("Settings") { + Toggle("Notifications", isOn: .constant(true)) +} + +// Replacement - content/header/footer trailing-closure initializer +Section { + Toggle("Notifications", isOn: .constant(true)) +} header: { + Text("Settings") +} footer: { + Text("Changes apply immediately.") +} + +// Deprecated/renamed - positional header/footer View arguments +Section(header: Text("Settings"), footer: Text("Changes apply immediately.")) { + Toggle("Notifications", isOn: .constant(true)) +} + +Section(header: Text("Settings")) { + Toggle("Notifications", isOn: .constant(true)) +} + +Section(footer: Text("Changes apply immediately.")) { + Toggle("Notifications", isOn: .constant(true)) +} +``` ### Presentation @@ -107,6 +148,11 @@ NavigationStack { - **`tint(_:)`** instead of `accentColor(_:)` - **`autocorrectionDisabled(_:)`** instead of `disableAutocorrection(_:)` +### Scroll Indicators and Search Suggestions + +- Replace `ScrollView(..., showsIndicators:)` with `ScrollView(...)` plus `scrollIndicators(_:axes:)`. +- Replace `searchable` overloads with an inline suggestions builder by composing `searchable(...)` with `searchSuggestions { ... }`. + ### Clipboard **Prefer `PasteButton` for user-initiated paste UI** to avoid paste prompts. It handles permissions automatically. Use `UIPasteboard` only when you need programmatic or non-`Transferable` clipboard access (triggers the paste permission prompt). @@ -181,10 +227,26 @@ Image("hero") ``` - **`.coordinateSpace(.named("scroll"))`** instead of `.coordinateSpace(name: "scroll")`. +Prefer overloads accepting `CoordinateSpaceProtocol` for `SpatialTapGesture`, location-aware `onTapGesture`, `onContinuousHover`, and `GeometryProxy.frame(in:)`. + +Resolve a color in the current environment before accessing Core Graphics: + +```swift +let cgColor = color.resolve(in: environment).cgColor +``` + --- ## When Targeting iOS 18+ +### Toolbar Visibility + +Use `toolbarVisibility(_:for:)` instead of `navigationBarHidden(_:)` or the older `toolbar(_:for:)` visibility overload. For deployment targets below iOS 18, retain the older modifier in the fallback branch. + +Use `toolbarBackgroundVisibility(_:for:)` instead of the `toolbarBackground(_:for:)` overload whose first argument is `Visibility`. + +On iOS, prefer `.topBarLeading` / `.topBarTrailing` over `.navigationBarLeading` / `.navigationBarTrailing`. + ### Tabs **Use the `Tab` API instead of `tabItem(_:)`.** @@ -199,6 +261,14 @@ TabView { When using `Tab(role:)`, all tabs must use the `Tab` syntax. Mixing `Tab(role:)` with `.tabItem()` causes compilation errors. +On iOS 18.4+ / macOS 15.4+, use the typed customization accessors: + +- `customization[section: id].tabOrder` +- `customization[tab: id].sidebarVisibility` +- `customization[section: id].resetTabOrder()` + +On iOS 27+, `defaultTabBarPlacement(_:)` chooses a sidebar or tab bar on platforms where a `.sidebarAdaptable` `TabView` cannot morph (such as iPhone), and `@Environment(\.isTabViewSidebarAvailable)` reports whether a tab sidebar is available inside the tab content. See [`sheet-navigation-patterns.md`](sheet-navigation-patterns.md#tab-bar-and-sidebar-ios-27). + ### Previews **Use `@Previewable` for dynamic properties in previews.** @@ -277,56 +347,11 @@ TabView { ### Toolbars -**Use `ToolbarSpacer` to control grouping of toolbar items.** Fixed spacers visually separate related groups; flexible spacers push items apart. - -```swift -.toolbar { - ToolbarItem(placement: .topBarTrailing) { - Button("Up", systemImage: "chevron.up") { } - } - ToolbarItem(placement: .topBarTrailing) { - Button("Down", systemImage: "chevron.down") { } - } - ToolbarSpacer(.fixed) - ToolbarItem(placement: .topBarTrailing) { - Button("Settings", systemImage: "gear") { } - } -} -``` - -**Use `sharedBackgroundVisibility(.hidden)` to remove the glass group background from an individual toolbar item.** - -```swift -ToolbarItem(placement: .topBarTrailing) { - Image(systemName: "person.circle.fill") - .sharedBackgroundVisibility(.hidden) -} -``` - -**Use `badge(_:)` on toolbar item content to display an indicator.** - -```swift -ToolbarItem(placement: .topBarTrailing) { - Button("Notifications", systemImage: "bell") { } - .badge(unreadCount) -} -``` - -> Source: "Build a SwiftUI app with the new design" (WWDC25, session 323) +For `ToolbarSpacer`, shared-background visibility, badges, customization, transitions, overflow, and minimization, consult [`toolbar-patterns.md`](toolbar-patterns.md). ### Search -**Use `searchToolbarBehavior(.minimizable)` to opt into a minimized search button.** The system may automatically minimize search into a toolbar button depending on available space. Use this modifier to explicitly opt in. - -```swift -NavigationStack { - ContentView() - .searchable(text: $query) - .searchToolbarBehavior(.minimizable) -} -``` - -> Source: "Build a SwiftUI app with the new design" (WWDC25, session 323) +Use `searchToolbarBehavior(.minimize)` on iOS or visionOS 26+ to opt into a minimized search button. See [`toolbar-patterns.md`](toolbar-patterns.md) for platform availability. ### Animations @@ -443,6 +468,8 @@ PhotoGrid(photos: photos) } ``` +Migrate the older location/`isTargeted` `dropDestination` overload to `dropDestination(for:isEnabled:action:)` when targeting iOS, macOS, or visionOS 26+. Its action receives a `DropSession` and returns `Void`, so this is a behavioral migration rather than a label-only rename. + > Source: "What's new in SwiftUI" (WWDC25, session 256) ### Scene Bridging @@ -453,14 +480,61 @@ PhotoGrid(photos: photos) --- +## When Targeting iOS 27+ + +Use the focused topic references for detailed guidance: + +- [`state-management.md`](state-management.md) +- [`view-structure.md`](view-structure.md) +- [`list-patterns.md`](list-patterns.md) +- [`image-optimization.md`](image-optimization.md) +- [`layout-best-practices.md`](layout-best-practices.md) +- [`sheet-navigation-patterns.md`](sheet-navigation-patterns.md) +- [`toolbar-patterns.md`](toolbar-patterns.md) + +On iOS 27+, use `toolbarVisibility(_:for: .statusBar)` instead of `statusBarHidden(_:)`. `ToolbarPlacement.statusBar` is iOS-only; on visionOS, remove `statusBarHidden` because it has no effect. The newer `dropDestination(for:isEnabled:action:)` overload is also available on visionOS 26+ (as well as iOS/macOS 26+). + +### Additional SDK 27 soft-deprecated families + +Use `Menu` / `MenuStyle` instead of `MenuButton`, `MenuButtonStyle`, and the legacy menu-button styles (`PullDownMenuButtonStyle`, `BorderlessPullDownMenuButtonStyle`, `BorderlessButtonMenuButtonStyle`, `DefaultMenuButtonStyle`, `BorderedButtonMenuStyle`, and `BorderlessButtonMenuStyle`). Use `.menuStyle(.menu)` or `.menuStyle(.button)` with a button style instead of `PopUpButtonPickerStyle`. + +Other lookup entries from the SDK include: + +- `ContextMenu` and `contextMenu(_:)` → `contextMenu(menuItems:)` +- `Section(header:...)/Section(footer:...)/Section(header:footer:...)` → trailing-closure `Section(content:header:footer:)` forms +- `GroupBox(label:content:)` → `GroupBox(content:label:)` +- `Picker(selection:label:content:)` → `Picker(selection:content:label:)` +- `Color(_:)` platform and `CGColor` initializers → `Color(uiColor:)`, `Color(nsColor:)`, and `Color(cgColor:)`; `Color.cgColor` → `resolve(in:).cgColor` +- `onLongPressGesture` overloads with `pressing:` → `onLongPressGesture(minimumDuration:maximumDuration:perform:onPressingChanged:)` or its shorter counterpart +- `Font.system(_:design:)` and legacy `Font.system(size:weight:design:)` forms → `system(_:weight:design:)` and the current size/weight/design overloads +- `Section.collapsible(_:)` → a standard `Section` initializer (collapsibility is no longer enabled by that modifier) +- string-type paste/drop APIs (`PasteButton`, `onPasteCommand`, `onInsert`, and `DropInfo.hasItemsConforming`) → UTType-based APIs + +Platform-specific entries include `CarouselTabViewStyle` → `VerticalTabViewStyle` and `listRowPlatterColor(_:)` → `listItemTint(_:)` on watchOS, `ControlActiveState` → `appearsActive` on macOS, and `SurroundingsEffect.systemDark` → `.dark` on visionOS. + +Search this file's lookup table when migrating an API that the 27 SDK marks soft-deprecated. Do not introduce unrelated migrations during feature work; follow [`soft-deprecation.md`](soft-deprecation.md). + +--- + +## When Targeting iOS 27.1+ + +- `ArrangementView`, `.split` / `.overlay`, and arrangement axis constraints provide adaptive two-region layout and tuning modifiers such as `splitArrangementLayoutRatio`. See [`layout-best-practices.md`](layout-best-practices.md). +- `ReservedRegion` and `GeometryProxy.reservedRegions(kind:options:layoutDirectionBehavior:)` expose division and occlusion geometry for custom layouts. See [`layout-best-practices.md`](layout-best-practices.md). +- `ToolbarContent.axisBehavior(_:)`, `toolbarVerticalEdge`, `toolbarVerticalCompressionBehavior(_:)`, and `toolbarVerticalBehavior(_:)` support adaptive vertical bars. See [`toolbar-patterns.md`](toolbar-patterns.md). +- `onHingeChange` and the optional `DeviceHingeContext.hinge` support live effects and interactions, not layout decisions. For iPhone Duo-specific use, see [`iphone-duo.md`](iphone-duo.md). + +These APIs are from the beta iOS 27.1 SDK. Gate runtime use with `#available(iOS 27.1, *)`, provide an earlier-system fallback, and recheck semantics against the shipping SDK. + +--- + ## Quick Lookup Table | Deprecated | Recommended | Since | |-----------|-------------|-------| | `navigationBarTitle(_:)` | `navigationTitle(_:)` | iOS 15+ | | `navigationBarItems(...)` | `toolbar { ToolbarItem(...) }` | iOS 15+ | -| `navigationBarHidden(_:)` | `toolbarVisibility(.hidden, for: .navigationBar)` | iOS 15+ | -| `statusBar(hidden:)` | `statusBarHidden(_:)` | iOS 15+ | +| `navigationBarHidden(_:)` | `toolbarVisibility(.hidden, for: .navigationBar)` | iOS 18+; retain old API in earlier fallback | +| `statusBar(hidden:)` / `statusBarHidden(_:)` | `toolbarVisibility(_:for: .statusBar)` | iOS 27+; retain old API in earlier fallback | | `edgesIgnoringSafeArea(_:)` | `ignoresSafeArea(_:edges:)` | iOS 15+ | | `colorScheme(_:)` | `preferredColorScheme(_:)` | iOS 15+ | | `foregroundColor(_:)` | `foregroundStyle(_:)` | iOS 15+ | @@ -471,6 +545,9 @@ PhotoGrid(photos: photos) | `accessibility(label:)` etc. | `accessibilityLabel()` etc. | iOS 15+ | | `TextField` `onCommit`/`onEditingChanged` | `onSubmit` + `focused` | iOS 15+ | | `animation(_:)` (no value) | `animation(_:value:)` | Back-deploys (iOS 13+) | +| `Section(header:content:)` | `Section(content:header:)` | Future-deprecated | +| `Section(footer:content:)` | `Section(content:footer:)` | Future-deprecated | +| `Section(header:footer:content:)` | `Section(content:header:footer:)` | Future-deprecated | | Manual `EnvironmentKey` | `@Entry` macro | Back-deploys (Xcode 16+) | | `NavigationView` | `NavigationStack` / `NavigationSplitView` | iOS 16+ | | `accentColor(_:)` | `tint(_:)` | iOS 16+ | @@ -483,6 +560,24 @@ PhotoGrid(photos: photos) | `coordinateSpace(name:)` | `coordinateSpace(.named(...))` | iOS 17+ | | `ObservableObject` | `@Observable` | iOS 17+ | | `tabItem(_:)` | `Tab` API | iOS 18+ | -| Manual `animatableData` | `@Animatable` macro | iOS 26+ | +| Manual 1:1 `animatableData` synthesis | `@Animatable` macro; keep manual logic for clamping/normalization | iOS 26+ | | `presentationBackground(_:)` on sheets | Default Liquid Glass sheet material | iOS 26+ | | Custom toolbar background hacks | `scrollEdgeEffectStyle(_:for:)` | iOS 26+ | +| `CarouselTabViewStyle` (watchOS) | `VerticalTabViewStyle` | SDK 27 soft-deprecated | +| `ControlActiveState` / `controlActiveState` (macOS) | `appearsActive` | SDK 27 soft-deprecated | +| `AnimatableModifier` | Conform the modifier to `Animatable` directly | SDK 27 soft-deprecated | +| `FileDocument`, `ReferenceFileDocument`, and legacy `DocumentGroup` initializers | `Document` (`ReadableDocument` / `WritableDocument`) and closure-based `DocumentGroup` | SDK 27 soft-deprecated; replacement requires aligned 27 releases | +| `TabView(selection:content:)` legacy builder | `TabContentBuilder`-based `TabView` initializers | SDK 27 soft-deprecated | +| `listRowPlatterColor(_:)` (watchOS) | `listItemTint(_:)` | SDK 27 soft-deprecated | +| `toolbarBackground(_:for:)` visibility overload | `toolbarBackgroundVisibility(_:for:)` | iOS 18+ / macOS 15+ | +| `toolbar(_:for:)` visibility overload | `toolbarVisibility(_:for:)` | iOS 18+ / macOS 15+ | +| `searchable(..., suggestions:)` builder overloads | `searchable(...)` plus `searchSuggestions { ... }` | iOS 16+ / macOS 13+ | +| `ScrollView(..., showsIndicators:)` | `ScrollView(...)` plus `scrollIndicators(_:axes:)` | iOS 16+ / macOS 13+ | +| Eager `NavigationLink(destination:)` initializers | Closure destination or value-based navigation | SDK 27 soft-deprecated | +| String type identifiers in paste/drop APIs | `UTType`-based overloads | SDK 27 soft-deprecated | +| Coordinate-space overloads taking `CoordinateSpace` | `CoordinateSpaceProtocol` overloads | iOS 17+ / macOS 14+ | +| Style initializers with `tint:` | Apply `View.tint(_:)` | SDK 27 soft-deprecated | +| Inset/bordered list or table styles with `alternatesRowBackgrounds:` | Base style plus `alternatingRowBackgrounds()` | SDK 27 soft-deprecated | +| `ToolbarItem(..., showsByDefault:)` | `defaultCustomization(_:options:)` with `.hidden` | SDK 27 soft-deprecated | +| `TabViewCustomization` legacy section/sidebar subscripts | Typed `section`/`tab` subscript properties | iOS 18.4+ / macOS 15.4+ | +| Location/`isTargeted` `dropDestination` overload | `dropDestination(for:isEnabled:action:)` with `DropSession` | iOS/macOS/visionOS 26+ | diff --git a/.agents/skills/swiftui-expert-skill/references/layout-best-practices.md b/.agents/skills/swiftui-expert-skill/references/layout-best-practices.md index 03e9a6d0..7045f41e 100644 --- a/.agents/skills/swiftui-expert-skill/references/layout-best-practices.md +++ b/.agents/skills/swiftui-expert-skill/references/layout-best-practices.md @@ -4,6 +4,11 @@ - [Relative Layout Over Constants](#relative-layout-over-constants) - [Context-Agnostic Views](#context-agnostic-views) +- [Adaptive and Resizable Interfaces](#adaptive-and-resizable-interfaces) +- [Adaptive Safe Areas](#adaptive-safe-areas) +- [Two-Column Reflow for Card Screens](#two-column-reflow-for-card-screens) +- [Two-Region Arrangements (iOS 27.1+)](#two-region-arrangements-ios-271) +- [Reserved Regions (iOS 27.1+)](#reserved-regions-ios-271) - [Own Your Container](#own-your-container) - [Layout Performance](#layout-performance) - [View Logic and Testability](#view-logic-and-testability) @@ -35,6 +40,8 @@ VStack { **Why**: Hard-coded values don't account for different screen sizes, orientations, or dynamic content (like status bars during phone calls). +Avoid fixed frames that match one device (for example `.frame(width: 390, height: 844)`) and hard-coded safe-area insets; both break when the window resizes. + ## Context-Agnostic Views **Views should work in any context.** Never assume presentation style or screen size. @@ -72,6 +79,151 @@ struct ProfileCard: View { **Why**: Views should work as full screens, modals, sheets, popovers, or embedded content. +## Adaptive and Resizable Interfaces + +Size views from the **proposed size**, not from a fixed screen or orientation. Prefer `@Environment(\.horizontalSizeClass)` / `verticalSizeClass`, `ViewThatFits`, and `AnyLayout` when choosing a layout variant. Avoid `UIScreen.main`, `UIScreen.main.bounds`, and portrait/landscape assumptions — those do not track the space actually offered to the view (split view, Stage Manager, windows, sheets). + +```swift +struct AdaptiveStack: View { + @Environment(\.horizontalSizeClass) private var horizontalSizeClass + @ViewBuilder let content: Content + + var body: some View { + let layout = horizontalSizeClass == .compact + ? AnyLayout(VStackLayout()) + : AnyLayout(HStackLayout()) + layout { content } + } +} +``` + +Use `ViewThatFits` when a compact alternative should replace a layout that overflows the proposal. Do not branch layout on device orientation or a cached screen size. + +Use size classes for *what* to show (for example, fewer or more columns) and the proposed size, `containerRelativeFrame`, or `GeometryReader` for *how big* to draw something. When a layout decision only changes at a breakpoint, prefer `onChange(of: horizontalSizeClass)` over `onChange(of: geometry.size)`, which fires on every resize step. + +Avoid branching on a size class between two containers that already adapt on their own, such as `TabView` and `NavigationSplitView`. Swapping the container changes view identity mid-resize and discards navigation state and collapse animations. Branch only when the two layouts are genuinely different, and let `NavigationSplitView` and toolbar overflow handle compact-to-regular transitions. For `TabView`, see [Tab Bar and Sidebar](sheet-navigation-patterns.md#tab-bar-and-sidebar-ios-27). + +At wide sizes, consider capping the width of long-form text with `.frame(maxWidth:)` so line lengths stay readable. + +Read `@Environment(\.horizontalSizeClass)` or `@Environment(\.verticalSizeClass)` in the `View` or `ViewModifier` nearest the layout decision. Do not cache a size class in an `App`, `Scene`, model, or view model: those objects do not own the view's current proposal and can go stale during resizing. Move the decision into the view, or pass the current value into non-view code at the point of use when that code genuinely needs it. + +At a representable boundary, use `context.environment.horizontalSizeClass` or `context.environment.verticalSizeClass` in `makeUIView` / `updateUIView` and the corresponding view-controller methods. This carries the SwiftUI layout context into the bridge without process-global state. + +Classify an idiom check before replacing it. Use a size class only when the underlying question is available width or height. A genuine platform, device-idiom, or product-capability decision is not equivalent to a size-class decision, and SwiftUI exposes no user-interface-idiom environment value. Preserve that distinction rather than inventing a size-class mapping or encouraging a global idiom read for ordinary layout. + +## Adaptive Safe Areas + +Make layout decisions from the size SwiftUI proposes to the view. Flag code that subtracts a `GeometryProxy`'s safe-area insets from its size, or reapplies those same insets as padding inside the reporting view: `GeometryProxy.size` already describes the offered content region, so that double-counts space SwiftUI reserved. Reading insets for diagnostics or passing geometry to a container that has a different proposal is not itself a bug; the problem is applying the same inset twice. + +Choose the safe-area modifier by content: + +- Use `safeAreaBar(edge:)` for bar content on iOS 26 and aligned releases. It reserves space and supplies bar appearance and scroll-edge behavior. Use `safeAreaInset(edge:)` as the fallback for older targets. +- Use `safeAreaInset(edge:)` for other controls or content that should occupy an inset region. +- When interactive bar content in a `ZStack` or overlay covers scrolling or other content, move the bar out to `safeAreaBar(edge:)` so SwiftUI reserves its space. Do not apply this replacement to a full-bleed background, gradient, artwork layer, or scrim. +- Use `safeAreaPadding` only for an intentional fixed design margin measured inward from the safe area. It does not read or track the current inset, so do not replace a hardcoded stand-in for a bar or device inset with `safeAreaPadding`; remove the stand-in and let safe-area layout reserve the space. +- Scope `ignoresSafeArea(_:edges:)` to only the intended edges. Ignoring all edges is appropriate for a truly full-bleed visual layer such as a background or scrim, not for readable or interactive content. + +Avoid `GeometryReader` whose only purpose is to read and reapply safe-area insets. Prefer `safeAreaBar`, `safeAreaInset`, or an intentional fixed `safeAreaPadding`, which express placement without manually carrying inset values. + +Vertical toolbar behavior, including `toolbarVerticalEdge`, belongs in [toolbar-patterns.md](toolbar-patterns.md). + +## Two-Column Reflow for Card Screens + +Apple's iPhone Duo guidance says not to just stretch the compact layout: reflow stacked content into two columns when width allows ([HIG](https://developer.apple.com/design/human-interface-guidelines/designing-for-iphone-duo)). For a scrolling card screen, write a custom `Layout` that reads each child's column from a `LayoutValueKey` (set through a small `.column(_:)` modifier). Children without a column span the full width. + +- Choose between the custom layout and `VStackLayout` through `AnyLayout` (see [Adaptive and Resizable Interfaces](#adaptive-and-resizable-interfaces)) when the cards own `@State`, so it survives resizing. A plain branch recreates the cards but is fine when state lives above them, and keeps a compact `LazyVStack`. +- For differently sized cards, assign columns explicitly (masonry). For uniform cards, use a row-major grid that proposes the row's tallest height to both cells; the card surface must accept it (`frame(maxHeight: .infinity)` before the background), opt-in. +- Keep reading and VoiceOver order equal to the single-column order, and keep accessibility Dynamic Type sizes in one column. +- Each column is narrower than the compact screen; grids nested inside may need fewer columns. +- With default `MainActor` isolation, `LayoutValueKey` types and helpers called from `Layout` methods need `nonisolated` if the compiler reports isolated-conformance errors. + +## Two-Region Arrangements (iOS 27.1+) + +`ArrangementView` is a layout container for a primary and secondary view. Prefer the system's adaptive navigation and presentation containers when they already express the interface. Use an arrangement for an existing custom two-region layout that would otherwise be an `HStack`/`VStack` or `ZStack`: + +- `.split` fits a main/detail or peer relationship where neither region should obscure the other. +- `.overlay` fits a foreground/background relationship where temporary overlap is acceptable. + +```swift +struct AdaptivePlayer: View { + var body: some View { + if #available(iOS 27.1, *) { + ArrangementView { + PlayerView() + } secondary: { + UpNextView() + } + .arrangementViewStyle(.split.axes(.horizontal)) + } else { + ViewThatFits { + HStack { + PlayerView() + UpNextView() + } + VStack { + PlayerView() + UpNextView() + } + } + } + } +} +``` + +Both split and overlay styles accept `axes(_:)`. Leave the axes unconstrained when either orientation is valid. Restrict the set only when the content relationship requires it; if a split cannot use the permitted axis in the current proposal, the arrangement may show a single region instead of forcing an unsuitable split. Keep the earlier-OS fallback equivalent in hierarchy and functionality. + +Treat these nesting combinations conservatively in the Xcode 27.1 beta: + +- Do not put `NavigationSplitView` inside `ArrangementView`, or `ArrangementView` inside `NavigationSplitView`. +- Do not put `ArrangementView` inside `List` or `ScrollView`. + +An arrangement supplies layout, not navigation infrastructure. Keep it inside a `NavigationStack` when the arranged content needs stack navigation. Each region handles its own scrolling. + +Apple favors small adjustments over rearrangement. Switching between an arrangement and a different layout rebuilds the regions and drops state such as playback or slider position, so consider keeping one arranged branch on the flat inner display (chosen by size classes) and varying only the split axis, with state that must survive owned above the branch. Use accessibility sort priorities when the arranged visual order differs from the logical order. + +Tuning modifiers (iOS 27.1+): `splitArrangementLayoutRatio`, `splitArrangementLayoutSize`, `splitArrangementFixedLayoutSize`, and `overlayArrangementEdge`; read `@Environment(\.splitArrangementAxis)` and `@Environment(\.overlayArrangementZIndex)` for the current axis and z-index. + +## Reserved Regions (iOS 27.1+) + +Start with system containers and presentations: they already adapt around relevant system UI and hardware regions. Query `GeometryProxy.reservedRegions(kind:options:layoutDirectionBehavior:)` only for custom edge-to-edge UI or manually laid-out controls that cannot be expressed with those containers. + +```swift +GeometryReader { proxy in + let divisions = proxy.reservedRegions(kind: .division) + let occlusions = proxy.reservedRegions(kind: .occlusion) + + CustomCanvas( + divisionFrames: divisions.map(\.frame), + occlusionFrames: occlusions.map(\.frame) + ) +} +``` + +A `.division` region separates the view's bounds into usable areas; use it to move or resize a coherent element into one area rather than spanning the divider. An `.occlusion` region covers a smaller frame within the bounds; keep important visible or interactive content out of that frame. Each `ReservedRegion` also exposes `margins` and `isActive`. + +Apple's documentation disagrees on whether a default query includes inactive regions, so do not rely on it: filter on `isActive` before displacing content, and pass `options: .includeInactive` when a decision needs to know a region exists while inactive: + +```swift +let possibleDivisions = proxy.reservedRegions( + kind: .division, + options: .includeInactive +) +``` + +Do not treat an inactive region as a current obstruction; inspect `isActive` before displacement. Inactive division regions can have a zero-sized frame. + +### Sizing a custom layout around a fold + +To put a gutter over a fold (for example in the [two-column reflow](#two-column-reflow-for-card-screens)), call `onGeometryChange` on the laid-out view, so the region frame shares its coordinate space, and store the result in `@State`. The transform closure is `@Sendable` and must return `Equatable & Sendable` values (`nonisolated` under default `MainActor` isolation). + +- Keep only vertical divisions (`height > width`) for column layouts; a horizontal fold through scrolling content needs no displacement. +- Query with `.includeInactive` so columns don't jump while folding, fall back to an even split for a zero-sized frame, and widen the gutter only while `isActive`. +- Grids: Apple prefers an even column count whenever a division exists, even an inactive one. While the fold is active, size each side separately (margins can be asymmetric) and let the last leading column's spacing cover the fold. + +The query's `layoutDirectionBehavior` defaults to `.mirrors`, so directional geometry follows right-to-left layout. Preserve that default for interface content. Override it only when coordinates intentionally represent physical hardware placement rather than leading/trailing UI, and keep the reason explicit. + +These APIs require the Xcode 27.1 SDK and iOS 27.1 at runtime. Put declarations that name the new types in an `@available(iOS 27.1, *)` scope, select them with `#available`, and keep a safe-area or ordinary adaptive-layout fallback for earlier systems. + ## Own Your Container **Custom views should own static containers but not lazy/repeatable ones.** @@ -256,6 +408,20 @@ Button("Publish Project") { - [ ] Use relative layout over hard-coded constants - [ ] Views work in any context (don't assume screen size) +- [ ] Adapt with proposed size, size classes, `ViewThatFits`, or `AnyLayout` — not `UIScreen.main` or orientation +- [ ] Size classes are read nearest the consuming view (or from representable context), not cached in app/model state +- [ ] Size classes replace available-space decisions, not genuine idiom or product-capability decisions +- [ ] No device-sized fixed frames or hard-coded safe-area insets +- [ ] Breakpoint decisions observe the size class, not every `geometry.size` change; self-adapting containers are not swapped by branch +- [ ] Bar content uses `safeAreaBar` (with an availability fallback); other inset content uses `safeAreaInset` +- [ ] Overlay bars that cover content move to `safeAreaBar`; full-bleed visual layers remain overlays/backgrounds +- [ ] `safeAreaPadding` represents a fixed design margin, not a stand-in for a dynamic inset +- [ ] `ignoresSafeArea` names only intended edges unless the layer is truly full-bleed +- [ ] `GeometryReader` is not used solely to read and reapply safe-area insets +- [ ] `ArrangementView` expresses a two-region layout, has an earlier-OS fallback, and avoids unsupported container nesting +- [ ] System containers are preferred before custom `reservedRegions` handling +- [ ] Reserved-region queries distinguish `.division` from `.occlusion`; `.includeInactive` is intentional +- [ ] Directional reserved-region geometry preserves RTL mirroring unless physical coordinates are explicitly required - [ ] Custom views own static containers - [ ] Avoid deep view hierarchies (layout thrash) - [ ] Gate frequent geometry updates by thresholds diff --git a/.agents/skills/swiftui-expert-skill/references/liquid-glass.md b/.agents/skills/swiftui-expert-skill/references/liquid-glass.md index 907b5c46..f570bc4a 100644 --- a/.agents/skills/swiftui-expert-skill/references/liquid-glass.md +++ b/.agents/skills/swiftui-expert-skill/references/liquid-glass.md @@ -40,7 +40,7 @@ if #available(iOS 26, *) { The primary modifier for applying glass effects to views: ```swift -.glassEffect(_ style: GlassEffectStyle = .regular, in shape: some Shape = .rect) +.glassEffect(_ glass: Glass = .regular, in shape: some Shape = DefaultGlassEffectShape()) ``` #### Basic Usage @@ -48,7 +48,7 @@ The primary modifier for applying glass effects to views: ```swift Text("Hello") .padding() - .glassEffect() // Default regular style, rect shape + .glassEffect() // Default regular style, capsule shape ``` #### With Shape @@ -68,22 +68,27 @@ Text("Capsule") .glassEffect(in: .capsule) ``` -### GlassEffectStyle +### Glass -#### Prominence Levels +#### Available Styles + +The `Glass` type exposes three static values — there is no `.prominent`: ```swift -.glassEffect(.regular) // Standard glass appearance -.glassEffect(.prominent) // More visible, higher contrast +.glassEffect(.regular) // Standard glass appearance (most common) +.glassEffect(.clear) // Nearly invisible glass surface +.glassEffect(.identity) // No-op / pass-through glass ``` +To make a surface appear more prominent, increase the tint opacity instead of reaching for a non-existent `.prominent` property. + #### Tinting Add color tint to the glass: ```swift .glassEffect(.regular.tint(.blue)) -.glassEffect(.prominent.tint(.red.opacity(0.3))) +.glassEffect(.regular.tint(.red.opacity(0.3))) ``` #### Interactivity @@ -194,6 +199,23 @@ struct MorphingExample: View { 3. Wrap in `GlassEffectContainer` 4. Apply animation to the container or parent +### Unioning glass effects + +Use `glassEffectUnion(id:namespace:)` when related glass views should render as one union while remaining separate views in the hierarchy. The ID is optional; use the same ID and namespace for views that belong to the union. + +```swift +@Namespace private var glassNamespace + +HStack { + ActionButton() + .glassEffectUnion(id: "actions", namespace: glassNamespace) + StatusView() + .glassEffectUnion(id: "actions", namespace: glassNamespace) +} +``` + +`glassEffectUnion(id:namespace:)` is available on iOS 26+, macOS 26+, tvOS 26+, and watchOS 26+; it is unavailable on visionOS. + ## Modifier Order **Critical**: Apply `glassEffect` after layout and visual modifiers: @@ -298,8 +320,8 @@ struct GlassSegmentedControl: View { if #available(iOS 26, *) { GlassEffectContainer(spacing: 4) { HStack(spacing: 4) { - ForEach(options.indices, id: \.self) { index in - Button(options[index]) { + ForEach(Array(options.enumerated()), id: \.offset) { index, option in + Button(option) { withAnimation(.smooth) { selection = index } @@ -307,7 +329,9 @@ struct GlassSegmentedControl: View { .padding(.horizontal, 16) .padding(.vertical, 8) .glassEffect( - selection == index ? .prominent.interactive() : .regular.interactive(), + selection == index + ? .regular.tint(.accentColor.opacity(0.4)).interactive() + : .regular.interactive(), in: .capsule ) .glassEffectID(selection == index ? "selected" : "option\(index)", in: animation) @@ -317,8 +341,8 @@ struct GlassSegmentedControl: View { } } else { Picker("Options", selection: $selection) { - ForEach(options.indices, id: \.self) { index in - Text(options[index]).tag(index) + ForEach(Array(options.enumerated()), id: \.offset) { index, option in + Text(option).tag(index) } } .pickerStyle(.segmented) @@ -353,12 +377,12 @@ if #available(iOS 26, *) { extension View { @ViewBuilder func glassEffectWithFallback( - _ style: GlassEffectStyle = .regular, + _ glass: Glass = .regular, in shape: some Shape = .rect, fallbackMaterial: Material = .ultraThinMaterial ) -> some View { if #available(iOS 26, *) { - self.glassEffect(style, in: shape) + self.glassEffect(glass, in: shape) } else { self.background(fallbackMaterial, in: shape) } @@ -403,6 +427,7 @@ An automatic scroll edge effect blurs and fades content under system toolbars to - Apply glass before padding/frame modifiers - Nest `GlassEffectContainer` unnecessarily - Add custom darkening backgrounds behind toolbars (conflicts with scroll edge effect) +- For toolbar grouping, customization, overflow, and minimization, see [toolbar-patterns.md](toolbar-patterns.md). ## Checklist @@ -413,4 +438,4 @@ An automatic scroll edge effect blurs and fades content under system toolbars to - [ ] `glassEffectID` with `@Namespace` for morphing - [ ] Consistent shapes and spacing across feature - [ ] Container spacing matches layout spacing -- [ ] Appropriate prominence levels used +- [ ] Tint opacity used instead of non-existent `.prominent` for emphasis diff --git a/.agents/skills/swiftui-expert-skill/references/list-patterns.md b/.agents/skills/swiftui-expert-skill/references/list-patterns.md index dee87ed7..e0fd2898 100644 --- a/.agents/skills/swiftui-expert-skill/references/list-patterns.md +++ b/.agents/skills/swiftui-expert-skill/references/list-patterns.md @@ -4,6 +4,8 @@ - [ForEach Identity and Stability](#foreach-identity-and-stability) - [Enumerated Sequences](#enumerated-sequences) +- [Reorderable Collections (SDK 27)](#reorderable-collections-sdk-27) +- [Swipe Actions Outside List (SDK 27)](#swipe-actions-outside-list-sdk-27) - [List with Custom Styling](#list-with-custom-styling) - [List with Pull-to-Refresh](#list-with-pull-to-refresh) - [Empty States with ContentUnavailableView (iOS 17+)](#empty-states-with-contentunavailableview-ios-17) @@ -15,6 +17,8 @@ **Always provide stable identity for `ForEach`.** Never use `.indices` for dynamic content. +The same identity rules apply to any data-driven initializer that behaves like `ForEach`: collection-driven `List` (including selection-aware overloads), `Table`, `OutlineGroup`, `Picker` collections, and `DisclosureGroup` content. Ids must be stable, unique, independent of position or mutable content, and cheap to hash. + ```swift // Good - stable identity via Identifiable extension User: Identifiable { @@ -81,6 +85,8 @@ var body: some View { } ``` +Cheap transformations — a small slice, `prefix(n)`, reading an already-prepared array — are fine inline. The rule targets work whose cost scales with the collection or that allocates new elements. + **Avoid `AnyView` in list rows:** ```swift @@ -89,7 +95,7 @@ ForEach(items) { item in AnyView(item.isSpecial ? SpecialRow(item: item) : RegularRow(item: item)) } -// Good - Create a unified row view +// Good - Create a unified row view with a single top-level container ForEach(items) { item in ItemRow(item: item) } @@ -98,17 +104,39 @@ struct ItemRow: View { let item: Item var body: some View { - if item.isSpecial { - SpecialRow(item: item) - } else { - RegularRow(item: item) + // The VStack keeps the row "unary" (one top-level view) so the + // List can template row ids without evaluating every row's body. + VStack { + if item.isSpecial { + SpecialRow(item: item) + } else { + RegularRow(item: item) + } } } } ``` +Replacing `AnyView` with a `@ViewBuilder` helper that still branches at the top level is only half the fix; wrap the branching content in a single-root container so the row stays unary. + **Why**: Stable identity is critical for performance and animations. Unstable identity causes excessive diffing, broken animations, and potential crashes. +### Prefer unary rows in `List` + +`List` needs the identity of every row up front. When each row's body produces a **single top-level view** (a "unary" row), SwiftUI can template the row id from the `ForEach` element's id alone, without running each row's `body`. When the body branches between different top-level shapes — a bare top-level `switch`, a top-level `if` without `else`, or an `AnyView` — structural identity varies per row, so SwiftUI falls back to evaluating every row's body just to compute ids. That cost scales with the number of rows. + +The fix is to wrap branching content in any single-root container (`VStack`, `HStack`, `ZStack`, or a custom wrapper) so the row is always exactly one top-level view, as shown above. `Group` is a passthrough rather than a layout container, so it does not make multiple children unary. A top-level `if` without an `else` is also "multi" (0 or 1 views); if some elements shouldn't be rows at all, filter the collection before it reaches the `ForEach` rather than producing a zero-view row. + +To find non-constant row builders in an existing app, launch with `-LogForEachSlowPath YES`; SwiftUI logs each `ForEach` inside a lazy container whose row body produces a non-constant number of views. + +### Keep ids stable, unique, and cheap + +Three more identity rules that prevent subtle bugs: + +- **The id must outlive the view and not change on edit.** Don't derive `id` from a mutable property (e.g. `var id: String { title }`). Editing the title changes the id, so SwiftUI treats it as a removal plus insertion — focus and per-row state are lost mid-edit. Use a stable `let id: UUID` or a server-assigned key. +- **Don't synthesize a fresh id inside `body`.** `ForEach(items.map { Item(title: $0) })` creates new `UUID`s on every body pass, so the whole collection reads as replaced every update. Create ids once in storage that outlives `body` (the model layer), not inline. +- **Keep the id cheap to hash.** Avoid `id: \.self` on a large `Hashable` struct; hashing walks every field on every diff. Use a small primitive (`UUID`, `Int`, short `String`, `URL`) and still pass the full element to the row. The fix is the id, not removing an unrelated `Hashable` conformance that may be used for selection, sets, or navigation. + ### Identifiable ID Must Be Truly Unique Non-unique IDs cause SwiftUI to treat different items as identical, leading to duplicate rendering or missing views: @@ -131,24 +159,84 @@ struct Article: Identifiable { **Classes get a default `ObjectIdentifier`-based `id`** when conforming to `Identifiable` without providing one. This is only unique for the object's lifetime and can be recycled after deallocation. +Do not conform a type to `Identifiable` just to satisfy `ForEach` when it has no meaningful identity. Pass an explicit `id:` key path for the property that acts as identity in that context. + ## Enumerated Sequences -**Always convert enumerated sequences to arrays. To be able to use them in a ForEach.** +**Using `.enumerated()` is fine; the index just must not be the identity.** Using `\.offset` as the id is the same anti-pattern as `\.self` on `items.indices` — the id becomes the position, not the element, so inserts and reorders reset row state and break animations. Keep the element's own identity as the id and treat the index as ordinary row data. ```swift -let items = ["A", "B", "C"] +// Wrong - offset is the position, not the element +ForEach(items.enumerated(), id: \.offset) { index, item in + ItemRow(number: index + 1, item: item) +} -// Correct -ForEach(Array(items.enumerated()), id: \.offset) { index, item in - Text("\(index): \(item)") +// Correct - id comes from the element; index is just data +ForEach(items.enumerated(), id: \.element.id) { index, item in + ItemRow(number: index + 1, item: item) } +``` -// Wrong - Doesn't compile, enumerated() isn't an array -ForEach(items.enumerated(), id: \.offset) { index, item in - Text("\(index): \(item)") +**No `Array(...)` wrapper is needed on Swift 6.1+.** As of Swift 6.1, the sequence returned by `.enumerated()` conditionally conforms to `RandomAccessCollection` when the base collection does, so `ForEach` accepts it directly. On earlier toolchains, wrap it in `Array(...)`. Favor the direct form in new code — it avoids an eager copy on every body evaluation. + +## Reorderable Collections (SDK 27) + +`reorderable()` on `ForEach` plus `reorderContainer(for:)` on the enclosing container bring drag reordering to lists, stacks, grids, and custom layouts: + +```swift +LazyVGrid(columns: columns) { + ForEach(items) { item in + ItemView(item) + } + .reorderable() } +.reorderContainer(for: Item.self) { difference in + apply(difference, to: &items) // drop moved items in source order, then insert +} +``` + +Availability: iOS, macOS, watchOS, and visionOS 27; unavailable on tvOS. Gate when the deployment target is older. + +`Item` must be `Identifiable` for the `for:` overload (it keys on `\.id`). If the type is not `Identifiable`, or you want a different identifier, use the `itemID:` key-path overload: `reorderContainer(for: Item.self, itemID: \.code)` paired with the same `.reorderable()`. + +`ReorderDifference` provides `sources` and a destination of `.before(id)` or `.end`. Apply it by dropping the moved items in a single pass that **preserves their source order**, then insert that captured sequence at the destination. Reconstructing from a `Set` loses order. For a single-collection container, `CollectionID` is `ReorderableSingleCollectionIdentifier`. For multiple sections, add `collectionID:` to each reorderable collection and use `reorderContainer(for:in:)`; route by `destination.collectionID`. + +### Drag and drop + +`.reorderContainer(for:)` already acts as a drag container and a drop destination. A standalone `.draggable` does not customize the reorder container; provide `dragContainer(for:)` instead. Return an empty collection from the `dragContainer` closure to disable drag for that item. + +Drag/drop customization availability differs from reordering: + +| API | iOS | macOS | watchOS | tvOS | visionOS | +|---|---|---|---|---|---| +| `reorderable()` / `reorderContainer(for:…)` | 27 | 27 | 27 | n/a | 27 | +| `dragContainer` / `draggable(containerItemID:)` | 27 | 26 | n/a | n/a | 27 | +| `DropSession` / `dropDestination(for:…session…)` | 26 | 26 | n/a | n/a | 26 | +| `DropSession.reorderDestination(for:)` | 27 | 27 | n/a | n/a | 27 | + +watchOS can reorder locally but has no system drag/drop integration. + +**Combine by dropping one item onto another.** Put `.dropDestination(for:isEnabled:)` on each child. The closure signature is `(items: [T], session: DropSession) -> Void`. Put the per-item predicate in `isEnabled:`, not inside the closure. Do not use the `dropDestination(for:) { } isTargeted: { }` overload here — that reports hover for custom visuals and does not gate combining. + +**Accept drops at the reorder position.** Put `.dropDestination(for:)` on the container and ask `session.reorderDestination(for:)`. A `nil` destination means the drop did not hover a specific item; append. + +## Swipe Actions Outside List (SDK 27) + +Rows in a scrollable stack or grid can use existing `swipeActions` when the enclosing scroll container has `swipeActionsContainer()`. Without that modifier, row swipe actions outside `List` have no effect. `edge` defaults to `.trailing` and `allowsFullSwipe` defaults to `true`. The `swipeActions(..., onPresentationChanged:)` overload reports whether actions are revealed. + +```swift +ScrollView { + LazyVStack { + ForEach(items) { item in + ItemRow(item: item).swipeActions { /* buttons */ } + } + } +} +.swipeActionsContainer() ``` +Availability: `swipeActionsContainer()` and `onPresentationChanged` are iOS, macOS, watchOS, and visionOS 27; unavailable on tvOS. The original row `swipeActions(edge:allowsFullSwipe:content:)` has been available since iOS 15 / macOS 12 / watchOS 8 / visionOS 1 and does not need gating inside `List`. + ## List with Custom Styling ```swift @@ -432,12 +520,15 @@ Table(people) { /* columns */ } ## Summary Checklist -- [ ] ForEach uses stable identity (never `.indices` for dynamic content) +- [ ] ForEach uses stable identity (never `.indices` or `\.offset` for dynamic content); the same id rules apply to selection-aware `List`, `Picker`, and disclosure collections +- [ ] SDK 27 reordering uses `reorderable()` + `reorderContainer`; apply `ReorderDifference` in source order +- [ ] Swipe actions outside `List` sit inside `swipeActionsContainer()` - [ ] Identifiable IDs are truly unique across all items -- [ ] Constant number of views per ForEach element +- [ ] id is stable across edits (not derived from a mutable property), created outside `body`, and cheap to hash +- [ ] Constant number of views per ForEach element; rows are unary (single top-level view) - [ ] No inline filtering in ForEach (prefilter and cache instead) - [ ] No `AnyView` in list rows -- [ ] Don't convert enumerated sequences to arrays +- [ ] `.enumerated()` uses the element's id (not `\.offset`); no `Array(...)` wrapper needed on Swift 6.1+ - [ ] Use `.refreshable` for pull-to-refresh - [ ] Use `ContentUnavailableView` for empty states (iOS 17+) - [ ] Use `.scrollContentBackground(.hidden)` for custom list backgrounds diff --git a/.agents/skills/swiftui-expert-skill/references/localization.md b/.agents/skills/swiftui-expert-skill/references/localization.md new file mode 100644 index 00000000..c2f7750d --- /dev/null +++ b/.agents/skills/swiftui-expert-skill/references/localization.md @@ -0,0 +1,194 @@ +# SwiftUI Localization Reference + +Guidance for user-facing text: `Text`, `Button`, `Label`, navigation/toolbar titles, alerts, and types that carry localizable strings. For the narrower "verbatim vs localized" decision on a single `Text`, see `references/text-patterns.md`. + +## Table of Contents + +- [SwiftUI Localizes String Literals Automatically](#swiftui-localizes-string-literals-automatically) +- [String Catalogs](#string-catalogs) +- [Bundle for Swift Packages and Frameworks](#bundle-for-swift-packages-and-frameworks) +- [Localizing Variables and Custom Types](#localizing-variables-and-custom-types) +- [LocalizedStringResource for Non-View Types](#localizedstringresource-for-non-view-types) +- [Interpolation vs Concatenation](#interpolation-vs-concatenation) +- [Casing](#casing) +- [Formatting Dates, Numbers, and Currencies](#formatting-dates-numbers-and-currencies) +- [Layout for Localization](#layout-for-localization) +- [Reading the Current Locale](#reading-the-current-locale) +- [String(localized:) Outside SwiftUI Views](#stringlocalized-outside-swiftui-views) +- [Comments for Translators](#comments-for-translators) + +## SwiftUI Localizes String Literals Automatically + +Initializers that accept `LocalizedStringKey` (`Text`, `Button`, `Label`, `.navigationTitle`, alert titles, and so on) treat string literals as localization keys automatically. Do not wrap literals in `NSLocalizedString`, `String(localized:)`, or `LocalizedStringResource` — that resolves the string eagerly and ignores `\.locale` overrides. + +```swift +// AVOID: double work, and resolves eagerly +Text(String(localized: "start_workout")) + +// PREFER: pass the literal directly +Text("start_workout") +``` + +Both opaque keys (`"start_workout"`) and natural-language strings (`"Start Workout"`) work as keys — pick whichever convention the project already uses. Use `Text(verbatim:)` only to opt a literal out of localization (e.g. a debug label interpolating a runtime value). When the argument is already a `String` variable, `Text(value)` calls the `StringProtocol` overload and skips localization on its own. + +## String Catalogs + +Most projects localize through String Catalogs (`.xcstrings`). Each build syncs new keys from code into the catalog, but the catalog file must already exist — Xcode doesn't create one automatically. If a project already uses `.strings` / `.stringsdict`, add new strings there rather than migrating. Route groups of strings to a specific catalog with `tableName:`. + +```swift +Text("Explore", tableName: "Navigation", + comment: "Tab bar item title for the Explore screen.") +``` + +## Bundle for Swift Packages and Frameworks + +Apps, app extensions, and XPC services are their own main bundle, so `bundle` can be omitted. Frameworks and Swift packages need an explicit `bundle:` — without one, SwiftUI looks up strings in `Bundle.main`, the lookup fails silently, and the string appears unlocalized at runtime. + +```swift +// AVOID (inside a framework/package): searches the app's catalog +Text("Save to Favorites") + +// PREFER: #bundle resolves to the current target's bundle +Text("Save to Favorites", bundle: #bundle, + comment: "Button to bookmark a recipe.") +``` + +`#bundle` is the preferred form; `Bundle.module` and `Bundle(for:)` still work but are older patterns. + +## Localizing Variables and Custom Types + +A `String` variable passed to `Text` runs the `StringProtocol` overload and is **not** localized. Wrapping it in `LocalizedStringKey(_:)` doesn't help — Xcode can't extract a literal from a runtime value, so nothing lands in the catalog. To localize a value chosen from a known set, model it with a type that exposes `LocalizedStringResource`: + +```swift +enum Category { + case appetizers, mains, desserts + var name: LocalizedStringResource { + switch self { + case .appetizers: "Appetizers" + case .mains: "Mains" + case .desserts: "Desserts" + } + } +} + +Text(category.name) +``` + +When a view or model exposes user-facing text, type the property as `LocalizedStringKey` or `LocalizedStringResource` rather than `String`. Every SwiftUI view that takes localized text accepts both, so deferring resolution costs nothing at the display site and preserves locale/bundle context. + +## LocalizedStringResource for Non-View Types + +When a non-view type carries user-facing text — a model object, a tip, a queued notification — use `LocalizedStringResource` instead of `String`. It defers resolution to display time, so it honors the locale active when the value actually renders, not when it was created. + +```swift +// AVOID: resolved at creation time, can't re-render in another locale +struct Tip { let headline: String } +let tip = Tip(headline: String(localized: "Tip of the Day")) + +// PREFER: resolution deferred to display time +struct Tip { let headline: LocalizedStringResource } +let tip = Tip(headline: "Tip of the Day") +``` + +Apply this when designing new types or changing user-facing text — don't sweep through existing `String` properties as part of unrelated edits. + +## Interpolation vs Concatenation + +String interpolation preserves `LocalizedStringKey` and produces a format string in the catalog (e.g. `"Welcome, %@"`). Concatenation with `+` produces a plain `String` and is not localized. Never glue separately localized fragments into a sentence — word order varies across languages. + +```swift +// AVOID: + produces String; sentence assembly breaks word order +Text("Error: " + statusMessage) +Text(String(localized: "Created by")) + Text(" ") + Text(authorName) + +// PREFER: one interpolated string translators can rearrange +Text("Error: \(statusMessage)") +Text("Created by \(authorName)") +``` + +## Casing + +Bake the desired case into the string rather than transforming at runtime via `.textCase(_:)`, `.localizedUppercase`, or `.localizedCapitalized`. A runtime transform forces the same casing on every translation, leaving translators no room to adjust per language. + +```swift +// AVOID +Text("Section Header").textCase(.uppercase) + +// PREFER +Text("SECTION HEADER") +``` + +This applies to localized strings; display user-entered text as-is. If a transform is unavoidable, prefer `.localizedUppercase` / `.localizedCapitalized`, which honor the user's locale. + +## Formatting Dates, Numbers, and Currencies + +Use `Text`'s `format:` parameter or `.formatted()` instead of `DateFormatter` / `NumberFormatter` with hardcoded format strings. Format styles adapt to the user's locale; hardcoded format strings don't. + +```swift +// AVOID +let f = DateFormatter(); f.dateFormat = "MM/dd/yyyy" +Text(f.string(from: workout.date)) +Text("$\(product.price, specifier: "%.2f")") + +// PREFER +Text(workout.date, format: .dateTime.month().day().year()) +Text(product.price, format: .currency(code: store.currencyCode)) +``` + +Field components (`.month()`, `.day()`) choose which fields appear; the locale decides the order. For lists, `Array.formatted()` inserts locale-correct separators and conjunctions instead of `joined(separator:)`. When `DateFormatter` is genuinely unavoidable, use `setLocalizedDateFormatFromTemplate(_:)` rather than assigning `dateFormat`. + +## Layout for Localization + +- Use `.leading` / `.trailing` instead of `.left` / `.right` — they flip for right-to-left locales. +- Don't hardcode frame widths/heights for text; translations vary in length and scripts vary in height. Use `ViewThatFits` when a layout might not fit longer translations. +- Use text styles (`.body`, `.headline`) rather than fixed point sizes, so line height adapts per script. + +```swift +// PREFER +Text(recipe.title) + .frame(maxWidth: .infinity, alignment: .leading) + +ViewThatFits { + HStack { actionButtons } + VStack { actionButtons } +} +``` + +## Reading the Current Locale + +Use `@Environment(\.locale)` for locale-dependent logic in views, not `Locale.current` — the environment respects preview overrides and per-view injection. + +## String(localized:) Outside SwiftUI Views + +When you need a localized `String` outside a view, use `String(localized:)`, not `NSLocalizedString`. Don't interpolate inside `NSLocalizedString` — Xcode extracts keys from literals at build time and can't extract interpolated values. `String(localized:)` supports interpolation (it extracts the format string and treats values as runtime arguments) and is preferred over `String(format:)`, which always renders digits as 0–9 regardless of locale. + +```swift +// PREFER +let title = String(localized: "activity_summary", comment: "Dashboard header") +``` + +## Comments for Translators + +Add a `comment:` describing the UI element and its purpose, especially for ambiguous strings. For interpolated strings, describe each placeholder by position — translators don't see Swift variable names. Comments can live at the call site or in the String Catalog's per-string Comment field; keep one source of truth per string. + +```swift +// AVOID: "Edit" could be a noun or a verb +Text("Edit") + +// PREFER +Text("Edit", comment: "Toolbar button that enters editing mode for the list.") +Text("Completed \(count) of \(total)", + comment: "Progress label — first variable is finished items, second is the total.") +``` + +## Summary Checklist + +- [ ] String literals passed directly to `Text`/`Button`/`Label` (not wrapped in `NSLocalizedString`/`String(localized:)`) +- [ ] `bundle: #bundle` on user-facing strings inside frameworks and Swift packages +- [ ] User-facing text on models/non-view types typed as `LocalizedStringResource`, not `String` +- [ ] Interpolation (not `+`) for dynamic strings; no sentence assembly from fragments +- [ ] Case baked into the string, not applied via `.textCase` +- [ ] Dates/numbers/currencies use `format:` / `.formatted()` with locale-aware styles +- [ ] `.leading`/`.trailing` (not `.left`/`.right`); no hardcoded text frame sizes +- [ ] `@Environment(\.locale)` for locale logic in views +- [ ] `comment:` provided for ambiguous strings and interpolated placeholders diff --git a/.agents/skills/swiftui-expert-skill/references/macos-scenes.md b/.agents/skills/swiftui-expert-skill/references/macos-scenes.md index c6056056..f6cef480 100644 --- a/.agents/skills/swiftui-expert-skill/references/macos-scenes.md +++ b/.agents/skills/swiftui-expert-skill/references/macos-scenes.md @@ -254,13 +254,15 @@ Document-based apps with automatic file management. On macOS, provides: - **Multiple document windows** simultaneously - On iOS, shows a document browser instead +> **SDK 27+:** on iOS 27 / macOS 27 / visionOS 27 and later, prefer the `Document` protocol (`ReadableDocument` / `WritableDocument`) with the closure-based `DocumentGroup` initializer — see `references/document-apps.md`. The rest of this section covers `FileDocument` and `ReferenceFileDocument`, which are soft-deprecated in the SDK 27 toolchain but remain the compatible option for older deployment targets. + ```swift DocumentGroup(newDocument: TextFile()) { config in ContentView(document: config.$document) } ``` -The document type must conform to `FileDocument` (value type) or `ReferenceFileDocument` (reference type). Key requirements: +For deployment targets below the 27 releases, the document type must conform to `FileDocument` (value type) or `ReferenceFileDocument` (reference type). Key requirements: ```swift struct TextFile: FileDocument { diff --git a/.agents/skills/swiftui-expert-skill/references/macos-views.md b/.agents/skills/swiftui-expert-skill/references/macos-views.md index 239a6d24..ff5335d7 100644 --- a/.agents/skills/swiftui-expert-skill/references/macos-views.md +++ b/.agents/skills/swiftui-expert-skill/references/macos-views.md @@ -90,7 +90,8 @@ Table(people) { /* columns */ } // Bordered with alternating row backgrounds Table(people) { /* columns */ } - .tableStyle(.bordered(alternatesRowBackgrounds: true)) + .tableStyle(.bordered) + .alternatingRowBackgrounds() // Inset (no borders) Table(people) { /* columns */ } @@ -101,6 +102,8 @@ Table(people) { /* columns */ } .tableColumnHeaders(.hidden) ``` +Apply `.alternatingRowBackgrounds()` as a separate modifier instead of passing `alternatesRowBackgrounds:` to `.bordered` (soft-deprecated in SDK 27). + --- ## PasteButton & CopyButton diff --git a/.agents/skills/swiftui-expert-skill/references/modifier-patterns.md b/.agents/skills/swiftui-expert-skill/references/modifier-patterns.md new file mode 100644 index 00000000..03a8d24c --- /dev/null +++ b/.agents/skills/swiftui-expert-skill/references/modifier-patterns.md @@ -0,0 +1,64 @@ +# SwiftUI Modifier and Identity Patterns + +Use this reference when a modifier is conditional or when modifier composition changes a view's structural identity. + +## Avoid Conditional `.if` Modifiers + +Do not create an `@ViewBuilder` extension that switches between `transform(self)` and `self`. Its branches produce different view types, so toggling the condition can replace the subtree, reset state, and break animations. + +```swift +// AVOID +extension View { + @ViewBuilder + func `if`( + _ condition: Bool, + transform: (Self) -> Content + ) -> some View { + if condition { transform(self) } else { self } + } +} +``` + +When two states describe the same view, keep one structural identity and vary the modifier's value: + +```swift +Text("Hello") + .foregroundStyle(isHighlighted ? .red : .primary) + .opacity(isEnabled ? 1 : 0.5) +``` + +Use `if` when the branches genuinely represent different views or when content is truly optional. Do not silently refactor an existing `.if` modifier during unrelated work; call out the identity risk and keep the behavioral change focused. + +## Use `AnyShapeStyle` When Style Types Differ + +Some `ShapeStyle` branches do not unify in a ternary. Preserve the view's identity by erasing the styles, not the view: + +```swift +Text("Status") + .foregroundStyle( + isActive + ? AnyShapeStyle(.primary) + : AnyShapeStyle(.tint) + ) +``` + +`AnyShapeStyle` is an appropriate value-type eraser and does not have the structural-identity cost of `AnyView`. Add it only when the original ternary does not compile; many combinations involving `Color`, such as `.yellow` and `.primary`, already unify. + +## Prefer No-Effect Values for Visual State + +For visibility or styling changes where the same view should retain state, prefer an always-present modifier with a no-effect value: + +```swift +DetailsView() + .opacity(isVisible ? 1 : 0) +``` + +Opacity keeps the view in layout and accessibility by default. Use conditional inclusion when hidden content should be removed from layout, interaction, or accessibility. + +## Checklist + +- [ ] Conditional styling changes modifier values instead of branching the whole view +- [ ] Existing `.if` helpers are reported as focused identity risks, not rewritten incidentally +- [ ] `AnyShapeStyle` is used only when different style types fail to unify +- [ ] `AnyView` is not introduced to solve a modifier type mismatch +- [ ] Visibility behavior intentionally accounts for layout, hit testing, and accessibility diff --git a/.agents/skills/swiftui-expert-skill/references/performance-patterns.md b/.agents/skills/swiftui-expert-skill/references/performance-patterns.md index 1a595afc..b62c68c2 100644 --- a/.agents/skills/swiftui-expert-skill/references/performance-patterns.md +++ b/.agents/skills/swiftui-expert-skill/references/performance-patterns.md @@ -232,7 +232,7 @@ struct ItemRow: View { } ``` -**Avoid storing frequently-changing values in the environment.** Even when a view doesn't read the changed key, SwiftUI still checks all environment readers. This cost adds up with many views and frequent updates (geometry values, timers). +For rapidly changing environment values, stable defaults, and closure comparison pitfalls, consult `references/environment-patterns.md`. Moving a raw value into `@Observable` is not enough by itself; readers need a coarsened or per-item property that changes less often. > Source: "Optimize SwiftUI performance with Instruments" (WWDC25, session 306) diff --git a/.agents/skills/swiftui-expert-skill/references/previews.md b/.agents/skills/swiftui-expert-skill/references/previews.md new file mode 100644 index 00000000..6e19d2bf --- /dev/null +++ b/.agents/skills/swiftui-expert-skill/references/previews.md @@ -0,0 +1,313 @@ +# SwiftUI Previews Reference + +## Table of Contents + +- [Preview Macro](#preview-macro) +- [Preview with Mock Data](#preview-with-mock-data) +- [@Previewable Property Wrappers](#previewable-property-wrappers) +- [Common Diagnostics](#common-diagnostics) +- [Summary Checklist](#summary-checklist) + +--- + +## Preview Macro + +The `#Preview` macro (Swift 5.9+, Xcode 15+) is the modern way to declare previews. The legacy `PreviewProvider` protocol still works; prefer `#Preview` for new code because it's less verbose and supports inline traits. + +### Basic Usage + +```swift +// Modern: #Preview macro +#Preview { + ContentView() +} + +// Named preview +#Preview("Dark Mode") { + ContentView() + .preferredColorScheme(.dark) +} + +// Legacy: PreviewProvider — still valid, but verbose for new code +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + ContentView() + } +} +``` + +### Multiple Previews + +Declare one `#Preview` per meaningful state so each renders independently in the canvas: + +```swift +#Preview("Default") { + SettingsRow(title: "Notifications", isOn: true) +} + +#Preview("Off State") { + SettingsRow(title: "Notifications", isOn: false) +} + +#Preview("Long Title") { + SettingsRow(title: "Enable Push Notifications for All Events", isOn: true) +} +``` + +### Preview Traits + +Traits configure the preview environment without modifying the view itself: + +```swift +// Fixed size +#Preview(traits: .fixedLayout(width: 300, height: 100)) { + CompactBanner(message: "Welcome") +} + +// Size that fits content +#Preview(traits: .sizeThatFitsLayout) { + BadgeView(count: 5) +} + +// Landscape orientation +#Preview(traits: .landscapeLeft) { + DashboardView() +} +``` + +### Previewing Inside NavigationStack + +Wrap previewed destinations in their navigation container so toolbar items, titles, and back buttons render correctly: + +```swift +#Preview { + NavigationStack { + DetailView(item: .sample) + } +} +``` + +--- + +## Preview with Mock Data + +Previews must compile and render without external dependencies. Live services, network calls, and disk I/O make previews slow, flaky, or broken; use self-contained sample data instead. + +### Static Sample Data + +Expose sample values as static properties on the model itself so any preview can reuse them without reconstructing values inline: + +```swift +struct Item: Identifiable { + let id: UUID + var name: String + var price: Double +} + +extension Item { + static let sample = Item(id: UUID(), name: "Widget", price: 9.99) + + static let samples: [Item] = [ + Item(id: UUID(), name: "Widget", price: 9.99), + Item(id: UUID(), name: "Gadget", price: 19.99), + Item(id: UUID(), name: "Doohickey", price: 4.99), + ] +} + +#Preview { + ItemListView(items: Item.samples) +} +``` + +### Mock Observable Models + +For views driven by an `@Observable` model (see `state-management.md` for fundamentals), expose pre-configured instances on the model itself: + +```swift +@Observable +@MainActor +final class CartModel { + var items: [Item] = [] + var isLoading = false + + static var preview: CartModel { + let model = CartModel() + model.items = Item.samples + return model + } + + static var emptyPreview: CartModel { + CartModel() + } + + static var loadingPreview: CartModel { + let model = CartModel() + model.isLoading = true + return model + } +} + +#Preview("With Items") { + CartView() + .environment(CartModel.preview) +} + +#Preview("Empty") { + CartView() + .environment(CartModel.emptyPreview) +} + +#Preview("Loading") { + CartView() + .environment(CartModel.loadingPreview) +} +``` + +### Preview with Environment Dependencies + +Inject any environment values the view depends on so the preview reflects a realistic runtime context: + +```swift +#Preview { + OrderDetailView(order: .sample) + .environment(CartModel.preview) + .environment(\.locale, Locale(identifier: "ja_JP")) + .environment(\.dynamicTypeSize, .xxxLarge) +} +``` + +### Mocking Async Data Sources + +When a view depends on a network or data service, give the dependency a protocol abstraction so previews can inject a synchronous mock that returns sample data immediately. This is one approach — adapt it to whatever pattern the surrounding codebase already uses. + +```swift +protocol DataFetching { + func fetchItems() async throws -> [Item] +} + +struct LiveDataFetcher: DataFetching { + let url: URL + + func fetchItems() async throws -> [Item] { + let (data, _) = try await URLSession.shared.data(from: url) + return try JSONDecoder().decode([Item].self, from: data) + } +} + +struct MockDataFetcher: DataFetching { + var result: Result<[Item], Error> = .success(Item.samples) + + func fetchItems() async throws -> [Item] { + try result.get() + } +} + +#Preview { + ItemListView(fetcher: MockDataFetcher()) +} + +#Preview("Error State") { + ItemListView(fetcher: MockDataFetcher(result: .failure(URLError(.notConnectedToInternet)))) +} +``` + +--- + +## @Previewable Property Wrappers + +`@Previewable` (iOS 18+, Xcode 16+) lets you use `@State`, `@FocusState`, and other property wrappers directly inside a `#Preview` block, removing the need for a wrapper view to host interactive state. + +### Interactive State + +```swift +// @Previewable: interactive toggle inline in the preview +#Preview { + @Previewable @State var isOn = false + Toggle("Notifications", isOn: $isOn) +} + +// Without @Previewable: requires a wrapper view +struct TogglePreviewWrapper: View { + @State private var isOn = false + var body: some View { + Toggle("Notifications", isOn: $isOn) + } +} + +#Preview { + TogglePreviewWrapper() +} +``` + +### Multiple Interactive Controls + +```swift +#Preview { + @Previewable @State var name = "Alice" + @Previewable @State var age = 25.0 + + VStack { + TextField("Name", text: $name) + Slider(value: $age, in: 0...100, step: 1) { + Text("Age: \(Int(age))") + } + Text("Hello, \(name)! Age: \(Int(age))") + } + .padding() +} +``` + +### @Previewable with @FocusState + +When seeding initial focus inside a preview, prefer `.defaultFocus` over writing to `@FocusState` from `.onAppear`. `.onAppear` can race the initial render and the focus assignment may be lost. See `focus-patterns.md` for the underlying rationale. + +```swift +#Preview { + @Previewable @FocusState var isFocused: Bool + + TextField("Search", text: .constant("")) + .focused($isFocused) + .defaultFocus($isFocused, true) +} +``` + +### Fallback for Pre-iOS 18 Targets + +If the project's minimum deployment target is below iOS 18, `@Previewable` is unavailable. Fall back to a wrapper view: + +```swift +private struct SliderPreview: View { + @State private var value = 0.5 + var body: some View { + CustomSlider(value: $value) + } +} + +#Preview { + SliderPreview() +} +``` + +--- + +## Common Diagnostics + +| Symptom | Cause | Fix | +|---|---|---| +| `#Preview` body type mismatch | The closure returns a non-`View` type | Make sure the final expression is a `View` | +| `@Previewable` only available in iOS 18+ | Using `@Previewable` with a lower deployment target | Use a wrapper view, or gate with `#available` | +| Preview crashes with "missing environment" | An `@Environment(SomeType.self)` value is not injected | Add `.environment(SomeType.preview)` to the preview | +| Preview hangs or renders blank | View depends on async data that never resolves | Inject a mock that returns immediately with sample data | +| `@MainActor`-isolated model accessed from non-isolated context | A preview helper touches main-actor-only API off the main actor | Mark the helper or the preview body `@MainActor` | + +--- + +## Summary Checklist + +- [ ] Prefer `#Preview` for new previews; `PreviewProvider` is still valid for older code +- [ ] Provide a named preview for each meaningful state (default, empty, error, loading) +- [ ] Use `@Previewable` for interactive previews when targeting iOS 18+; wrapper views otherwise +- [ ] Expose static `.sample` / `.preview` data on models so previews don't reconstruct values inline +- [ ] Inject mock services through a protocol when a view depends on async data +- [ ] Never depend on live network or disk I/O in a preview +- [ ] Prefer `.defaultFocus` over `.onAppear` writes when seeding `@FocusState` in previews diff --git a/.agents/skills/swiftui-expert-skill/references/scroll-patterns.md b/.agents/skills/swiftui-expert-skill/references/scroll-patterns.md index 7fe50018..6827d556 100644 --- a/.agents/skills/swiftui-expert-skill/references/scroll-patterns.md +++ b/.agents/skills/swiftui-expert-skill/references/scroll-patterns.md @@ -2,15 +2,23 @@ ## Table of Contents +- [Choose the Appropriate Scroll API](#choose-the-appropriate-scroll-api) - [ScrollViewReader for Programmatic Scrolling](#scrollviewreader-for-programmatic-scrolling) - [Scroll Position Tracking](#scroll-position-tracking) - [Scroll Transitions and Effects](#scroll-transitions-and-effects) - [Scroll Target Behavior](#scroll-target-behavior) - [Summary Checklist](#summary-checklist) +## Choose the Appropriate Scroll API + +- On iOS 18+, use `onScrollGeometryChange(for:of:action:)` to observe scroll geometry. +- On iOS 18+, use `scrollPosition(_:)` with `ScrollPosition` to scroll by identity, offset, or edge. +- On iOS 17+, use `scrollPosition(id:)` when an optional ID binding is sufficient. +- Use `ScrollViewReader` when proxy-based scrolling or support for earlier versions is needed. + ## ScrollViewReader for Programmatic Scrolling -**Use `ScrollViewReader` for scroll-to-top, scroll-to-bottom, and anchor-based jumps.** +**Use `ScrollViewReader` for proxy-based scroll-to-top, scroll-to-bottom, and anchor-based jumps.** ```swift struct ChatView: View { @@ -77,92 +85,130 @@ struct FeedView: View { } ``` -**Why**: `ScrollViewReader` provides programmatic scroll control with stable anchors. Always use stable IDs and explicit animations. +**Why**: `ScrollViewReader` provides proxy-based programmatic scroll control. Use stable IDs for scroll targets, and add animation when an animated transition is appropriate. ## Scroll Position Tracking -### Basic Scroll Position +> **iOS 18+**: Use `onScrollGeometryChange(for:of:action:)` to observe scroll geometry and `scrollPosition(_:)` with a `ScrollPosition` binding for flexible programmatic scrolling. For iOS 17, use `scrollPosition(id:)` with an optional ID binding. + +### Observe Scroll Geometry (iOS 18+) -**Avoid** - Storing scroll position directly triggers view updates on every scroll frame: +`onScrollGeometryChange` transforms frequently changing `ScrollGeometry` into an `Equatable` value and runs its action when that transformed value changes. Extract the smallest value needed by the feature. + +When exact offset tracking is required, extract `contentOffset`. This value normally changes on every scrolling frame, so avoid using it to update large or expensive view hierarchies: ```swift -// ❌ Bad Practice - causes unnecessary re-renders -struct ContentView: View { - @State private var scrollPosition: CGFloat = 0 +struct OffsetTrackingView: View { + @State private var scrollOffset: CGFloat = 0 var body: some View { ScrollView { content - .background( - GeometryReader { geometry in - Color.clear - .preference( - key: ScrollOffsetPreferenceKey.self, - value: geometry.frame(in: .named("scroll")).minY - ) - } - ) } - .coordinateSpace(name: "scroll") - .onPreferenceChange(ScrollOffsetPreferenceKey.self) { value in - scrollPosition = value + .onScrollGeometryChange(for: CGFloat.self) { geometry in + geometry.contentOffset.y + } action: { _, newValue in + scrollOffset = newValue } } } ``` -**Preferred** - Check scroll position and update a flag based on thresholds for smoother, more efficient scrolling: +When only a threshold matters, transform the geometry into a `Bool` so the action runs only when the scroll view crosses that threshold. The header visibility example below demonstrates this pattern. + +### Programmatic Scroll Position (iOS 18+) + +The unlabeled `scrollPosition(_:)` overload requires a `Binding`. Add `scrollTargetLayout()` to the layout containing the identified views: ```swift -// ✅ Good Practice - only updates state when crossing threshold -struct ContentView: View { - @State private var startAnimation: Bool = false +struct ProgrammaticScrollView: View { + @State private var position = ScrollPosition(idType: Item.ID.self) var body: some View { ScrollView { - content - .background( - GeometryReader { geometry in - Color.clear - .preference( - key: ScrollOffsetPreferenceKey.self, - value: geometry.frame(in: .named("scroll")).minY - ) - } - ) + LazyVStack { + ForEach(items) { item in + ItemRow(item: item) + } + } + .scrollTargetLayout() } - .coordinateSpace(name: "scroll") - .onPreferenceChange(ScrollOffsetPreferenceKey.self) { value in - if value < -100 { - startAnimation = true - } else { - startAnimation = false + .scrollPosition($position) + .toolbar { + Button("Scroll to First") { + if let firstID = items.first?.id { + withAnimation { + position.scrollTo(id: firstID) + } + } } } } } +``` -struct ScrollOffsetPreferenceKey: PreferenceKey { - static var defaultValue: CGFloat = 0 - static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { - value = nextValue() +For iOS 17, bind the ID using the labeled overload instead: + +```swift +@State private var scrolledID: Item.ID? + +ScrollView { + LazyVStack { + ForEach(items) { item in + ItemRow(item: item) + } } + .scrollTargetLayout() } +.scrollPosition(id: $scrolledID) ``` ### Scroll-Based Header Visibility +Extracting the threshold as a `Bool` avoids running the action for every offset change: + ```swift struct ContentView: View { @State private var showHeader = true - + var body: some View { VStack(spacing: 0) { if showHeader { HeaderView() .transition(.move(edge: .top)) } - + + ScrollView { + content + } + .onScrollGeometryChange(for: Bool.self) { geometry in + geometry.contentOffset.y + geometry.contentInsets.top > 50 + } action: { _, isPastThreshold in + withAnimation { + showHeader = !isPastThreshold + } + } + } + } +} +``` + +

+Pre-iOS 18 compatibility — GeometryReader + PreferenceKey + +Use this approach when supporting iOS 17 or earlier. `GeometryReader` and preferences remain available, but require a named coordinate space and a custom `PreferenceKey`. + +```swift +struct ContentView: View { + @State private var showHeader = true + + var body: some View { + VStack(spacing: 0) { + if showHeader { + HeaderView() + .transition(.move(edge: .top)) + } + ScrollView { content .background( @@ -175,19 +221,29 @@ struct ContentView: View { } ) } - .coordinateSpace(name: "scroll") + .coordinateSpace(.named("scroll")) .onPreferenceChange(ScrollOffsetPreferenceKey.self) { offset in - if offset < -50 { // Scrolling down - withAnimation { showHeader = false } - } else if offset > 50 { // Scrolling up - withAnimation { showHeader = true } + let shouldShowHeader = offset >= -50 + if shouldShowHeader != showHeader { + withAnimation { + showHeader = shouldShowHeader + } } } } } } + +struct ScrollOffsetPreferenceKey: PreferenceKey { + static var defaultValue: CGFloat = 0 + static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { + value = nextValue() + } +} ``` +
+ ## Scroll Transitions and Effects > **iOS 17+**: All APIs in this section require iOS 17 or later. @@ -284,10 +340,13 @@ struct SnapScrollView: View { ## Summary Checklist -- [ ] Use `ScrollViewReader` with stable IDs for programmatic scrolling -- [ ] Always use explicit animations with `scrollTo()` +- [ ] Use `ScrollViewReader` with stable IDs when proxy-based scrolling is needed - [ ] Use `.visualEffect` for scroll-based visual changes - [ ] Use `.scrollTargetBehavior(.paging)` for paging behavior - [ ] Use `.scrollTargetBehavior(.viewAligned)` for snap-to-item behavior -- [ ] Gate frequent scroll position updates by thresholds -- [ ] Use preference keys for custom scroll position tracking +- [ ] Use `onScrollGeometryChange` (iOS 18+) and extract only the value needed +- [ ] Use `scrollPosition(_:)` with `ScrollPosition` for flexible scrolling on iOS 18+ +- [ ] Use `scrollPosition(id:)` with an optional ID binding on iOS 17+ +- [ ] Add `.scrollTargetLayout()` when scrolling to identified views +- [ ] Derive threshold values instead of propagating every offset change when possible +- [ ] Use the `GeometryReader` + preference approach when supporting pre-iOS 18 versions diff --git a/.agents/skills/swiftui-expert-skill/references/sheet-navigation-patterns.md b/.agents/skills/swiftui-expert-skill/references/sheet-navigation-patterns.md index d06b3878..d09845a0 100644 --- a/.agents/skills/swiftui-expert-skill/references/sheet-navigation-patterns.md +++ b/.agents/skills/swiftui-expert-skill/references/sheet-navigation-patterns.md @@ -3,6 +3,7 @@ ## Table of Contents - [Sheet Patterns](#sheet-patterns) +- [Item-Driven Alerts and Confirmation Dialogs (SDK 27)](#item-driven-alerts-and-confirmation-dialogs-sdk-27) - [Navigation Patterns](#navigation-patterns) - [Multi-Column Navigation with NavigationSplitView](#multi-column-navigation-with-navigationsplitview) - [Inspector](#inspector) @@ -116,6 +117,30 @@ struct ArticlesView: View { **Why**: A single `@State` property and one `.sheet(item:)` modifier replaces N boolean properties and N sheet modifiers, improving readability and preventing only-one-sheet-at-a-time conflicts. +## Item-Driven Alerts and Confirmation Dialogs (SDK 27) + +SDK 27 adds `alert(_:item:actions:message:)` and `confirmationDialog(_:item:titleVisibility:actions:message:)`. The optional binding alone drives presentation, the unwrapped value is passed to the action and message closures, and dismissal resets the binding to `nil`. The item does not need to conform to `Identifiable`. + +```swift +@State private var photoToDelete: Photo? + +var body: some View { + PhotoList { photoToDelete = $0 } + .confirmationDialog( + "Delete photo?", + item: $photoToDelete + ) { photo in + Button("Delete \(photo.name)", role: .destructive) { + delete(photo) + } + } message: { photo in + Text("\(photo.name) will be removed.") + } +} +``` + +Prefer the item overload for an action tied to an optional value instead of synchronizing a separate Boolean or pairing `isPresented` with `presenting:`. Do not use the older `Alert`-returning `alert(item:)`. These overloads require the SDK 27 toolchain but back-deploy to iOS 15, macOS 12, tvOS 15, watchOS 8, and visionOS 1; no runtime availability gate is needed at those deployment targets. + ## Navigation Patterns ### Type-Safe Navigation with NavigationStack @@ -242,9 +267,42 @@ struct ContentView: View { | **macOS** | Columns always visible side-by-side; sidebar has translucent material; variable-width column resizing by dragging | | **iPadOS (regular)** | Sidebar can overlay or push detail; supports column visibility toggle via toolbar button | | **iOS / iPadOS (compact)** | Collapses into a single `NavigationStack`; sidebar items show disclosure chevrons; back button navigates between columns | -| **iPhone (all sizes)** | Always collapsed into a stack; sidebar appears as the root list; selections push detail onto the stack | +| **iOS / iPadOS (regular)** | Can show columns tiled or as overlays, depending on available size and context | | **watchOS / tvOS** | Collapses into a single stack | +Do not infer split-view behavior from the device family. Respond to the space SwiftUI offers: an iPhone can provide a regular-width context, including the inner display of iPhone Duo, where `NavigationSplitView` can show multiple columns. The same scene can later become compact and collapse, so keep selection and navigation state consistent through the transition. + +### Large Displays + +When rows push further screens (settings, mailboxes, folders), `NavigationSplitView` shows the next level beside the list on large displays and collapses on compact width; see [the screen-structure rule](iphone-duo.md#choose-the-technique-by-screen-structure). + +- Keep the sidebar visible with `columnVisibility` `.all` plus `toolbar(removing: .sidebarToggle)` when hiding the list would strand the user. +- Use `navigationSplitViewColumnWidth(min:ideal:)` if sidebar cards or buttons wrap at the default width. Avoid `max:`: in a fold-aligned pose the system can widen the sidebar to the fold, and a maximum caps it short. +- Consider choosing the default detail by importance, not position. When pushed pages are secondary, a regular-width-only overview page selected from a summary row atop the sidebar (as in Settings) can beat auto-selecting the first row. +- The split view can reset selection to `nil` on expand: re-fill it on regular width, and clear regular-only selections on collapse so compact width returns to the list. +- Use a `NavigationStack` in the detail column for deeper pushes. +- In Xcode 27.1, a selectable `List` rendered `Link` and `Button` rows in the primary color rather than the tint. + +### Tab Bar and Sidebar (iOS 27+) + +On iPadOS, a `TabView` with `.tabViewStyle(.sidebarAdaptable)` morphs between a tab bar and a sidebar. On iPhone the bar cannot morph, so only one representation is shown. On iOS 27 an iPhone app can opt into the sidebar representation with `defaultTabBarPlacement(_:)`; on iPadOS the modifier has no effect and `defaultAdaptableTabBarPlacement(_:)` applies instead. + +```swift +@available(iOS 27.0, *) +struct RootTabs: View { + var body: some View { + TabView { + Tab("Home", systemImage: "house") { HomeView() } + Tab("Favorites", systemImage: "star") { FavoritesView() } + } + .tabViewStyle(.sidebarAdaptable) + .defaultTabBarPlacement(.sidebar) + } +} +``` + +The system decides between tab bar and sidebar from the space available, and people cannot toggle it. Read `@Environment(\.isTabViewSidebarAvailable)` inside the tab content to learn whether a sidebar is (or can become) visible; it returns `false` outside a sidebar-capable `TabView`'s content. Use it rather than inspecting size classes for this question. When no sidebar is available, make sure content that lives behind nested tabs or sections stays reachable some other way. Keep a plain `TabView` fallback for earlier systems. + ## Inspector > **Availability:** iOS 17.0+, macOS 14.0+ @@ -304,7 +362,7 @@ MyEditorView() | **macOS** | Trailing-edge sidebar panel; resizable by dragging edge; integrates with window toolbar | | **iPadOS (regular)** | Trailing column alongside content; toggleable via toolbar button | | **iOS / iPadOS (compact)** | Adapts to a sheet presentation; swipe-to-dismiss supported | -| **iPhone (all sizes)** | Always presented as a sheet (no trailing column); dismiss via swipe or button | +| **iOS / iPadOS (regular)** | Can appear as a trailing column when the presentation context provides enough space | > **Tip:** Use `InspectorCommands` in your app's `.commands` to include the default inspector toggle keyboard shortcut. @@ -345,7 +403,7 @@ struct ContentView: View { } ``` -For `alert` and `confirmationDialog` API patterns, see `latest-apis.md`. +For older `alert` and `confirmationDialog` API patterns, see `latest-apis.md`. Prefer the SDK 27 item overloads above when the presentation is tied to an optional value. ## Summary Checklist @@ -354,10 +412,11 @@ For `alert` and `confirmationDialog` API patterns, see `latest-apis.md`. - [ ] Use `NavigationStack` with `navigationDestination(for:)` for type-safe navigation - [ ] Use `NavigationPath` for programmatic navigation - [ ] Use `NavigationSplitView` for sidebar-driven multi-column layouts +- [ ] `sidebarAdaptable` tab sidebars on iPhone use `defaultTabBarPlacement(_:)` behind `#available(iOS 27.0, *)`, with nested-tab content reachable when no sidebar is shown - [ ] Use `Inspector` for trailing-edge supplementary panels - [ ] Set column widths with `navigationSplitViewColumnWidth(min:ideal:max:)` or `inspectorColumnWidth(min:ideal:max:)` - [ ] Use appropriate presentation modifiers (sheet, fullScreenCover, popover) -- [ ] Alerts and confirmation dialogs use modern API with actions +- [ ] Alerts and confirmation dialogs use modern API with actions; prefer the SDK 27 `item:` overload for an optional value - [ ] Avoid passing dismiss/save callbacks to sheets - [ ] Use enum-based `Identifiable` type with `.sheet(item:)` when presenting multiple sheets - [ ] Navigation state can be saved/restored when needed diff --git a/.agents/skills/swiftui-expert-skill/references/soft-deprecation.md b/.agents/skills/swiftui-expert-skill/references/soft-deprecation.md new file mode 100644 index 00000000..355f1ce6 --- /dev/null +++ b/.agents/skills/swiftui-expert-skill/references/soft-deprecation.md @@ -0,0 +1,39 @@ +# Handling Soft-Deprecated APIs + +This file covers *how to behave* when you encounter soft-deprecated SwiftUI APIs. For the actual list of deprecated-to-modern transitions, see `references/latest-apis.md`. + +## What "soft-deprecated" means + +A soft-deprecated API is marked deprecated in the SDK headers but with a placeholder deprecation version (`100000.0`) that suppresses compiler warnings. It still compiles and works correctly — it just signals that the API shouldn't be used in new code. Examples include `NavigationView` (use `NavigationStack` / `NavigationSplitView`), `ActionSheet` / `Alert` (use the `.confirmationDialog` / `.alert` modifiers), `MagnificationGesture` (renamed `MagnifyGesture`), and `PresentationMode` (use `\.dismiss`). + +Because these still work, treat them as **informational**, not urgent. + +## Scoping rule — read this first + +All soft-deprecation guidance is scoped to the code you are **directly modifying**. If a file contains several views and the task touches only one, the other views are out of scope. + +- Only discuss the view(s) you actually edited. +- Do not mention, flag, or offer to migrate soft-deprecated APIs in code you weren't asked to change — including trailing "while I'm here, want me to migrate `OtherView`?" questions. +- This takes precedence over any prompt asking for "observations" or "other notes." + +Mentioning soft-deprecated APIs in untouched code creates noise, distracts from the task, and pressures the user into unrelated work. + +## When generating new code + +Never introduce a new usage of a soft-deprecated API. If you're unsure whether an API is soft-deprecated, check `references/latest-apis.md` before recommending it — any API that worked in a prior release could have been soft-deprecated since. + +## When asked to review, refactor, modernize, or clean up + +Point out soft-deprecated APIs in the code under review and suggest the modern replacement. Keep the tone informational — these still compile and run, so frame migration as an improvement, not a bug fix. + +## When asked to add a feature or fix a bug + +If the view you're editing already uses a soft-deprecated API, **keep it as-is** in your change. Don't silently swap `NavigationView` for `NavigationStack` while adding a search bar — that produces unexpected diffs, risks regressions (state resets, navigation behavior changes), and makes the change harder to review. After delivering the requested change, you may add a brief one-line offer to migrate as a separate step. + +If a *different* view in the same file uses a soft-deprecated API, ignore it entirely (see the scoping rule). + +## General guidance + +- Never introduce new usages of soft-deprecated APIs in code written from scratch. +- Don't proactively scan a codebase for soft-deprecated APIs — only notice them when they appear in code you're directly modifying for the user's request. +- Migrations are real edits with behavioral risk; they belong in their own focused change, not bundled into unrelated work. diff --git a/.agents/skills/swiftui-expert-skill/references/state-management.md b/.agents/skills/swiftui-expert-skill/references/state-management.md index 8b350645..7a8b3572 100644 --- a/.agents/skills/swiftui-expert-skill/references/state-management.md +++ b/.agents/skills/swiftui-expert-skill/references/state-management.md @@ -4,14 +4,17 @@ - [Property Wrapper Selection Guide](#property-wrapper-selection-guide) - [@State](#state) +- [SDK 27 `@State` Macro](#sdk-27-state-macro) - [Property Wrappers Inside @Observable Classes](#property-wrappers-inside-observable-classes) +- [Make @Observable Property Types Equatable](#make-observable-property-types-equatable) +- [@Observable Dependency Granularity](#observable-dependency-granularity) - [@Binding](#binding) - [@FocusState](#focusstate) - [@StateObject vs @ObservedObject (Legacy - Pre-iOS 17)](#stateobject-vs-observedobject-legacy---pre-ios-17) -- [Don't Pass Values as @State](#dont-pass-values-as-state) +- [Don't Store Parent-Owned Inputs as @State](#dont-store-parent-owned-inputs-as-state) - [@Bindable (iOS 17+)](#bindable-ios-17) -- [let vs var for Passed Values](#let-vs-var-for-passed-values) -- [Environment and Preferences](#environment-and-preferences) +- [Passed Value Inputs](#passed-value-inputs) +- [Isolate Side-Effect-Only Dependencies](#isolate-side-effect-only-dependencies) - [Decision Flowchart](#decision-flowchart) - [State Privacy Rules](#state-privacy-rules) - [Avoid Nested ObservableObject](#avoid-nested-observableobject) @@ -25,7 +28,6 @@ | `@Binding` | Child view needs to modify parent's state | Don't use for read-only | | `@Bindable` | iOS 17+: View receives `@Observable` object and needs bindings | For injected observables | | `let` | Read-only value passed from parent | Simplest option | -| `var` | Read-only value that child observes via `.onChange()` | For reactive reads | **Legacy (Pre-iOS 17):** | Wrapper | Use When | Notes | @@ -73,6 +75,31 @@ struct MyView: View { **Note**: You may want to mark `@Observable` classes with `@MainActor` to ensure thread safety with SwiftUI, unless your project or package uses Default Actor Isolation set to `MainActor`—in which case, the explicit attribute is redundant and can be omitted. +## SDK 27 `@State` Macro + +SDK 27 migrates `@State` from a property wrapper to a macro. When an initializer intentionally seeds view-owned state, drop the declaration's initial value and assign it once in `init`: + +```swift +struct CounterView: View { + let name: String + @State private var count: Int + + init(name: String, count: Int) { + self.name = name + self.count = count + } +} +``` + +Do not fix “used before being initialized” by reordering assignments. Assigning in `init` to state that already has a declaration default remains incorrect: SwiftUI preserves the declaration's state storage, and later parent arguments do not replace child-owned state. + +Other source-compatibility failures: + +- “Invalid redeclaration of synthesized property”: another property wrapper composed with `@State` is colliding with macro-generated storage. Remove the redundant wrapper or restructure the composition. +- Missing private memberwise initializer: SDK 27 may not synthesize it for a view containing `@State`. Define the initializer explicitly instead of delegating to the missing memberwise initializer. + +Keep `@State` private. Use an initializer seed only for intentional one-time ownership; use a plain value or `@Binding` when later parent updates must propagate. + ## Property Wrappers Inside @Observable Classes **Critical**: The `@Observable` macro transforms stored properties to add observation tracking. Property wrappers (like `@AppStorage`, `@SceneStorage`, `@Query`) also transform properties with their own storage. These two transformations conflict, causing a compiler error. @@ -104,6 +131,45 @@ This applies to **any** property wrapper used inside an `@Observable` class, inc **Never remove `@ObservationIgnored`** from property-wrapper properties in `@Observable` classes — doing so causes a compiler error. +## Make @Observable Property Types Equatable + +The `@Observable` macro generates a setter that **skips invalidation when the new value equals the current one** — but only when it can compare them, which means only when the property's type is `Equatable`. Without that conformance, every assignment notifies observing views, even when the value is identical. This is an easy win for properties written frequently with the same value (polling, streaming updates, timers). + +```swift +// AVOID: not Equatable — every assignment invalidates, even no-op writes +enum DeliveryStatus { case placed, preparing, shipped, delivered } + +// PREFER: Equatable lets the generated setter short-circuit redundant writes +enum DeliveryStatus: Equatable { case placed, preparing, shipped, delivered } +``` + +This applies to collection properties too: an `Array`/`Set`/`Dictionary` is only `Equatable` when its element type is, so a non-`Equatable` element defeats the short-circuit for the whole collection. (The check is emitted into the generated setter as user code, so it applies on every OS that supports `@Observable` when built with current Xcode.) + +This is distinct from `Equatable` *views* (see `references/performance-patterns.md`): that conformance lets SwiftUI skip a view's body; this one lets the model skip notifying observers in the first place. + +## @Observable Dependency Granularity + +Observation tracks reads at the **property** level, not the field level — so reading any part of a compound property establishes a dependency on the whole thing. Three common traps and their fixes: + +- **A computed property establishes dependencies transitively.** `var currentUser: User? { users.first { $0.id == currentID } }` reads `users` in its body, so any view reading `currentUser` depends on the entire `users` array. Renaming the access doesn't change what observation tracks. +- **A struct-typed stored property drags the whole struct.** A view reading `session.user.name` depends on `session.user`; editing any other field of `user` invalidates it. +- **An array/collection read drags the whole collection.** Reading one element establishes a dependency on the entire stored collection. +- **A row that receives the parent model plus an index subscribes too broadly.** The list that owns the `ForEach` legitimately depends on the collection. A row that looks up `state.users[index]` also depends on the entire collection, so editing one element invalidates every row. Pass the element (or the fields the row reads) directly. + +```swift +// PREFER: cache derived values as stored properties, kept in sync in didSet +@MainActor @Observable +final class AppState { + var users: [User] = [] { didSet { recomputeCurrentUser() } } + var currentID: User.ID? { didSet { recomputeCurrentUser() } } + + private(set) var currentUser: User? + private func recomputeCurrentUser() { currentUser = users.first { $0.id == currentID } } +} +``` + +For struct-typed properties, expose the fields the views actually read as individual properties on the model (each is then tracked separately). If the struct must remain round-trippable (re-encoded to a payload), keep both: a stored `var user: User` for the original shape and the flattened properties for view consumption, kept in sync in `didSet` on `user`. When many rows each observe several fields of their element, model each element as its own `@Observable` and have the parent **persist** the instances — see the per-item view model pattern in `references/performance-patterns.md`. Reading several already-narrow properties from one model is fine and does not need splitting. + ## @Binding Use only when child view needs to **modify** parent's state. If child only reads the value, use `let` instead. @@ -134,6 +200,58 @@ struct ChildView: View { - **Don't use `@Binding` for read-only values.** If the child only displays the value and never modifies it, use `let` instead. `@Binding` adds unnecessary overhead and implies a write contract that doesn't exist. +### Declare a Binding with @Binding, Not a Plain Property + +A binding you react to must be `@Binding var x: T`. SwiftUI subscribes only to `DynamicProperty` properties (`@State`, `@Binding`, `@Environment`, …); a binding held in an undecorated property (`let x: Binding`) is just a value it never looks inside, so external changes to the bound value don't re-evaluate the view. + +```swift +struct SelectionBadge: View { + // let selection: Binding // WRONG - untracked; external changes missed + @Binding var selection: Item? // CORRECT - DynamicProperty, tracked + + var body: some View { Text(selection?.name ?? "None") } +} +``` + +Debug builds can mask this with extra graph passes, so it often fails only in Release. It bites hardest in `UIViewRepresentable`/`NSViewRepresentable`, where the missing re-evaluation means `updateUIView(_:context:)` never runs (e.g. a presented controller that won't dismiss when its bound item is reset). + +### Prefer KeyPath Bindings Over Closure Bindings + +When you need a binding into a model, prefer a KeyPath/subscript-based binding over a hand-written `Binding(get:set:)` closure. A closure binding allocates a new closure each time `body` runs and can't be compared, which can trigger unnecessary invalidations. + +```swift +// BAD - closure binding: heap allocation each body pass, defeats comparison +let binding = Binding( + get: { model[scoreFor: player] }, + set: { model[scoreFor: player] = $0 } +) +PlayerScoreRow(player: player, score: binding) + +// GOOD - project through a subscript with @Bindable +@Bindable var model = model +PlayerScoreRow(player: player, score: $model[scoreFor: player]) +``` + +If no suitable subscript exists, add one (a labeled subscript reads as a clean projection into the model). Reserve closure bindings for cases where no key path or subscript can express the transform. + +For an argumentless projection, use a computed property. A marker-enum subscript (`$model[playback: .isPlaying]`) is ceremony around a property that takes no arguments: + +```swift +// AVOID: marker enum dresses up an argumentless projection +fileprivate subscript(playback _: PlaybackProjection) -> Bool { + get { rate > 0 } + set { rate = newValue ? 1 : 0 } +} +Toggle("Play", isOn: $model[playback: .isPlaying]) + +// PREFER: computed property +var isPlaying: Bool { + get { rate > 0 } + set { rate = newValue ? 1 : 0 } +} +Toggle("Play", isOn: $model.isPlaying) +``` + ## @FocusState See `references/focus-patterns.md` for comprehensive focus management guidance including `@FocusState`, `@FocusedValue`, `.focusable()`, default focus, and common pitfalls. @@ -172,9 +290,9 @@ _viewModel = StateObject(wrappedValue: MovieDetailsViewModel(movie: movie)) **Modern Alternative**: Use `@Observable` with `@State` instead. -## Don't Pass Values as @State +## Don't Store Parent-Owned Inputs as @State -**Critical**: Never declare passed values as `@State` or `@StateObject`. They only accept an initial value and ignore subsequent updates from the parent. +Do not declare a changing parent-owned input as `@State` or `@StateObject`. State accepts an initial value and then remains owned by the child, so subsequent parent updates are ignored. ```swift // WRONG - child ignores parent updates @@ -190,7 +308,7 @@ struct ChildView: View { } ``` -**Prevention**: Always mark `@State` and `@StateObject` as `private`. This prevents them from appearing in the generated initializer. +Mark `@State` and `@StateObject` as `private` so they do not appear in a generated initializer. A custom initializer may intentionally seed private, view-owned state once; make that ownership explicit and do not expect later argument changes to replace the state. See [SDK 27 `@State` Macro](#sdk-27-state-macro) for initialization diagnostics. ## @Bindable (iOS 17+) @@ -223,9 +341,9 @@ struct EditUserView: View { } ``` -## let vs var for Passed Values +## Passed Value Inputs -### Use `let` for read-only display +Use `let` for read-only values passed from a parent. A view can still observe replacement values with `.onChange`; the property does not need to be `var`. ```swift struct ProfileHeader: View { @@ -241,85 +359,56 @@ struct ProfileHeader: View { } ``` -### Use `var` when reacting to changes with `.onChange()` +### Pass only the fields a view reads + +SwiftUI compares value-type inputs field by field. A child that accepts an entire struct can re-evaluate when any field changes, even if its body displays only one field. Passing a large value can also make comparison walk nested fields and collections. ```swift -struct ReactiveView: View { - var externalValue: Int // Watch with .onChange() - @State private var displayText = "" +// AVOID: unrelated User changes can invalidate AvatarBadge. +struct AvatarBadge: View { + let user: User var body: some View { - Text(displayText) - .onChange(of: externalValue) { oldValue, newValue in - displayText = "Changed from \(oldValue) to \(newValue)" - } + AsyncImage(url: user.avatarURL) } } -``` - -## Environment and Preferences -### @Environment - -Access environment values provided by SwiftUI or parent views: - -```swift -struct MyView: View { - @Environment(\.colorScheme) private var colorScheme - @Environment(\.dismiss) private var dismiss +// PREFER: the input matches what the view reads. +struct AvatarBadge: View { + let avatarURL: URL var body: some View { - Button("Done") { dismiss() } - .foregroundStyle(colorScheme == .dark ? .white : .black) + AsyncImage(url: avatarURL) } } ``` -### Custom Environment Values with @Entry - -Use the `@Entry` macro (Xcode 16+, backward compatible to iOS 13) to define custom environment values without boilerplate: - -```swift -extension EnvironmentValues { - @Entry var accentTheme: Theme = .default -} - -// Inject -ContentView() - .environment(\.accentTheme, customTheme) - -// Access -struct ThemedView: View { - @Environment(\.accentTheme) private var theme -} -``` +This rule primarily applies to value types. Class references compare by identity; an `@Observable` class additionally tracks the individual properties read during `body`. Compound properties still have broad granularity: reading one element of an observed array or one field of an observed struct establishes a dependency on that whole stored property. -The `@Entry` macro replaces the manual `EnvironmentKey` conformance pattern. It also works with `TransactionValues`, `ContainerValues`, and `FocusedValues`. +## Isolate Side-Effect-Only Dependencies -### @Environment with @Observable (iOS 17+ - Preferred) +An `.onChange(of:)` expression reads its value in the enclosing view's body scope. If a dependency exists only to trigger a side effect, every change still re-evaluates that view's body. -**Always prefer this pattern** for sharing state through the environment: +For a non-trivial parent, consider moving the dependency and `.onChange` into a focused `ViewModifier`. This gives the side effect its own invalidation boundary: ```swift -@Observable -@MainActor -final class AppState { - var isLoggedIn = false -} - -// Inject -ContentView() - .environment(AppState()) +private struct CounterSyncModifier: ViewModifier { + @Environment(\.counter) private var counter + let model: Model -// Access -struct ChildView: View { - @Environment(AppState.self) private var appState + func body(content: Content) -> some View { + content.onChange(of: counter) { + model.counter = counter + } + } } ``` -### @EnvironmentObject (Legacy - Pre-iOS 17) +Do not add this indirection when the dependency also affects rendering or the parent body is already trivial; it would not reduce meaningful work. + +## Environment -Legacy pattern: inject with `.environmentObject(AppState())`, access with `@EnvironmentObject var appState: AppState`. Prefer `@Observable` with `@Environment` instead. +For custom environment values, `@Entry`, focused values, stable defaults, and invalidation costs, consult `references/environment-patterns.md`. ## Decision Flowchart @@ -337,7 +426,7 @@ Is this value owned by this view? │ └─ NO: Does child need BINDINGS to its properties? │ ├─ YES (@Observable) → @Bindable var │ └─ NO: Does child react to changes? - │ ├─ YES → var + .onChange() + │ ├─ YES → let + .onChange() │ └─ NO → let │ └─ Is it a legacy ObservableObject from parent? @@ -379,10 +468,17 @@ SwiftUI can't track changes through nested `ObservableObject` properties. Workar ## Key Principles 1. **Always prefer `@Observable` over `ObservableObject`** for new code -2. **Mark `@Observable` classes with `@MainActor` for thread safety (unless using default actor isolation)`** +2. **Mark `@Observable` classes with `@MainActor` for thread safety (unless using default actor isolation)** 3. Use `@State` with `@Observable` classes (not `@StateObject`) 4. Use `@Bindable` for injected `@Observable` objects that need bindings 5. **Always mark `@State` and `@StateObject` as `private`** -6. **Never declare passed values as `@State` or `@StateObject`** +6. Do not store changing parent-owned inputs as `@State` or `@StateObject`; use private state only for intentional child ownership 7. With `@Observable`, nested objects work fine; with `ObservableObject`, pass nested objects directly to child views 8. **Always add `@ObservationIgnored` to property wrappers** (e.g., `@AppStorage`, `@SceneStorage`, `@Query`) inside `@Observable` classes — they conflict with the macro's property transformation +9. **Prefer `Equatable` types for frequently-written `@Observable` properties** so the generated setter skips redundant invalidations +10. Pass value-type views only the fields they read +11. Isolate side-effect-only dependencies when they would invalidate an expensive parent +12. Follow `references/environment-patterns.md` for custom environment and focused values +13. **Prefer KeyPath/subscript bindings over closure bindings**; use a computed property, not a marker-enum subscript, for argumentless projections +14. **Declare a binding you react to as `@Binding`, not a plain `Binding`-typed property** — a plain property isn't tracked, so external changes won't re-evaluate the view (often a Release-only failure) +15. Do not pass a parent `@Observable` plus an index into a row; pass the element or the fields the row reads diff --git a/.agents/skills/swiftui-expert-skill/references/styled-text-editing.md b/.agents/skills/swiftui-expert-skill/references/styled-text-editing.md new file mode 100644 index 00000000..09f083d2 --- /dev/null +++ b/.agents/skills/swiftui-expert-skill/references/styled-text-editing.md @@ -0,0 +1,198 @@ +# Styled Text Editing + +> Attributed `TextEditor`, `AttributedTextSelection`, and `AttributedTextFormattingDefinition` require iOS 26, macOS 26, or visionOS 26. `TextEditor` itself is **unavailable on watchOS and tvOS**. For the verbatim-vs-localized decision on `Text`, see `references/text-patterns.md`. + +## Table of Contents + +- [Attributed TextEditor](#attributed-texteditor) +- [AttributedTextSelection](#attributedtextselection) +- [Reading Attributes at the Selection](#reading-attributes-at-the-selection) +- [Transforming Attributes](#transforming-attributes) +- [Resolving Fonts](#resolving-fonts) +- [Editing Text While Keeping the Selection Valid](#editing-text-while-keeping-the-selection-valid) +- [Formatting Definitions](#formatting-definitions) +- [Text and Markdown](#text-and-markdown) + +--- + +## Attributed TextEditor + +`TextEditor` has three initializers. The attributed one accepts an optional selection binding: + +```swift +TextEditor(text: Binding) // iOS 14+ +TextEditor(text: Binding, selection: Binding) // iOS 18+ +TextEditor(text: Binding, selection: Binding? = nil) // iOS 26+ +``` + +Binding an `AttributedString` gives you a rich-text editor with no extra work — the system handles bold, italic, and the standard formatting commands. + +```swift +struct RichTextEditor: View { + @State private var text = AttributedString("Editable styled text") + @State private var selection = AttributedTextSelection() + + var body: some View { + TextEditor(text: $text, selection: $selection) + } +} +``` + +Pass a selection binding whenever you need custom formatting controls; without it you cannot read or transform what the person has selected. + +## AttributedTextSelection + +`AttributedTextSelection` is an opaque `Equatable, Sendable` value. Resolve it against the text to inspect it: + +```swift +switch selection.indices(in: text) { +case .insertionPoint(let index): + // caret only, no characters selected +case .ranges(let rangeSet): + // one or more selected ranges +} +``` + +Initializers: `init()`, `init(range:)`, `init(ranges:)`, and `init(insertionPoint:typingAttributes:)`. `affinity(in:)` returns a `TextSelectionAffinity` for the caret's direction. + +Because a selection can hold a `RangeSet` (discontiguous ranges), don't assume a single `Range`. Use the provided helpers rather than reaching for the indices directly. + +## Reading Attributes at the Selection + +`typingAttributes(in:)` returns the `AttributeContainer` that would apply to newly typed text. This is what you want for driving control state, since it works for a bare insertion point as well as a range: + +```swift +private var selectionColor: Color { + selection.typingAttributes(in: text).foregroundColor ?? .primary +} +``` + +`attributes(in:)` returns a `Sequence` of `AttributeContainer` values covering the selection, with a subscript for a single key. Use it to detect mixed values across a selection: + +```swift +let underlines = selection.attributes(in: text)[\.underlineStyle] +let allUnderlined = underlines.allSatisfy { $0 != nil } +``` + +## Transforming Attributes + +`AttributedString.transformAttributes(in:body:)` is the mutating entry point for formatting commands. It takes the selection `inout` and hands you an `inout AttributeContainer` to modify: + +```swift +private func toggleUnderline() { + text.transformAttributes(in: &selection) { container in + container.underlineStyle = container.underlineStyle == nil ? .single : nil + } +} + +private func setColor(_ color: Color) { + text.transformAttributes(in: &selection) { container in + container.foregroundColor = color + } +} +``` + +When the selection is an insertion point, the change applies to the typing attributes instead of any characters, so the next typed character picks up the formatting. That is why the selection is `inout` — the transform updates it. + +## Resolving Fonts + +`Font` values are declarative and may be relative (`.body`, `.headline`), so you cannot read a weight or an italic flag off them directly. Read `\.fontResolutionContext` from the environment (a `Font.Context`) and call `resolve(in:)` to get a `Font.Resolved` with concrete `isBold`, `isItalic`, and `weight`: + +```swift +struct FormattingBar: View { + @Binding var text: AttributedString + @Binding var selection: AttributedTextSelection + @Environment(\.fontResolutionContext) private var fontResolutionContext + + var body: some View { + HStack { + Button("Bold", systemImage: "bold") { toggleBold() } + Button("Italic", systemImage: "italic") { toggleItalic() } + } + } + + private func toggleBold() { + text.transformAttributes(in: &selection) { container in + let font = container.font ?? .default + let resolved = font.resolve(in: fontResolutionContext) + container.font = font.bold(!resolved.isBold) + } + } + + private func toggleItalic() { + text.transformAttributes(in: &selection) { container in + let font = container.font ?? .default + let resolved = font.resolve(in: fontResolutionContext) + container.font = font.italic(!resolved.isItalic) + } + } +} +``` + +Note the `?? .default` fallback: an unstyled run has no `font` attribute at all. Resolving the context (rather than assuming `.body`) keeps the toggle correct under Dynamic Type and inherited font modifiers. + +## Editing Text While Keeping the Selection Valid + +Mutating an `AttributedString` invalidates indices, which can leave a stored selection pointing at the wrong place. Use the selection-aware replacement APIs so SwiftUI updates the selection with the text: + +```swift +text.replaceSelection(&selection, with: AttributedString("replacement")) +text.replaceSelection(&selection, withCharacters: "plain replacement") +``` + +Foundation's `transform(updating:)` accepts attributed-string index ranges, not `AttributedTextSelection`. Use it only after resolving and managing those ranges yourself. + +## Formatting Definitions + +An `AttributedTextFormattingDefinition` constrains which attribute values an editor accepts, so pasted or system-applied formatting is normalized instead of rejected ad hoc. The protocol has a `Scope` (an `AttributeScope`) and a `body` built from constraints: + +```swift +struct BrandFormatting: AttributedTextFormattingDefinition { + struct Scope: AttributeScope { + let foregroundColor: AttributeScopes.SwiftUIAttributes.ForegroundColorAttribute + let font: AttributeScopes.SwiftUIAttributes.FontAttribute + } + + var body: some AttributedTextFormattingDefinition { + ValueConstraint(for: \.foregroundColor, values: [.primary, .brandRed], default: .primary) + } +} +``` + +`ValueConstraint` takes a key path (or attribute type), a `Set` of allowed values, and a default that replaces anything outside the set. Custom constraints conform to `AttributedTextValueConstraint` and implement `constrain(_:)`, which receives a mutable proxy over the attribute container. + +Apply a definition with `attributedTextFormattingDefinition(_:)`. Overloads also accept a bare `AttributeScope` type or a `KeyPath` when you only want to limit *which* attributes survive: + +```swift +TextEditor(text: $text, selection: $selection) + .attributedTextFormattingDefinition(BrandFormatting()) +``` + +The modifier is `attributedTextFormattingDefinition(_:)` — not `textFormattingDefinition(_:)`. + +Attributes outside the scope are dropped from the editor's text, which is the mechanism that keeps a document's attribute set closed. Restricting the scope also means your persistence layer only ever sees attributes you declared. + +## Text and Markdown + +`Text` accepts Markdown in a localized string literal, but only an inline subset. Interpolating a `String` variable bypasses both localization and Markdown parsing. + +```swift +Text("This is **bold** and *italic*") +Text("Visit [Apple](https://www.apple.com)") +``` + +Supported: emphasis, strong emphasis, strikethrough, inline code, and links. **Not** supported: headings, lists, block quotes, code blocks, tables, images, and hard or soft line breaks — `Text` parses with `inlineOnlyPreservingWhitespace`, so a `#` or `-` renders literally and a newline in the literal is preserved as whitespace rather than becoming a break. + +For block-level Markdown, parse it yourself into `AttributedString` with a full `AttributedString.MarkdownParsingOptions` configuration and lay the blocks out as separate views. + +For read-only styled content, build an `AttributedString` and hand it to `Text`: + +```swift +var styled = AttributedString("Red and Blue") +if let range = styled.range(of: "Red") { + styled[range].foregroundColor = .red +} +Text(styled) +``` + +Prefer `foregroundStyle(_:)` over `foregroundColor(_:)` on `Text`; the former accepts any `ShapeStyle`, including gradients and materials. diff --git a/.agents/skills/swiftui-expert-skill/references/text-patterns.md b/.agents/skills/swiftui-expert-skill/references/text-patterns.md index 19fd5a3a..351097f9 100644 --- a/.agents/skills/swiftui-expert-skill/references/text-patterns.md +++ b/.agents/skills/swiftui-expert-skill/references/text-patterns.md @@ -1,5 +1,9 @@ # SwiftUI Text Patterns Reference +> For broader localization guidance — String Catalogs, `#bundle` for packages, `LocalizedStringResource`, locale-aware formatting, RTL layout, and translator comments — see `references/localization.md`. This file covers only the verbatim-vs-localized decision for a single `Text`. +> +> For rich text — attributed `TextEditor` with `AttributedTextSelection`, `transformAttributes(in:)`, font resolution, formatting definitions, and the Markdown subset `Text` supports — see `references/styled-text-editing.md`. + ## Table of Contents - [Text Initialization: Verbatim vs Localized](#text-initialization-verbatim-vs-localized) diff --git a/.agents/skills/swiftui-expert-skill/references/toolbar-patterns.md b/.agents/skills/swiftui-expert-skill/references/toolbar-patterns.md new file mode 100644 index 00000000..c7586aee --- /dev/null +++ b/.agents/skills/swiftui-expert-skill/references/toolbar-patterns.md @@ -0,0 +1,215 @@ +# SwiftUI Toolbar Patterns + +## Customizable toolbars (iOS 26+, macOS 26+, tvOS 26+, watchOS 26+, visionOS 26+) + +Use `.toolbar(id:)` when people should be able to add, remove, or rearrange toolbar content. Every customizable `ToolbarItem` needs a stable, unique string ID. Keep IDs tied to the meaning of the action rather than to a changing array position. + +```swift +.toolbar(id: "main-toolbar") { + ToolbarItem(id: "tag") { + TagButton() + } + ToolbarItem(id: "share") { + ShareButton() + } + ToolbarSpacer(.fixed) + ToolbarItem(id: "more") { + MoreButton() + } +} +``` + +`ToolbarItem(id:placement:content:)` is available on iOS 14+, macOS 11+, tvOS 14+, and watchOS 7+ (visionOS 1+). The `showsByDefault:` overload is soft-deprecated in the SDK 27 toolchain; use `defaultCustomization(_:options:)` instead. + +`ToolbarSpacer` separates groups of toolbar content. `ToolbarSpacer(.fixed)` creates a fixed-width gap; `ToolbarSpacer(.flexible)` expands to push content apart. The initializer also accepts a placement. `ToolbarSpacer` is available on iOS 26+ and macOS 26+; it is unavailable on tvOS, watchOS, and visionOS. + +## System-defined toolbar content + +`DefaultToolbarItem` places a system-defined item, such as search or the sidebar toggle, at a chosen placement. It is available on iOS 26+, macOS 26+, tvOS 26+, watchOS 26+, and visionOS 26+. + +```swift +.toolbar { + DefaultToolbarItem(kind: .search, placement: .bottomBar) + DefaultToolbarItem(kind: .sidebarToggle, placement: .navigationBarLeading) +} +``` + +The `.search` kind is available on iOS, macOS, and visionOS 26+; it is unavailable on tvOS and watchOS. The `.sidebarToggle` kind is available on every platform supported by `DefaultToolbarItem`. + +The `.largeSubtitle` placement supplies content in the large navigation-title subtitle area. It takes precedence over the value supplied by `navigationSubtitle(_:)`. It is available on iOS 26+ only. + +On iOS 26+ and macOS 26+, use `sharedBackgroundVisibility(.hidden)` on the `ToolbarItem` when one item should not participate in the shared Liquid Glass background. It is unavailable on tvOS, watchOS, and visionOS. Apply `badge(_:)` to the item's view to show an indicator: + +```swift +.toolbar { + ToolbarItem(placement: .topBarTrailing) { + Button("Notifications", systemImage: "bell") { } + .badge(unreadCount) + } + ToolbarItem(placement: .topBarTrailing) { + ProfileButton() + } + .sharedBackgroundVisibility(.hidden) +} +``` + +## Search + +Use `.searchToolbarBehavior(.minimize)` to opt into a compact, button-like search control that expands when selected. The modifier is available on all aligned 26 releases, but `.minimize` is available only on iOS and visionOS; use `.automatic` elsewhere. + +## Transitioning from toolbar controls + +Attach `matchedTransitionSource(id:in:)` to toolbar content that presents another view, then use a zoom navigation transition with the same ID and namespace in the destination. + +```swift +@Namespace private var namespace + +.toolbar { + ToolbarItem(placement: .topBarTrailing) { + Button("Show details", systemImage: "info") { + isPresented = true + } + } + .matchedTransitionSource(id: "details", in: namespace) +} +.sheet(isPresented: $isPresented) { + DetailsView() + .navigationTransition(.zoom(sourceID: "details", in: namespace)) +} +``` + +The view `matchedTransitionSource(id:in:)` is available on iOS 18+, macOS 15+, tvOS 18+, watchOS 11+, and visionOS 2+. Its toolbar-content form is available on iOS 26+ and is unavailable on macOS, tvOS, watchOS, and visionOS. The zoom navigation transition is available on iOS 18+, macOS 15+, tvOS 18+, watchOS 11+, and visionOS 2+. + +## Adaptive vertical bars (iOS 27.1+) + +Build with the iOS 27.1 SDK and attach `.toolbar` content to a system `NavigationStack`, `NavigationSplitView`, or `TabView`. Those containers can move eligible controls between horizontal and vertical bars as available space and context change; a hand-built bar does not gain this behavior. + +Describe every action with both a title and icon, even when the visible representation is symbol-only. The system needs the title for accessibility, expanded representations, and overflow: + +```swift +NavigationStack { + ContentView() + .toolbar { + ToolbarItem(placement: .cancellationAction) { + Button("Close", systemImage: "xmark") { close() } + } + ToolbarItem(placement: .topBarPinnedTrailing) { + Button("Share", systemImage: "square.and.arrow.up") { share() } + } + } +} +``` + +Keep semantic placements so ordering remains meaningful on either axis: navigation and cancellation actions lead, prominent actions use `.topBarPinnedTrailing`, and bottom-bar actions remain grouped as bottom actions. Do not position items by reading a physical edge. + +SwiftUI infers axis eligibility from the item. Symbol-capable items can move vertically, while title-only and complex custom views generally remain horizontal. Override that inference only when needed: + +```swift +ToolbarItem { + SelectOrDoneButton() +} +.axisBehavior(.horizontalOnly) + +ToolbarItem { + CompactCompassControl() +} +.axisBehavior(.verticalPreferred) +``` + +Use `.horizontalOnly` when related states must stay together and one representation cannot fit a fixed-width vertical bar. Use `.verticalPreferred` only when a custom view has a compact vertical representation. Otherwise keep `.automatic`. + +For a custom item's presentation details, an iOS 27.1-only view can read `@Environment(\.toolbarVerticalEdge)`. A non-`nil` value means the environment supports a vertical bar on that directional edge; use it to select a compact representation, not to add safe-area spacing. Keep the property declaration in an `@available(iOS 27.1, *)` type selected behind `#available`. + +When a view combines a toolbar and tab bar, `.toolbarVerticalCompressionBehavior(.prefersToolbarItems)` keeps toolbar actions visible longer, while `.prefersTabBar` favors destinations. The default `.automatic` compresses toolbar items first. Choose based on the experience's primary task, then use the existing SDK 27 [overflow and visibility](#sdk-27-overflow-and-visibility) APIs to prioritize individual actions rather than duplicating overflow controls. + +Most interfaces should keep automatic vertical behavior. Use `.toolbarVerticalBehavior(.disabled)` only for a narrow exception, such as a bottom-heavy single-page interface or a sheet whose lone toolbar item would cost more space than it saves. All of these vertical-bar APIs require iOS 27.1; preserve the ordinary system toolbar as the earlier-OS fallback. + +## SDK 27 overflow and visibility + +When toolbar content does not fit, the system can move lower-priority items into an overflow menu. `visibilityPriority(_:)` is available on iOS 27+, macOS 26.1+, watchOS 27+, tvOS 27+, and visionOS 27+. `.automatic` is available on every supported platform. `.low` and `.high` are available only on iOS and macOS. `ToolbarItemVisibilityPriority(higherThan:)` and `(lowerThan:)` are available on iOS 27+ and macOS 27+. + +```swift +.toolbar { + ToolbarItemGroup { + UndoButton() + RedoButton() + } + .visibilityPriority(.high) +} +``` + +`ToolbarOverflowMenu` is toolbar content whose children always appear in the overflow menu. The `View.toolbarOverflowMenu { ... }` modifier provides the same behavior outside a toolbar builder. Both are available on iOS 27+ and visionOS 27+ only. The type and modifier have different syntaxes: + +```swift +.toolbar { + ToolbarOverflowMenu { + ExportButton() + ClearButton() + } +} + +content + .toolbarOverflowMenu { + ExportButton() + ClearButton() + } +``` + +`.topBarPinnedTrailing` keeps a `ToolbarItem` at the trailing edge and prevents it from moving into overflow. It is available on iOS 27+ and visionOS 27+ only. + +For deployment targets below SDK 27, prefer one availability check around the toolbar content when using these APIs: + +```swift +.toolbar { + if #available(iOS 27, *) { + ToolbarItem(placement: .topBarPinnedTrailing) { + ShareButton() + } + ToolbarOverflowMenu { + ExportButton() + } + } else { + ToolbarItem { + ShareButton() + } + } +} +``` + +## Minimization, margins, and status bar + +`toolbarMinimizationBehavior(_:for:)`, `toolbarMinimizationSafeAreaAdjustment(_:for:)`, and `toolbarMinimizationRestoration(_:for:)` are available on all Apple platforms in SDK 27. The behavior cases `.automatic`, `.onScrollDown`, `.onScrollUp`, and `.never` and the safe-area cases `.automatic`, `.enabled`, and `.disabled` have platform-specific availability; use `.automatic` for cross-platform code and gate iOS-only cases as needed. + +```swift +ScrollView { + Content() +} +.toolbarMinimizationBehavior(.onScrollDown, for: .navigationBar) +.toolbarMinimizationSafeAreaAdjustment(.automatic, for: .navigationBar) +``` + +`contentMarginsRemoved(_:)` removes the system margins around toolbar content. It is available on iOS 27+, macOS 27+, tvOS 27+, watchOS 27+, and visionOS 27+. + +On iOS 27+, `ToolbarPlacement.statusBar` can be passed to `toolbarVisibility(_:for:)` to control status-bar visibility. It is iOS-only; keep `statusBarHidden(_:)` in an earlier deployment fallback and do not suggest a replacement on visionOS, where there is no status bar. + +```swift +.toolbarVisibility(.hidden, for: .statusBar) +``` + +## Dynamic toolbar content + +`ForEach` conforms to `ToolbarContent` when built with the SDK 27 toolchain and back-deploys to iOS 16+, macOS 13+, watchOS 9+, tvOS 16+, and visionOS 1+. Give the collection elements stable identity. `EmptyView` as toolbar content requires iOS 27+, macOS 27+, tvOS 27+, watchOS 27+, and visionOS 27+. + +```swift +.toolbar { + ForEach(actions) { action in + ToolbarItem { + Button(action.title) { + action.perform() + } + } + } +} +``` + +For broader Liquid Glass styling, see [liquid-glass.md](liquid-glass.md). For macOS window and toolbar concerns, keep platform-specific guidance in the macOS references. diff --git a/.agents/skills/swiftui-expert-skill/references/trace-recording.md b/.agents/skills/swiftui-expert-skill/references/trace-recording.md index e84eeb21..fcfdd1d9 100644 --- a/.agents/skills/swiftui-expert-skill/references/trace-recording.md +++ b/.agents/skills/swiftui-expert-skill/references/trace-recording.md @@ -10,6 +10,21 @@ The bundled `scripts/record_trace.py` wraps `xctrace record` with: - **Manual stop** via Ctrl+C, a stop-file, or `--time-limit`. - JSON discovery for devices and templates. - Normal Python exit codes so an agent can orchestrate. +- Redacted command logging for values passed through `--env`. +- An explicit acknowledgement gate for system-wide recordings. + +## Privacy and consent + +Prefer `--attach` or `--launch`, which limits collection to the app being +diagnosed. A system-wide recording can capture activity and metadata from +unrelated applications. Before using `--all-processes`, explain that scope to +the user and obtain their explicit approval. Then pass +`--allow-system-wide-recording` to record that acknowledgement in the command. + +Values passed through `--env KEY=VALUE` are forwarded to `xctrace`, but the +wrapper redacts each value from its displayed command. Avoid placing secrets on +command lines when a safer launch configuration is available, because other +local process-inspection tools may still expose process arguments. ## Typical flows @@ -106,6 +121,14 @@ the user to connect/unlock/trust the device before recording. For ad-hoc hang hunting on any target, `Time Profiler` or `Animation Hitches` alone may be enough. +For an explicitly approved system-wide recording: + +```bash +python3 "${SKILL_DIR}/scripts/record_trace.py" \ + --all-processes --allow-system-wide-recording \ + --time-limit 30s --output ~/Desktop/system-wide.trace +``` + ## Chaining into analysis The recording script prints `trace written: ` on exit. Feed that diff --git a/.agents/skills/swiftui-expert-skill/references/view-structure.md b/.agents/skills/swiftui-expert-skill/references/view-structure.md index abb7893d..6b60fc53 100644 --- a/.agents/skills/swiftui-expert-skill/references/view-structure.md +++ b/.agents/skills/swiftui-expert-skill/references/view-structure.md @@ -3,12 +3,14 @@ ## Table of Contents - [View Structure Principles](#view-structure-principles) -- [Recommended View File Structure](#recommended-view-file-structure) +- [View File Structure (optional readability suggestion)](#view-file-structure-optional-readability-suggestion) - [Struct or Method / Computed Property?](#struct-or-method--computed-property) -- [Prefer Modifiers Over Conditional Views](#prefer-modifiers-over-conditional-views) - [Extract Subviews, Not Computed Properties](#extract-subviews-not-computed-properties) - [@ViewBuilder](#viewbuilder) +- [SDK 27 `@ContentBuilder`](#sdk-27-contentbuilder) - [Keep View Body Simple and Avoid High-Cost Operations](#keep-view-body-simple-and-avoid-high-cost-operations) +- [Keep View `init` Cheap](#keep-view-init-cheap) +- [Single-Child Group](#single-child-group) - [When to Extract Subviews](#when-to-extract-subviews) - [Container View Pattern](#container-view-pattern) - [Utilize Lazy Containers for Large Data Sets](#utilize-lazy-containers-for-large-data-sets) @@ -26,16 +28,9 @@ SwiftUI's diffing algorithm compares view hierarchies to determine what needs updating. Proper view composition directly impacts performance. -## Recommended View File Structure +## View File Structure (optional readability suggestion) -Use a consistent order when declaring SwiftUI views: - -1. Environment Properties -2. State Properties -3. Private Properties -4. Initializer (if needed) -5. Body -6. Computed Properties/Methods for Subviews +Property ordering has no effect on correctness or performance, so treat this as a personal/team readability preference rather than a rule. Some developers find a consistent order easier to scan — for example, environment, then state, then passed-in properties, then `init`, body, and helper subviews. Adopt it only if your team wants the consistency; never reorder existing code solely to match it. ```swift struct ContentView: View { @@ -90,13 +85,13 @@ struct ContentView: View { var titleView: some View { Text("Hello from Property") .font(.largeTitle) - .foregroundColor(.blue) + .foregroundStyle(.blue) } func messageView(text: String, color: Color) -> some View { Text(text) .font(.title) - .foregroundColor(color) + .foregroundStyle(color) .padding() } @@ -109,73 +104,13 @@ struct ContentView: View { } ``` -## Prefer Modifiers Over Conditional Views - -**Prefer "no-effect" modifiers over conditionally including views.** When you introduce a branch, consider whether you're representing multiple views or two states of the same view. - -### Use Opacity Instead of Conditional Inclusion - -```swift -// Good - same view, different states -SomeView() - .opacity(isVisible ? 1 : 0) - -// Avoid - creates/destroys view identity -if isVisible { - SomeView() -} -``` - -**Why**: Conditional view inclusion can cause loss of state, poor animation performance, and breaks view identity. Using modifiers maintains view identity across state changes. - -### When Conditionals Are Appropriate - -Use conditionals when you truly have **different views**, not different states: - -```swift -// Correct - fundamentally different views -if isLoggedIn { - DashboardView() -} else { - LoginView() -} - -// Correct - optional content -if let user { - UserProfileView(user: user) -} -``` - -### Conditional View Modifier Extensions Break Identity - -A common pattern is an `if`-based `View` extension for conditional modifiers. This changes the view's return type between branches, which destroys view identity and breaks animations: - -```swift -// Problematic -- different return types per branch -extension View { - @ViewBuilder func `if`(_ condition: Bool, transform: (Self) -> T) -> some View { - if condition { - transform(self) // Returns T - } else { - self // Returns Self - } - } -} -``` - -Prefer applying the modifier directly with a ternary or always-present modifier: +For conditional modifier composition and `AnyShapeStyle`, consult `references/modifier-patterns.md`. -```swift -// Good -- same view identity maintained -Text("Hello") - .opacity(isHighlighted ? 1 : 0.5) +## Extract Subviews, Not Computed Properties -// Good -- modifier always present, value changes -Text("Hello") - .foregroundStyle(isError ? .red : .primary) -``` +A view is SwiftUI's unit of invalidation. When an input changes, SwiftUI re-runs the body of the smallest enclosing **view type** that depends on it — every conditional, modifier chain, and string interpolation in that body, even if only one leaf actually depends on what changed. A computed property or `@ViewBuilder` helper is inlined into the parent's body, so it shares the parent's invalidation boundary and does not reduce update cost; it only reorganizes the code. A separate `View` type with narrow inputs becomes its own boundary and re-runs only when its own inputs change. -## Extract Subviews, Not Computed Properties +This is why "split your body for readability" is also a performance tool — but only when you split into real `View` types, not computed properties. ### The Problem with @ViewBuilder Functions @@ -245,6 +180,31 @@ struct ComplexSection: View { 2. Since nothing changed, SwiftUI skips calling `ComplexSection.body` 3. The complex view code never executes unnecessarily +### Multi-section detail views + +The most common place this rule gets dropped is a detail screen with several distinct sections — `header + gallery + description + reviews`, `header + ingredients + steps`, `hero + specs + related`. The tempting shape is one big view with `private var header: some View`, `private var gallery: some View`, and so on. That shape shares one invalidation boundary, so a change that affects one section re-evaluates all of them. Factor each named section into its own `View` type that takes only the fields it renders, and keep the parent thin — it just composes the sections. + +```swift +// PREFER: each section is its own type with narrow inputs. +struct ProductDetailView: View { + let product: Product + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 24) { + ProductHeader(name: product.name, price: product.price) + ProductGallery(images: product.imageURLs) + ProductDescription(text: product.descriptionText) + ProductReviews(average: product.averageStars, count: product.reviewCount) + } + .padding() + } + } +} +``` + +This generalizes to every `*DetailView`: one `View` type per section, narrow inputs each, a thin parent that composes them. Small `@ViewBuilder` fragments reused two or three times within the same body are still fine — the rule targets factoring done for organization or to manage body length, where a real `View` type does the right thing. + ## @ViewBuilder Use `@ViewBuilder` functions for small, simple sections (a few views, no expensive computation) that don't affect performance. They work particularly well for static content that doesn't depend on any `@State` or `@Binding`, since SwiftUI won't need to diff them independently. Extract to a separate `struct` when the section is complex, depends on state, or needs to be skipped during re-evaluation. @@ -282,6 +242,21 @@ Prefer `@ViewBuilder` when: - there is conditional branching between multiple view types - extracting a separate `struct` would not provide meaningful separation +## SDK 27 `@ContentBuilder` + +SDK 27 unifies many SwiftUI result builders under `@ContentBuilder`. Block contents are no longer constrained to `View`, so previously compiling source can become ambiguous. Choose the narrow fix matching the diagnostic. Do not broadly rewrite working builders or rename unrelated types. + +- For ambiguous `ShapeStyle.opacity` or `blendMode` passed directly to `overlay` or `background`, select the builder overload: + ```swift + Rectangle().overlay { + Color.blue.opacity(0.3).blendMode(.overlay) + } + ``` +- Fully qualify a shadowed SwiftUI type, such as `SwiftUI.Color.clear`. +- Avoid spelling concrete `TupleView` or `TupleContent` generic structures; prefer opaque `some View`. If a concrete SDK 27 type is unavoidable, the builder now produces `TupleContent`. When the deployment target is below OS 27 and a concrete `TupleView` constraint is unavoidable, construct `TupleView((...))` explicitly inside the builder as a back-deployment fallback. +- If an empty nested builder is ambiguous, provide `EmptyContent()` or `EmptyView()`. This can occur with MapKit in the dependency graph even when the file does not import MapKit, if member-import visibility is disabled. It also occurs with a conditional-compilation branch that becomes empty. +- For deeply branching Charts content that times out only when back-deployed (typically around 10+ `if`/`else if` or `switch` branches), extract the branches into an `@ChartContentBuilder` helper. + ## Keep View Body Simple and Avoid High-Cost Operations Refrain from performing complex operations within the `body` of your view. Instead of passing a ready-to-use sequence with filtering, mapping, or sorting directly into `ForEach`, prepare the sequence outside the body. @@ -298,26 +273,18 @@ var body: some View { } ``` -Prefer: +Prefer already-prepared values. `init` is not a one-time filter — it reruns whenever the parent re-evaluates, so treat it as a constant-time copy of inputs. Cache derived collections on the model (or in `@State` updated from `.onChange`) and pass the prepared sequence in: ```swift struct FilteredListView: View { - private let filteredValues: [Int] - - init(values: [Int]) { - self.filteredValues = values.filter { $0 > 0 } // Perform filtering once - } + let filteredValues: [Int] var body: some View { List { - content - } - } - - private var content: some View { - ForEach(filteredValues, id: \.self) { value in - Text(String(value)) - .padding() + ForEach(filteredValues, id: \.self) { value in + Text(String(value)) + .padding() + } } } } @@ -330,7 +297,52 @@ General guidance: - avoid filtering, sorting, and mapping inline in `body` - avoid constructing expensive formatters in `body` - avoid heavy branching in large view trees -- move data preparation into init, model layer, or dedicated helpers +- move data preparation into the model layer or dedicated helpers; do not filter in `init` + +## Keep View `init` Cheap + +A view's `init` runs every time the parent re-evaluates its body, which can be many times per second for views inside `List`, `LazyVStack`, scroll containers, or animated parents. Treat `init` as a constant-time copy of inputs into stored properties. Don't decode JSON, build a `DateFormatter`, touch the file system, or allocate large structures there — that work repeats on every parent body pass even when the inputs are identical. + +```swift +// AVOID: decoding and formatting on every init +init(rawJSON: Data, date: Date) { + self.summary = try! JSONDecoder().decode(WeatherSummary.self, from: rawJSON) + let formatter = DateFormatter() + formatter.dateStyle = .medium + self.formattedDate = formatter.string(from: date) +} + +// PREFER: take already-prepared values; format lazily in body +let summary: WeatherSummary +let date: Date + +var body: some View { + VStack { + Text(summary.headline) + Text(date, format: .dateTime.day().month().year()) // cached, locale-aware + } +} +``` + +If a derived value genuinely needs to be computed once and kept, store it on an `@State`-owned `@Observable` model or compute it asynchronously in `.task` — not in `init`. `init` is not a one-time setup hook; it runs as often as the parent's body does. + +## Single-Child Group + +`Group { SomeView() }` — a `Group` with exactly one concrete child — wraps the view in an extra `Group` type for no visual benefit. Every modifier chained after it must be type-checked against that wrapper, adding avoidable type-checking overhead in long chains. Drop the `Group` and chain modifiers directly on the child. + +```swift +// AVOID: single concrete child wrapped in Group +Group { Text(status) } + .padding(.horizontal, 8) + .background(.thinMaterial, in: Capsule()) + +// PREFER: chain directly on the child +Text(status) + .padding(.horizontal, 8) + .background(.thinMaterial, in: Capsule()) +``` + +The rule is specifically about one concrete view. A `Group` whose content is a `ForEach`, multiple sibling views, or an `if`/`else` (which produces `_ConditionalContent`) is doing real work — applying a shared modifier across siblings or both branches — and is fine. ## When to Extract Subviews @@ -689,6 +701,8 @@ struct MapView: UIViewRepresentable { ### Debug SwiftUI Renderings +> See `references/performance-patterns.md` (item #8) for the `_printChanges()` vs `_logChanges()` comparison and the `@self`/`@identity` output meaning. The snippets below show the call sites. + If it is needed to debug render cycles and read console output you can leverage the `_printChanges()` or `_logChanges()` methods on `View`. These methods print information about when the view is being evaluated and what changes are triggering updates. This can be very helpful when your view body is called multiple times and you want to know why. ```swift @@ -759,13 +773,13 @@ Ways to fix it: ## Summary Checklist -- [ ] Follow a consistent view file structure (Environment → State → Private → Init → Body → Subviews) -- [ ] Prefer modifiers over conditional views for state changes -- [ ] Avoid `if`-based conditional modifier extensions (they break view identity) - [ ] Extract complex views into separate subviews, not computed properties - [ ] Keep views small for readability and performance - [ ] Use `@ViewBuilder` only where it actually adds value -- [ ] Avoid heavy filtering, mapping, sorting, or formatter creation inside `body` +- [ ] Avoid heavy filtering, mapping, sorting, or formatter creation inside `body` or `init` +- [ ] Keep view `init` cheap (constant-time input copy; it runs on every parent body pass) +- [ ] Resolve SDK 27 `@ContentBuilder` ambiguity with the matching narrow fix +- [ ] Avoid single-child `Group { OneView() }` (chain modifiers directly on the child) - [ ] Use lazy containers for large data sets - [ ] Container views use `@ViewBuilder let content: Content` - [ ] Prefer `overlay` / `background` for decoration and `ZStack` for peer composition diff --git a/.agents/skills/swiftui-expert-skill/references/webkit-integration.md b/.agents/skills/swiftui-expert-skill/references/webkit-integration.md new file mode 100644 index 00000000..c2a79841 --- /dev/null +++ b/.agents/skills/swiftui-expert-skill/references/webkit-integration.md @@ -0,0 +1,242 @@ +# WebKit Integration in SwiftUI + +> `WebView` and `WebPage` require iOS 26, macOS 26, or visionOS 26 and are **unavailable on watchOS and tvOS**. A few members require the aligned 27 releases; those are called out inline. Both types are `@MainActor`. + +## Table of Contents + +- [WebView](#webview) +- [WebPage](#webpage) +- [Configuration and Data Stores](#configuration-and-data-stores) +- [Loading Content](#loading-content) +- [Observing Navigation](#observing-navigation) +- [Deciding Navigation Policy](#deciding-navigation-policy) +- [Calling JavaScript](#calling-javascript) +- [Find Navigator](#find-navigator) +- [View Modifiers](#view-modifiers) +- [Exporting PDF and Images](#exporting-pdf-and-images) +- [Custom URL Schemes](#custom-url-schemes) + +--- + +## WebView + +`WebView` has two initializers: one for a bare URL, one backed by a `WebPage`. + +```swift +import SwiftUI +import WebKit + +WebView(url: URL(string: "https://www.swift.org")) +``` + +`WebView(url:)` is enough for read-only display; the view reloads when the URL changes. Use the `WebPage` initializer when you need the page's title, loading state, back-forward list, JavaScript, or navigation policy. + +## WebPage + +`WebPage` is an observable `@MainActor` class that owns the web content. Because it is observable, reading its properties in a `body` re-renders automatically. + +```swift +struct BrowserView: View { + @State private var page = WebPage() + + var body: some View { + NavigationStack { + WebView(page) + .navigationTitle(page.title) + } + .onAppear { + _ = page.load(URL(string: "https://www.apple.com")) + } + } +} +``` + +Observable properties include `url`, `title` (a non-optional `String`), `isLoading`, `estimatedProgress`, `backForwardList`, `serverTrust`, and `customUserAgent`. Note that `title` is not optional — don't write `if let title = page.title`. + +```swift +ProgressView(value: page.estimatedProgress) + .opacity(page.isLoading ? 1 : 0) +``` + +## Configuration and Data Stores + +`WebPage.Configuration` is a value type applied at initialization; changing it afterwards has no effect on an existing page. + +```swift +var configuration = WebPage.Configuration() +configuration.loadsSubresources = true +configuration.defaultNavigationPreferences.allowsContentJavaScript = true +configuration.websiteDataStore = .nonPersistent() + +let page = WebPage(configuration: configuration) +``` + +`websiteDataStore` is a `WKWebsiteDataStore`. Use `.default()` to share cookies and caches with other pages in the app, or `.nonPersistent()` for private browsing where nothing survives the session. `defaultNavigationPreferences` supplies the baseline `NavigationPreferences` (JavaScript, `ContentMode`) for every navigation; a `NavigationDeciding` can override it per navigation. + +Set `page.customUserAgent` on the page itself, not the configuration. + +## Loading Content + +Every `load` overload returns an `AsyncSequence` of `WebPage.NavigationEvent` values, so you can iterate it to follow that specific navigation — or bind it to `_` when you don't care. + +```swift +_ = page.load(URLRequest(url: url)) +_ = page.load(html: "

Hello

", baseURL: URL(string: "https://example.com")!) +_ = page.load(data, mimeType: "text/html", characterEncoding: .utf8, baseURL: baseURL) +_ = page.load(simulatedRequest: request, responseHTML: html) +_ = page.reload(fromOrigin: false) +page.stopLoading() +``` + +`baseURL` resolves relative links and determines the origin for HTML and `Data` loads. Back-forward navigation loads an item from the list: + +```swift +if let backItem = page.backForwardList.backItem { + _ = page.load(backItem) +} +``` + +## Observing Navigation + +`page.navigations` is an `AsyncSequence` of `NavigationEvent` covering all navigations; the per-call sequence returned by `load` covers just that one. Cases are `.startedProvisionalNavigation`, `.receivedServerRedirect`, `.committed`, and `.finished`. Failures surface as thrown `WebPage.NavigationError` values (`.failedProvisionalNavigation`, `.pageClosed`, `.webContentProcessTerminated`, `.invalidURL`). + +```swift +.task { + do { + for try await event in page.navigations { + if event == .finished { await indexPage() } + } + } catch { + // handle NavigationError + } +} +``` + +For simple loading indicators, prefer the observable `page.isLoading` and `page.estimatedProgress` over consuming the event stream. + +## Deciding Navigation Policy + +Conform a type to `WebPage.NavigationDeciding` and pass it to the initializer. Every requirement has a default implementation, so implement only what you need. + +```swift +struct LinkPolicy: WebPage.NavigationDeciding { + func decidePolicy( + for action: WebPage.NavigationAction, + preferences: inout WebPage.NavigationPreferences + ) async -> WKNavigationActionPolicy { + guard action.request.url?.host() != "blocked.example.com" else { return .cancel } + preferences.allowsContentJavaScript = true + return .allow + } + + func decidePolicy( + for response: WebPage.NavigationResponse + ) async -> WKNavigationResponsePolicy { + (response.response as? HTTPURLResponse)?.statusCode == 200 ? .allow : .cancel + } +} + +let page = WebPage(navigationDecider: LinkPolicy()) +``` + +`decideAuthenticationChallengeDisposition(for:)` handles `URLAuthenticationChallenge`, and `willSubmit(formInfo:)` (iOS/macOS/visionOS 27+) observes form submissions. A separate `dialogPresenter:` parameter takes a `WebPage.DialogPresenting` type for JavaScript alerts, confirms, and prompts. + +## Calling JavaScript + +```swift +let result = try await page.callJavaScript( + """ + const meta = document.querySelector('meta[name="description"]'); + return meta ? meta.getAttribute('content') : ''; + """ +) +let description = result as? String +``` + +`callJavaScript(_:arguments:in:contentWorld:)` takes a **function body**, so use `return` to produce a value. `arguments` is a `[String: Any]` dictionary whose keys become in-scope variables — pass values that way instead of interpolating strings. `in:` targets a `WebPage.FrameInfo`; `contentWorld:` takes a `WKContentWorld` (`.page`, `.defaultClient`, or a custom world) to isolate your script's globals from the page's own. + +## Find Navigator + +`WebView` participates in the standard SwiftUI find navigator: + +```swift +WebView(page) + .findNavigator(isPresented: $isSearching) +``` + +## View Modifiers + +Applied to the `WebView`: + +| Modifier | Purpose | +|---|---| +| `webViewBackForwardNavigationGestures(_:)` | `.automatic` / `.enabled` / `.disabled` swipe navigation | +| `webViewMagnificationGestures(_:)` | Pinch-to-zoom behavior | +| `webViewLinkPreviews(_:)` | Long-press / force-touch link previews | +| `webViewTextSelection(_:)` | Takes a `TextSelectability`, e.g. `.enabled` | +| `webViewElementFullscreenBehavior(_:)` | Allows HTML element fullscreen | +| `webViewContentBackground(_:)` | Takes a `Visibility` — hide it to show your own background behind the page | +| `webViewContextMenu(menu:)` | macOS only. Builds a menu from a `WebView.ActivatedElementInfo` (its `linkURL`). | +| `webViewScrollPosition(_:)` | Binds a `ScrollPosition` | +| `webViewOnScrollGeometryChange(for:of:action:)` | Observes `ScrollGeometry` changes | +| `webViewScrollInputBehavior(_:for:)` | Enables or disables a `ScrollInputKind` | + +On macOS: + +```swift +WebView(page) + .webViewContentBackground(.hidden) + .background(.regularMaterial) + .webViewContextMenu { element in + if let url = element.linkURL { + ShareLink(item: url) + } + } +``` + +## Exporting PDF and Images + +`WebPage` conforms to `Transferable`, so it can be dragged or shared directly. For explicit exports, call `exported(as:)` with a `WebPage.ExportedContentConfiguration`: + +```swift +let pdf = try await page.exported(as: .pdf(region: .contents)) +let png = try await page.exported(as: .image(region: .rect(bounds), snapshotWidth: 1024)) +``` + +`Region` is either `.contents` or `.rect(_:)`, and both factories accept `allowTransparentBackground`. Both calls return `Data`. + +`WebPage` has no web-archive API. Web archives remain a `WKWebView` API (`createWebArchiveData(completionHandler:)`), so reach for `WKWebView` in a representable only when you specifically need `.webarchive` output. + +## Custom URL Schemes + +`URLSchemeHandler` replies with an `AsyncSequence` of `URLSchemeTaskResult` values — first a `.response`, then one or more `.data` elements. Register handlers in the configuration's `urlSchemeHandlers` dictionary keyed by `URLScheme`. + +```swift +struct AssetSchemeHandler: URLSchemeHandler { + func reply(for request: URLRequest) -> AsyncThrowingStream { + AsyncThrowingStream { continuation in + guard let url = request.url else { + continuation.finish(throwing: URLError(.badURL)) + return + } + let html = "

\(url.path())

" + continuation.yield(.response(URLResponse( + url: url, + mimeType: "text/html", + expectedContentLength: -1, + textEncodingName: "utf-8" + ))) + continuation.yield(.data(Data(html.utf8))) + continuation.finish() + } + } +} + +var configuration = WebPage.Configuration() +if let scheme = URLScheme("myapp") { + configuration.urlSchemeHandlers[scheme] = AssetSchemeHandler() +} +let page = WebPage(configuration: configuration) +``` + +`URLScheme(_:)` is failable — the system rejects reserved schemes such as `http` and `https`. Cancellation is expressed by terminating the returned sequence, so honor `Task` cancellation inside it rather than implementing a separate stop callback. diff --git a/.agents/skills/swiftui-expert-skill/scripts/record_trace.py b/.agents/skills/swiftui-expert-skill/scripts/record_trace.py index 5f1ac237..16cd69d7 100644 --- a/.agents/skills/swiftui-expert-skill/scripts/record_trace.py +++ b/.agents/skills/swiftui-expert-skill/scripts/record_trace.py @@ -64,6 +64,11 @@ def main(argv: list[str] | None = None) -> int: help="Attach to a running process by pid or name.") target.add_argument("--all-processes", action="store_true", help="Record every process (system-wide).") + parser.add_argument( + "--allow-system-wide-recording", + action="store_true", + help="Acknowledge that --all-processes may capture data from unrelated apps.", + ) args = parser.parse_args(argv) @@ -86,6 +91,22 @@ def main(argv: list[str] | None = None) -> int: file=sys.stderr) return 2 + if args.all_processes and not args.allow_system_wide_recording: + print( + "error: --all-processes may capture sensitive data from unrelated apps. " + "Review the recording scope and pass --allow-system-wide-recording " + "to confirm.", + file=sys.stderr, + ) + return 2 + + if args.allow_system_wide_recording and not args.all_processes: + print( + "error: --allow-system-wide-recording only applies with --all-processes.", + file=sys.stderr, + ) + return 2 + output = args.output or Path.cwd() / _default_trace_name(args.template) if output.exists(): print(f"error: output already exists: {output}", file=sys.stderr) @@ -105,7 +126,7 @@ def main(argv: list[str] | None = None) -> int: if args.time_limit: stop_hints.append(f"after {args.time_limit}") print(f"[record] stop via: {', '.join(stop_hints)}", flush=True) - print(f"[record] cmd: {' '.join(_shell_quote(c) for c in cmd)}", flush=True) + print(f"[record] cmd: {_format_command_for_display(cmd)}", flush=True) # Start xctrace in its own process group so we can signal cleanly. proc = subprocess.Popen(cmd, start_new_session=True) @@ -248,5 +269,20 @@ def _shell_quote(s: str) -> str: return "'" + s.replace("'", "'\\''") + "'" +def _format_command_for_display(cmd: list[str]) -> str: + """Render a command for logs without exposing launched-app env values.""" + display: list[str] = [] + redact_next = False + for arg in cmd: + if redact_next: + key = arg.split("=", 1)[0] + display.append(f"{key}=" if key else "") + redact_next = False + continue + display.append(arg) + redact_next = arg == "--env" + return " ".join(_shell_quote(arg) for arg in display) + + if __name__ == "__main__": sys.exit(main()) diff --git a/skills-lock.json b/skills-lock.json index 6eff8f35..e445ce36 100644 --- a/skills-lock.json +++ b/skills-lock.json @@ -4,8 +4,8 @@ "swiftui-expert-skill": { "source": "avdlee/swiftui-agent-skill", "sourceType": "github", - "skillPath": "swiftui-expert-skill/SKILL.md", - "computedHash": "9db9a694b7354dea993bff22d038bc39e4d64b28a9c598b84793f2e1153db1cb" + "skillPath": "skills/swiftui-expert-skill/SKILL.md", + "computedHash": "5388cd2368b525d2906798ac313c70415e971da35670e571e98baf8a7140505f" } } }