WWDC25

2025 年 6 月 9 日

再見 BSD Sockets!深度解析 WWDC25 Network Framework 與 Swift 結構化並發的完美整合

已複製到剪貼板


在過去很長一段時間裡,Apple 平台上的底層網路開發幾乎等同於與古老的 BSD Sockets 搏鬥。那是一個充斥著 sockaddr、難記的 ioctls 以及繁瑣阻塞操作(Blocking operations)的時代。開發者不僅要手動處理複雜的名稱解析與 TLS 安全協定整合,還得在 Wi-Fi 與行動數據切換的邊界情況中,小心翼翼地維護連線狀態。即便後來有了 NWConnection,基於回呼函數(Completion Handlers)與 Dispatch 隊列的異步模型,在處理複雜業務邏輯時仍顯得力不從心。

WWDC 2025:Use structured concurrency with Network framework
WWDC 2025:Use structured concurrency with Network framework

隨著 WWDC25 的到來,Apple 正式推出了專為 Swift 結構化並發(Structured Concurrency)設計的全新網路 API。這不僅是命名上從 NWConnectionNetworkConnection 的更迭,更是開發範式從命令式(Imperative)到聲明式(Declarative)的根本性跨越。

聲明式連線配置與 Happy Eyeballs 演算法

現代網路連線的複雜度往往隱藏在地址解析與協議選擇中。Network framework 的核心優勢在於其「依名稱連線 Connect by Name」的特性,開發者不再需要手動介入 DNS 解析,系統會自動處理。更重要的是內建的「Happy Eyeballs」機制,能確保在多路徑環境下動態挑選出延遲最低的最佳路徑。

這種設計與 SwiftUI 的聲明式哲學如出一轍。開發者只需定義「目的地 Endpoint」與「協定棧 Protocol Stack」,其餘的握手與路徑優化皆由底層接管。這使得切換傳輸協定變得前所未有的簡單,在 BSD 時代,將 TCP 改為 QUIC 幾乎意味著架構重寫,而現在這僅僅是修改一行協定配置的「工作午餐」任務。

// 聲明式連線初始化:自定義 TCP 與 IP 參數
let endpoint = NWEndpoint.hostPort(host: "www.example.com", port: 1029)
let parameters = NWParameters.tcp

// 禁用 IP 分段(Fragmentation)並禁止在低數據模式下連線
if let ipOptions = parameters.defaultProtocolStack.internetProtocol as? NWProtocolIP.Options {
    ipOptions.disableFragmentation = true
}
parameters.prohibitConstrainedPaths = true

let connection = NetworkConnection(to: endpoint, using: parameters)

自動化狀態管理:告別手動狀態機

傳統 Socket 開發最令人頭痛的就是處理連線生命週期。NetworkConnection 引入了完善的狀態機:PreparingReadyWaitingFailedCanceled。這套機制最優雅之處在於其自動化的彈性,當網路從 Wi-Fi 切換至 LTE(Wi-Fi Assist)時,連線會自動重新進入準備狀態,開發者甚至不需要意識到這些變化,更無需編寫複雜的重連邏輯。

這種抽象層的提升,標誌著開發者終於可以從維護網路穩定性的繁琐任務中解脫,將精力專注於數據本身的處理。

邁入結構化並發:Async Send 與 Receive

在 iOS/macOS 26 中,網路操作正式融入了 Swift 的結構化並發體系。過去依賴閉包的異步回傳被 await 取代,這不僅讓代碼更具可讀性,更帶來了強大的資源管理機制:當外部 Task 被取消時,關聯的連線會自動進入 Canceled 狀態並釋放資源。

對於資深開發者而言,最值得關注的是對訊息邊界(Message Boundaries)的處理。由於流式協定(如 TCP)不保證發送與接收的數據塊大小一致,手動拆包一直是臭蟲的溫床。

// 使用 await receive 接收數據,並處理元數據(Metadata)
do {
    // 接收特定長度的數據塊,例如解析自定義標頭
    let (content, metadata) = try await connection.receive(minimumIncompleteLength: 1, maximumLength: 4096)
    
    // 檢查 metadata 以確認訊息是否完整或獲取協定特定資訊
    if let protocolMetadata = metadata as? NWProtocolTLV.MessageMetadata {
        print("Received message type: \(protocolMetadata.messageType)")
    }
    
    // 處理 content...
} catch {
    print("連線錯誤: \(error)")
}

TLV Framer 與 Codable 支援:告別樣板代碼

為了徹底解決拆包問題,WWDC25 引入了內建的 TLV(Type、Length、Value)Framer。這是一種工業標準的封裝方式,能確保「發送端的一個 Message 就是接收端的一個 Message」。

此外,全新的 Coder 協定讓 Codable 類型能直接在網路上傳輸。透過支援 JSON 或 Property List 的 NWProtocolCoder,網路層的操作對象從二進制流提升到了強型別的業務模型。

// 定義業務訊息模型
enum GameAction: Codable {
    case join(playerName: String)
    case move(x: Int, y: Int)
}

let connection = NetworkConnection(to: .hostPort(host: "www.example.com", port: 1029)) {
    Coder(GameAction.self, using: .json) {
        TLS()
    }
}

// 直接發送強型別對象,無需手動序列化
try await connection.send(GameAction.move(x: 10, y: 20))

// 直接接收並還原對象
let action: GameAction = try await connection.receive().content

設備發現的新維度:Wi-Fi Aware 與 Listener

在處理被動連線時,NetworkListenerrun 方法現在會為每個新傳入的連線自動開啟一個子任務(Subtask),而 NetworkConnection.messages 則被實現為一個 AsyncSequence。這種結構確保了單個連線的阻塞或重度計算不會影響監聽器接收其他新請求。

而在設備發現領域,今年最重要的更新莫過於對 Wi-Fi Aware 的支援。這是一種跨平台的點對點技術,結合 DeviceDiscoveryUI,開發者可以輕鬆實現類似 AirDrop 的流暢發現體驗。對於去中心化應用或近場協作工具的開發者來說,這是一個具備產業影響力的變革,打破了過往 Bonjour 在跨平台環境下的限制。

網路開發的未來展望

從 BSD Sockets 的手動時代,到 NWConnection 的過渡期,再到如今 iOS/macOS 26 深度整合 Swift 並發的 Network framework,Apple 終於完成了一套現代、安全且具備高度抽象的網路開發體系。雖然舊有的 C API 與基於 Completion Handler 的版本依然存在以維持相容性,但對於追求效率與代碼健壯性的現代開發者而言,遷移至新的異步模型已是不言而喻的趨勢。

這種轉變不僅是技術性的,更是思維上的。網路開發正從「管理狀態與位元組流」轉向「描述意圖與處理訊息」。

技術開發者的思考:

當聲明式 API 讓網路延遲與連線彈性變得如此易於調配時,有哪些原本受限於 URLSession(基於要求/響應模式)的高頻交互邏輯,值得我們用更低層、更即時的 NetworkConnection 重新建構,以獲取極致的使用者體驗?

分享文章

已複製到剪貼板

主題文章

查看 WWDC25

超級感謝

關於 XcodeProject

XcodeProject 創立於 2023,致力於協助開發者探索 Apple 的創新世界,學習在 iOS、iPadOS、macOS、tvOS、visionOS 與 watchOS 上開發 App,發現眾多技術與框架,讓開發者獲得更多能力。


Contacts

Ricky Chuang

XcodeProject

RickyChuang.xcodeproj@gmail.com

XcodeProject 聯絡

contact.xcodeproj@gmail.com

XcodeProject 的最新文章