# Rastrillo Native

Optional native components and app starting points in the Rastrillo family.
The first package supports iOS 17+ and macOS 14+. Android and Go Mobile
integration are documented extension points, not tested shipped adapters.

## Use the package

Add `https://amadan.net/rastrillo/native` to your Swift package dependencies,
pinned to a reviewed commit, then depend on its `RastrilloNative` product.
Read [SKILL.md](SKILL.md) before integrating it.

```swift
import RastrilloNative

@MainActor
final class Inbox {
    private let refresh = CoalescedRunner()

    func reload() async {
        await refresh.run {
            // Fetch and publish this inbox's current state here.
        }
    }
}
```

Use a runner for one operation and account. Calls during a refresh queue one
trailing refresh; every caller waits until shared work completes. Calls
during the trailing refresh can queue another pass. The first caller's
closure supplies every pass, so do not mix different operations in one runner.
Handle errors within that closure. Cancelling a caller does not cancel the
shared refresh. Calling the same runner from its own pass deadlocks.

## Start a companion app

`examples/companion` is a small SwiftUI app with iOS and macOS targets. It
connects to a Rastrillo server's public `/api/version` endpoint. It has no
account linking, credentials, offline data or push enrolment.

Copy that directory into your app. Replace the local package path in
`project.yml` with the repository URL and a reviewed revision, change the
bundle identifiers, and add your app's screens. Run `xcodegen generate` in
the copied directory and open `Companion.xcodeproj`. Sign with your own team
for physical devices or distribution.

Prefer fully native UI so navigation, menus, contextual actions, links and
accessibility meet the platform's expectations. For a complex app, keep a
native shell around selected webview screens. A shared app manifest can
describe destinations and commands for separate web and native renderers;
that is a possible architecture, not a compiler supplied by this kit. See
[docs/app-architecture.md](docs/app-architecture.md). Bind shared Go logic only
when it removes duplication: see [docs/go-mobile.md](docs/go-mobile.md).

## Validate

`make ci` runs the Swift tests and compiles both companion targets. It
requires macOS, Xcode and XcodeGen. Builds are unsigned; this gate does not
claim physical-device, signing or store-distribution validation.

## Provenance

`CoalescedRunner` comes from Eleven/Ocho's `ios/LChatCore` at commit
`000b882c`, also copied into Keymail's `apple/KeymailCore`. The extraction
preserves its implementation and tests the failure it prevented: concurrent
refresh bursts and callers resuming before their new data has been fetched.
Consumer branches replace the copies with public type aliases so existing
call sites keep their API. See the adoption status on amadan before treating
a consumer branch as landed.

MPL-2.0; see [LICENSE](LICENSE). The extracted source retains that licence.
