Swift中执行同步API调用的简洁方案及2021年推荐实现方式
Swift 同步REST请求实现方案(2021年首选)
重要提醒:同步网络请求会阻塞当前线程,仅适合无UI的命令行工具、后台脚本等特定场景,iOS/macOS带UI的应用绝对禁止使用,会直接导致界面卡死。
首选第三方库方案(类比Python requests)
如果追求Python requests式的极简写法,首选第三方库 Just,引入后可以直接一行完成同步请求,和Python的使用体验几乎一致。
GET请求示例
// 先引入库 import Just // 同步GET请求,写法和Python requests高度相似 let response = Just.get("https://jsonplaceholder.typicode.com/posts")
POST请求示例
// 同步POST请求,带JSON参数 let postResponse = Just.post( "https://jsonplaceholder.typicode.com/posts", json: ["title": "foo", "body": "bar", "userId": 1] )
常用返回值获取方式
- 状态码:
response.statusCode - 响应头:
response.headers - 解析后的JSON结果:
response.json - 原始二进制数据:
response.content
无第三方依赖的原生实现
如果不想引入外部依赖,可以基于URLSession加DispatchSemaphore封装,封装为工具函数后调用也非常简单:
封装同步GET工具函数
func syncGet(url: String) -> (data: Data?, response: URLResponse?, error: Error?) { let targetUrl = URL(string: url)! let semaphore = DispatchSemaphore(value: 0) var result: (Data?, URLResponse?, Error?) URLSession.shared.dataTask(with: targetUrl) { data, response, error in result = (data, response, error) semaphore.signal() }.resume() semaphore.wait() return result }
调用示例
let (data, response, error) = syncGet(url: "https://jsonplaceholder.typicode.com/posts")
POST请求只需要修改工具函数的入参加上请求体、指定请求方法即可,逻辑完全一致。
2021年方案选择建议
- 项目允许引入第三方库的前提下,Just 是最优选择,完全匹配类requests的极简调用体验
- 不能引入外部依赖时,自行封装基于信号量的URLSession工具函数是首选,封装完成后调用也足够简洁
- 所有同步方案仅限命令行工具、后台脚本等无UI场景使用,带UI的应用请使用异步URLSession或者第三方库的异步接口,避免阻塞主线程
内容的提问来源于stack exchange,提问作者Timo
相关产品推荐
相关产品推荐

