This repo contains all the downloadable materials and projects associated with the Swift SDK for Android module in:
- This course is part of Program, which you can take as either on-demand or live bootcamp from Kodeco.
Learn how to integrate Swift code into your Android applications using Swift SDK for Android! This 3-lesson module teaches you how to build a hybrid Task Manager app that leverages Swift for business logic while maintaining a native Kotlin UI with Jetpack Compose.
By the end of this module, you'll have created a fully functional Task Manager app that demonstrates real-world Swift-Android integration patterns.
Before building these projects, ensure you have:
- macOS 13.0+ (Ventura or later) or Ubuntu 20.04+ / Debian 12+
- Android Studio (Iguana 2023.2.1 or later)
- Android SDK with API Level 34
- Android NDK 27
- JDK 21 (for daily builds) and JDK 25 (one-time setup for SwiftKitCore publishing)
- Git for cloning the repository
Swiftly is the official Swift toolchain manager that makes it easy to install and manage Swift versions.
curl -L https://swift-server.github.io/swiftly/swiftly-install.sh | bashcurl -L https://swift-server.github.io/swiftly/swiftly-install.sh | bashAfter installation, restart your terminal or run:
source ~/.local/share/swiftly/env.shVerify installation:
swiftly --versionInstall the Swift 6.3 development snapshot (required for Swift SDK for Android):
swiftly install 6.3-snapshot
swiftly use 6.3-snapshotVerify Swift installation:
swift --version
# Should show: Swift version 6.3-devInstall the Swift SDK for Android:
swift sdk install https://download.swift.org/swift-6.3-branch/android-sdk/swift-6.3-DEVELOPMENT-SNAPSHOT-2026-01-16-a/swift-6.3-DEVELOPMENT-SNAPSHOT-2026-01-16-a_android.artifactbundle.tar.gz --checksum 080da5553cdd12d286f715d86527089e7c924093733f8f4e1195f2bd2137d45cNote: Check swift.org/install for the latest snapshot URL and checksum if this is outdated.
Verify SDK installation:
swift sdk list
# Should show: swift-6.3-DEVELOPMENT-SNAPSHOT-2026-01-16-a_android (installed)swift-java requires two JDK versions:
- JDK 21 - For all project builds (daily use)
- JDK 25 - For one-time SwiftKitCore publishing
First install sdkman using homebrew
brew tap sdkman/tap
brew install sdkman-cliAfter successful installation add the following lines to the end of your .bash_profile or .zshrc
export SDKMAN_DIR=$(brew --prefix sdkman-cli)/libexec
[[ -s "${SDKMAN_DIR}/bin/sdkman-init.sh" ]] && source "${SDKMAN_DIR}/bin/sdkman-init.sh"Open a new terminal and type
sdk versionThe output should look similar to this
SDKMAN!
script: 5.19.0
native: 0.7.4 (macos aarch64)
Next, install JDK 21 with sdkman
# Using sdkman (recommended)
sdk install java 21.0.5-tem
sdk use java 21.0.5-tem
# Set as default
sdk default java 21.0.5-tem
# Verify
java -version # Should show: openjdk version "21.0.5"# Using sdkman
sdk install java 25.0.1-tem
# Or download from: https://jdk.java.net/25/-
Open Android Studio and install:
- Android SDK Platform 34
- Android NDK 27.2.12479018 (via SDK Manager → SDK Tools → NDK)
- Android SDK Build-Tools 34.0.0
-
Configure NDK Path:
- Open Preferences, and search for Android SDK
- Go to SDK Tools tab
- Check NDK (Side by side)
- Note the NDK path (typically
~/Library/Android/sdk/ndk/27.2.12479018)
-
Set Environment Variables (add to
~/.zshrcor~/.bash_profile):
export ANDROID_HOME=$HOME/Library/Android/sdk
export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/27.2.12479018
export JAVA_HOME="/Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home"
export PATH=$JAVA_HOME/bin:$PATH
export PATH=$PATH:$ANDROID_HOME/platform-tools
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/binThen reload your shell:
source ~/.zshrc # or source ~/.bash_profileRequired for swift-java integration - this only needs to be done once per machine:
# Switch to JDK 25 (required for SwiftKitCore compilation)
export JAVA_HOME="/Library/Java/JavaVirtualMachines/jdk-25.jdk/Contents/Home"
java -version # Verify: openjdk version "25.0.1"
# Clone swift-java repository
cd ~
git clone https://github.com/swiftlang/swift-java.git
cd swift-java
# Publish SwiftKitCore to local Maven
./gradlew :SwiftKitCore:publishToMavenLocal
# Verify publication
ls ~/.m2/repository/org/swift/swiftkit/swiftkit-core/
# Should show: 1.0-SNAPSHOT/
# Switch back to JDK 21 for all other builds
export JAVA_HOME="/Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home"
java -version # Verify: openjdk version "21.0.5"What this does: Publishes the swift-java core library (SwiftKitCore) to your local Maven repository at ~/.m2/repository. This is required for JExtractSwiftPlugin to generate Java bindings from Swift code.
Why JDK 25? SwiftKitCore requires JDK 25 to compile. After this one-time setup, you'll use JDK 21 for all daily project builds.
Critical: After installing both the Swift SDK and Android NDK, run the setup script to link them:
cd ~/Library/org.swift.swiftpm || cd ~/.swiftpm
./swift-sdks/swift-6.3-DEVELOPMENT-SNAPSHOT-2026-01-16-a_android.artifactbundle/swift-android/scripts/setup-android-sdk.shYou should see this success message:
setup-android-sdk.sh: success: ndk-sysroot linked to Android NDK at android-ndk-r27d/toolchains/llvm/prebuilt
Why this is needed: The Swift SDK expects the NDK at a specific symlink path. Without this step, builds will fail with "ndk-sysroot not found" or "semaphore.h not found" errors.
- Clone the repository:
git clone https://github.com/kodecocodes/m3-swfa-materials.git
cd m3-swfa-materials- Navigate to a project (e.g., Lesson 1 Final):
cd 01-swift-java-interop/Final- Build Swift code:
# Build the Swift library module
./gradlew :taskmanager-lib:buildSwiftAllThis task:
- Compiles Swift for 3 architectures (arm64-v8a, armeabi-v7a, x86_64)
- Auto-generates Java wrapper classes via JExtractSwiftPlugin
- Generates libTaskManagerKit.so for each architecture
- Copies all libraries to
app/src/main/jniLibs/ - Includes Swift runtime libraries (~28 files per architecture)
Generated Java classes location:
taskmanager-lib/.build/plugins/outputs/taskmanagerkit/TaskManagerKit/JExtractSwiftPlugin/
└── src/generated/java/
├── Task.java
├── Priority.java
├── TaskValidator.java
├── TaskManager.java
└── SwiftArena.java
These classes are automatically included in your Android build - no manual imports needed!
- Build the Android app:
./gradlew assembleDebugOr open the project in Android Studio and click Run
Issue: Swift SDK not found
- Solution: Run
swift sdk listto verify SDKs are installed - Ensure you're using Swift 6.3 snapshot:
swiftly use 6.3-snapshot
Issue: NDK not found
- Solution: Set
ANDROID_NDK_HOMEenvironment variable - Verify NDK is installed:
ls $ANDROID_HOME/ndk/
Issue: Could not find org.swift:swiftkitcore:1.0-SNAPSHOT
- Solution: Publish SwiftKitCore to Maven (Step 6)
- Verify publication:
ls ~/.m2/repository/org/swift/swiftkitcore/ - Make sure you used JDK 25 for publishing
Issue: Kotlin compiler requires JDK 21 or version errors
- Solution: Ensure you're using JDK 21 for builds:
export JAVA_HOME="/Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home" java -version # Should show 21.0.5
- JDK 25 is only for publishing SwiftKitCore (one-time)
Issue: buildSwiftAll task fails
- Solution: Check Swift installation:
swift --version - Ensure Swift SDK for Android is installed:
swift sdk list - Verify JDK 21 is active:
java -version
Issue: JExtractSwiftPlugin not generating classes
- Solution: Verify
swift-java.configexists in Swift Sources directory - Check Package.swift includes swift-java dependency
- Clean and rebuild:
./gradlew clean :taskmanager-lib:buildSwiftAll
Issue: Build succeeds but app crashes on launch
- Solution: Verify correct libraries are in
jniLibs/folders - Check that Swift runtime libraries were copied (should be ~29 files per architecture)
- Verify generated Java classes exist in
.build/plugins/outputs/
- For Emulator: Use x86_64 image (API 28+)
- For Physical Device: Use ARM64 device (most modern Android phones)
- Grant Permissions: Camera permission required for Lessons 2 & 3
m3-swfa-materials/
├── 01-swift-java-interop/
│ ├── Starter/
│ │ ├── taskmanager-lib/ # Swift library module
│ │ │ ├── build.gradle.kts # Swift build + JExtract config
│ │ │ ├── Package.swift # Swift dependencies (includes swift-java)
│ │ │ ├── gradle.properties
│ │ │ └── Sources/TaskManagerKit/
│ │ │ ├── Task.swift
│ │ │ ├── TaskManager.swift
│ │ │ ├── TaskValidator.swift
│ │ │ └── swift-java.config # JExtract configuration
│ │ ├── app/ # Android app module
│ │ │ ├── build.gradle.kts # Depends on :taskmanager-lib
│ │ │ └── src/main/
│ │ │ ├── java/ # Kotlin UI code
│ │ │ └── jniLibs/ # Generated .so files
│ │ ├── build.gradle.kts # Root build config
│ │ └── settings.gradle.kts # Multi-module declaration
│ └── Final/ # (same structure)
├── 02-platform-integration/ # (same structure + image processing)
├── 03-data-persistence/ # (same structure + persistence)
├── images/ # Screenshots and assets
├── scratch/ # Development documentation
└── README.md # This file
Multi-Module Architecture:
Each project uses a multi-module Gradle structure:
-
taskmanager-lib/ - Swift library module
- Compiles Swift code for Android
- Uses JExtractSwiftPlugin to auto-generate Java bindings
- Produces
.solibraries and Java wrapper classes - No manual JNI exports needed!
-
app/ - Android app module
- Kotlin/Compose UI
- Imports auto-generated Java classes from
taskmanager-lib - Uses type-safe Swift APIs through generated wrappers
Key Files:
- Package.swift - Swift dependencies (includes swift-java package)
- swift-java.config - Configures Java package name and JNI mode
- build.gradle.kts - Gradle build with JExtractSwiftPlugin
- settings.gradle.kts - Declares both modules (
app,taskmanager-lib)
After completing all three lessons, your Task Manager app will feature:
Lesson 1: Swift-Java Interoperability
- Swift-based validation for task titles (3-50 characters) and descriptions (10-200 characters)
- swift-java auto-generated bindings for type-safe Swift-Kotlin interop
- Zero manual JNI code - JExtractSwiftPlugin generates Java wrappers automatically
- SwiftArena memory management for proper object lifecycle
Lesson 2: Platform Integration
- Camera capture using CameraX
- Real-time image processing with Swift filters:
- Grayscale conversion
- Blur effects
- Brightness adjustments
- Photo attachment to tasks
Lesson 3: Data Persistence & Testing
- JSON-based task persistence (tasks survive app restarts)
- Photo persistence
- Full CRUD operations (Create, Read, Update, Delete)
- Material Design 3 UI with priority badges
- Hybrid Architecture: Swift handles business logic and validation, Kotlin handles UI
- swift-java Integration: Auto-generated type-safe bindings, zero manual JNI
- Multi-Module Design: Clean separation between Swift library and Android app
- Production Patterns: Repository pattern, singleton managers, proper error handling
- Modern UI: Material Design 3 with Jetpack Compose
- Real-World Integration: Demonstrates practical Swift SDK for Android usage
Each edition has its own branch, named versions/[VERSION]. The default branch for this repo is for the most recent edition.
| Branch | Version | Release Date |
|---|---|---|
| versions/1.0 | 1.0 | YYYY-MM-DD |
