These bindings are low-level FFI interfaces. For most iOS/macOS development, use the XMTPiOS SDK instead, which provides a Swift-native API built on top of these bindings.
Installation
The bindings are distributed as an XCFramework through Swift Package Manager:Swift Package Manager
Add to yourPackage.swift:
- File → Add Package Dependencies
- Enter repository URL:
https://github.com/xmtp/libxmtp - Select version and add to your target
Requirements
- iOS 14.0+ or macOS 11.0+
- Swift 6.1+
- Xcode 15.0+
Architecture
The Swift bindings use UniFFI to generate Swift code from Rust, providing memory-safe cross-language communication.Key Technologies
- UniFFI: Mozilla’s tool for generating foreign-language bindings from Rust
- XCFramework: Pre-compiled binary framework containing native code for all Apple platforms
- FFI (Foreign Function Interface): Low-level interface between Swift and Rust
- Tokio Integration: Rust async runtime with Swift async/await bridging
Binary Artifacts
The package includes two XCFramework variants:- Static
- Dynamic
LibXMTPSwiftFFI.xcframework - Statically linked framework (default)- Smaller app size when bundled
- No runtime dependencies
- Enabled by default trait
Object Lifetimes
UniFFI manages object lifetimes usingArc<> pointers:
- Objects crossing the FFI boundary are wrapped in
Arc<> - Swift ARC automatically releases Rust objects when no longer referenced
- No manual memory management required
Async and Concurrency
The bindings use Tokio’s multi-threaded runtime:- Swift async/await calls map to Rust async functions
- Rust operations may resume on different threads after
await - All exposed objects are
Send + Syncfor thread safety - No mutable references (
&mut self) across FFI boundary
Basic Usage
Here’s a basic example of creating a client and sending messages:Development
Prerequisites
For development, you need:- macOS with Xcode
- Rust toolchain
- Cross-compilation tools for iOS targets
Build Commands
Linting and Formatting
.swiftlint.yml- SwiftLint configuration.swiftformat- SwiftFormat rules
Testing
Running Tests
Tests require a running XMTP backend:Test Structure
Tests are located insdks/ios/Tests/XMTPTests/:
ClientTests.swift- Client creation and managementConversationTests.swift- Conversation operationsGroupTests.swift- Group messagingDmTests.swift- Direct messagesCryptoTests.swift- Cryptographic operations
Example Test
Package Structure
FromPackage.swift:
Key Dependencies
- Runtime
- Development
LibXMTPSwiftFFI- FFI bindings (local XCFramework)Connect- gRPC client for SwiftCryptoSwift- Cryptographic utilities
Advanced Patterns
Database Encryption
All local data is encrypted using a key you provide:Environment Configuration
Inbox State Management
Streaming Updates
Performance Considerations
Memory Management
- UniFFI uses Arc for shared ownership between Swift and Rust
- Swift ARC automatically deallocates objects
- Large data transfers are zero-copy where possible
Threading
- Tokio runtime uses multiple threads for Rust operations
- Swift async/await integrates seamlessly
- All callbacks are Send + Sync safe
Database Performance
- SQLite with encryption (SQLCipher)
- Write-ahead logging (WAL) enabled
- Connection pooling for concurrent access
Troubleshooting
Framework Not Found
If you see “Framework not found LibXMTPSwiftFFI”:Database Errors
If you encounter database errors:Async Context Required
Many methods require async context:Resources
UniFFI Documentation
Learn about the UniFFI framework
Source Code
View the bindings source code
XMTPiOS SDK
Use the high-level Swift SDK
Example Tests
See real usage examples
