使用 WebAssembly 和 Swift:从入门到精通

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

WebAssembly 和 Swift 简介

WebAssembly (WASM) 是一种低级二进制指令格式,允许以各种语言(C、C++、Rust、Swift)编写的代码在浏览器内外以接近原生的速度运行。对于 iOS 和 macOS 平台上的 Swift 开发者来说,与 WebAssembly 的集成开辟了新的可能性:移植现有库、加速计算任务以及跨平台统一。

在本文中,您将学习如何配置环境、将 Swift 代码编译为 WASM 并从原生应用程序中调用它。我们将探讨实际示例并分析常见错误。



1. WebAssembly 基础:架构与优势

WebAssembly 是一个具有线性内存和严格类型化的虚拟机。主要特点:

  • 安全性 — 隔离执行(沙箱);
  • 性能 — 通过预编译接近原生;
  • 紧凑性 — .wasm 二进制格式占用空间小;
  • 集成性 — 易于从 JavaScript、Swift、Rust 调用。

对于 Swift,有一个名为 SwiftWasm 的项目,它允许将 Swift 代码编译为 WASM。这对于创建随后在 iOS 应用程序中使用的计算模块特别有用。



2. SwiftWasm 环境配置

在编写代码之前,请安装工具。打开终端并执行:

# 安装 SwiftWasm(通过 Homebrew)brew install swiftwasm/tap/swiftwasm

# 检查版本swift --version

还需要 wasmtime 用于本地测试:

brew install wasmtime

创建一个新的 Swift 包:

mkdir MyWasmApp && cd MyWasmAppswift package init --type executable


3. 编写 Swift 模块并编译为 WASM

考虑一个简单的例子——两个数相加的函数。编辑文件 Sources/main.swift:

@_extern(wasm, module: "env", name: "add")func add(_ a: Int, _ b: Int) -> Int

@mainstruct App { static func main() { let result = add(5, 3) print("Result: \\(result)") }}

现在编译为 WASM:

swift build --triple wasm32-unknown-wasi

成功构建后,将出现文件 .build/wasm32-unknown-wasi/release/MyWasmApp.wasm。通过 wasmtime 运行它:

wasmtime .build/wasm32-unknown-wasi/release/MyWasmApp.wasm

您应该看到输出:Result: 8。



4. 将 WebAssembly 集成到原生 iOS/macOS 应用程序中

现在最有趣的部分——从 iOS 上的 Swift 应用程序调用 WASM 函数。使用 WasmKit 库(或 WASMInterfaces)。

4.1 添加依赖

在您的 iOS 项目的 Package.swift 中添加:

dependencies: [    .package(url: "https://github.com/swiftwasm/WasmKit.git", from: "0.1.0")],targets: [    .target(        name: "YourApp",        dependencies: ["WasmKit"]    )]

4.2 加载并调用 WASM 模块

加载 .wasm 文件并调用函数的示例代码:

import WasmKit

func callWasmAdd() throws { guard let wasmURL = Bundle.main.url(forResource: "MyWasmApp", withExtension: "wasm") else { fatalError("WASM file not found") } let wasmData = try Data(contentsOf: wasmURL) let engine = WasmEngine() let module = try engine.loadModule(wasmData) let instance = try module.instantiate() // 调用 add 函数 let result = try instance.exports["add"]?.function?.call([5, 3]) print("WASM result: \\(result?.first ?? 0)")}

不要忘记将 .was

博客

书籍推荐