From a2fc08786948b6298a5d2710bbc17e2e96e4fb95 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Wed, 22 Apr 2026 22:53:39 -0400 Subject: [PATCH 1/4] Documentation package --- .gitignore | 3 ++ Package.swift | 16 +++++++ README.md | 11 +++++ .../Documentation.docc/BuildingForAndroid.md | 45 +++++++++++++++++++ .../Documentation.docc/Documentation.md | 19 ++++++++ .../Documentation.docc/GettingStarted.md | 36 +++++++++++++++ .../Documentation.docc/Integration.md | 40 +++++++++++++++++ .../Documentation.docc/PortingPackages.md | 41 +++++++++++++++++ Sources/SwiftAndroid/Empty.swift | 1 + 9 files changed, 212 insertions(+) create mode 100644 Package.swift create mode 100644 Sources/SwiftAndroid/Documentation.docc/BuildingForAndroid.md create mode 100644 Sources/SwiftAndroid/Documentation.docc/Documentation.md create mode 100644 Sources/SwiftAndroid/Documentation.docc/GettingStarted.md create mode 100644 Sources/SwiftAndroid/Documentation.docc/Integration.md create mode 100644 Sources/SwiftAndroid/Documentation.docc/PortingPackages.md create mode 100644 Sources/SwiftAndroid/Empty.swift diff --git a/.gitignore b/.gitignore index 7922dd4..1d53b7e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,9 @@ build/ local.properties jniLibs +# generated documentation from swift package generate-documentation +docs/ + # Kotlin Gradle plugin data # See https://kotlinlang.org/docs/whatsnew20.html#new-directory-for-kotlin-data-in-gradle-projects .kotlin/ diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..5b071ee --- /dev/null +++ b/Package.swift @@ -0,0 +1,16 @@ +// swift-tools-version: 6.0 + +import PackageDescription + +let package = Package( + name: "swift-android-examples", + products: [ + .library(name: "SwiftAndroid", targets: ["SwiftAndroid"]) + ], + dependencies: [ + .package( + url: "https://github.com/swiftlang/swift-docc-plugin", from: "1.1.0") + ], + targets: [ + .target(name: "SwiftAndroid") + ]) diff --git a/README.md b/README.md index 0742f37..fa33109 100644 --- a/README.md +++ b/README.md @@ -58,3 +58,14 @@ Examples using raw JNI, without generated bridging sources: - **[hello-swift-raw-jni](hello-swift-raw-jni/)** - basic Swift integration that calls a Swift function. - **[hello-swift-raw-jni-callback](hello-swift-raw-jni-callback/)** - demonstrates bidirectional communication with Swift timer callbacks updating Android UI. - **[hello-swift-raw-jni-library](hello-swift-raw-jni-library/)** - shows how to package Swift code as a reusable Android library component. + +## Documentation + +The `Sources/SwiftAndroid/Documentation.docc` directory contains a DocC documentation catalog for Swift on Android. To build and preview it locally: + +```shell +swift package generate-documentation --target SwiftAndroid --transform-for-static-hosting --output-path docs +python3 -m http.server 8000 --directory docs +``` + +Then open in your browser. diff --git a/Sources/SwiftAndroid/Documentation.docc/BuildingForAndroid.md b/Sources/SwiftAndroid/Documentation.docc/BuildingForAndroid.md new file mode 100644 index 0000000..530073b --- /dev/null +++ b/Sources/SwiftAndroid/Documentation.docc/BuildingForAndroid.md @@ -0,0 +1,45 @@ +# Building for Android + +Cross-compile Swift code and package it into Android applications + +## Overview + +Swift on Android uses cross-compilation: you build on a macOS or Linux host, and the compiler produces native ARM or x86_64 binaries targeting Android. + +```shell +$ swift build --swift-sdk aarch64-unknown-linux-android28 +``` + +## Conditional compilation + +Use `#if os(Android)` to conditionalize code for Android: + +```swift +#if os(Android) +import Android +#elseif canImport(Darwin) +import Darwin +#endif +``` + +## Foundation + +Foundation networking types require a separate import on non-Apple platforms: + +```swift +import Foundation +#if canImport(FoundationNetworking) +import FoundationNetworking +#endif +``` + +## JNI integration + +Export Swift functions for JNI using `@_cdecl`: + +```swift +@_cdecl("Java_com_example_MyClass_hello") +func hello(env: UnsafeMutablePointer, thisObj: jobject) -> jstring { + return env.pointee.pointee.NewStringUTF(env, "Hello from Swift")! +} +``` diff --git a/Sources/SwiftAndroid/Documentation.docc/Documentation.md b/Sources/SwiftAndroid/Documentation.docc/Documentation.md new file mode 100644 index 0000000..3943832 --- /dev/null +++ b/Sources/SwiftAndroid/Documentation.docc/Documentation.md @@ -0,0 +1,19 @@ +# Swift on Android + +Use Swift to build native libraries and applications for Android + +@Metadata { + @TechnologyRoot +} + +## Topics + +### Getting Started + +- +- + +### Guides + +- +- diff --git a/Sources/SwiftAndroid/Documentation.docc/GettingStarted.md b/Sources/SwiftAndroid/Documentation.docc/GettingStarted.md new file mode 100644 index 0000000..d6e138c --- /dev/null +++ b/Sources/SwiftAndroid/Documentation.docc/GettingStarted.md @@ -0,0 +1,36 @@ +# Getting Started + +Install the Swift toolchain, Android NDK, and Swift SDK for Android + +## Overview + +Development requires three components: + +1. **Swift Toolchain** -- install with [swiftly](https://github.com/swiftlang/swiftly): `swiftly install latest` +2. **Android NDK** -- download from [developer.android.com](https://developer.android.com/ndk/downloads) (r27d+ recommended) +3. **Swift SDK for Android** -- install with `swift sdk install` (see [swift.org](https://www.swift.org/documentation/articles/swift-sdk-for-android-getting-started.html)) + +## Install the SDK + +```shell +$ swift sdk install https://download.swift.org/swift-6.1-release/android-sdk/swift-6.1-RELEASE/swift-6.1-RELEASE_android.artifactbundle.tar.gz +$ swift sdk list +``` + +## Hello World + +```shell +$ swift package init --type executable +$ swift build --swift-sdk aarch64-unknown-linux-android28 +$ adb push .build/aarch64-unknown-linux-android28/debug/HelloWorld /data/local/tmp/ +$ adb shell /data/local/tmp/HelloWorld +Hello, world! +``` + +## Target triples + +| Architecture | Triple | +|---|---| +| ARM64 | `aarch64-unknown-linux-android28` | +| ARM32 | `armv7-unknown-linux-androideabi28` | +| x86_64 | `x86_64-unknown-linux-android28` | diff --git a/Sources/SwiftAndroid/Documentation.docc/Integration.md b/Sources/SwiftAndroid/Documentation.docc/Integration.md new file mode 100644 index 0000000..f8980fb --- /dev/null +++ b/Sources/SwiftAndroid/Documentation.docc/Integration.md @@ -0,0 +1,40 @@ +# Integration + +Integrate Swift builds with Android tooling and frameworks + +## Gradle + +Add a custom Gradle task to invoke `swift build` and copy the resulting `.so` into `jniLibs/`: + +```kotlin +tasks.register("buildSwiftLibrary") { + workingDir = file("${rootDir}/swift") + commandLine("swift", "build", + "--swift-sdk", "aarch64-unknown-linux-android28", + "-c", "release", "--static-swift-stdlib") +} +``` + +## Swift Package Manager + +```shell +$ swift build --swift-sdk aarch64-unknown-linux-android28 +``` + +## Skip + +[Skip](https://skip.dev) transpiles Swift and SwiftUI to Kotlin and Jetpack Compose: + +```shell +$ brew install skiptools/skip/skip +$ skip android build +$ skip android run +``` + +## Resources + +- [Swift SDK for Android -- Getting Started](https://www.swift.org/documentation/articles/swift-sdk-for-android-getting-started.html) +- [Porting Swift Packages](https://skip.dev/docs/porting/) +- [swift-java](https://github.com/swiftlang/swift-java) -- Java/Kotlin interop +- [swift-android-action](https://github.com/skiptools/swift-android-action) -- GitHub Actions +- [Swift Forums](https://forums.swift.org/) diff --git a/Sources/SwiftAndroid/Documentation.docc/PortingPackages.md b/Sources/SwiftAndroid/Documentation.docc/PortingPackages.md new file mode 100644 index 0000000..b970657 --- /dev/null +++ b/Sources/SwiftAndroid/Documentation.docc/PortingPackages.md @@ -0,0 +1,41 @@ +# Porting Swift Packages to Android + +Adapt existing Swift packages to build and run on Android + +## Overview + +Many Swift packages build for Android with minimal changes. The typical process is: attempt a build, fix platform-specific code with conditional compilation, then test on a device. + +For a detailed walkthrough, see [Porting Swift Packages](https://skip.dev/docs/porting/) on the Skip website. + +## Good candidates + +- Business logic, algorithms, data structures +- Networking and API clients +- Parsers, formatters, encoders/decoders +- SQLite and other database access + +## Conditional imports + +```swift +#if canImport(Darwin) +import Darwin +#elseif canImport(Android) +import Android +#elseif canImport(Glibc) +import Glibc +#endif +``` + +## Testing on Android + +```shell +$ skip android test +``` + +## CI with GitHub Actions + +```yaml +- name: Test on Android + uses: skiptools/swift-android-action@v2 +``` diff --git a/Sources/SwiftAndroid/Empty.swift b/Sources/SwiftAndroid/Empty.swift new file mode 100644 index 0000000..114df8d --- /dev/null +++ b/Sources/SwiftAndroid/Empty.swift @@ -0,0 +1 @@ +// This file is included so SwiftPM considers the target to be a Swift target. From c8b72827dccbbc4bdff9d0b50707025e1d122de2 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Wed, 22 Apr 2026 22:59:50 -0400 Subject: [PATCH 2/4] cat README.md From da4a19ddaee3c770f42f07fa4d442c4dc2a3bbde Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Wed, 22 Apr 2026 23:03:27 -0400 Subject: [PATCH 3/4] Update links --- .../SwiftAndroid/Documentation.docc/Integration.md | 13 +------------ .../Documentation.docc/PortingPackages.md | 14 -------------- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/Sources/SwiftAndroid/Documentation.docc/Integration.md b/Sources/SwiftAndroid/Documentation.docc/Integration.md index f8980fb..b8b98ce 100644 --- a/Sources/SwiftAndroid/Documentation.docc/Integration.md +++ b/Sources/SwiftAndroid/Documentation.docc/Integration.md @@ -21,20 +21,9 @@ tasks.register("buildSwiftLibrary") { $ swift build --swift-sdk aarch64-unknown-linux-android28 ``` -## Skip - -[Skip](https://skip.dev) transpiles Swift and SwiftUI to Kotlin and Jetpack Compose: - -```shell -$ brew install skiptools/skip/skip -$ skip android build -$ skip android run -``` - ## Resources - [Swift SDK for Android -- Getting Started](https://www.swift.org/documentation/articles/swift-sdk-for-android-getting-started.html) -- [Porting Swift Packages](https://skip.dev/docs/porting/) - [swift-java](https://github.com/swiftlang/swift-java) -- Java/Kotlin interop -- [swift-android-action](https://github.com/skiptools/swift-android-action) -- GitHub Actions +- [swift-android-action](https://github.com/marketplace/actions/swift-android-action) -- GitHub Actions - [Swift Forums](https://forums.swift.org/) diff --git a/Sources/SwiftAndroid/Documentation.docc/PortingPackages.md b/Sources/SwiftAndroid/Documentation.docc/PortingPackages.md index b970657..3944136 100644 --- a/Sources/SwiftAndroid/Documentation.docc/PortingPackages.md +++ b/Sources/SwiftAndroid/Documentation.docc/PortingPackages.md @@ -6,8 +6,6 @@ Adapt existing Swift packages to build and run on Android Many Swift packages build for Android with minimal changes. The typical process is: attempt a build, fix platform-specific code with conditional compilation, then test on a device. -For a detailed walkthrough, see [Porting Swift Packages](https://skip.dev/docs/porting/) on the Skip website. - ## Good candidates - Business logic, algorithms, data structures @@ -27,15 +25,3 @@ import Glibc #endif ``` -## Testing on Android - -```shell -$ skip android test -``` - -## CI with GitHub Actions - -```yaml -- name: Test on Android - uses: skiptools/swift-android-action@v2 -``` From 338cfe060a98dde581fe6bd8e46a41ab6b38070f Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Wed, 22 Apr 2026 23:05:14 -0400 Subject: [PATCH 4/4] Remove install instructions --- Sources/SwiftAndroid/Documentation.docc/GettingStarted.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Sources/SwiftAndroid/Documentation.docc/GettingStarted.md b/Sources/SwiftAndroid/Documentation.docc/GettingStarted.md index d6e138c..c876791 100644 --- a/Sources/SwiftAndroid/Documentation.docc/GettingStarted.md +++ b/Sources/SwiftAndroid/Documentation.docc/GettingStarted.md @@ -10,13 +10,6 @@ Development requires three components: 2. **Android NDK** -- download from [developer.android.com](https://developer.android.com/ndk/downloads) (r27d+ recommended) 3. **Swift SDK for Android** -- install with `swift sdk install` (see [swift.org](https://www.swift.org/documentation/articles/swift-sdk-for-android-getting-started.html)) -## Install the SDK - -```shell -$ swift sdk install https://download.swift.org/swift-6.1-release/android-sdk/swift-6.1-RELEASE/swift-6.1-RELEASE_android.artifactbundle.tar.gz -$ swift sdk list -``` - ## Hello World ```shell