引言

iOS 开发中进行网络恳求有两种主要办法:运用苹果原生的URLSession和运用第三方库Alamofire,下面将对这两种网络恳求办法进行别离介绍

URLSession

概述

URLSession是苹果官方供给的原生的网络恳求框架,供给了与网络通信相关的一系列类和办法。但是,运用朴实的 URLSession进行网络恳求或许需求处理许多底层细节,如构建恳求处理呼应处理过错

示例

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 恳求办法:

  1. AF.request():发起一个惯例的HTTP 恳求,支持不同的HTTP 办法GETPOSTPUTDELETE等)和参数,可以在呼应闭包中处理回来的数据和过错

  2. AF.upload():用于上传文件或数据,可以在呼应闭包中处理上传进展、呼应数据和过错

  3. AF.download():用于下载文件,可以在呼应闭包中处理下载进展、下载后的文件路径和过错

  4. AF.streamRequest():用于处理流式的网络恳求,适用于长连接或服务器推送等场景

呼应处理办法
  1. response: 处理通用的呼应数据,可以在闭包中访问呼应的状况码、头部和数据。适用于通用的JSON、文本等呼应
AF.request("").response { response in
    if let data = response.data {
        print("Response Data: \(data)")
    }
    if let statusCode = response.response?.statusCode {
        print("Status Code: \(statusCode)")
    }
}
  1. responseJSON: 将呼应的数据解析为JSON 格式,并在闭包中处理解析后的 JSON 数据
AF.request("").responseJSON { response in
    switch response.result {
    case .success(let json):
        print("JSON Response: \(json)")
    case .failure(let error):
        print("Error: \(error)")
    }
}
  1. responseDecodable: 运用Codable 协议将呼应的数据解码为特定的数据模型,适用于处理JSON 数据的主动解析
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办法来解析数据

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)")
    }
}
  1. responseData: 以原始数据的形式回来呼应数据,适用于处理二进制数据
AF.request("").responseData { response in
    switch response.result {
    case .success(let imageData):
        print("Image Data: \(imageData)")
    case .failure(let error):
        print("Error: \(error)")
    }
}
  1. downloadProgress: 在下载恳求中,可以运用此办法来监听下载进展的变化
AF.download("").downloadProgress { progress in
    print("Download Progress: \(progress.fractionCompleted)")
}
.response { response in
    print("Download Completed!")
}
  1. uploadProgress: 在上传恳求中,可以运用此办法来监听上传进展的变化
let image = UIImage(named: "example.jpg")!
AF.upload(image, to: "").uploadProgress { progress in
    print("Upload Progress: \(progress.fractionCompleted)")
}
.response { response in
    print("Upload Completed!")
}

示例

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是一个用于办理SwiftObjective-C项目中第三方库包办理器。它可以轻松地集成和办理各种库,然后减少了手动办理库的复杂性。想了解更多就去 CocoaPods官网 看看

下面是CocoaPodsmacOS上的装置步骤:

  1. 装置CocoaPods

    在终端中运转以下指令来装置CocoaPods及其所依靠的Ruby环境(若没有):

    sudo gem install cocoapods
    

    macOS自带了Ruby,可以在履行上面指令时在终端中运转以下指令来查看:

    ruby -v
    

    CocoaPods是基于Ruby编写的

  2. 验证装置

    装置完成后,可以运转以下指令来验证是否装置成功:

    pod --version
    

    假如装置成功,将显现CocoaPods的版别号

  3. 定时更新

    CocoaPods的版别和依靠或许会发生变化,所以主张定时更新CocoaPods以坚持最新。可以运用以下指令来更新CocoaPods

    sudo gem update cocoapods
    

拓展

  1. Alamofire各类恳求的呼应类型都是DataResponse类型,包括了许多特点:requestresponsedataresultvalue

    • request:表明原始的恳求目标,包括了恳求的URLHTTP 办法等信息
    • response:表明呼应目标,包括了服务器回来的HTTP 呼应,其间或许包括状况码头部信息
    • data:表明原始的呼应数据,以字节数组Data的形式存储,适用于需求手动处理原始数据的状况
    • result:一个Result枚举的相关值,表明恳求的成果。Result枚举可以包括成功的状况(带有数据相关值)或失败的状况(带有过错相关值)
    • value:表明result的枚举值,假如恳求成功,会包括成功数据的枚举值;假如恳求失败,则包括失败信息的枚举值
  2. Alamofire中,responseresponseJSONresponseDataresponseDecodable等办法都是为了便利开发者处理不同类型的呼应数据而规划的。response回来的是原始数据,而其他办规律供给了更高层次的抽象来便利处理不同类型的数据。其间,responseJSONresponseDataresponseDecodable等办法都是对response办法进一步的封装,用来更便利处理不同类型的呼应数据,比方将JSON 数据解析成字典数组,或者解析成遵从 Decodable 协议的模型目标

  3. responseresponseJSONresponseDataresponseDecodable呼应的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将呼应成果解析成合适特定状况的类型,使得处理网络恳求变得愈加灵敏和便利

  4. responseData办法的呼应目标的dataresultvalue特点值的类型都是Data,且值也都是一样的

  5. 枚举相关值是指在声明枚举成员时,可以附加额定的数据信息,以便在实际运用中可以存储和处理更多的信息。相关值使得枚举成员愈加灵敏,可以表明不同的数据状况,而不仅仅是经过简单的标签表明

// suspended 和 banned 这两个枚举成员都附带了相关值
enum UserStatus {
    case active
    case suspended(reason: String)
    case banned(reason: String, duration: Int)
}
// 相关值只要类型,没有声明变量
@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)")
}