引言
在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 cocoapods
macOS
自带了Ruby
,可以在执行上面命令时在终端中运行以下命令来检查:bashruby -v
CocoaPods
是基于Ruby
编写的 -
验证安装
安装完成后,可以运行以下命令来验证是否安装成功:
bashpod --version
如果安装成功,将显示
CocoaPods
的版本号 -
定期更新
CocoaPods
的版本和依赖可能会发生变化,所以建议定期更新CocoaPods
以保持最新。可以使用以下命令来更新CocoaPods
:bashsudo gem update cocoapods
拓展
-
Alamofire
各类请求的响应类型都是DataResponse
类型,包含了诸多属性:request
、response
、data
、result
、value
request
:表示原始的请求对象
,包含了请求的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
属性类型response
result
属性的类型是Result<Data, AFError>
response
方法并未对响应数据做类型处理,所以是原始响应数据类型
responseJSON
result
属性的类型是Result<Any, AFError>
responseJSON
方法将响应数据解析为JSON 格式
,JSON
可以包含任何类型的数据
,因此解析后的类型是Any
responseData
result
属性的类型是Result<Data, AFError>
responseData
方法直接返回原始的二进制数据,解析后的类型是Data
responseDecodable
result
属性的类型是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)")
}