feat(ios): hoist DebugBridgeTouch into canonical templates

Bridges.swift.template imports DebugBridgeTouch but no .m/.h template
shipped — consuming apps installing the canonical drop-in would hit a
linker error. Closes that gap with the fixture's verified working code.

Changes:

- New ios-qa/templates/DebugBridgeTouch.{h,m}.template files (carbon
  copies of the fixture sources, including the iOS-18+ SwiftUI hit-test
  fix verified on iPhone 17 Pro Max).
- Package.swift.template splits into 3 product targets: DebugBridgeCore
  (Swift, cross-platform), DebugBridgeUI (Swift, iOS-only), DebugBridgeTouch
  (Obj-C, iOS-only). Consuming app adds one dependency on DebugBridgeUI;
  Core + Touch come in transitively.
- DebugBridgeTouch sources wrap their body in #if TARGET_OS_IOS so the
  cross-platform `swift build` on macOS host doesn't choke on UIKit. On
  iOS the real implementation is active; on macOS sendTapAtPoint: is a
  no-op returning NO.
- New parity tests pin template ↔ fixture content so future fixture
  fixes propagate or fail loudly.
- Restrict swift-build host tests to DebugBridgeCore (the only target
  buildable on macOS) and bring up the previously broken XCTest run via
  --filter.

Verified post-change: real iPhone 17 Pro Max, iOS 26.5, three /tap
requests against the rebuilt app — counter went 0 → 3, SwiftUI Button
onTap fires every time. Templates now sufficient to ship to any
consuming iOS app.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-05-20 07:37:31 -07:00
parent cf65bb055a
commit c2f2acebf6
8 changed files with 504 additions and 29 deletions
+21 -4
View File
@@ -842,10 +842,27 @@ fi
## Phase 2: Bootstrap the device bridge
1. Add the `DebugBridge` SPM target (Debug-config-only via
`.when(configuration: .debug)`).
2. Add `DebugBridgeManager.shared.start()` to the app's `@main` entry, gated
on `#if DEBUG`.
1. Add the `DebugBridge` SPM dependency to the app's `Package.swift`. The package
ships three Debug-config-only library products:
- `DebugBridgeCore` (Swift, cross-platform) — StateServer + bridge protocols.
- `DebugBridgeTouch` (Objective-C, iOS-only) — KIF-derived in-process touch
synthesis with iOS 18+ `_UIHitTestContext` SwiftUI hit-testing.
- `DebugBridgeUI` (Swift, iOS-only) — Screenshot / Elements / Mutation
bridge implementations.
The app target depends on `DebugBridgeUI` with `.when(configuration: .debug)`
(transitively pulls in Core + Touch). Release builds refuse to link these
targets.
2. Wire the bridges from the `@main` App init, gated on `#if DEBUG`:
```swift
#if DEBUG
import DebugBridgeCore
StateServer.shared.start()
#if canImport(UIKit)
import DebugBridgeUI
DebugBridgeUIWiring.installAll()
#endif
#endif
```
3. Build + deploy to the device with `xcodebuild -scheme <SchemeName>
-destination 'platform=iOS,id=<UDID>' build install`.
4. Launch via `devicectl device process launch --device <UDID> --console <bundle-id>`.