跳到主要内容

第6章:网络请求与API调用

在网络开发中,iOS应用经常需要与服务器进行数据交互。通过网络请求获取数据并将其展示在应用中是iOS开发中的核心技能之一。在本章中,我们将学习如何使用URLSession进行网络请求,如何解析JSON数据,以及如何使用异步编程与GCD来处理网络请求的响应。


6.1 URLSession:基础的网络请求

URLSession是iOS和macOS中用于处理网络请求的标准API。它支持HTTP和HTTPS协议,并提供了灵活的配置选项。在这一节中,我们将学习如何使用URLSession发送HTTP请求并获取响应。

6.1.1 发送GET请求

GET请求是最常见的HTTP方法,用于从服务器获取数据。我们可以通过URLSessiondataTask方法来发送GET请求。

示例代码:发送GET请求并获取响应

let url = URL(string: "https://api.example.com/data")!
let request = URLRequest(url: url)

let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error)")
return
}

if let response = response as? HTTPURLResponse {
print("Status code: \(response.statusCode)")
}

if let data = data {
// 处理返回的数据
print("Received data: \(String(data: data, encoding: .utf8) ?? "")")
}
}

task.resume()

代码说明:

  1. 创建一个URL对象,表示要请求的资源地址。
  2. 创建一个URLRequest对象,配置请求头和其他参数(可选)。
  3. 使用URLSession.shared获取一个默认的会话实例。
  4. 使用dataTask方法创建一个任务,任务会在闭包中处理响应数据。
  5. 调用task.resume()启动任务。

6.1.2 发送POST请求

POST请求用于向服务器提交数据,例如表单数据或JSON数据。我们可以使用URLSessiondataTask方法发送POST请求。

示例代码:发送POST请求

let url = URL(string: "https://api.example.com/submit")!
var request = URLRequest(url: url)
request.httpMethod = "POST"

// 设置请求体
let parameters = ["name": "John", "age": 30]
do {
request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: [])
} catch {
print("Failed to serialize parameters: \(error)")
return
}

let task = URLSession.shared.dataTask(with: request) { data, response, error in
// 处理响应
}

task.resume()

代码说明:

  1. 设置httpMethod"POST"以发送POST请求。
  2. 使用JSONSerialization将参数转换为JSON数据,并设置为httpBody
  3. 同样使用dataTask方法启动任务。

6.2 JSON解析:将服务器返回的数据转化为可使用的格式

在实际开发中,服务器通常会返回JSON格式的数据。我们需要将这些JSON数据解析为Swift对象,以便在应用中使用。

6.2.1 使用JSONSerialization解析JSON

JSONSerialization是iOS提供的用于解析JSON数据的API。我们可以使用它将JSON数据转换为DictionaryArray

示例代码:解析JSON数据

if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let jsonArray = json as? [Dictionary<String, Any>] {
// 处理数组
print("Received array: \(jsonArray)")
} else if let jsonObject = json as? [String: Any] {
// 处理字典
print("Received object: \(jsonObject)")
}
} catch {
print("Failed to parse JSON: \(error)")
}
}

代码说明:

  1. 使用JSONSerialization.jsonObject(with:options:)将数据解析为Any类型。
  2. 检查解析结果是数组还是字典,并进行相应的处理。

6.2.2 使用Codable进行数据解析

Codable是Swift提供的一种简便的数据编码/解码协议。通过Codable,我们可以将JSON数据直接转换为自定义的模型对象。

定义Codable模型

struct User: Codable {
let name: String
let age: Int
let email: String
}

示例代码:使用Codable解析JSON

if let data = data {
do {
let user = try JSONDecoder().decode(User.self, from: data)
print("User name: \(user.name), age: \(user.age), email: \(user.email)")
} catch {
print("Failed to decode JSON: \(error)")
}
}

代码说明:

  1. 使用JSONDecoder将JSON数据解码为User对象。
  2. 模型必须遵循Codable协议,并且属性名称必须与JSON键匹配。

6.3 异步编程与GCD:处理耗时操作

网络请求通常是耗时操作,如果直接在主线程上执行,会导致UI卡顿。为了解决这个问题,我们可以使用GCD(Grand Central Dispatch)将网络请求放在后台线程执行,并在主线程上更新UI。

6.3.1 使用GCD处理异步任务

示例代码:使用GCD进行异步处理

let queue = DispatchQueue(label: "com.example.backgroundQueue", attributes: .concurrent)

queue.async {
// 在后台线程执行网络请求
let url = URL(string: "https://api.example.com/data")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
// 处理响应数据
if let data = data {
// 解析数据
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print("Received JSON: \(json)")
} catch {
print("Failed to parse JSON: \(error)")
}
}
}
task.resume()

// 在后台线程完成后,回到主线程更新UI
DispatchQueue.main.async {
print("UI updated on main thread")
}
}

代码说明:

  1. 创建一个并发队列,用于执行网络请求。
  2. 在队列中异步执行网络请求。
  3. 在完成网络请求后,使用DispatchQueue.main.async回到主线程更新UI。

6.4 总结

在本章中,我们学习了如何使用URLSession发送网络请求,如何使用JSONSerializationCodable解析JSON数据,以及如何使用GCD处理异步任务。这些技能是iOS开发中的基础,能够帮助我们实现数据交互和动态内容展示。

通过本章的学习,你应该能够:

  1. 发送GETPOST请求。
  2. 解析服务器返回的JSON数据。
  3. 在后台线程执行耗时操作,并在主线程更新UI。

接下来,你可以尝试将网络请求集成到实际项目中,并使用这些知识实现数据的动态加载和展示。


实践练习:

  1. 使用URLSession发送一个GET请求,获取一个公共API的数据(例如:GitHub API)。
  2. 将返回的JSON数据解析为一个自定义的Codable模型。
  3. 在主线程上更新UI,显示解析后的数据。

通过不断的实践,你会对网络请求和API调用有更深入的理解。