欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

iOS 使用Moya網(wǎng)絡(luò)請(qǐng)求的實(shí)現(xiàn)方法

 更新時(shí)間:2018年07月24日 13:41:09   作者:海神Lewis  
這篇文章主要介紹了iOS 使用Moya網(wǎng)絡(luò)請(qǐng)求的實(shí)現(xiàn)方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

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

Moya簡(jiǎn)介

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

Moya有幾個(gè)比較好的特性:

  • 編譯時(shí)檢查正確的API端點(diǎn)訪問(wèn).
  • 使你定義不同端點(diǎn)枚舉值對(duì)應(yīng)相應(yīng)的用途更加明晰.
  • 提高測(cè)試地位從而使單元測(cè)試更加容易.

Swift我們用 Alamofire 來(lái)做網(wǎng)絡(luò)庫(kù).而 Moya 在Alamofire的基礎(chǔ)上又封裝了一層,如下流程圖說(shuō)明 Moya 的簡(jiǎn)單工作流程圖:

Moya的官方下載地址點(diǎn)我強(qiáng)大的Moya ,有具體的使用方法在demo里面有說(shuō)明。

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

  • 設(shè)置請(qǐng)求頭部信息 設(shè)
  • 置超時(shí)時(shí)間
  • 自定義插件
  • 自簽名證書(shū)

注意:以下所出現(xiàn)的 NetAPIManager 跟官網(wǎng)上demo的** GitHub**是一樣類型的文件,都是這個(gè)enum實(shí)現(xiàn)一個(gè)協(xié)議TargetType,點(diǎn)進(jìn)去可以看到TargetType定義了我們發(fā)送一個(gè)網(wǎng)絡(luò)請(qǐng)求所需要的東西,什么baseURL,parameter,method等一些計(jì)算性屬性,我們要做的就是去實(shí)現(xiàn)這些東西,當(dāng)然有帶默認(rèn)值的我們可以不去實(shí)現(xiàn),但是設(shè)置頭部信息跟超時(shí)時(shí)間就要修改這些系統(tǒng)默認(rèn)設(shè)置了。

為了看得更加清楚,貼上 NetAPIManager 文件的內(nèi)容

//
// NetAPIManager.swift
// NN110
//
// Created by 陳亦海 on 2017/5/12.
// Copyright © 2017年 陳亦海. All rights reserved.
//

import Foundation
import Moya


enum 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 {//服務(wù)器地址
  
  switch self {
  case .request( _, _, _):
   return URL(string: "https://www.pmphmall.com")!
  default:
   return URL(string: "https://httpbin.org")!
  }
  
  
 }
 
 var path: String {//具體某個(gè)方法的路徑
  switch self {
  case .Show:
   return ""
  case .upload(_):
   return ""
  case .request(_, _, _):
   return "/app/json.do"
  case .download:
   return ""
  }
 }
 
 var method: Moya.Method {//請(qǐng)求的方法 get或者post之類的
  switch self {
  case .Show:
   return .get
  case .request(_, _, _):
   return .post
  default:
   return .post
  }
 }
 
 var parameters: [String: Any]? {//請(qǐng)求的get post給服務(wù)器的參數(shù)
  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 { //編碼轉(zhuǎn)義
  return "{}".data(using: String.Encoding.utf8)!
 }
 
 var task: Task { //一個(gè)請(qǐng)求任務(wù)事件
  
  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
  }
  
 }
 //以下兩個(gè)參數(shù)是我自己寫(xiě),用來(lái)控制網(wǎng)絡(luò)加載的時(shí)候是否允許操作,跟是否要顯示加載提示,這兩個(gè)參數(shù)在自定義插件的時(shí)候會(huì)用到
 var touch: Bool { //是否可以操作
  
  switch self {
  case .request(let isTouch, _, _):
   return isTouch
  default:
   return false
  }
  
 }
 
 var show: Bool { //是否顯示轉(zhuǎn)圈提示
  
  switch self {
  case .request( _, _,let isShow):
   return isShow
  default:
   return false
  }
  
 }
 
 
}

如何設(shè)置Moya請(qǐng)求頭部信息

頭部信息的設(shè)置在開(kāi)發(fā)過(guò)程中很重要,如服務(wù)器生成的token,用戶唯一標(biāo)識(shí)等 我們直接上代碼,不說(shuō)那么多理論的東西,哈哈

// MARK: - 設(shè)置請(qǐng)求頭部信息
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
 )

 //在這里設(shè)置你的HTTP頭部信息
 return endpoint.adding(newHTTPHeaderFields: [
  "Content-Type" : "application/x-www-form-urlencoded",
  "ECP-COOKIE" : ""
  ])
 
}

