Skip to content

iOS

The iOS host is a Swift package (BareHost) that ships as a git-fetchable package from the repo root Package.swift, so consumers add it as a normal SPM dependency at an exact ekrooh tag. The runtime binary (BareKit.xcframework) is bundled as a .binaryTarget resolved through the same tag — no sibling checkout, no cross-repo npm step.

  • BareProtocol — Swift mirror of the binary wire protocol (buildErrorResponse(…type:)).
  • HostIpcCoordinator / HostIpcRouter — IPC frames; delegates host plugins. Malformed fields (empty, non-string, over 256 bytes) and unreadable headers are answered FRAME_INVALID; a non-JSON handler result is INVALID_RESPONSE; an oversized one FRAME_TOO_LARGE.
  • HostPluginRegistry — plugin ID → handler map, with a per-handler timeout (defaultInvokeTimeout 30 s, userMediatedInvokeTimeout 5 min, clamped to maxInvokeTimeout 1 day; invokeTimeout(pluginId:event:)). A non-positive or NaN timeout traps (precondition).
  • BareStorage / BareStorageDirectories / BareStorageError — worklet directories in Application Support (excluded from backup) and Caches.
  • BareHandoff — parses and deletes handoff.json; builds the bootstrap user script.
  • BareNavigationPolicy / BareNavigationDecision (allow, cancel, openExternally, loadInPlace for a same-origin new window) / BareNavigationDelegate — loopback-origin confinement.
  • BareWebHost — configure(_:) (WebView hardening) and load(_:in:delegate:) (bootstrap injection + first load).
  • BareHostLogger — unified logger (subsystem: "to.holepunch.bare.ios").

The public Swift API is pinned by ios/public-api.swift.snap (security.apple.test.ts); after an intended, reviewed change regenerate it with vp test security.apple.test.ts -u. See iOS Embedding for how a shell uses these.

  • BareKit — vendored Worklet/IPC bridge (Sources/BareKit + Sources/BareKitBridge, from holepunchto/bare-kit-swift, Apache-2.0).
  • BareKit.xcframework — the runtime binary, bundled as a SwiftPM .binaryTarget resolved from the release tag artifact. Vendoring the bridge (rather than depending on the upstream git package) is what lets it resolve <BareKit/BareKit.h> with no consumer FRAMEWORK_SEARCH_PATHS.
  • P2P addons (udx-native, rocksdb-native, sodium-native, + hypercore’s native deps) linked via bare-link and verified on the simulator.
.package(url: "https://github.com/AndersCan/ekrooh", exact: "X.Y.Z")
// targets:
.product(name: "BareHost", package: "ekrooh")
.product(name: "BareKit", package: "ekrooh")

Xcode embeds BareKit through the package product; do not embed the prebuild a second time. An app target must still embed the bare-link --preset ios addon frameworks. See ios/readme.md for the full contract.

examples/ios-app runs the same web assets with the library’s storage, handoff and navigation pieces; the reference host wires a real picker/camera (PHPickerViewController + UIImagePickerController) and real permissions (AVCaptureDevice.requestAccess).

Terminal window
npm run prebuilds # prebuilds/ios/BareKit.xcframework
npm run build:ios # addons/, Resources/, ios-app.xcodeproj
npm run test:ios # XCTest + UI test on the simulator

Tests: Tests/BareHostTests/ (XCTest mirroring the JUnit suite) + a UI test against the reference app.