亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS 使用Moya網絡請求的實現方法

2019-10-21 18:40:06
字體:
來源:轉載
供稿:網友

由于前段時間寫了這篇文章,最新Moya已更新最新版本,故此也更新了下用法,本人已使用,故特意奉上最新的使用demo供參考。Moya11.0.2Demo

Moya簡介

Moya是你的 app 中缺失的網絡層。不用再去想在哪兒(或者如何)安放網絡請求,Moya 替你管理。

Moya有幾個比較好的特性:

  • 編譯時檢查正確的API端點訪問.
  • 使你定義不同端點枚舉值對應相應的用途更加明晰.
  • 提高測試地位從而使單元測試更加容易.

Swift我們用 Alamofire 來做網絡庫.而 Moya 在Alamofire的基礎上又封裝了一層,如下流程圖說明 Moya 的簡單工作流程圖:

 

 
iOS,Moya,網絡請求

 

Moya的官方下載地址點我強大的Moya ,有具體的使用方法在demo里面有說明。

本文主要介紹一下 Moya 的用法

  • 設置請求頭部信息 設
  • 置超時時間
  • 自定義插件
  • 自簽名證書

注意:以下所出現的 NetAPIManager 跟官網上demo的** GitHub**是一樣類型的文件,都是這個enum實現一個協議TargetType,點進去可以看到TargetType定義了我們發送一個網絡請求所需要的東西,什么baseURL,parameter,method等一些計算性屬性,我們要做的就是去實現這些東西,當然有帶默認值的我們可以不去實現,但是設置頭部信息跟超時時間就要修改這些系統默認設置了。

為了看得更加清楚,貼上 NetAPIManager 文件的內容

//// NetAPIManager.swift// NN110//// Created by 陳亦海 on 2017/5/12.// Copyright © 2017年 陳亦海. All rights reserved.//import Foundationimport Moyaenum NetAPIManager { case Show case upload(bodyData: Data) case download case request(isTouch: Bool, body: Dictionary<String, Any>? ,isShow: Bool)}extension NetAPIManager: TargetType { var baseURL: URL {//服務器地址    switch self {  case .request( _, _, _):   return URL(string: "https://www.pmphmall.com")!  default:   return URL(string: "https://httpbin.org")!  }     }  var path: String {//具體某個方法的路徑  switch self {  case .Show:   return ""  case .upload(_):   return ""  case .request(_, _, _):   return "/app/json.do"  case .download:   return ""  } }  var method: Moya.Method {//請求的方法 get或者post之類的  switch self {  case .Show:   return .get  case .request(_, _, _):   return .post  default:   return .post  } }  var parameters: [String: Any]? {//請求的get post給服務器的參數  switch self {  case .Show:   return nil  case .request(_, _, _):   return ["msg":"H4sIAAAAAAAAA11SSZJFIQi7EqPAEgTvf6TP62W7sMoSQhKSWDrs6ZUKVWogLwYV7RjHFBZJlNlzloN6LVqID4a+puxqRdUKVNLwE1TRcZIC/fjF2rPotuXmb84r1gMXbiASZIZbhQdKEewJlz41znDkujCHuQU3dU7G4/PmVRnwArMLXukBv0J23XVahNO3VX35wlgce6TLUzzgPQJFuHngAczl6VhaNXpmRLxJBlMml6gdLWiXxTdO7I+iEyC7XuTirCQXOk4dotgArgkH/InxVjfNTnE/uY46++hyAiLFuFL4cv1Z8WH5DgB2GnvFXMh5gm53Tr13vqqrEYtcdXfkNsMwKB+9sAQ77grNJmquFWOhfXA/DELlMB0KKFtHOc/ronj1ml+Z7qas82L3VWiCVQ+HEitjTVzoFw8RisFN/jJxBY4awvq427McXqnyrfCsl7oeEU6wYgW9yJtj1lOkx0ELL5Fw4z071NaVzRA9ebxWXkFyothgbB445cpRmTC+//F73r1kOyQ3lTpec12XNDR00nnq5/YmJItW3+w1z27lSOLqgVctrxG4xdL9WVPdkH1tkiZ/pUKBGhADAAA="]  default:   return nil    } }  var sampleData: Data { //編碼轉義  return "{}".data(using: String.Encoding.utf8)! }  var task: Task { //一個請求任務事件    switch self {    case let .upload(data):  return .upload(.multipart([MultipartFormData(provider: .data(data), name: "file", fileName: "gif.gif", mimeType: "image/gif")]))     default:   return .request  }  }  var parameterEncoding: ParameterEncoding {//編碼的格式  switch self {  case .request(_, _, _):   return URLEncoding.default  default:   return URLEncoding.default  }   } //以下兩個參數是我自己寫,用來控制網絡加載的時候是否允許操作,跟是否要顯示加載提示,這兩個參數在自定義插件的時候會用到 var touch: Bool { //是否可以操作    switch self {  case .request(let isTouch, _, _):   return isTouch  default:   return false  }   }  var show: Bool { //是否顯示轉圈提示    switch self {  case .request( _, _,let isShow):   return isShow  default:   return false  }   }  }