如何設(shè)置請(qǐng)求超時(shí)時(shí)間

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

自定義插件

自定義插件必須 PluginType 協(xié)議的兩個(gè)方法willSend與didReceive

//
// MyNetworkActivityPlugin.swift
// NN110
//
// Created by 陳亦海 on 2017/5/10.
// Copyright © 2017年 CocoaPods. All rights reserved.
//

import Foundation
import Result
import 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: - 自定義的網(wǎng)絡(luò)提示請(qǐng)求插件
let myNetworkPlugin = MyNetworkActivityPlugin { (state,target) in
 if state == .began {
  //  SwiftSpinner.show("Connecting...")
  
  let api = target as! NetAPIManager
  if api.show {
   print("我可以在這里寫(xiě)加載提示")
  }
  
  if !api.touch {
   print("我可以在這里寫(xiě)禁止用戶操作,等待請(qǐng)求結(jié)束")
  }

  print("我開(kāi)始請(qǐng)求\(api.touch)")
  
  UIApplication.shared.isNetworkActivityIndicatorVisible = true
 } else {
  //  SwiftSpinner.show("request finish...")
  //  SwiftSpinner.hide()
  print("我結(jié)束請(qǐng)求")
  UIApplication.shared.isNetworkActivityIndicatorVisible = false
  
 }
}

自簽名證書(shū)

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

HTTPS: 簡(jiǎn)單來(lái)說(shuō),HTTPS就是HTTP協(xié)議上再加一層加密處理的SSL協(xié)議,即HTTP安全版。相比HTTP,HTTPS可以保證內(nèi)容在傳輸過(guò)程中不會(huì)被第三方查看、及時(shí)發(fā)現(xiàn)被第三方篡改的傳輸內(nèi)容、防止身份冒充,從而更有效的保證網(wǎng)絡(luò)數(shù)據(jù)的安全。 HTTPS客戶端與服務(wù)器交互過(guò)程: 1、 客戶端第一次請(qǐng)求時(shí),服務(wù)器會(huì)返回一個(gè)包含公鑰的數(shù)字證書(shū)給客戶端; 2、 客戶端生成對(duì)稱加密密鑰并用其得到的公鑰對(duì)其加密后返回給服務(wù)器; 3、 服務(wù)器使用自己私鑰對(duì)收到的加密數(shù)據(jù)解密,得到對(duì)稱加密密鑰并保存; 4、 然后雙方通過(guò)對(duì)稱加密的數(shù)據(jù)進(jìn)行傳輸。

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

  1. 一種是向權(quán)威認(rèn)證機(jī)構(gòu)購(gòu)買(mǎi)的證書(shū),服務(wù)端使用該種證書(shū)時(shí),因?yàn)樘O(píng)果系統(tǒng)內(nèi)置了其受信任的簽名根證書(shū),所以客戶端不需額外的配置。為了證書(shū)安全,在證書(shū)發(fā)布機(jī)構(gòu)公布證書(shū)時(shí),證書(shū)的指紋算法都會(huì)加密后再和證書(shū)放到一起公布以防止他人偽造數(shù)字證書(shū)。而證書(shū)機(jī)構(gòu)使用自己的私鑰對(duì)其指紋算法加密,可以用內(nèi)置在操作系統(tǒng)里的機(jī)構(gòu)簽名根證書(shū)來(lái)解密,以此保證證書(shū)的安全。
  2. 另一種是自己制作的證書(shū),即自簽名證書(shū)。好處是不需要花錢(qián)購(gòu)2買(mǎi),但使用這種證書(shū)是不會(huì)受信任的,所以 需要我們?cè)诖a中將該證書(shū)配置為信任證書(shū).

自簽名證書(shū)具體實(shí)現(xiàn): 我們?cè)谑褂米院灻C書(shū)來(lái)實(shí)現(xiàn)HTTPS請(qǐng)求時(shí),因?yàn)椴幌駲C(jī)構(gòu)頒發(fā)的證書(shū)一樣其簽名根證書(shū)在系統(tǒng)中已經(jīng)內(nèi)置了,所以我們需要在App中內(nèi)置自己服務(wù)器的簽名根證書(shū)來(lái)驗(yàn)證數(shù)字證書(shū)。首先將服務(wù)端生成的.cer格式的根證書(shū)添加到項(xiàng)目中,注意在添加證書(shū)要一定要記得勾選要添加的targets。

 這里有個(gè)地方要注意 :蘋(píng)果的ATS要求服務(wù)端必須支持TLS 1.2或以上版本;必須使用支持前向保密的密碼;證書(shū)必須使用SHA-256或者更好的簽名hash算法來(lái)簽名,如果證書(shū)無(wú)效,則會(huì)導(dǎo)致連接失敗。由于我在生成的根證書(shū)時(shí)簽名hash算法低于其要求,在配置完請(qǐng)求時(shí)一直報(bào) NSURLErrorServerCertificateUntrusted = -1202錯(cuò)誤,希望大家可以注意到這一點(diǎn)。

