Integrating with Xcode
It is possible to generate Swift bindings at compile time for Xcode projects and incorporate them alongside hand-written Swift code to form a larger module. Broadly, you will need to:
- Add a build phase to compile the Rust crate into a static lib and link it into your framework.
- Add a build phase to run
uniffi-bindgen
and generate the Swift bindings. - Include the generated bridging header into your overall bridging header.
There is also an example app in the UniFFI project repo that may be helpful.
Compiling the Rust crate.
Sorry, configuring Xcode to compile the Rust crate into a staticlib
is beyond the scope of this document. However you do so, make sure you
include the resulting libexample.a
file in the "Link Binary with Libraries"
build phase for your framework.
This repository contains an example iOS app (at ./examples/app/ios
) which
may be useful for reference. It contains an xc-universal-binary.sh
shell
script which can invoke cargo
with the necessary settings to produce a
static library of Rust code.
Generating the bindings
In the "Build Rules" section of your config, add a rule to process .udl
files
using uniffi-bindgen
. We recommend having it generate the output files
somewhere in your source tree, rather than in Xcode's default $DERIVED_FILE_DIR
;
this both helps with debugging the build output, and makes it easier to configure
how the generated files are used.
- Add a build rule processing files with names matching
*.udl
.- Use something like the following as the custom script:
$HOME/.cargo/bin/uniffi-bindgen generate $INPUT_FILE_PATH --language swift --out-dir $INPUT_FILE_DIR/Generated
- Add both the
.swift
file and the generated bridging header as output files:$(INPUT_FILE_DIR)/Generated/$(INPUT_FILE_BASE).swift
$(INPUT_FILE_DIR)/Generated/$(INPUT_FILE_BASE)FFI.h
- Use something like the following as the custom script:
- Add your
.udl
file to the "Compile Sources" build phase for your framework, so that Xcode will process it using the new build rule and will include the resulting outputs in the build.
You do not need to add the generated Swift code to the list of "Compile Sources" and should not attempt to compile it explicitly; Xcode will figure out what it needs to do with this code based on it being generated from the Build Rule for your .udl file.
Including the bridging header
In the overall bridging header for your module, include the header file generated by UniFFI in the previous step:
#include "exampleFFI.h"
For this to work without complaint from Xcode, you also need to add the generated header file as a Public header in the "Headers" build phase of your project (which is why it's useful to generate this file somewhere in your source tree, rather than in a temporary build directory).