如何設置Moya請求頭部信息

頭部信息的設置在開發過程中很重要,如服務器生成的token,用戶唯一標識等 我們直接上代碼,不說那么多理論的東西,哈哈

// MARK: - 設置請求頭部信息let myEndpointClosure = { (target: NetAPIManager) -> Endpoint<NetAPIManager> in   let url = target.baseURL.appendingPathComponent(target.path).absoluteString let endpoint = Endpoint<NetAPIManager>(  url: url,  sampleResponseClosure: { .networkResponse(200, target.sampleData) },  method: target.method,  parameters: target.parameters,  parameterEncoding: target.parameterEncoding ) //在這里設置你的HTTP頭部信息 return endpoint.adding(newHTTPHeaderFields: [  "Content-Type" : "application/x-www-form-urlencoded",  "ECP-COOKIE" : ""  ]) }

如何設置請求超時時間

// MARK: - 設置請求超時時間let requestClosure = { (endpoint: Endpoint<NetAPIManager>, done: @escaping MoyaProvider<NetAPIManager>.RequestResultClosure) in  guard var request = endpoint.urlRequest else { return }  request.timeoutInterval = 30 //設置請求超時時間 done(.success(request))}

自定義插件

自定義插件必須 PluginType 協議的兩個方法willSend與didReceive

//// MyNetworkActivityPlugin.swift// NN110//// Created by 陳亦海 on 2017/5/10.// Copyright © 2017年 CocoaPods. All rights reserved.//import Foundationimport Resultimport Moya/// Network activity change notification type.public enum MyNetworkActivityChangeType { case began, ended}/// Notify a request's network activity changes (request begins or ends).public final class MyNetworkActivityPlugin: PluginType {    public typealias MyNetworkActivityClosure = (_ change: MyNetworkActivityChangeType, _ target: TargetType) -> Void let myNetworkActivityClosure: MyNetworkActivityClosure  public init(newNetworkActivityClosure: @escaping MyNetworkActivityClosure) {  self.myNetworkActivityClosure = newNetworkActivityClosure }  // MARK: Plugin  /// Called by the provider as soon as the request is about to start public func willSend(_ request: RequestType, target: TargetType) {  myNetworkActivityClosure(.began,target) }  /// Called by the provider as soon as a response arrives, even if the request is cancelled. public func didReceive(_ result: Result<Moya.Response, MoyaError>, target: TargetType) {  myNetworkActivityClosure(.ended,target) }}

使用自定義插件方法

// MARK: - 自定義的網絡提示請求插件let myNetworkPlugin = MyNetworkActivityPlugin { (state,target) in if state == .began {  //  SwiftSpinner.show("Connecting...")    let api = target as! NetAPIManager  if api.show {   print("我可以在這里寫加載提示")  }    if !api.touch {   print("我可以在這里寫禁止用戶操作,等待請求結束")  }  print("我開始請求/(api.touch)")    UIApplication.shared.isNetworkActivityIndicatorVisible = true } else {  //  SwiftSpinner.show("request finish...")  //  SwiftSpinner.hide()  print("我結束請求")  UIApplication.shared.isNetworkActivityIndicatorVisible = false   }}

自簽名證書

在16年的WWDC中,Apple已表示將從2017年1月1日起,**所有新提交的App必須強制性應用HTTPS協議來進行網絡請求。**默認情況下非HTTPS的網絡訪問是禁止的并且不能再通過簡單粗暴的向Info.plist中添加NSAllowsArbitraryLoads 設置繞過ATS(App Transport Security)的限制(否則須在應用審核時進行說明并很可能會被拒)。所以還未進行相應配置的公司需要盡快將升級為HTTPS的事項提上進程了。本文將簡述HTTPS及配置數字證書的原理并以配置實例和出現的問題進行說明,希望能對你提供幫助。(比心~)

iOS,Moya,網絡請求

HTTPS: 簡單來說,HTTPS就是HTTP協議上再加一層加密處理的SSL協議,即HTTP安全版。相比HTTP,HTTPS可以保證內容在傳輸過程中不會被第三方查看、及時發現被第三方篡改的傳輸內容、防止身份冒充,從而更有效的保證網絡數據的安全。 HTTPS客戶端與服務器交互過程: 1、 客戶端第一次請求時,服務器會返回一個包含公鑰的數字證書給客戶端; 2、 客戶端生成對稱加密密鑰并用其得到的公鑰對其加密后返回給服務器; 3、 服務器使用自己私鑰對收到的加密數據解密,得到對稱加密密鑰并保存; 4、 然后雙方通過對稱加密的數據進行傳輸。

