最近在看swift,看到Moya在网络请求封装这一块儿做的非常好。
具体优点:
1.模块化封装,可以按具体的业务划分成模块,业务逻辑清晰,可维护性强;
2.统一配置,可以配置共同的参数值;
3.解耦,根据不同的请求枚举类型返回不同的请求参数.
下面看一下Moya给出的Demo, 这是一个GitHub Api的封装:
//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 can't be serialized.
}
}
//初始化请求类
let gitHubProvider = MoyaProvider<GitHub>(plugins: [NetworkLoggerPlugin(verbose: true, responseDataFormatter: JSONResponseDataFormatter)])
//String的拓展
private extension String {
var urlEscaped: String {
return self.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
}
}
//按照业务声明接口枚举,非常清晰
public enum GitHub {
case zen
case userProfile(String)
case userRepositories(String)
}
//网络请求配置
extension GitHub: TargetType {
//baseUrl
public var baseURL: URL { return URL(string: "https://api.github.com")! }
//根据不同业务返回请求路由
public var path: String {
switch self {
case .zen:
return "/zen"
case .userProfile(let name):
return "/users/\(name.urlEscaped)"
case .userRepositories(let name):
return "/users/\(name.urlEscaped)/repos"
}
}
//设置请求类型,可根据不同也去设置不同的类型
public var method: Moya.Method {
return .get
}
public var task: Task {
switch self {
case .userRepositories:
return .requestParameters(parameters: ["sort": "pushed"], encoding: URLEncoding.default)
default:
return .requestPlain
}
}
//验证类型
public var validationType: ValidationType {
switch self {
case .zen:
return .successCodes
default:
return .none
}
}
//mock的数据
public var sampleData: Data {
switch self {
case .zen:
return "Half measures are as bad as nothing at all.".data(using: String.Encoding.utf8)!
case .userProfile(let name):
return "{\"login\": \"\(name)\", \"id\": 100}".data(using: String.Encoding.utf8)!
case .userRepositories(let name):
return "[{\"name\": \"\(name)\"}]".data(using: String.Encoding.utf8)!
}
}
//请求头
public var headers: [String: String]? {
return nil
}
}
//拼接成完整的请求URL
public func url(_ route: TargetType) -> String {
return route.baseURL.appendingPathComponent(route.path).absoluteString
}
//返回值拓展
extension Moya.Response {
func mapNSArray() throws -> NSArray {
let any = try self.mapJSON()
guard let array = any as? NSArray else {
throw MoyaError.jsonMapping(self)
}
return array
}
}
发起请求
gitHubProvider.request(.userRepositories(username)) { result in
do {
let response = try result.dematerialize()
let value = try response.mapNSArray()
} catch {
let printableError = error as CustomStringConvertible
}
}
返回结果

网友评论