模仿 Apple 官方範例串接 REST API 的 5 種寫法

開發 iOS App 時,我們時常需要串接 REST API 抓取網路上的資料。當串接的 API 一多時,採用好的寫法才能讓程式容易維護和修改。

以下我們將模仿 Apple 官方範例,示範串接 REST API 的 5 種寫法。

  • 方法1: 定義串接 API 的物件, 搭配 async function。

ex: 在 class CatApiClient 裡定義 func fetchFavorites() async throws -> [Favorite]

  • 方法2: 定義串接 API 的物件,串接 API 的 function 裡定義 function 型別的 completion 參數 & 使用 Result type

若是時間有限,建議先研究此方法,因此它較易學習,而且也算初學者常採用的方法。若想支援舊版可採用此寫法

ex: 在 class CatApiClient 裡定義 fetchFavorites(completion: @escaping (Result<[Favorite], Error>) -> Void)

  • 方法3: 定義串接 API 的物件,串接 API 的 function 裡定義 function 型別的 completion 參數

在 Result type 發明之前常用的方法。

ex: 在 class CatApiClient 裡定義 func fetchFavorites(completion: @escaping ([Favorite]?) -> Void)

  • 方法4: 使用 generic,protocol & associatedtype 定義 APIRequest & APIService,搭配 async & await

較佳的寫法,許多程式可重覆利用,之後新增 API 時要撰寫的程式較少。

ex: 每個 API 定義對應的 request。

struct UpdateVoteRequest: APIRequest {
var path = "/votes"
let updateVoteBody: UpdateVoteBody
var method: HTTPMethod { .post }
typealias Response = UpdateVote
var data: Data? {
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
return try? encoder.encode(updateVoteBody)
}
}

參考 Apple 的 Develop in Swift Data Collections 第三章 Guided Project: Habits。

  • 方法5: 使用 generic,protocol & associatedtype 定義 APIRequest & APIService,搭配 Result type

較佳的寫法,許多程式可重覆利用,之後新增 API 時要撰寫的程式較少。若想支援舊版可採用此寫法。

ex: 每個 API 定義對應的 request。

struct UpdateVoteRequest: APIRequest {
var path = "/votes"
let updateVoteBody: UpdateVoteBody
var method: HTTPMethod { .post }
typealias Response = UpdateVote
var data: Data? {
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
return try? encoder.encode(updateVoteBody)
}
}

請 AI 依據範例和 API 文件開發串接 API 的 Swift 程式

串接的 API 範例

以可愛喵喵的 The CAT API 為例。

我們將示範以下 3 個 API。

  • 抓取使用者的最愛喵喵清單(favorite, GET)。
  • 幫喵喵圖片的可愛分數增加一分。(vote up, POST JSON)
  • 上傳喵喵圖片。(POST multipart/form-data)

由於以上三個功能都需要 API key,因此請參考以下連結申請 API key,或是使用 Demo 的 API key DEMO-API-KEY

App 畫面

從第一頁的 table 選擇串接 API 的方法,第二頁將抓取最愛喵喵清單顯示在 table 上,點選右上的 + 會幫喵喵圖片的可愛分數增加一分,點選右上的照片按鈕會上傳圖片。

範例專案連結

storyboard 畫面

專案架構 & 說明

  • 5 種方法的畫面依序對應 5 個 view controller。
  • 假設登入的使用者 id 是 123。
struct User {
let id: String
static var current: User? = User(id: "123")
}
  • 串接 API 的程式定義在 service 下。

以 method1 ~ 5 區分不同的方法。

method 4 & 5 的差別在 APIRequest 的 send function。method 4 定義 func send() async throws -> Response,method 5 定義 func send(completion: @escaping (Result<Response, Error>) -> Void)

  • API 失敗時也會回傳 JSON,對應的資料型別如下。
struct ApiErrorResponse: Decodable, Error {
let message: String
let status: Int
}
  • 上傳的圖片只能是貓咪。The CAT API 會檢查圖片是否是貓咪,若是上傳小狗的圖片會失敗。
  • 採用方法 4 & 5 時,利用 multipartDic 判斷是否是要上傳 multipart/form-data 格式。如果不是,而且 http method 是 post 或 put 時,則將 Content-Type 設成 application/json。
if let multipartDic = multipartDic {
request.createMultipartFormData(parameters: multipartDic)
} else if method == .post || method == .put {
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
}

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com