iOS,Moya,網絡請求

數字證書: 在HTTPS客戶端與服務器第一次交互時,服務端返回給客戶端的數字證書是讓客戶端驗證這個數字證書是不是服務端的,證書所有者是不是該服務器,確保數據由正確的服務端發來,沒有被第三方篡改。數字證書可以保證數字證書里的公鑰確實是這個證書的所有者(Subject)的,或者證書可以用來確認對方身份。證書由公鑰、證書主題(Subject)、數字簽名(digital signature)等內容組成。其中數字簽名就是證書的防偽標簽,目前使用最廣泛的SHA-RSA加密。 證書一般分為兩種:

  1. 一種是向權威認證機構購買的證書,服務端使用該種證書時,因為蘋果系統內置了其受信任的簽名根證書,所以客戶端不需額外的配置。為了證書安全,在證書發布機構公布證書時,證書的指紋算法都會加密后再和證書放到一起公布以防止他人偽造數字證書。而證書機構使用自己的私鑰對其指紋算法加密,可以用內置在操作系統里的機構簽名根證書來解密,以此保證證書的安全。
  2. 另一種是自己制作的證書,即自簽名證書。好處是不需要花錢購2買,但使用這種證書是不會受信任的,所以 需要我們在代碼中將該證書配置為信任證書.

自簽名證書具體實現: 我們在使用自簽名證書來實現HTTPS請求時,因為不像機構頒發的證書一樣其簽名根證書在系統中已經內置了,所以我們需要在App中內置自己服務器的簽名根證書來驗證數字證書。首先將服務端生成的.cer格式的根證書添加到項目中,注意在添加證書要一定要記得勾選要添加的targets。

 這里有個地方要注意 :蘋果的ATS要求服務端必須支持TLS 1.2或以上版本;必須使用支持前向保密的密碼;證書必須使用SHA-256或者更好的簽名hash算法來簽名,如果證書無效,則會導致連接失敗。由于我在生成的根證書時簽名hash算法低于其要求,在配置完請求時一直報 NSURLErrorServerCertificateUntrusted = -1202錯誤,希望大家可以注意到這一點。

那么如何在Moya中使用自簽名的證書來實現HTTPS網絡請求呢,請期待下回我專門分享......需要自定義一個Manager管理

綜合使用的方法如下

定義一個公用的Moya請求服務對象

let MyAPIProvider = MoyaProvider<NetAPIManager>(endpointClosure: myEndpointClosure,requestClosure: requestClosure, plugins: [NetworkLoggerPlugin(verbose: true, responseDataFormatter: JSONResponseDataFormatter),myNetworkPlugin])// MARK: -創建一個Moya請求func sendRequest(_ postDict: Dictionary<String, Any>? = nil,     success:@escaping (Dictionary<String, Any>)->(),     failure:@escaping (MoyaError)->()) -> Cancellable? {  let request = MyAPIProvider.request(.Show) { result in   switch result {  case let .success(moyaResponse):         do {    let any = try moyaResponse.mapJSON()    let data = moyaResponse.data    let statusCode = moyaResponse.statusCode    MyLog("/(data) --- /(statusCode) ----- /(any)")        success(["":""])       } catch {       }           case let .failure(error):      print(error)   failure(error)  } }  return request}

取消所有的Moya請求

