tiktoken icon indicating copy to clipboard operation
tiktoken copied to clipboard

Swift Binding Generation via UniFFI

Open narner opened this issue 6 months ago • 0 comments

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-platform XCFramework

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

narner avatar Aug 14 '25 21:08 narner