引言
在iOS 开发中进行网络请求有两种主要方式:使用苹果原生的URLSession和使用第三方库Alamofire,下面将对这两种网络请求方式进行分别介绍
URLSession
概述
URLSession是苹果官方提供的原生的网络请求框架,提供了与网络通信相关的一系列类和方法。然而,使用纯粹的 URLSession进行网络请求可能需要处理很多底层细节,如构建请求、处理响应、处理错误等
示例
swift
import Foundation
class Service {
func requestWithURLSession() {
guard let url = URL(string: "") else {
return
}
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print("Error: \(error)")
} else if let data = data {
DispatchQueue.main.async {
self.data = data
}
}
}.resume()
}
}
Alamofire + CocoaPods
Alamofire
Alamofire是一个在URLSession基础上进行封装的第三方网络请求库,封装了URLSession的诸多底层细节,提供了更友好的API。它旨在简化网络请求的编写和管理,提供了更高级的抽象,使得网络请求变得更加易用和灵活,让开发者能够更专注于业务逻辑而不是网络细节
通过使用Alamofire,可以更轻松地执行常见的网络请求操作,处理认证、上传、下载、错误处理等。它还支持链式调用和响应验证等功能,让你的代码更具可读性和可维护性
请求方法与响应方法
Alamofire提供了一系列方法来处理不同类型的请求和响应,以满足不同场景的需求。下面将介绍一些常见的Alamofire请求和响应的处理方法
请求处理方法
Alamofire提供了多种方法来创建和发起网络请求。以下是一些常用的 Alamofire 请求方法:
-
AF.request() :发起一个常规的
HTTP 请求,支持不同的HTTP 方法(GET、POST、PUT、DELETE等)和参数,可以在响应闭包中处理返回的数据和错误 -
AF.upload() :用于上传文件或数据,可以在响应闭包中处理上传进度、响应数据和错误
-
AF.download() :用于下载文件,可以在响应闭包中处理下载进度、下载后的文件路径和错误
-
AF.streamRequest() :用于处理流式的网络请求,适用于长连接或服务器推送等场景
响应处理方法
- response : 处理通用的响应数据,可以在闭包中访问响应的状态码、头部和数据。适用于通用的
JSON、文本等响应
swift
AF.request("").response { response in
if let data = response.data {
print("Response Data: \(data)")
}
if let statusCode = response.response?.statusCode {
print("Status Code: \(statusCode)")
}
}
- responseJSON : 将响应的数据解析为
JSON 格式,并在闭包中处理解析后的 JSON 数据
swift
AF.request("").responseJSON { response in
switch response.result {
case .success(let json):
print("JSON Response: \(json)")
case .failure(let error):
print("Error: \(error)")
}
}
- responseDecodable : 使用
Codable 协议将响应的数据解码为特定的数据模型,适用于处理JSON 数据的自动解析
swift
struct Post: Codable {
let userId: Int
let id: Int
let title: String
let body: String
}
AF.request("").responseDecodable(of: Post.self) { response in
switch response.result {
case .success(let post):
print("Post Title: \(post.title)")
case .failure(let error):
print("Error: \(error)")
}
}
AF.responseDecodable方法可以替代手动创建JSONDecoder实例并使用decode方法来解析数据
swift
AF.request("").response { response in
if let data = response.data {
let decoder = JSONDecoder()
let post = try decoder.decode(Post.self, from: data)
print("Post Title: \(post.title)")
}
if let statusCode = response.response?.statusCode {
print("Status Code: \(statusCode)")
}
}
- responseData : 以原始数据的形式返回响应数据,适用于处理
二进制数据
swift
AF.request("").responseData { response in
switch response.result {
case .success(let imageData):
print("Image Data: \(imageData)")
case .failure(let error):
print("Error: \(error)")
}
}
- downloadProgress : 在
下载请求中,可以使用此方法来监听下载进度的变化
swift
AF.download("").downloadProgress { progress in
print("Download Progress: \(progress.fractionCompleted)")
}
.response { response in
print("Download Completed!")
}
- uploadProgress : 在
上传请求中,可以使用此方法来监听上传进度的变化
swift
let image = UIImage(named: "example.jpg")!
AF.upload(image, to: "").uploadProgress { progress in
print("Upload Progress: \(progress.fractionCompleted)")
}
.response { response in
print("Upload Completed!")
}
示例
swift
import Foundation
import Alamofire
class Service {
func requestWithAlamofire() {
guard let url = URL(string: "") else {
return
}
AF.request(url).responseData { response in
switch response.result {
case .success(let data):
DispatchQueue.main.async {
self.data = data
}
case .failure(let error):
print("Error: \(error)") }
}
}
}
}
CocoaPods
CocoaPods是一个用于管理Swift和Objective-C项目中第三方库的包管理器。它可以轻松地集成和管理各种库,从而减少了手动管理库的复杂性。想了解更多就去 CocoaPods官网 看看
下面是CocoaPods在macOS上的安装步骤:
-
安装
CocoaPods在终端中运行以下命令来安装
CocoaPods及其所依赖的Ruby环境(若没有):bashsudo gem install cocoapodsmacOS自带了Ruby,可以在执行上面命令时在终端中运行以下命令来检查:bashruby -vCocoaPods是基于Ruby编写的 -
验证安装
安装完成后,可以运行以下命令来验证是否安装成功:
bashpod --version如果安装成功,将显示
CocoaPods的版本号 -
定期更新
CocoaPods的版本和依赖可能会发生变化,所以建议定期更新CocoaPods以保持最新。可以使用以下命令来更新CocoaPods:bashsudo gem update cocoapods
拓展
-
Alamofire各类请求的响应类型都是DataResponse类型,包含了诸多属性:request、response、data、result、valuerequest:表示原始的请求对象,包含了请求的URL、HTTP 方法等信息response:表示响应对象,包含了服务器返回的HTTP 响应,其中可能包含状态码、头部信息等data:表示原始的响应数据,以字节数组Data的形式存储,适用于需要手动处理原始数据的情况result:一个Result枚举的关联值,表示请求的结果。Result枚举可以包含成功的情况(带有数据关联值)或失败的情况(带有错误关联值)value:表示result的枚举值,如果请求成功,会包含成功数据的枚举值;如果请求失败,则包含失败信息的枚举值
-
在
Alamofire中,response、responseJSON、responseData、responseDecodable等方法都是为了方便开发者处理不同类型的响应数据而设计的。response返回的是原始数据,而其他方法则提供了更高层次的抽象来方便处理不同类型的数据。其中,responseJSON、responseData、responseDecodable等方法都是对response方法进一步的封装,用来更方便处理不同类型的响应数据,比如将JSON 数据解析成字典、数组,或者解析成遵循 Decodable 协议的模型对象 -
response、responseJSON、responseData、responseDecodable响应的result属性类型responseresult属性的类型是Result<Data, AFError>response方法并未对响应数据做类型处理,所以是原始响应数据类型
responseJSONresult属性的类型是Result<Any, AFError>responseJSON方法将响应数据解析为JSON 格式,JSON可以包含任何类型的数据,因此解析后的类型是Any
responseDataresult属性的类型是Result<Data, AFError>responseData方法直接返回原始的二进制数据,解析后的类型是Data
responseDecodableresult属性的类型是Result<DecodableType, AFError>responseDecodable方法将响应数据解析为特定的遵循Decodable协议的数据类型,解析后的类型是指定的模型对象类型
这种设计使得在处理不同类型的网络请求结果时,可以根据需要进行适当的类型转换和操作。通过使用不同的方法,
Alamofire将响应结果解析成适合特定情况的类型,使得处理网络请求变得更加灵活和方便 -
responseData方法的响应对象的data、result、value属性值的类型都是Data,且值也都是一样的 -
枚举的关联值是指在声明枚举成员时,可以附加额外的数据信息,以便在实际使用中可以存储和处理更多的信息。关联值使得枚举成员更加灵活,能够表示不同的数据情况,而不仅仅是通过简单的标签表示
swift
// suspended 和 banned 这两个枚举成员都附带了关联值
enum UserStatus {
case active
case suspended(reason: String)
case banned(reason: String, duration: Int)
}
swift
// 关联值只有类型,没有声明变量
@frozen public enum Result<Success, Failure> where Failure : Error {
case success(Success)
case failure(Failure)
}
// 使用时指定变量
let result: Result<Int, Error> = .success(42)
switch result {
case .success(let value):
print("Success: \(value)")
case .failure(let error):
print("Failure: \(error)")
}