如何在iOS 中使用Moya網(wǎng)絡(luò)請(qǐng)求?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。
新樂(lè)ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!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í)間
自定義插件
自簽名證書
注意:以下所出現(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++hyAiLFuFL4cv1Z8WH5DgB2GnvFXMh6gm53Tr13vqqrEYtcdXfkNsMwKB+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ù)是我自己寫,用來(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("我可以在這里寫加載提示") } if !api.touch { print("我可以在這里寫禁止用戶操作,等待請(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 } }
自簽名證書
在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í)例和出現(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ù)字證書給客戶端; 2、 客戶端生成對(duì)稱加密密鑰并用其得到的公鑰對(duì)其加密后返回給服務(wù)器; 3、 服務(wù)器使用自己私鑰對(duì)收到的加密數(shù)據(jù)解密,得到對(duì)稱加密密鑰并保存; 4、 然后雙方通過(guò)對(duì)稱加密的數(shù)據(jù)進(jìn)行傳輸。
數(shù)字證書: 在HTTPS客戶端與服務(wù)器第一次交互時(shí),服務(wù)端返回給客戶端的數(shù)字證書是讓客戶端驗(yàn)證這個(gè)數(shù)字證書是不是服務(wù)端的,證書所有者是不是該服務(wù)器,確保數(shù)據(jù)由正確的服務(wù)端發(fā)來(lái),沒(méi)有被第三方篡改。數(shù)字證書可以保證數(shù)字證書里的公鑰確實(shí)是這個(gè)證書的所有者(Subject)的,或者證書可以用來(lái)確認(rèn)對(duì)方身份。證書由公鑰、證書主題(Subject)、數(shù)字簽名(digital signature)等內(nèi)容組成。其中數(shù)字簽名就是證書的防偽標(biāo)簽,目前使用最廣泛的SHA-RSA加密。 證書一般分為兩種:
一種是向權(quán)威認(rèn)證機(jī)構(gòu)購(gòu)買的證書,服務(wù)端使用該種證書時(shí),因?yàn)樘O果系統(tǒng)內(nèi)置了其受信任的簽名根證書,所以客戶端不需額外的配置。為了證書安全,在證書發(fā)布機(jī)構(gòu)公布證書時(shí),證書的指紋算法都會(huì)加密后再和證書放到一起公布以防止他人偽造數(shù)字證書。而證書機(jī)構(gòu)使用自己的私鑰對(duì)其指紋算法加密,可以用內(nèi)置在操作系統(tǒng)里的機(jī)構(gòu)簽名根證書來(lái)解密,以此保證證書的安全。
另一種是自己制作的證書,即自簽名證書。好處是不需要花錢購(gòu)2買,但使用這種證書是不會(huì)受信任的,所以需要我們?cè)诖a中將該證書配置為信任證書.
自簽名證書具體實(shí)現(xiàn): 我們?cè)谑褂米院灻C書來(lái)實(shí)現(xiàn)HTTPS請(qǐng)求時(shí),因?yàn)椴幌駲C(jī)構(gòu)頒發(fā)的證書一樣其簽名根證書在系統(tǒng)中已經(jīng)內(nèi)置了,所以我們需要在App中內(nèi)置自己服務(wù)器的簽名根證書來(lái)驗(yàn)證數(shù)字證書。首先將服務(wù)端生成的.cer格式的根證書添加到項(xiàng)目中,注意在添加證書要一定要記得勾選要添加的targets。
這里有個(gè)地方要注意:蘋果的ATS要求服務(wù)端必須支持TLS 1.2或以上版本;必須使用支持前向保密的密碼;證書必須使用SHA-256或者更好的簽名hash算法來(lái)簽名,如果證書無(wú)效,則會(huì)導(dǎo)致連接失敗。由于我在生成的根證書時(shí)簽名hash算法低于其要求,在配置完請(qǐng)求時(shí)一直報(bào)NSURLErrorServerCertificateUntrusted= -1202錯(cuò)誤,希望大家可以注意到這一點(diǎn)。
那么如何在Moya中使用自簽名的證書來(lái)實(shí)現(xiàn)HTTPS網(wǎng)絡(luò)請(qǐng)求呢,請(qǐng)期待下回我專門分享......需要自定義一個(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() } //} }
關(guān)于如何在iOS 中使用Moya網(wǎng)絡(luò)請(qǐng)求問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站m.rwnh.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
本文題目:如何在iOS中使用Moya網(wǎng)絡(luò)請(qǐng)求-創(chuàng)新互聯(lián)
本文鏈接:http://m.rwnh.cn/article30/ddooso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營(yíng)銷型網(wǎng)站建設(shè)、標(biāo)簽優(yōu)化、移動(dòng)網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作、域名注冊(cè)、軟件開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容