2025年Swift中的HTTP请求:20分钟从新手到专家

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么Swift开发者还在搜索HTTP请求?



如果你曾经写过与服务器通信的Swift应用程序,你肯定遇到过这个问题。看起来很简单?发送请求,接收响应。但实际上,每两个开发者中就有一个人(即使有经验)会打开Stack Overflow搜索:"How to make HTTP request in Swift?"。这很正常。



为什么?因为Swift生态系统在不断变化。昨天大家还在写闭包和代理。今天则是async/await。明天可能还会有新的东西出现。到了2025年,网络请求的方法已经趋于稳定,但魔鬼总是在细节中:线程管理、错误处理、请求取消、测试。



在本文中,我们将探讨Swift中执行HTTP请求的真正最佳实践——从基础的URLSession到使用async/await和第三方库的高级技术。你将学习如何编写干净、安全且高性能的网络代码。开始吧!



1. URLSession:每个人都必须掌握的基础



我们从最重要的开始。Swift标准库(Foundation)中包含了处理HTTP所需的一切——这就是URLSession类。请记住:对于90%的任务,你不需要第三方库。URLSession是一个强大、灵活且原生的工具。



1.1. 简单的GET请求(旧风格)



让我们回顾一下以前的做法。你仍然可能在遗留项目中看到这样的代码:



let url = URL(string: "https://api.pythonlib.ru/users")!let task = URLSession.shared.dataTask(with: url) { data, response, error in    if let error = error {        print("错误:\\(error.localizedDescription)")        return    }    guard let data = data else {        print("没有数据")        return    }    // 处理数据    print("收到字节数:\\(data.count)")}task.resume()


这段代码可以工作。但它有缺点:

  • 回调地狱——如果需要执行一系列请求,代码会变得难以阅读。
  • 内存泄漏——很容易忘记在闭包中使用weak self。
  • 难以取消——需要保存对task的引用。


在2025年,我们采用不同的写法。



1.2. 使用async/await的现代GET请求



从Swift 5.5(iOS 15,macOS 12)开始,我们有了结构化并发。这改变了一切:



func fetchUsers() async throws -> [User] {    let url = URL(string: "https://api.pythonlib.ru/users")!    let (data, response) = try await URLSession.shared.data(from: url)        guard let httpResponse = response as? HTTPURLResponse,          (200...299).contains(httpResponse.statusCode) else {        throw URLError(.badServerResponse)    }        return try JSONDecoder().decode([User].self, from: data)}


很漂亮,对吧?没有闭包,没有resume()。代码读起来像同步代码,但实际上是异步执行的。这是2025年的事实标准。



2. POST请求:向服务器发送数据



现在让我们发送数据。假设我们需要创建一个新用户。



2.1. 带JSON体的POST请求



func createUser(name: String, email: String) async throws -> User {    let url = URL(string: "https://api.pythonlib.ru/users")!    var request = URLRequest(url: url)    request.httpMethod = "POST"    request.setValue("application/json", forHTTPHeaderField: "Content-Type")        let body = ["name": name, "email": email]    request.httpBody = try JSONSerialization.data(withJSONObject: body)        let (data, response) = try await URLSession.shared.data(for: request)    // 处理响应...    return try JSONDecoder().decode(User.self, from: data)}

                
                

博客

书籍推荐