1.Moya的定义
Moya
是一个高度抽象的网络库,他的理念是让你不用关心网络请求的底层的实现细节,只用定义你关心的业务。且Moya
采用桥接和组合来进行封装(默认桥接了Alamofire
),使得Moya
非常好扩展,让你不用修改Moya
源码就可以轻易定制。官方给出几个Moya
主要优点:- 编译时检查
API endpoint
权限 - 让你使用枚举定义各种不同
Target
,endpoints
- 把
stubs
当做一等公民对待,因此测试超级简单。
- 编译时检查
2.Moya的使用
Moya
的使用分成几步,首先需要先自定义一个枚举类型。
enum SHChannelViewModelApiManager{
case getChannelList(Bool)
case getItemList(String)
}
- 然后遵循开闭原则,让枚举的分类遵循
Moya
的TargetType
,按需实现定义的各种get
方法
public protocol TargetType {
/// The target's base `URL`.
var baseURL: URL { get }
/// The path to be appended to `baseURL` to form the full `URL`.
var path: String { get }
/// The HTTP method used in the request.
var method: Moya.Method { get }
/// Provides stub data for use in testing.
var sampleData: Data { get }
/// The type of HTTP task to be performed.
var task: Task { get }
/// A Boolean value determining whether the embedded target performs Alamofire validation. Defaults to `false`.
var validate: Bool { get }
/// The headers to be used in the request.
var headers: [String: String]? { get }
}
extension SHChannelViewModelApiManager:TargetType {
var baseURL: URL {
return URL(string: baseUrl)!
}
var task: Task {
switch self {
case .getChannelList:
return .requestPlain
case .getItemList(let pipe):
return .requestParameters(parameters: ["pipe":pipe], encoding: URLEncoding.queryString)
}
}
var method: Moya.Method {
return .get
}
var path: String {
switch self {
case .getChannelList(let isToday):
if isToday{
return "/Youmeng/chaxunservletall"
}else{
return "/Youmeng/chaxunservletallhistory"
}
case .getItemList:
return itemListUrl
}
}
}
- 最后创建
MoyaProvider
对象,泛型允许传入任何你定义的遵循TargetType
协议的枚举,
let provider = MoyaProvider<SHChannelViewModelApiManager>()
- 使用
MoyaProvider
对象发起请求
provider.rx.request(.getItemList(pipe)).mapArr([SHChannelItemTopModel].self).subscribe(onSuccess: { [weak self](model) in
self?.topModels = model
self?.itemOutput.onNext(true)
}) { [weak self](error) in
self?.itemOutput.onNext(false)
}.disposed(by: bag)
}
3.Moya的所有文件解析
-
Provider
-
Task (是一个枚举,定义了任务的形式,是传参呢还是啥都不传了,是上传了还是下载任务)
-
Cancellable (只是标明了请求是否可以被取消,和一个取消请求的方法)
-
TargetType
-
MultiTarget (
MultiTarget
用于使MoyaProvider
能够处理多个TargetType
)
-
Result
-
MoyaError (是一个枚举,定义了
Moya
可能抛出的各种错误,包括上面说的Response
三个map
方法出错,状态码出错,解码出错,和参数编码错误等,同时有两个get
方法,得出错误的Response
返回以及错误描述返回)
-
Plugins
-
Alamofire
这里有一个iOS交流圈:891 488 181 分享BAT,阿里面试题、面试经验,讨论技术, 感兴趣的话大家一起交流学习!- Moya+Alamofire (
Moya
和Alamofire
的桥接文件,桥接模式保证了最少知道原则,如果进行替换Alamofire
,主要修改这个文件) - MultipartFormData (多文件上传与
Alamofire
的桥接,通过append
等方法把moya
形式的MultipartFormData
添加到Alamofire
里去)
- Moya+Alamofire (
-
URL
-
URL+Moya(通过获取
TargetType
的baseURL
和path
初始化一个URL
) -
URLRequest+Encoding(对
URLRequest
的两个encoded
方法)
-
3.1.MoyaProvider
MoyaProvider 初始化
MoyaProvider
是请求提供者类。只能通过该类发起请求,类的初始化如下
public init(endpointClosure: @escaping EndpointClosure = MoyaProvider.defaultEndpointMapping,
requestClosure: @escaping RequestClosure = MoyaProvider.defaultRequestMapping,
stubClosure: @escaping StubClosure = MoyaProvider.neverStub,
callbackQueue: DispatchQueue? = nil,
manager: Manager = MoyaProvider<Target>.defaultAlamofireManager(),
plugins: [PluginType] = [],
trackInflights: Bool = false) {
self.endpointClosure = endpointClosure
self.requestClosure = requestClosure
self.stubClosure = stubClosure
self.manager = manager
self.plugins = plugins
self.trackInflights = trackInflights
self.callbackQueue = callbackQueue
}
由以上代码可以得知,初始化可传入的参数。
-
EndpointClosure
是一个把传入的Target
转化为Endpoint
对象的闭包,public typealias EndpointClosure = (Target) -> Endpoint<Target>
既然如此