进阶课程(4)网络请求核武器之纯想框架使用
下载赵纯想武器库
所依赖的库
pod 'Moya'# 网络底层
pod 'Moya/Combine', '~> 15.0'#
pod 'KakaJSON'# JSON处理
pod 'SwiftyJSON'# JSON处理
文件夹结构
.
├── Apis
│ └── UserAPI.swift - 写Api子弹的地方
├── Config
│ ├── ApiConfig.swift - Api总体配置的地方
│ └── NetWorking.swift - 请求方法函数
├── Extension
│ ├── MoyaProviderType+Extension.swift - 扩展别动
│ ├── MoyaResult+Extension.swift - 扩展别动
│ └── Response+Extension.swift - 扩展别动
└── Plugin
├── NetworkLoggerPlugin.swift - 日志插件
├── TokenPlugin.swift - Token插件别动
└── WarningPlugin.swift - 警告插件
本课语法相关:协议Protocol
协议是 Swift 中的一种特殊类型,它定义了一组方法、属性和其他特性的要求。类、结构体和枚举都可以遵循协议。
定义一个协议,需要使用 protocol 关键字,如下所示:
protocol ExampleProtocol {
// 协议定义
}
类、结构体或枚举遵循协议,需要在类型名称后面加上协议名称,如下所示:
struct ExampleStruct: ExampleProtocol {
// 结构体定义
}
示例:
- 自定义一个可被打印的协议
protocol Printable {
func printSelf()
}
struct Person: Printable {
var name: String
func printSelf() {
print(name)
}
}
- 定义一个协议,要求遵循协议的类型必须具有某个属性
protocol HasWidth {
var width: Double { get }
}
struct Room: HasWidth {
let width: Double
}
- 定义一个协议,要求遵循协议的类型必须具有某个方法
protocol Doable {
func doIt()
}
class Task: Doable {
func doIt() {
print("Task is done!")
}
}
本课语法相关:枚举Case
枚举是 Swift 语言中的一种数据类型,它可以定义一组有限的可能值。枚举通常用来表示一个变量可能的状态。
以下是一个简单的枚举定义示例:
enum CompassPoint {
case north
case south
case east
case west
}
在上面的示例中,我们定义了一个名为 CompassPoint 的枚举,它有四个可能的值: north,south,east 和 west。
您可以使用这种方式为枚举类型的变量赋值:
var directionToHead = CompassPoint.west
directionToHead = .east
您也可以使用枚举类型的值作为控制语句中的条件:
if directionToHead == .north {
print("Lots of planets have a north")
} else if directionToHead == .south {
print("Watch out for penguins")
} else if directionToHead == .east {
print("Where the sun rises")
} else if directionToHead == .west {
print("Where the skies are blue")
}
您还可以将枚举类型的值作为参数传递给函数:
func navigate(direction: CompassPoint) {
if direction == .north {
print("Going north")
} else if direction == .south {
print("Going south")
} else if direction == .east {
print("Going east")
} else if direction == .west {
print("Going west")
}
}
navigate(direction: .west)
这就是 Swift 中枚举的基本用法。您还可以在枚举中添加关联值或原始值来扩展其功能。
TargetType 协议介绍
import Foundation
public protocol TargetType {
/// 目标的基础`URL`。
var baseURL: URL { get }
/// 需要添加到`baseURL`上以形成完整`URL`的路径。
var path: String { get }
/// 请求中使用的HTTP方法。
var method: Moya.Method { get }
/// 提供测试中使用的桩数据。默认为`Data()`。
var sampleData: Data { get }
/// 要执行的HTTP任务的类型。
var task: Task { get }
/// 对请求执行的验证类型。默认为`ValidationType.none`。
var validationType: ValidationType { get }
/// 请求中使用的标头。
var headers: [String: String]? { get }
}
public extension TargetType {
/// 对请求执行的验证类型。默认为`ValidationType.none`。
var validationType: ValidationType { .none }
/// 提供测试中使用的桩数据。默认为`Data()`。
var sampleData: Data { Data() }
}
满足 TargetType 协议
配置一个API的过程
import Foundation
enum SearchAPI: ChunxiangTargetType {
// 搜索食物的卡路里,keyword为关键词
case searchCalory(keyword: String)
// API路径
var path: String {
switch self {
case .searchCalory:
return "food_heat/food/search"
}
}
// 请求方法,这里为GET请求
var method: HTTPRequestMethod {
switch self {
case .searchCalory:
return .get
}
}
// 请求参数,包括关键词、页码、app_id、app_secret
var parameters: [String: Any]? {
switch self {
case .searchCalory(keyword: let keyword):
return ["keyword": keyword,
"page": 1,
"app_id": "rgihdrm0kslojqvm",
"app_secret": "WnhrK251TWlUUThqaVFWbG5OeGQwdz09"]
}
}
}
这些是每个子弹都相同的基础信息,只需要设置一次 通常与项目有关
public extension ChunxiangTargetType {
// 基础URL
var baseURL: URL {
URL(string: "https://www.mxnzp.com/api")!
}
// 路径
var path: String {
let path = String(describing: self)
return "/" + path.components(separatedBy: "(").first!
}
// 示例数据
var sampleData: Data {
"".data(using: String.Encoding.utf8)!
}
// 请求任务
var task: Task {
switch method {
case .get:
if let parameters = parameters {
return .requestParameters(parameters: parameters, encoding: parameterEncoding)
}
return .requestPlain
case .post, .put, .delete:
return .requestParameters(parameters: parameters ?? [:], encoding: parameterEncoding)
default:
return .requestPlain
}
}
// 请求参数
var parameters: [String: Any]? { nil }
// 参数编码
var parameterEncoding: ParameterEncoding {
switch method {
case .get: return URLEncoding.default
default: return JSONEncoding.default
}
}
// 设置通用的Header
var headers: [String: String]? {
var headers: [String: String] = [:]
headers["Content-Type"] = "application/json"
return headers
}
}