注:二次封装不仅需要Alamofire库,还需要HandyJSON库
pod 'Alamofire', '5.5.0'
pod 'HandyJSON', '5.0.2'
1.错误信息
enum ResponseError : Int {
case unkown = 0
case success = 200
case failure = 500
case expaired = 401
case beOffLine = 402
}
2.服务器返回的数据转化为model后,存放在此结构中的.
struct ResponseModel<T:HandyJSON>{
var errorCode : ResponseError = .unkown
var errorMessage : String = "未知错误"
var model : T?
var models : [T?]?
var resultData : Any?
}
3.请求头
struct RequestHeaders : HandyJSON{
var timestamp : String?
var token : String?
var sign : String?
}
4.不需要返回参数时使用的默认Model
struct ResponseDefault : HandyJSON {}
5.服务器返回的最外层数据
struct ResponseData : HandyJSON{
var code : Int?
var msg : String?
var data : Any?
}
6.调用的类
class NetManager {
/// 单例
public class var defualt : NetManager{
struct Static {
static let instance :NetManager = NetManager()
}
return Static.instance
}
/// 请求头
var YJBHeaders : HTTPHeaders{
get{
var headers = RequestHeaders()
headers.sign = ""
headers.token = ""
headers.timestamp = ""
guard let jsonHeader = headers.toJSON() ,let jsonHeader = jsonHeader as? [String:String] else {
return []
}
return HTTPHeaders.init(jsonHeader)
}
}
/// 接口地址
let RequestUrlHost : String = "http://test.17jbshop.com/"
/// 参数编码方式
let YJBParameterEncoder : ParameterEncoder = URLEncodedFormParameterEncoder.default
}
7.网络请求调用方法
typealias ResponseBlock<T:HandyJSON> = (_ responseModel:ResponseModel<T>) -> ()
extension NetManager{
///可无参数,无模型数据返回
class func request(url:String,
method:HTTPMethod = .post,
parametersDic:[String:String]? = [:],
resultBlock:ResponseBlock<ResponseDefault>?){
self.request(url: url, method: method, parametersDic: parametersDic, modelType: ResponseDefault.self, resultBlock: resultBlock)
}
/// 可无参数
class func request<T:HandyJSON>(url:String,
method:HTTPMethod = .post,
parametersDic:[String:String]? = [:],
modelType:T.Type,
resultBlock:ResponseBlock<T>?){
self.request(url: url, method: method, parameters: parametersDic, modelType: modelType, resultBlock: resultBlock)
}
/// 无模型数据返回
class func request<Parameters: Encodable>(url:String,
method:HTTPMethod = .post,
parameters:Parameters,
resultBlock:ResponseBlock<ResponseDefault>?){
self.request(url: url, method: method, parameters: parameters, modelType: ResponseDefault.self, resultBlock: resultBlock)
}
/// 数据模型返回
class func request<T:HandyJSON,Parameters: Encodable>(url:String,
method:HTTPMethod = .post,
parameters:Parameters,
modelType:T.Type,
resultBlock:ResponseBlock<T>?)
{
NetManager.InitDataRequest(url: url, method: method, parameters: parameters)
.responseString { string in
if let error = string.error{
print(error.errorDescription as Any)
return
}
self.response(modelType, string.value,resultBlock)
}
}
}
提取的相同配置:
extension NetManager{
fileprivate class func InitDataRequest<Parameters: Encodable>(url:String,
method:HTTPMethod = .post,
parameters:Parameters? = nil
) -> DataRequest{
let headers : HTTPHeaders = NetManager.defualt.YJBHeaders
let encoder : ParameterEncoder = NetManager.defualt.YJBParameterEncoder
let requestUrl = url
let request : DataRequest = AF.request(requestUrl, method: method, parameters: parameters, encoder: encoder, headers: headers, interceptor: nil, requestModifier: nil)
return request
}
}
数据转模型方法:
///解析服务器返回的数据转化为model
fileprivate class func response<T:HandyJSON>
(
_ modelType:T.Type,
_ responseData:String?,
_ resultBlock:ResponseBlock<T>?
){
guard let resultBlock = resultBlock else {
return
}
var responseModel = ResponseModel<T>()
let baseModel = ResponseData.deserialize(from: responseData)
guard let baseModel = baseModel else {
return resultBlock(responseModel)
}
responseModel.errorCode = ResponseError(rawValue: baseModel.code ?? 0) ?? .unkown
if let _ = baseModel.msg{
responseModel.errorMessage = baseModel.msg!
}
responseModel.resultData = baseModel.data
// 当被转模型数据不存在,停止转模型.
guard let data = baseModel.data else {
return resultBlock(responseModel)
}
if let dataArray = data as? [Any]{ // 解析数组
responseModel.models = [T].deserialize(from: dataArray)
return resultBlock(responseModel)
}
else if let data = data as? [String : Any]{ //解析字典
responseModel.model = T.deserialize(from: data)
return resultBlock(responseModel)
}
else{ //原样返回Data数据
return resultBlock(responseModel)
}
}
8.举个例子:
服务器数据结构:
{
code = 200,
msg = "成功"
data = [
{
name = "haha",
age = 1
},
{
name = "hehe",
age = 2
}
]
}
请求参数,参数结构需要遵循Encodebale协议或者本身就遵循协议的[Sting,String]之类:
class TestParam : Encodable{
var id : Int?
}
response model结构需要遵循HandyJSON协议,并且是data的数据结构:
class TestModel : HandyJSON{
var name : String?
var age : Int?
}
发出请求:
let API = "userInfo"
let param = TestParam()
param.id = 1
NetManager.request(url:API,method:.post, parameters: param,modelType: TestModel.self { responseModel in
// responseModel为ResponseModel类
}
注:如果data中的数据为字典则model为responseModel.model中,如果data为数组,则model为responseModel.models中.
9.不足之处
由于需求的特别性,可能有共同的请求参数,尝试过使用继承来达到目的,但是最终无法获取到对应的参数。同理返回参数中有共同参数也无法实现。目前只使用协议来标记参数和返回参数。
代码地址:https://gitee.com/perhapys/alamofireSimpleUse
网友评论