Swift Bindings
UniFFI ships with production-quality support for generating Swift bindings. Concepts from the UDL file map into Swift as follows:
- Primitive datatypes map to their obvious Swift counterpart, e.g.
u32
becomesUInt32
,string
becomesString
,bytes
becomesData
, etc. - An object interface declared as
interface T
is represented as a Swiftprotocol TProtocol
and a concrete Swiftclass T
that conforms to it. Having the protocol declared explicitly can be useful for mocking instances of the class in unittests. - A dictionary struct declared as
dictionary T
is represented as a Swiftstruct T
with public mutable fields. - An enum declared
enum T
or[Enum] interface T
is represented as a Swiftenum T
with appropriate variants. - Optional types are represented using Swift's builtin optional type syntax
T?
. - Sequences are represented as Swift arrays, and Maps as Swift dictionaries.
- Errors are represented as Swift enums that conform to the
Error
protocol. - Function calls that have an associated error type are marked with
throws
, and hence must be called using one of Swift'stry
syntax variants. - Failing assertions, Rust panics, and other unexpected errors in the generated code
are translated into a private enum conforming to the
Error
protocol.- If this happens inside a throwing Swift function, it can be caught and handled
by a catch-all
catch
statement (but do so at your own risk, because it indicates that something has gone seriously wrong). - If this happens inside a non-throwing Swift function, it will be converted into a fatal Swift error that cannot be caught.
- If this happens inside a throwing Swift function, it can be caught and handled
by a catch-all
Generated files
UniFFI generates several kinds of files for Swift bindings:
- C header files declaring the FFI structs/functions used by the Rust scaffolding code
- A modulemap, which defines a Swift module for the C FFI definitions in the header file.
- A Swift source file that defines the Swift API used by consumers. This imports the FFI module.