// MARK: -取消所有請求func cancelAllRequest() {// MyAPIProvider.manager.session.invalidateAndCancel() //取消所有請求 MyAPIProvider.manager.session.getTasksWithCompletionHandler { dataTasks, uploadTasks, downloadTasks in  dataTasks.forEach { $0.cancel() }  uploadTasks.forEach { $0.cancel() }  downloadTasks.forEach { $0.cancel() } }  //let sessionManager = Alamofire.SessionManager.default //sessionManager.session.getTasksWithCompletionHandler { dataTasks, uploadTasks, downloadTasks in // dataTasks.forEach { $0.cancel() } // uploadTasks.forEach { $0.cancel() } // downloadTasks.forEach { $0.cancel() } //}}

 完畢,待續更高級的用法...

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到IOS開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品h片在线播放| 欧美国产精品日韩| 久久大大胆人体| 日本在线观看天堂男亚洲| 欧美第一淫aaasss性| 九九精品视频在线观看| 在线观看欧美视频| 91国内精品久久| 成人h视频在线观看播放| 欧美日韩国产一区在线| 成人久久一区二区三区| 欧美国产日韩xxxxx| 成人免费福利视频| 亚洲男人的天堂在线播放| 日韩精品视频在线观看免费| 97精品国产97久久久久久免费| 亚洲国产成人av在线| 色午夜这里只有精品| 91高清视频免费观看| 亚洲伦理中文字幕| 日本午夜在线亚洲.国产| 国产欧美精品va在线观看| 国产精品女视频| 456亚洲影院| xxxxx91麻豆| 海角国产乱辈乱精品视频| 国产97色在线| 精品人伦一区二区三区蜜桃网站| 97在线观看视频国产| 亚洲精品美女在线| 欧美大片在线看免费观看| 国产成人精品电影| xvideos国产精品| 亚洲国产婷婷香蕉久久久久久| 日韩精品视频在线播放| 日本在线精品视频| 伊人久久久久久久久久| 久久久影视精品| www.久久色.com| 国产精品久久久久免费a∨大胸| 日韩av成人在线| 欧美激情中文字幕在线| 久久久在线观看| 爱福利视频一区| 欧美区二区三区| 亚洲国产婷婷香蕉久久久久久| 精品福利一区二区| 动漫精品一区二区| 国产精品久久久久久久久久ktv| 91精品久久久久久久久| 欧美三级xxx| 欧美一级免费视频| 国产不卡在线观看| 狠狠久久五月精品中文字幕| 日韩在线激情视频| 色诱女教师一区二区三区| 久久精品视频在线| 亚洲香蕉av在线一区二区三区| 亚洲乱码一区av黑人高潮| 日韩av综合中文字幕| 91在线中文字幕| 欧美大成色www永久网站婷| 国产欧美婷婷中文| 久久综合亚洲社区| 欧美在线视频导航| 亚洲精品720p| 久久久久久久av| 国产亚洲福利一区| 国产成人久久久精品一区| 久久精品久久精品亚洲人| 庆余年2免费日韩剧观看大牛| 亚洲白虎美女被爆操| 视频在线观看一区二区| 色妞欧美日韩在线| 精品精品国产国产自在线| 中文字幕亚洲精品| 亚洲人成电影在线观看天堂色| 亚洲国产欧美一区二区丝袜黑人| 亚洲三级免费看| 久久五月天色综合| 欧美日韩免费区域视频在线观看| 欧美午夜激情视频| 国产精品久久久久久久久久三级| 国产色婷婷国产综合在线理论片a| 精品久久在线播放| 69影院欧美专区视频| 精品久久久久国产| 日韩在线视频导航| 日韩视频免费在线| 欧美国产精品人人做人人爱| 欧美黑人xxxx| 亚洲精品ady| 亚洲欧洲视频在线| 97精品视频在线观看| 亚洲人成在线免费观看| 欧美成年人视频| 久久九九全国免费精品观看| 91免费国产网站| www.日韩视频| 亚洲自拍偷拍福利| 狠狠综合久久av一区二区小说| 亚洲精品国产精品乱码不99按摩| 久久亚洲国产精品成人av秋霞| 久久久爽爽爽美女图片| 亚洲精品国偷自产在线99热| 免费97视频在线精品国自产拍| 国产在线高清精品| 成人欧美在线观看| 欧美性猛交xxxx富婆| 97在线看免费观看视频在线观看| 亚洲最大成人网色| 欧美激情国产高清| 成人性生交大片免费看视频直播| 青青草原一区二区| www.久久久久久.com| 国产精品高清免费在线观看| 91免费精品国偷自产在线| 欧美夫妻性视频| 91成人天堂久久成人| 国产欧美久久一区二区| 欧美专区在线播放| 亚洲а∨天堂久久精品9966| 亚洲一区二区久久久久久久| 91精品综合久久久久久五月天| 亚洲三级免费看| 精品久久香蕉国产线看观看亚洲| 久久久av一区| 日韩在线欧美在线国产在线| 亚洲精品视频二区| 亚洲一区二区三区在线免费观看| 欧美在线一级va免费观看| 91精品国产综合久久香蕉| 国模精品视频一区二区| 国产精品福利网站| 色偷偷偷综合中文字幕;dd| 中文精品99久久国产香蕉| 亚洲欧美精品suv| 国产成人精品免费视频| 精品美女永久免费视频| 亚洲美女动态图120秒| 97国产精品人人爽人人做| 久久成人免费视频| 欧美性猛xxx| 亚洲最大成人免费视频| 中文字幕在线日韩| 欧美日韩国产va另类| 欧美在线视频导航| 国产精品久久久久秋霞鲁丝| 亚洲精品v天堂中文字幕| 国产精品白丝jk喷水视频一区| 国产精品国内视频| 久久久精品免费视频| 国产午夜精品美女视频明星a级| 97在线视频免费| 国产成人欧美在线观看| 国产精品视频一区二区三区四| 91av在线免费观看| 久久精品国产综合| 色综合男人天堂| 精品国产一区二区三区久久久狼| 精品国产乱码久久久久久天美| 国产成人激情小视频| 81精品国产乱码久久久久久| 亚洲aⅴ男人的天堂在线观看|