Rust ↔ Swift 零成本互调:swift-bridge 10 行代码跑通 1 级性能

Photos provided by Unsplash OR Pexels

本文基于最新版本 swift-bridge 0.2+(支持 Rust 1.75+、Swift 5.9+、iOS 13+/macOS 13+)以及实际生产项目经验,系统性地讲解如何高效、正确、安全地使用 swift-bridge,实现 Rust 与 Swift 之间真正“零成本抽象”的双向调用。

一、为什么选择 swift-bridge?(与其他方案对比)

方案是否类型安全生成代码量支持复杂类型(String/Option/Result/Struct/Enum)双向调用难度维护成本性能
UniFFI(Mozilla)优秀
swift-bridge极高极少完美支持(包括泛型、关联类型)极低最高
手动写 C 绑定
diplomat一般

swift-bridge 最大优势

  • 完全基于 Rust 的类型系统自动生成 Swift 代码,几乎不需要手写任何 C 头文件
  • 支持 Rust → Swift 和 Swift → Rust 双向持有同一块内存的对象(真正共享)
  • StringVec<T>Option<T>Result<T,E>#[swift_bridge::bridge] 结构体/枚举零成本转换
  • 生成的 Swift 类是真正的 Swift Reference Type(继承 NSObject,可用 @objc)

二、项目结构推荐(最佳实践)

my_rust_swift_app/
├── Cargo.toml
├── swift-bridge/                  # 必须的目录,swift-bridge 生成的文件会放在这里
├── src/
│   └── lib.rs
├── swift-sources/                 # 放生成的 Swift 代码(可选,Xcode 也会自动生成)
└── MyApp.xcodeproj

三、完整实战教程(由浅入深)

第 1 步:创建 Rust 库

cargo new --lib rust-core
cd rust-core

第 2 步:添加依赖(Cargo.toml)

[package]
name = "rust-core"
version = "0.1.0"
edition = "2021"

[lib]
name = "rust_core"
crate-type = ["staticlib", "cdylib"]   # iOS/macOS 都需要

[dependencies]
swift-bridge = "0.2"

# 如果要支持 async(推荐)
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }

# 可选:日志、序列化等
log = "0.4"
serde = { version = "1.0", features = ["derive"] }

第 3 步:编写第一个 Hello World

src/lib.rs

// 必须放在文件最上面
::swift_bridge::bridge("SwiftBridgeModule")
mod ffi {
    use swift_bridge::{SwiftResult, ToSwiftResult};

    // 暴露一个简单的同步函数
    #[swift_bridge::swift_name("hello")]
    pub extern "Rust" fn rust_say_hello(name: &str) -> String {
        format!("Hello {name} from Rust! 🚀")
    }

    // 返回 Option
    #[swift_bridge::swift_name("findUser")]
    pub extern "Rust" fn find_user(id: u64) -> Option<User> {
        if id == 42 {
            Some(User {
                id,
                name: "Elon Musk".to_string(),
                is_premium: true,
            })
        } else {
            None
        }
    }

    // 返回 Result
    #[swift_bridge::swift_name("divide")]
    pub extern "Rust" fn divide(a: f64, b: f64) -> SwiftResult<f64, DivisionError> {
        if b == 0.0 {
            DivisionError::DividedByZero.to_swift_result()
        } else {
            SwiftResult::ok(a / b)
        }
    }

    // 结构体必须在这里定义
    #[swift_bridge::swift_bridge]
    pub struct User {
        pub id: u64,
        pub name: String,
        pub is_premium: bool,
    }

    #[derive(Debug)]
    pub enum DivisionError {
        DividedByZero,
    }

    impl std::fmt::Display for DivisionError {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
            match self {
                DivisionError::DividedByZero => write!(f, "Division by zero"),
            }
        }
    }
}

编译后会自动生成:

swift-bridge/SwiftBridgeModule/
├── SwiftBridgeModule.swift
├── SwiftBridgeModuleFFI.h
├── SwiftBridgeModuleFFI.m
└── ...

第 4 步:在 Xcode 中使用(iOS/macOS 通用)

  1. 将整个 rust-core 项目拖入 Xcode(Add Files → Create folder references)
  2. 在 Build Phases → Link Binary With Libraries 添加生成的 librust_core.a.dylib
  3. 在 Bridging Header 中引入:
// MyApp-Bridging-Header.h
#import "swift-bridge/SwiftBridgeModule/SwiftBridgeModuleFFI.h"
  1. Swift 中直接使用(完全类型安全!)
