Introdução: por que um desenvolvedor iOS/macOS precisaria de WebAssembly?
WebAssembly (Wasm) é um formato binário de instruções que foi originalmente criado para navegadores, mas rapidamente encontrou aplicação no desenvolvimento nativo. Para desenvolvedores Swift em iOS e macOS, a integração com WebAssembly abre possibilidades únicas: você pode reutilizar código de alto desempenho em C/C++, Rust ou Go sem reescrevê-lo em Swift, e executá-lo com velocidade quase nativa. Isso é especialmente relevante para trabalhar com gráficos, criptografia, simulações e algoritmos complexos.
Neste artigo, vamos abordar como compilar código para Wasm, integrá-lo em um projeto Swift para iOS/macOS, transmitir dados e tratar erros. Todos os exemplos são escritos em Swift 5.9+ e voltados para Xcode 15+.
1. Compilação de código para WebAssembly em um projeto Swift
O primeiro passo é obter o módulo Wasm. A maneira mais popular é compilar código em C/C++ usando Emscripten ou WasmEdge. Vejamos um exemplo em C.
Crie o arquivo math_ops.c:
// math_ops.c#include <emscripten.h>
EMSCRIPTEN_KEEPALIVEint add(int a, int b) { return a + b;}
EMSCRIPTEN_KEEPALIVEdouble multiply(double a, double b) { return a * b;}
EMSCRIPTEN_KEEPALIVEint factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1);}Compile-o para Wasm usando Emscripten (instale via Homebrew: brew install emscripten):
emcc math_ops.c -o math_ops.wasm -s WASM=1 -s EXPORTED_FUNCTIONS='["_add", "_multiply", "_factorial"]' -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -O3Como resultado, você obterá o arquivo math_ops.wasm e math_ops.js (o wrapper js não será necessário; trabalharemos diretamente com o Wasm).
2. Integração do módulo Wasm em Swift (iOS/macOS)
Para trabalhar com WebAssembly em Swift nativo, usaremos o framework WasmKit ou SwiftWasm. Recomendamos o WasmKit — ele suporta iOS 15+ e macOS 12+.
2.1. Instalação do WasmKit via Swift Package Manager
Adicione a dependência no Package.swift ou via Xcode: File → Add Packages → https://github.com/swiftwasm/WasmKit.
2.2. Carregamento e execução do módulo Wasm
Crie o arquivo Swift WasmEngine.swift:
import WasmKitimport Foundation
class WasmEngine { private var instance: Instance? private var store: Store? /// Carrega o módulo Wasm a partir de um arquivo func loadModule(from url: URL) throws { let data = try Data(contentsOf: url) let module = try Module(data: data) let engine = Engine() store = Store(engine: engine) let imports = Imports() // Aqui você pode adicionar importação de funções do Swift (veja seção 3) instance = try Instance(module: module, imports: imports, store: store!) } /// Chama uma função exportada func callFunction(_ name: String, args: [Value]) throws -> [Value] { guard let instance = instance else { throw WasmError.moduleNotLoaded } let function = instance.exports[name] as! Function return try function(args) }}
enum WasmError: Error { case moduleNotLoaded case functionNotFound}2.3. Uso em uma aplicação SwiftUI
import SwiftUI
struct ContentView: View { @State private var result: String = "0" private let engine = WasmEngine() var body: some View { VStack(spacing: 20) { Text("Resultado: \\(result)") .font(.title) Button("Calcular fatorial de 5") { do { let wasmURL = Bundle.main.url(forResource: "math_ops", withExtension: "wasm")!```