diff --git a/docs/concepts/api-design.md b/docs/concepts/api-design.md index d790612..422ba01 100644 --- a/docs/concepts/api-design.md +++ b/docs/concepts/api-design.md @@ -87,7 +87,7 @@ metered = many cases) or stuff axes inside one case's payload, defeating exhaustiveness. Enum-per-axis still gives Swift consumers exhaustive `switch` over transport -individually via SKIE: `switch status.transport { case .wifi: …; case +individually: `switch status.transport { case .wifi: …; case .cellular: …; … }`. `data class` brings `equals`, `hashCode`, `copy()`, and destructuring for free. @@ -121,7 +121,7 @@ val reachability: Reachability = Reachability.shared ``` From Swift: `Reachability.shared` (via a Swift extension compiled into the -framework by SKIE; no companion prefix needed). +framework; no companion prefix needed). **Why we use a singleton, not a mandatory factory.** On Android, the `Context` requirement means that anything consuming reachability via @@ -192,7 +192,7 @@ own a platform observer (`nw_path_monitor` or `NetworkCallback`) and a path on both Apple and Android, so cleanup is explicit. `AutoCloseable.close()` is the universal idiom across Kotlin, Java, and -Swift; SKIE renders it as `close()` without any name mangling. The +Swift; it surfaces in Swift as `close()` without any name mangling. The implementation is idempotent and synchronous. `Reachability.shared` is an exception: `close()` is an intentional no-op diff --git a/docs/index.md b/docs/index.md index 93a9c48..69225ce 100644 --- a/docs/index.md +++ b/docs/index.md @@ -55,11 +55,9 @@ Apple's `nw_path_is_expensive` and `nw_path_is_constrained` (cellular, hotspot, and Low Data Mode) both fold into `isDataMetered`. Android uses `NET_CAPABILITY_NOT_METERED` for the same signal. -The Swift surface is generated by [SKIE]: enums become exhaustive Swift -enums, `StateFlow` becomes `AsyncSequence`, `suspend fun` becomes -`async throws`. - -[SKIE]: https://skie.touchlab.co/ +The Swift surface is idiomatic: Kotlin enums arrive as exhaustive Swift +enums, `StateFlow` is consumed as an `AsyncSequence`, and +`suspend fun` becomes `async throws`. ## Install diff --git a/docs/installation.md b/docs/installation.md index 87de9c9..636ddb6 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -5,12 +5,12 @@ Reachable ships through two channels: | Channel | For | Artifacts | |---|---|---| | **Maven Central** | Gradle — Android, JVM, Kotlin Multiplatform | Android AAR, `kotlinMultiplatform` metadata, per-target klibs (`iosArm64`, `iosSimulatorArm64`, `macosArm64`) | -| **Swift Package Manager** | Pure-Swift iOS / macOS apps, no Kotlin toolchain | Prebuilt [SKIE](https://skie.touchlab.co/)-enhanced `Reachable.xcframework`, hosted as a GitHub Release asset | +| **Swift Package Manager** | Pure-Swift iOS / macOS apps, no Kotlin toolchain | Prebuilt `Reachable.xcframework`, hosted as a GitHub Release asset | Kotlin Multiplatform projects should use the Maven artifact from `commonMain` — KMP resolves the right per-target slice automatically, and -SKIE bridging happens at *your* project's framework build. The Swift -package is for apps with no Kotlin in them at all — see +the Swift surface is produced at *your* project's framework build. The +Swift package is for apps with no Kotlin in them at all — see [Swift Package Manager](#swift-package-manager) below. ## Platform floors @@ -20,7 +20,7 @@ package is for apps with no Kotlin in them at all — see | iOS / iPadOS | iOS 18 | | macOS | macOS 15 | | Android | API 30 (Android 11), `arm64-v8a` only | -| Kotlin | 2.3.x (K2). The upper bound tracks SKIE — see [SKIE releases](https://github.com/touchlab/SKIE/releases). | +| Kotlin | 2.3.x (K2) | ## Gradle (Android, JVM, KMP) @@ -113,8 +113,8 @@ when the block throws. ## Swift Package Manager -Pure-Swift apps consume Reachable as a binary Swift package: a prebuilt, -SKIE-enhanced `Reachable.xcframework` with `iosArm64`, `iosSimulatorArm64`, +Pure-Swift apps consume Reachable as a binary Swift package: a prebuilt +`Reachable.xcframework` with `iosArm64`, `iosSimulatorArm64`, and `macosArm64` slices. No Kotlin toolchain, no Gradle, no authentication — the package manifest lives at the root of this repository and the binary is a public GitHub Release asset, pinned by sha256 checksum in the manifest. @@ -142,7 +142,7 @@ a public GitHub Release asset, pinned by sha256 checksum in the manifest. ] ``` -Then `import Reachable`. The SKIE bridge is baked into the framework, so +Then `import Reachable`. The Swift bridge is baked into the framework, so `StateFlow` arrives as a Swift `AsyncSequence`, sealed types `switch` exhaustively via `onEnum(of:)`, and `suspend` functions are `async throws`. @@ -153,8 +153,8 @@ resolve` downloads a prebuilt framework instead of compiling Kotlin. If you're working from a KMP project, don't add the Swift package — the iOS / macOS targets are consumed transparently via the `kotlinMultiplatform` metadata published alongside the Android AAR, and -SKIE bridging happens at your project's framework build time, not the -library's. +the Swift surface is produced at your project's framework build time, not +the library's. ## Local development override diff --git a/docs/platforms/ios.md b/docs/platforms/ios.md index 2b33a9d..60de956 100644 --- a/docs/platforms/ios.md +++ b/docs/platforms/ios.md @@ -19,11 +19,9 @@ let reachability: any Reachability = Reachability.shared it constructs an `nw_path_monitor`-backed observer and starts it eagerly. Subsequent accesses return the same instance. -The Swift `Reachability.shared` property is provided by an in-framework -Swift extension (`src/appleMain/swift/Reachability+Shared.swift`), which -SKIE auto-discovers and compiles into the `Reachable` module. Consumers -don't need any additional configuration — `Reachability.shared` just -works. +The Swift `Reachability.shared` property is provided by a Swift +extension compiled into the `Reachable` module. Consumers don't need any +additional configuration — `Reachability.shared` just works. Calling `close()` on `Reachability.shared` is an intentional no-op — the singleton's lifetime is the process. @@ -38,9 +36,9 @@ import Reachable let reachability: any Reachability = Reachability() ``` -`Reachability()` is a top-level Swift function that SKIE generates from the -top-level Kotlin factory `fun Reachability(): Reachability` in -`appleMain/Reachability.apple.kt`. Construction: +`Reachability()` is a top-level Swift function bridged from the +top-level Kotlin factory `fun Reachability(): Reachability`. +Construction: 1. Creates a per-instance serial dispatch queue (`dispatch_queue_create("dev.reachable.monitor", null)`). diff --git a/docs/platforms/macos.md b/docs/platforms/macos.md index acaac37..92917f0 100644 --- a/docs/platforms/macos.md +++ b/docs/platforms/macos.md @@ -14,8 +14,8 @@ let reachability: any Reachability = Reachability.shared ``` `Reachability.shared` is a process-lifetime singleton provided by the -same Swift extension as on iOS (`src/appleMain/swift/Reachability+Shared.swift`, -compiled into the `Reachable` module by SKIE). On first access, constructs +same Swift extension as on iOS, compiled into the `Reachable` module. +On first access, constructs an `nw_path_monitor`-backed observer and starts it eagerly. Calling `close()` on this instance is a no-op. diff --git a/docs/recipes/swiftui-binding.md b/docs/recipes/swiftui-binding.md index eb1fdc7..e6b84e6 100644 --- a/docs/recipes/swiftui-binding.md +++ b/docs/recipes/swiftui-binding.md @@ -1,7 +1,7 @@ # SwiftUI binding -SKIE bridges `StateFlow` as `AsyncSequence`, so the integration is a -single `for await` loop. Wrap that in an `@MainActor` +`StateFlow` is bridged to Swift as an `AsyncSequence`, so the +integration is a single `for await` loop. Wrap that in an `@MainActor` `ObservableObject` view-model and bind from a SwiftUI view. ## With `Reachability.shared` (recommended) @@ -143,9 +143,9 @@ if now.isReachable { } ``` -`StateFlow.value` is non-optional in Kotlin, but SKIE renders it as -Swift `Any?`. The `!` unwraps the bridged value to `ReachabilityStatus`. -SKIE may relax this in a future version. +`StateFlow.value` is non-optional in Kotlin, but the bridged Swift +property is typed `Any?`. The `!` unwraps the bridged value to +`ReachabilityStatus`. This may tighten in a future release. For a one-shot suspending read in an `async` function: diff --git a/mkdocs.yml b/mkdocs.yml index 94d904f..465998b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,4 +1,4 @@ -# Reachable docs site (CLAUDE.md §10). +# Reachable docs site. # # Source of truth for docs structure. Auto-discovery is deliberately disabled — # explicit `nav:` keeps page ordering deterministic. @@ -67,7 +67,7 @@ markdown_extensions: - toc: permalink: true toc_depth: 3 - # PyMdown — same set as Backgrounder. + # PyMdown extensions. - pymdownx.details - pymdownx.highlight: anchor_linenums: true diff --git a/reachable-testing/src/commonMain/kotlin/com/happycodelucky/reachable/testing/FakeReachability.kt b/reachable-testing/src/commonMain/kotlin/com/happycodelucky/reachable/testing/FakeReachability.kt index c885fb8..e86088a 100644 --- a/reachable-testing/src/commonMain/kotlin/com/happycodelucky/reachable/testing/FakeReachability.kt +++ b/reachable-testing/src/commonMain/kotlin/com/happycodelucky/reachable/testing/FakeReachability.kt @@ -64,7 +64,7 @@ import kotlin.native.ObjCName * shared singleton via `Reachability.installForTesting`, runs your test * block, then uninstalls and closes the fake in `finally`. * - * Renames cleanly across the SKIE bridge: in Swift the class reads as + * Renames cleanly across the Swift bridge: in Swift the class reads as * `FakeReachability`, with `emit(status:)`, `setReachable(_:)`, * `setTransport(_:)`, `setDataMetered(_:)`, `reset()`, `closeCallCount`, * `wasClosed`.