target的作用插件plugin的基本使用添加token封装了一个可以判断token和加载带转菊花的pluginProvider的作用和封装发送请求调用request方法
moya是把alamofire再封装的一个swift 网络请求框架.
他和原生的alamofire和 AFNetworking 的区别是.他多了一个 Target和一个plugin
一个target可以放多个接口,并且每个接口都可以单独指定url和请求类型,和参数类型.利用的枚举类型
下面代码展示target的用法.先定义一个 enum类型,然后遵守moya的 TargetType协议.
baseURL是接口前面的服务器地址,一般都是返回一个.也可以通过不同的case枚举成员,设置不同的服务器地址path是每个接口的子地址method返回.post 和 .get 等接口请求类型,可以根据不同的枚举成员返回不同的方法sampleData的解释是用于测试,暂时用不上task 用于可以设置发送的请求,和请求类型,例如可以设置http请求和json请求,并且可以把参数列表放进去header是请求头,但是我下面例子注释掉了,统一返回空的请求头,因为我把请求头,放在了Plugin插件协议里面.在这个协议里面可以更好的设置header下面例子,我在一个叫做JiaZhang的target枚举对象里面添加了3个接口.我在一个viewModel中,设置了3个接口.login,circle,logout
import UIKit import Moya import SwiftyJSON import RxSwift import RxCocoa import HandyJSON public enum JiaZhang :TargetType{ case login([String:String]) //登录 case circle([String:String]) //朋友圈 case logout([String:String]) //退出 public var baseURL: URL { URL(string: "https://kindergarten.wozhijiao.cn:5057//kindergartenapi/")! } public var path: String { switch self{ case .login: return "security/oauth/token" case .circle: return "circle/circle/queryCircle" case .logout: return "base/user/logout" default: return "" } } public var method: Moya.Method { return .post } public var sampleData: Data { switch self{ case .login(let param): return "登录参数是:(param)".data(using: .utf8)! default: return "没有对应类型".data(using: .utf8)! } } public var task: Task { switch self{ case .login(let params): return .requestParameters(parameters: params, encoding: URLEncoding.default)//encoding代表接收的请求用什么编码 case .circle(let params): return .requestParameters(parameters: params, encoding: JSONEncoding.default) case .logout(let params): return .requestParameters(parameters: params, encoding: JSONEncoding.default) default: return .requestPlain } } public var headers: [String : String]? { switch self{ case .login: return nil default: return nil } } // 通过statuscode过滤返回内容 public var validationType: ValidationType { switch self { case .login: return .successCodes default: return .none } } }插件plugin的基本使用添加token
PluginType,这个协议,也是我们要自己写一个子类继承自PluginType.里面有一个prepare方法是每次发送请求之前执行的.在这里可以添加token,注意要新建一个临时变量 var request = request,要不然不能更改里面的值
import UIKit import Moya import SwiftyJSON final class TdwMoyaPlugin: PluginType { public func prepare(_ request: URLRequest, target: TargetType) -> URLRequest { var request = request request.addValue("token值", forHTTPHeaderField: "token名字") return request } }封装了一个可以判断token和加载带转菊花的plugin
import UIKit import Moya import SwiftyJSON public protocol TdwMoyaToken{ var existToken:Bool { get } } final class TdwMoyaPlugin: PluginType { //当前的视图控制器 var vc:UIViewController var existToken = true //活动状态指示器(菊花进度条) private var spinner: UIActivityIndicatorView! //插件初始化的时候传入当前的视图控制器 init(vc:UIViewController) { self.vc = vc spinner = UIActivityIndicatorView(style: .gray)//转菊花 spinner.center = self.vc.view.center } var tokenVal:String { get { guard let myInfo = O2UserDefaults.shared.myInfo else { //加载自己的token return "" } return myInfo.token ?? "" } } var clientVal:String { get { let version = ProcessInfo.processInfo.operatingSystemVersion let versionString = "(version.majorVersion).(version.minorVersion).(version.patchVersion)" return "iOS (versionString)" } } public func prepare(_ request: URLRequest, target: TargetType) -> URLRequest { var request = request //加上通用头 request.addValue(clientVal, forHTTPHeaderField: "x-client") if let authorizable = target as? TdwMoyaToken,authorizable.existToken == false { return request } print("clientVal=",clientVal) //加上token let tokenName = O2AuthSDK.shared.tokenName() request.addValue(tokenVal, forHTTPHeaderField: tokenName) print("tokenVal=",tokenVal) print("tokenName=",tokenName) return request } //开始发起请求 func willSend(_ request: RequestType, target: TargetType) { //请求时在界面中央显示一个活动状态指示器 DispatchQueue.main.async {[weak self] in self?.vc.view.addSubview(self!.spinner) self?.spinner.startAnimating() } } //收到请求 func didReceive(_ result: ResultProvider的作用和封装, target: TargetType) { //移除界面中央的活动状态指示器 DispatchQueue.main.async {[weak self] in self?.spinner.removeFromSuperview() self?.spinner.stopAnimating() } //只有请求错误时会继续往下执行 guard case let Result.failure(error) = result else { return } //d出并显示错误信息 let message = error.errorDescription ?? "未知错误" let alertViewController = UIalertController(title: "请求失败", message: "(message)", preferredStyle: .alert) alertViewController.addAction(UIalertAction(title: "确定", style: .default, handler: nil)) vc.present(alertViewController, animated: true) } }
调用插件plugin发送请求request
provider是用来发送请求的,里面有request方法.我们使用的时候自己定义一个provider.继承自框架的MoyaProvider.
之所以继承的好处是,让provider可以指定自己的plugin插件,例如我下面的
import UIKit import Moya import RxSwift import RxCocoa import SwiftyJSON class TdwMoyaProvider发送请求调用request方法: MoyaProvider where Target:TargetType{ open var plugin:TdwMoyaPlugin! let disposeBag = DisposeBag() init(vc:UIViewController,existToken:Bool){ self.plugin = TdwMoyaPlugin(vc: vc)//调用自己的plugin super.init( plugins: [self.plugin]) } func requestTdw(target:Target,success: @escaping (_ JSON: JSON) -> Void, fail: @escaping (_ error:Error) -> Void){ self.rx.request(target).subscribe { event in//rxswift使用moya发送请求 print("event=",event) switch event { case .success(let response): let data = response.data let json = JSON(data) success(json) case .error(let error): print(error) fail(error) } }.disposed(by: disposeBag) } }
var provider = TdwMoyaProvider(vc: self, existToken: true) provider.request(JiaZhang.login(param)) { json in print("json=",json) }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)