---
title: "如何優雅的過橋，放棄 SwiftUI，擁抱 Expo"
description: "原本一直以為跨平台一定會卡、一定會慢，最近認真用了 Expo 跟它生態上的工具，發現事實不是如此。"
author: "kidneyweakx"
published: 2026-06-02T00:00:00.000Z
updated: 2026-10-29T10:17:47.594Z
lang: zh-TW
tags: ["expo", "react-native", "swiftui", "ios"]
canonical: https://kidneyweakx.com/blog/%E5%A6%82%E4%BD%95%E5%84%AA%E9%9B%85%E7%9A%84%E9%81%8E%E6%A9%8B-%E6%94%BE%E6%A3%84-swiftui-%E6%93%81%E6%8A%B1-expo
---

# 如何優雅的過橋，放棄 SwiftUI，擁抱 Expo

> 原本一直以為跨平台一定會卡、一定會慢，最近認真用了 Expo 跟它生態上的工具，發現事實不是如此。

我做 Solid(ar)ity（一個自己掌握鑰匙的身份頁跟名片 app）的時候，第一版是用 SwiftUI 寫的。2025 年 9 月開始寫，原生、漂亮、Apple 親生的，那時候覺得這就是正確答案。

結果 2026 年 5 月底開了 Expo 的專案，6 月底就把整個 SwiftUI app、Xcode 專案跟 Swift 設定全部刪掉了。**一個月，整個過橋。**

這篇記錄一下為什麼要過、怎麼過，還有過完之後發現的事。

<br />

## 為什麼要過橋

最直接的理由是 **Android**。名片跟身份這種東西，對方用什麼手機你管不了，只做 iOS 等於一半的人掃不到你的卡。用 SwiftUI 就代表 Android 要整個重寫一份，兩份 code 要同步兩份加密邏輯，光想到就頭痛。

第二個理由是**迭代速度**。SwiftUI 的 Preview 時好時壞，改個 UI 等編譯等到懷疑人生；Expo 改完存檔，畫面就變了。

## 我以為跨平台會遇到的問題

以前對 React Native 的印象大概停在幾年前：

- bridge 很慢，動畫會卡
- 碰到原生功能（相機、Keychain、Face ID）就要自己寫 native module，寫到哭
- 加密、零知識證明這種重運算，JS 一定撐不住

結果實際用下來，這幾個問題現在都有解。

## 實際上的解法

**1. 原生的東西，用 Nitro Modules 寫**

需要碰原生的地方，像是護照 NFC 驗證、Keychain、Apple Vision 的 OCR，我們都寫成 Nitro Module。TypeScript 寫規格，codegen 產生 C++/Swift/Kotlin 的骨架，再填實作。JS 呼叫原生就像呼叫一般函式，沒有以前 bridge 那種序列化的開銷。

**2. 相機用 VisionCamera v5**

QR 掃描、護照 MRZ 辨識都靠 VisionCamera 的 frame processor。這部分踩的坑多到可以另外寫一篇（真的另外寫了，〈地獄難度：手機相機效能優化〉）。

**3. 重運算放在原生，JS 只負責流程**

ZK 證明用 Mopro 編好的 xcframework，在原生端跑，JS 只負責把結果接回來。效能跟純原生一樣，因為它**本來就是原生**。

<br />

## 怎麼過橋不掉下去

最怕的是：舊版 app 的使用者資料怎麼辦？加密格式不一樣，備份就全部報銷了。

我們的做法是先寫**對拍測試**。在 Swift 版加一個 FixtureExporter，把 AES-GCM 加密的結果、名片的資料格式匯出成測試資料，然後 Expo 版用 bun test 跑同一份資料，確保**兩邊加密出來的東西一模一樣、互相解得開**。對拍全部通過之後，才敢把 Swift 版刪掉。

後來也真的有用到：從 Swift 時代留下來的備份檔，格式跟新版不太一樣，還是補了一個修正讓新版讀得懂舊備份。如果沒有先做對拍，這種問題大概是上線後才會被使用者罵出來。

## 過完橋之後

現在 Solid(ar)ity 2.0 是 Expo SDK 57、React Native 0.86，iOS 跟 Android 一份 code。發現幾件事：

- **跨平台不等於慢**。慢的通常是你把重的東西放在 JS 跑。原生該做的事交給原生，JS 只管流程跟 UI，體感跟原生 app 差不多
- **但原生知識沒有省掉**。Xcode Cloud 的建置、Metal shader 預編譯、Android 的 minSdk，這些坑一個都沒少，只是從「整個 app 都是坑」變成「邊界上有坑」
- **SwiftUI 沒有不好**。只做 iOS、而且很吃 Apple 新 API 的話，它還是最好的選擇。我只是剛好不是那種 app

<br />

所以標題說「優雅的過橋」，其實一點都不優雅，就是先把兩岸的東西對齊，確定踩得過去，再把舊橋拆掉。**能優雅，是因為先做了很不優雅的對拍。**
