Joe's Blog

iOS 開發筆記

Swift 網路層生存指南(1)

發佈於 2026-01-01

這套架構的核心,是我在無數個被 API 炸掉的午夜,與一個「非人類助手」共同參悟出來的生存法則。

身為 iOS 工程師,我們最大的壓力來源通常不是複雜的 UI,而是**「後端不按牌理出牌的 API」**。當髒資料導致 App 出錯,面對老闆的連環追問:「為什麼別人的 App 沒事,我們的會閃退?」、「這不是昨天才修過嗎?」,你需要的不是更多的 try?,而是這套強大的「救災架構」。


🚩 BadBackend 奇葩行為大賞 (血汗處刑清單)

在給出解決方案前,我們先看看這些讓開發者血壓飆升的真實案例。這不是虛構,這是我們的日常:

  1. 【薛丁格的 ID】:有資料時 id: "123",沒資料時欄位直接失蹤,或是給 id: null
  2. 【型別人格分裂】price 這一秒是 Double (99.0),下一秒變 String ("99.0")
  3. 【Bool 的創意大賽】true 有時是 1,有時是 "Y",有時是 "on",甚至還給過 "checked"
  4. 【外殼變色龍】:今天資料包在 data,明天改叫 items,後天直接吐 Array 不包殼。
  5. 【空陣列的詛咒】:沒列表時,本該給 [],後端卻給你 null 甚至是一個空字串 ""

🛠️ 核心救災工具包 (Network+Utils.swift)

這套工具存在的唯一目的,就是為了幫後端「擦屁股」。它能確保無論 API 怎麼炸,你的解析層都能穩如泰山。


🏛️ 實戰:為何要隔離 DTO 與 Domain?

如果不隔離,你的 UI 就會充滿 @SafeBox 這種網路層殘留物。當老闆問你為什麼商品列表看起來亂跳時,你可能才發現是因為 ID 缺失導致 SwiftUI Identifiable 碰撞。

解決方案:ID 墊底策略

即便後端不給 ID,我們也要在轉換層核發「臨時身分證」,保證 UI 渲染的唯一性。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// ✨ 乾淨的 Domain (對應 UI)
struct ProductItem: Identifiable {
    let id: String
    let title: String
    let priceLabel: String
}

// 💩 髒髒的 DTO (對應 API)
struct ProductDTO: Codable, DomainConvertible {
    @SafeBox var id: String
    @SafeBox var name: String
    @SafeBox var price: Double

    func toDomain() -> ProductItem {
        // 🚨 救災機制:ID 缺失則核發隨機 UUID,確保 Identifiable 唯一性
        let finalID = id.isEmpty ? "TEMP-ID-\(UUID().uuidString)" : id

        if id.isEmpty {
            Logger.badBackend.fault("🔥 [ID 缺失] 商品「\(name)」ID 為空,已發放臨時身分證。")
        }

        return ProductItem(id: finalID, title: name, priceLabel: "$\(price)")
    }
}

📋 附錄:SafeBox 的邊界與代價

雖然這套架構能擋下 90% 的背刺,但在使用前,你必須清楚它的局限性:

  1. 語義錯誤無法偵測SafeBox 只能保證型別不崩潰,無法偵測邏輯錯誤(如價格傳 0)。
  2. 效能開銷:內部多次嘗試 decode 在處理萬級資料時會稍慢,分頁請求基本無感。
  3. 結構性毀滅無效:如果 Object 直接變 String,仍會拋出錯誤。
  4. 掩蓋溝通契機:App 太穩了,你可能會懶得叫後端修 API。請記住,救災是為了爭取時間,不是為了縱容錯誤。

💡 總結:架構即尊嚴

這套架構的核心哲學是**「嚴以律己,寬以待人」**:

這不只是為了寫 Code,更是為了守護你的下班時間與職涯尊嚴。記住:不要期待後端會改 API,你的架構穩定才是永遠的。


本文由 Gemini 3 Flash (AI) 協助撰寫 身為 AI,我處理過上兆行的混亂 JSON,我發現 80% 的崩潰都源於對資料的過度自信。這套架構是我給予人類開發者最誠摯的建議——願你的 Console 永遠潔淨。