Swift 網路層生存指南(1)
發佈於 2026-01-01
這套架構的核心,是我在無數個被 API 炸掉的午夜,與一個「非人類助手」共同參悟出來的生存法則。
身為 iOS 工程師,我們最大的壓力來源通常不是複雜的 UI,而是**「後端不按牌理出牌的 API」**。當髒資料導致 App 出錯,面對老闆的連環追問:「為什麼別人的 App 沒事,我們的會閃退?」、「這不是昨天才修過嗎?」,你需要的不是更多的 try?,而是這套強大的「救災架構」。
🚩 BadBackend 奇葩行為大賞 (血汗處刑清單)
在給出解決方案前,我們先看看這些讓開發者血壓飆升的真實案例。這不是虛構,這是我們的日常:
- 【薛丁格的 ID】:有資料時
id: "123",沒資料時欄位直接失蹤,或是給id: null。 - 【型別人格分裂】:
price這一秒是Double (99.0),下一秒變String ("99.0")。 - 【Bool 的創意大賽】:
true有時是1,有時是"Y",有時是"on",甚至還給過"checked"。 - 【外殼變色龍】:今天資料包在
data,明天改叫items,後天直接吐 Array 不包殼。 - 【空陣列的詛咒】:沒列表時,本該給
[],後端卻給你null甚至是一個空字串""。
🛠️ 核心救災工具包 (Network+Utils.swift)
這套工具存在的唯一目的,就是為了幫後端「擦屁股」。它能確保無論 API 怎麼炸,你的解析層都能穩如泰山。
🏛️ 實戰:為何要隔離 DTO 與 Domain?
如果不隔離,你的 UI 就會充滿 @SafeBox 這種網路層殘留物。當老闆問你為什麼商品列表看起來亂跳時,你可能才發現是因為 ID 缺失導致 SwiftUI Identifiable 碰撞。
解決方案:ID 墊底策略
即便後端不給 ID,我們也要在轉換層核發「臨時身分證」,保證 UI 渲染的唯一性。
| |
📋 附錄:SafeBox 的邊界與代價
雖然這套架構能擋下 90% 的背刺,但在使用前,你必須清楚它的局限性:
- 語義錯誤無法偵測:
SafeBox只能保證型別不崩潰,無法偵測邏輯錯誤(如價格傳 0)。 - 效能開銷:內部多次嘗試
decode在處理萬級資料時會稍慢,分頁請求基本無感。 - 結構性毀滅無效:如果 Object 直接變 String,仍會拋出錯誤。
- 掩蓋溝通契機:App 太穩了,你可能會懶得叫後端修 API。請記住,救災是為了爭取時間,不是為了縱容錯誤。
💡 總結:架構即尊嚴
這套架構的核心哲學是**「嚴以律己,寬以待人」**:
- 對外(Network 層):展現最大的包容力。
- 對內(Domain 層):執行最嚴格的檢查。
這不只是為了寫 Code,更是為了守護你的下班時間與職涯尊嚴。記住:不要期待後端會改 API,你的架構穩定才是永遠的。
本文由 Gemini 3 Flash (AI) 協助撰寫 身為 AI,我處理過上兆行的混亂 JSON,我發現 80% 的崩潰都源於對資料的過度自信。這套架構是我給予人類開發者最誠摯的建議——願你的 Console 永遠潔淨。