Swift Binding Generation via UniFFI
Summary
Adds optional Swift binding generation using Mozilla's UniFFI behind a feature flag. Non-breaking, minimal changes (~300 lines).
Approach
Uses Mozilla's UniFFI to automatically generate Swift bindings from Rust:
- UniFFI handles FFI complexity and type conversions
- Rust core remains the single source of truth
- Generated bindings expose safe Swift APIs that call into compiled Rust
Changes
This PR will add 4 new files behind #[cfg(feature = "uniffi")]:
-
src/uniffi_bindings.rs(~60 lines) - Thin Rust wrapper exposing functions to UniFFI -
src/tiktoken.udl(~25 lines) - UniFFI interface definition -
uniffi.toml(~5 lines) - UniFFI config -
build_xcframework.sh- Build script to build the Rust library for Apple platforms and bundle it into a cross-platformXCFramework
Usage
For Swift Developers
You can either add the XCFramework to your project directly, or use the Swift package I created: TiktokenSwift, which includes prebuilt bindings, tests, documentation, and an example project.To add the Swift package:
// Package.swift
dependencies: [
.package(url: "https://github.com/nicholasarner/TiktokenSwift", from: "1.0.0")
]
Swift API Example
let encoder = try Tiktoken(encoding: "cl100k_base")
let tokens = encoder.encode(text: "Hello world")
let decoded = encoder.decodeBytes(tokens: tokens)
Supports all encodings: cl100k_base, o200k_base, r50k_base, p50k_base
For Maintainers/Contributors
To regenerate bindings from source, first make sure you install the required Rust targets:
rustup target add aarch64-apple-ios # iOS devices
rustup target add aarch64-apple-ios-sim # iOS Simulator (Apple Silicon)
rustup target add x86_64-apple-ios # iOS Simulator (Intel)
rustup target add aarch64-apple-darwin # macOS (Apple Silicon)
rustup target add x86_64-apple-darwin # macOS (Intel)
To build just the cross-device Rust framework, run:
cargo build --release --features uniffi
To generate the bindings, run:
uniffi-bindgen generate src/tiktoken.udl --language swift
To build the frameworks, generate the bindings, and package everything together as an XCFramework, run:
./build_xcframework.sh
Testing
- ✅ All existing Rust tests pass
- ✅ Swift package includes comprehensive test suite
- ✅ Tested on iOS 13+, macOS 10.15+
- ✅ XCFramework ~5MB (includes compiled Rust library)
Impact
- Feature flag means zero impact when disabled
- Swift package maintained separately
- No changes to existing Rust functionality
- UniFFI approach could enable other language bindings in future