406 words
2 minutes
Swift6之后更现代的REST API方法

目前网上检索到的关于Swift的REST API Call实现很多已经在swift6之后算是过时了的,Swift6强化了并发安全,以及URLsession API也相应增加了async版本(旧版本使用callback),更modern的方法是使用async/await以及Task来构建REST API Call

以下均使用URLsession进行REST API Call

在旧版Swift中, Get接口是这么call的

func fetchPage(completion: @escaping (Result<PageData, Error>) -> Void) {
let url = URL(string: "http://127.0.0.1:8080/community/page/get")!
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
completion(.failure(error))
return
}
guard let data = data else {
completion(.failure(URLError(.badServerResponse)))
return
}
do {
let result = try JSONDecoder().decode(PageData.self, from: data)
completion(.success(result))
} catch {
completion(.failure(error))
}
}.resume()
}

大量使用了回调函数。 另外值得说的是在Swift6中xcode默认会给没有显式隔离的代码视作@MainActor,也就是默认跑主线程,所以在老式写法里对于let result = try JSONDecoder().decode(PageData.self, from: data)这里要在PageData的结构体上标注一个nonisolated

Swift6以后,新式Get Call 的async/await写法是这样的

func fetchPage() async throws -> PageData {
let url = URL(string: "http://127.0.0.1:8080/community/page/get")!
let (data, _) = try await URLSession.shared.data(from: url)
return try JSONDecoder().decode(PageData.self, from: data)
}

wrap的时候可以通过Task来执行它

func load() {
Task{
let newPageData = try await fetchPage()
···
······
·········
}
}

同样的这是Swift6之后现代版的Post Call

func createTopic(title: String, content: String, time: Int64) async throws -> Topic {
let newTopic = Topic(
id: nil,
title: title,
content: content,
create_time: time
)
guard let url = URL(string: "http://127.0.0.1:8080/community/page/addtopic") else {
throw URLError(.badURL)
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONEncoder().encode(newTopic)
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
200..<300 ~= httpResponse.statusCode else {
throw URLError(.badServerResponse)
}
return try JSONDecoder().decode(Topic.self, from: data)
}

wrap之后用Task执行也是和get同理

Swift6之后更现代的REST API方法
https://www.modo.org.cn/posts/swift6之后更现代的rest-api方法/
Author
Welcome, traveler
Published at
2026-03-12
License
CC BY-NC-SA 4.0