import SwiftBridgeModule

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let greeting = RustCore.rustSayHello(name: "Swift Developer")
        print(greeting)  // "Hello Swift Developer from Rust! 🚀"
        
        if let user = RustCore.findUser(id: 42) {
            print("Found: \(user.name), Premium: \(user.isPremium)")
        }
        
        let result = RustCore.divide(a: 10, b: 2)
        switch result {
        case .success(let value):
            print("Result: \(value)")
        case .failure(let error):
            print("Error: \(error)")
        }
    }
}

第 5 步:高级用法 — 真正的对象共享(重磅)

// lib.rs 中
#[swift_bridge::bridge]
mod ffi {
    #[swift_bridge(swift_repr = "class")]
    pub struct Counter {
        value: std::sync::atomic::AtomicI32,
    }

    impl Counter {
        #[swift_bridge(constructor)]
        pub extern "Rust" fn new(initial: i32) -> Self {
            Counter {
                value: std::sync::atomic::AtomicI32::new(initial),
            }
        }

        #[swift_bridge(associated_function)]
        pub extern "Rust" fn increment(&self) {
            self.value.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
        }

        #[swift_bridge(getter)]
        pub extern "Rust" fn value(&self) -> i32 {
            self.value.load(std::sync::atomic::Ordering::Relaxed)
        }
    }
}

Swift 中使用(同一对象在两端共享内存!)

let counter = Counter(initial: 100)
print(counter.value) // 100
counter.increment()
print(counter.value) // 101  ← Rust 端也同步变为 101

第 6 步:Async/Await 支持(生产必备)

#[swift_bridge::swift_async]
pub extern "Rust" async fn fetch_user_profile(user_id: u64) -> Result<UserProfile, ApiError> {
    // 可以直接用 tokio、reqwest 等
    let client = reqwest::Client::new();
    let resp = client.get(format!("https://api.example.com/users/{user_id}"))
        .send()
        .await?
        .json::<UserProfile>()
        .await?;
    Ok(resp)
}

Swift 中:

Task {
    let profile = await RustCore.fetchUserProfile(userId: 123)
    switch profile {
    case .success(let p): print(p.name)
    case .failure(let e): print(e.localizedDescription)
    }
}

第 7 步:最佳实践配置(避免 99% 坑)

1. build.rs(推荐)

// build.rs
fn main() {
    swift_bridge::build::generate(
        "SwiftBridgeModule",
        "swift-bridge",
        &["src/lib.rs"],
    );
}

2. Cargo.toml 添加 build-dependencies

[build-dependencies]
swift-bridge-build = "0.2"

3. Xcode Build Settings 关键配置

HEADER_SEARCH_PATHS = $(SRCROOT)/rust-core/swift-bridge
LIBRARY_SEARCH_PATHS = $(SRCROOT)/rust-core/target/$(CONFIGURATION)-$(PLATFORM_NAME)
OTHER_LDFLAGS = -lrust_core -framework Foundation

4. 支持多架构(iOS 真机 + 模拟器)

# 构建脚本 build_rust.sh
cargo build --release --target aarch64-apple-ios
cargo build --release --target x86_64-apple-ios
cargo build --release --target aarch64-apple-ios-sim

# 使用 lipo 合并
lipo -create \
  target/aarch64-apple-ios/release/librust_core.a \
  target/x86_64-apple-ios/release/librust_core.a \
  target/aarch64-apple-ios-sim/release/librust_core.a \
  -output XcodeProject/librust_core.a

四、完整生产级项目模板(强烈推荐直接 clone)

https://github.com/chinedufn/swift-bridge/tree/master/examples

五、参考资料(官方 & 优质文章)

  1. 官方文档(最全):https://chinedufn.github.io/swift-bridge/index.html
  2. GitHub 主仓库:https://github.com/chinedufn/swift-bridge
  3. 高级特性详解(Class + Async):https://github.com/chinedufn/swift-bridge/blob/main/guide/classes.md
  4. 与 UniFFI 对比深度分析:https://fasterthanli.me/articles/so-you-want-to-call-rust-from-swift
  5. 2025 年最新实战视频(B 站搜索:swift-bridge 2025)

总结:一句话记住 swift-bridge

“用 Rust 写核心逻辑,用 Swift 写 UI,两者之间用 swift-bridge 像调用本地函数一样丝滑互通,性能零损耗,类型零转换,维护成本极低。”

掌握了这篇文章,你已经站在了 2025 年 Rust + Swift 混合开发的最前沿。祝你写出飞快的 App!🚀

版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)