enum RequestMethod {
case get
case post
case delete
case put
}
func parseError(_ json: JSON) -> RequestError? {
let retCode = Int(json["retCode"].stringValue) ?? 0
let retMsg = json["retMsg"].stringValue
switch retCode {
case 0:
return nil
case 2:
return .itemExist(errorMsg: retMsg)
case 3:
return .tokenInvalid
case 8:
return .accountException(errorMsg: retMsg)
case 9:
return .authorizeError
case 10:
return .vipExpired(errorMsg: retMsg)
default:
return .requestFailed(errorCode: retCode, errorMsg: retMsg)
}
}
let defaultSessionManager = { (baseUrl: String) -> AFHTTPSessionManager in
let manager = AFHTTPSessionManager(baseURL: URL(string: baseUrl))
if baseUrl.hasPrefix("https") {
let securityPolicy = AFSecurityPolicy(pinningMode: .none)
securityPolicy.allowInvalidCertificates = true
securityPolicy.validatesDomainName = false
manager.securityPolicy = securityPolicy
}
return manage
}
protocol RequestProtocol: AuthorizeProtocol {
func baseUrl() -> String
func path() -> String
func timeoutInterval() -> TimeInterval
func sessionManager() -> AFHTTPSessionManager
func requestMethod() -> RequestMethod
func shouldMergeDefaultParameters() -> Bool
}
extension RequestProtocol {
func baseUrl() -> String {
return AppConfig.BaseUrl
}
func path() -> String {
return ""
}
func timeoutInterval() -> TimeInterval {
return 60
}
func sessionManager() -> AFHTTPSessionManager {
return defaultSessionManager(baseUrl())
}
func requestMethod() -> RequestMethod {
return .get
}
func shouldMergeDefaultParameters() -> Bool {
return false
}
extension RequestProtocol {
func mergeDefaultParams(_ params: [String : Any]?) -> [String : Any] {
var resultParams = params ?? [:]
//TODO: add default params
return resultParams
}
}
@objc
protocol Cancellable: class {
func cancel()
}
extension URLSessionDataTask: Cancellable {
}
extension RequestProtocol {
@discardableResult
func request(
parameters: [String : Any]? = [:],
constructingBodyWith bodyBlock: @escaping (AFMultipartFormData) -> Void,
success: @escaping (_ dataTask: URLSessionDataTask?, _ responseObject: Any?) -> Void,
failure: @escaping (_ dataTask: URLSessionDataTask?, _ error: Error?) -> Void ) -> Cancellable? {
guard AFNetworkReachabilityManager.shared().isReachable else {
DispatchQueue.main.async {
failure(nil, RequestError.connectionFailed)
}
return nil
}
// configure session manager
let manager = sessionManager()
manager.requestSerializer = requestSerializer()
manager.requestSerializer.timeoutInterval = timeoutInterval()
manager.responseSerializer = responseSerializer()
let params = mergeDefaultParams(parameters)
return manager.post(
path(),
parameters:params,
constructingBodyWith: bodyBlock,
progress:nil,
success: { (dataTask, resp) in
#if DEBUG
print(dataTask.currentRequest?.url ?? "")
print(resp ?? "")
#endif
success(dataTask, resp)
},
failure: { (dataTask, error) in
#if DEBUG
debugPrint(error)
#endif
failure(dataTask, error)
})
}
@discardableResult
func request(
parameters: [String : Any]? = [:],
success: @escaping (_ dataTask: URLSessionDataTask?, _ responseObject: Any?) -> Void,
failure: @escaping (_ dataTask: URLSessionDataTask?, _ error: Error?) -> Void ) -> Cancellable? {
guard AFNetworkReachabilityManager.shared().isReachable else {
DispatchQueue.main.async {
failure(nil, RequestError.connectionFailed)
}
return nil
}
// Handle network request and return cancellable request handler
// which can cancel this request
}
}
请求解析回调处理
protocol ResponseConvertible {
associatedtype Target
@discardableResult
func request(_ parameters: [String : Any]?,
completionHandler: @escaping (Result<Target>) -> Void) -> Cancellable?
}
extension ResponseConvertible {
@discardableResult
func request(_ completionHandler: @escaping (Result<Target>) -> Void) -> Cancellable? {
return request(nil, completionHandler: completionHandler)
}
}
extension ResponseConvertible where Target: ModelConvertibleFromJSON, Self: RequestProtocol {
@discardableResult
func request(_ parameters: [String : Any]?,
completionHandler: @escaping (Result<Target>) -> Void) -> Cancellable? {
if validateAuthorize() {
return request(
parameters,
transform: { Target($0["data"]) },
completionHandler: completionHandler
)
} else {
DispatchQueue.main.async {
completionHandler(.failure(RequestError.authorizeError))
}
return nil
}
}
}
extension ResponseConvertible where Target: Sequence
, Target.Iterator.Element: ModelConvertibleFromJSON
, Self: RequestProtocol {
@discardableResult
func request(_ parameters: [String : Any]?,
completionHandler: @escaping (Result<Target>) -> Void) -> Cancellable? {
if validateAuthorize() {
return request(
parameters,
transform: { json -> Target in
return json["data"].arrayValue.flatMap { Target.Iterator.Element($0) } as! Target
},
completionHandler: completionHandler
)
} else {
DispatchQueue.main.async {
completionHandler(.failure(RequestError.authorizeError))
}
return nil
}
}
}
extension ResponseConvertible where Target == Void, Self: RequestProtocol {
@discardableResult
func request(_ parameters: [String : Any]?,
completionHandler: @escaping (Result<Target>) -> Void) -> Cancellable?{
if validateAuthorize() {
return request(
parameters,
transform: { _ in },
completionHandler: completionHandler
)
} else {
DispatchQueue.main.async {
completionHandler(.failure(RequestError.authorizeError))
}
return nil
}
}
}
extension ResponseConvertible where Self: RequestProtocol {
@discardableResult
func request(_ parameters: [String : Any]?,
completionHandler: @escaping (Result<Target>) -> Void) -> Cancellable? {
if validateAuthorize() {
return request(
parameters,
transform: { $0 as! Target },
completionHandler: completionHandler
)
} else {
DispatchQueue.main.async {
completionHandler(.failure(RequestError.authorizeError))
}
return nil
}
}
@discardableResult
func request(_ parameters: [String : Any]?,
transform: @escaping (_ json: JSON) throws -> Target ,
completionHandler: @escaping (Result<Target>) -> Void) rethrows -> Cancellable? {
if validateAuthorize() {
return request(
parameters: parameters,
success: { (_, responseObject) in
let json = JSON(responseObject!)
if let error = parseError(json) {
completionHandler(.failure(error))
} else {
if let model = try? transform(json) {
completionHandler(.success(model))
} else {
completionHandler(.failure(RequestError.connectionFailed))
}
}
},
failure: { (dataTask, error) in
completionHandler(.failure(RequestError.connectionFailed))
})
} else {
DispatchQueue.main.async {
completionHandler(.failure(RequestError.authorizeError))
}
return nil
}
}
@discardableResult
func request(_ parameters: [String : Any]?,
constructingBodyWith bodyBlock: @escaping (AFMultipartFormData) -> Void,
completionHandler: @escaping (Result<Target>) -> Void) -> Cancellable? {
if validateAuthorize() {
return request(
parameters,
constructingBodyWith: bodyBlock,
transform: { $0 as! Target },
completionHandler: completionHandler
)
} else {
DispatchQueue.main.async {
completionHandler(.failure(RequestError.authorizeError))
}
return nil
}
}
@discardableResult
func request(_ parameters: [String : Any]?,
constructingBodyWith bodyBlock: @escaping (AFMultipartFormData) -> Void,
transform: @escaping (_ json: JSON) throws -> Target ,
completionHandler: @escaping (Result<Target>) -> Void) rethrows -> Cancellable? {
if validateAuthorize() {
return request(
parameters: parameters,
constructingBodyWith: bodyBlock,
success: { (_, responseObject) in
let json = JSON(responseObject!)
if let error = parseError(json) {
completionHandler(.failure(error))
} else {
if let model = try? transform(json) {
completionHandler(.success(model))
} else {
completionHandler(.failure(RequestError.connectionFailed))
}
}
},
failure: { (dataTask, error) in
completionHandler(.failure(RequestError.connectionFailed))
})
} else {
DispatchQueue.main.async {
completionHandler(.failure(RequestError.authorizeError))
}
return nil
}
}
}