那么如何在Moya中使用自簽名的證書(shū)來(lái)實(shí)現(xiàn)HTTPS網(wǎng)絡(luò)請(qǐng)求呢,請(qǐng)期待下回我專門(mén)分享......需要自定義一個(gè)Manager管理

綜合使用的方法如下

定義一個(gè)公用的Moya請(qǐng)求服務(wù)對(duì)象

let MyAPIProvider = MoyaProvider<NetAPIManager>(endpointClosure: myEndpointClosure,requestClosure: requestClosure, plugins: [NetworkLoggerPlugin(verbose: true, responseDataFormatter: JSONResponseDataFormatter),myNetworkPlugin])

// MARK: -創(chuàng)建一個(gè)Moya請(qǐng)求
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請(qǐng)求

// MARK: -取消所有請(qǐng)求
func cancelAllRequest() {
// MyAPIProvider.manager.session.invalidateAndCancel() //取消所有請(qǐng)求
 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() }
 //}

}

 完畢,待續(xù)更高級(jí)的用法...

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • iOS json解析出錯(cuò)的幾種情況總結(jié)

    iOS json解析出錯(cuò)的幾種情況總結(jié)

    這篇文章主要介紹了iOS json解析出錯(cuò)的幾種情況總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • iOS輸出手機(jī)系統(tǒng)版本號(hào)

    iOS輸出手機(jī)系統(tǒng)版本號(hào)

    這篇文章主要介紹了iOS輸出手機(jī)系統(tǒng)版本號(hào)的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • iOS獲取到用戶當(dāng)前位置

    iOS獲取到用戶當(dāng)前位置

    這篇文章主要為大家詳細(xì)介紹了iOS獲取到用戶當(dāng)前位置,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • h5 ios輸入框和鍵盤(pán)的兼容性優(yōu)化指南

    h5 ios輸入框和鍵盤(pán)的兼容性優(yōu)化指南

    這篇文章主要給大家介紹了關(guān)于h5 ios輸入框和鍵盤(pán)的兼容性優(yōu)化的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • IOS CocoaPods詳細(xì)使用方法

    IOS CocoaPods詳細(xì)使用方法

    自從有了CocoaPods以后,這些繁雜的工作就不再需要我們親力親為了,只需要我們做好少量的配置工作,CocoaPods會(huì)為我們做好一切
    2016-09-09
  • iOS用兩行代碼完美解決數(shù)據(jù)持久化

    iOS用兩行代碼完美解決數(shù)據(jù)持久化

    所謂的持久化,就是將數(shù)據(jù)保存到硬盤(pán)中,使得在應(yīng)用程序或機(jī)器重啟后可以繼續(xù)訪問(wèn)之前保存的數(shù)據(jù)。在iOS開(kāi)發(fā)中,有很多數(shù)據(jù)持久化的方案,接下來(lái)我將嘗試著介紹一種巧妙的方法,用兩行代碼解決這個(gè)問(wèn)題,一起來(lái)學(xué)習(xí)下。
    2016-08-08
  • Objective-C的NSOperation多線程類基本使用指南

    Objective-C的NSOperation多線程類基本使用指南

    這篇文章主要介紹了Objective-C的NSOperation多線程類基本使用指南,談到了Operations的執(zhí)行順序和并發(fā)量等設(shè)置操作,需要的朋友可以參考下
    2016-02-02
  • IOS 粒子系統(tǒng) (CAEmitterLayer)實(shí)例詳解

    IOS 粒子系統(tǒng) (CAEmitterLayer)實(shí)例詳解

    這篇文章主要介紹了IOS 粒子系統(tǒng) (CAEmitterLayer)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2016-09-09
  • 詳解Swift model 解析的兩種方法

    詳解Swift model 解析的兩種方法

    這篇文章主要介紹了詳解Swift model 解析的兩種方法的相關(guān)資料,希望通過(guò)本文大家能夠掌握這里的兩種實(shí)現(xiàn)方法,需要的朋友可以參考下
    2017-09-09
  • 兩行IOS代碼實(shí)現(xiàn)輪播圖

    兩行IOS代碼實(shí)現(xiàn)輪播圖

    這篇文章主要為大家詳細(xì)介紹了兩行IOS代碼實(shí)現(xiàn)輪播圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12

最新評(píng)論