一、Moya的常规调用
1、API
public enum XXXAPI {
case action1(param1:String,param2:Int)
case action2
}
2、TargetType设置
extension XXXAPI:TargetType {
//url
public var baseURL: URL {
return URL(string: BaseURL)!
}
//path
public var path:String {
switch self {
case action1:
return "action1"
case action2:
return "action2"
}
}
//method
public var method: Moya.Method {
switch self {
case action1:
return .post
case action2:
return .get
}
}
//header
public var headers: [String : String]? {
return ["":""]
}
//data
public var sampleData: Data {
return "{}".data(using: String.Encoding.utf8)!
}
//Task
public var task: Task {
var params:[String: Any] = [:]
//URLEncoding:httpBody.queryString.methodDependent.default
var ecodingType = URLEncoding.default
switch self {
case action1(let param1,let param2):
params["param1"] = param1
params["params2"] = param2
return .requestParameters(parameters: params, encoding: ecodingType)
case action2:
return .requestParameters(parameters: params, encoding: ecodingType)
}
}
}
3、APIProvider 调用入口
class XXXAPIProvider: MoyaProvider<XXXAPI> {
/*
*method: 请求调用方法
*param: 特殊参数说明
*target:由于API继承TargetType,当前参数为XXAPI.action2
*JSONResponseDataFormatter:data转为jsonData
* NetworPlugin:继承自PluginType,添加请求过程执行代理
*/
public static func request(_ target: Target,
callbackQueue: DispatchQueue? = .none,
progress: ProgressBlock? = .none,
completion: @escaping (String?,Error?) -> Void) -> Void {
let mXXXAPIProvider = MoyaProvider<XXXAPI>(plugins: [NetworkLoggerPlugin(verbose: true, responseDataFormatter: JSONResponseDataFormatter),NetworPlugin()])
let callbackQueue = callbackQueue ?? .none
let _: Cancellable = mXXXAPIProvider.requestNormal(target, callbackQueue: callbackQueue, progress: progress) { (result) in
switch result {
case let .success(response):
let jsonString = String(data: response.data, encoding: String.Encoding.utf8)
completion(jsonString,nil)
case let .failure(error):
completion(nil,error)
}
}
}
}
// 请求过程代理类
/// A Moya Plugin receives callbacks to perform side effects wherever a request is sent or received.
///
/// for example, a plugin may be used to
/// - log network requests
/// - hide and show a network activity indicator
/// - inject additional information into a request
public protocol PluginType {
/// Called to modify a request before sending.
func prepare(_ request: URLRequest, target: TargetType) -> URLRequest
/// Called immediately before a request is sent over the network (or stubbed).
func willSend(_ request: RequestType, target: TargetType)
/// Called after a response has been received, but before the MoyaProvider has invoked its completion handler.
func didReceive(_ result: Result<Moya.Response, MoyaError>, target: TargetType)
/// Called to modify a result before completion.
func process(_ result: Result<Moya.Response, MoyaError>, target: TargetType) -> Result<Moya.Response, MoyaError>
}
//继承PluginType,监听请求过程,方便在请求过程中,执行所需业务
public final class NetworPlugin: PluginType {
public func willSend(_ request: RequestType, target: TargetType) {
}
public func didReceive(_ result: Result<Moya.Response, MoyaError>, target: TargetType) {
switch result {
case let .success(response):
default:break
}
}
}
//data序列化为jsondata
func JSONResponseDataFormatter(_ data: Data) -> Data {
do {
let dataAsJSON = try JSONSerialization.jsonObject(with: data)
let prettyData = try JSONSerialization.data(withJSONObject: dataAsJSON, options: .prettyPrinted)
return prettyData
} catch {
return data // fallback to original data if it can't be serialized.
}
}
4、Plugin的的类型及基本使用
(1) NetworkLoggerPlugin 网络日志
NetworkLoggerPlugin(verbose: true, responseDataFormatter: JSONResponseDataFormatter)
//日志log data转json
private func JSONResponseDataFormatter(_ data: Data) -> Data {
do {
let dataAsJSON = try JSONSerialization.jsonObject(with: data)
let prettyData = try JSONSerialization.data(withJSONObject: dataAsJSON, options: .prettyPrinted)
return prettyData
} catch {
return data //fallback to original data if it cant be serialized
}
}
(2)NetworkActivityPlugin 网络状态
let networkActivityPlugin = NetworkActivityPlugin { (status) -> () in
switch(status) {
case .ended:
// 电池条小菊花
UIApplication.shared.isNetworkActivityIndicatorVisible = false
case .began:
UIApplication.shared.isNetworkActivityIndicatorVisible = true
}
}
(3)CredentialsPlugin 证书配置
Provides each request with optional URLCredentials.给每一个请求配置独立证书
(4)AccessTokenPlugin token鉴权
给request的headers添加Authorization
(5)自定义plugin
在pluginType的四个协议接口中,处理自定义plugin事件
eg:
1.发送请求之前设置cookies持有
httpShouldHandleCookies = true
2. 对特定path做处理
二、HandyJson + 泛型
外部结构和规范有关
1、整个接口返回结构
class BaseBean<T>: HandyJSON {
var code:Int32?
var message:String?
var serverTime:Int64?
var data:T?
required init() {
}
}
2、返回为列表时的结构
class BaseListBean<T>:HandyJSON {
var content:[T]?
var number:Int?
var size:Int?
var totalElements:Int?
required init() {
}
}
使用举例1:获取单个数据
func action1< T:Basebean< XXXModel > >(param1:String,param2:Int,complete:@escaping (T?)->Void) {
XXXAPIProvider.request(XXXAPI.action1(param1: param1, param2: param2)) { (jsonString, error) in
let bean = T.deserialize(from: jsonString)
complete(bean)
}
}
使用举例2:获取批量数据
func action2< T:Basebean < BaseListBean < XXXModel > > >(complete:@escaping (T?)->Void) {
XXXAPIProvider.request(XXXAPI.action2) { (jsonString, error) in
let bean = T.deserialize(from: jsonString)
complete(bean)
}
}