日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Swift -《从0到1 - 5》:封装网络请求工具类(Alamofire + Moya + SwiftyJSON)和链式封装

發布時間:2023/12/14 javascript 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Swift -《从0到1 - 5》:封装网络请求工具类(Alamofire + Moya + SwiftyJSON)和链式封装 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在OC開發中網絡請求通常都使用AFNetworking,在Swift雖然也可以使用,但是推薦使用Swift語法實現的網絡請求庫Alamofire。
通常大家會對請求庫進行一次或多次封裝,方便維護,我也不另外。剛開始參考了很多文章,最終決定使用Alamofire + Moya + SwiftyJSON 實現網絡請求工具類和API管理類
本篇末尾介紹另一種通過鏈式封裝Alamofire的實現方式

GitHub Demo 地址

Alamofire是一個使用Swift開發的網絡請求庫,其開發團隊是AFNetworking的原團隊。它語法簡潔,采用鏈式編程的思想,使用起來是相當的舒服。本質是基于NSURLSession進行封裝。
Moya是對Alamofire的再次封裝。
SwiftyJSON是數據解析

github地址:

Alamofire
Moya
SwiftyJSON

pods引用:

pod 'Alamofire', '4.9.1' pod 'Moya', '13.0.1' pod 'SwiftyJSON', '5.0.1'

首先需要創建3個Swift文件:
一個是網絡請求工具類:JhHttpTool.swift
一個Moya配置文件:MoyaConfig.swift
一個API管理文件:APIManager.swift

接下來直接上代碼

JhHttpTool

// // JhHttpTool.swift // JhSwiftDemo // // Created by Jh on 2021/12/28. // 網絡請求工具類:Alamofire + Moya + SwiftyJSON import Foundation import Moya import SwiftyJSONpublic class JhHttpTool {/// 使用Moya的請求封裝////// - Parameters:/// - target: 請求API,TargetType里的枚舉值/// - success: 成功的回調/// - error: 連接服務器成功但是數據獲取失敗/// - failure: 連接服務器失敗public class func request<T: TargetType>(_ target: T, success: @escaping((Any) -> Void), failure: ((Int?, String) ->Void)?) {let provider = MoyaProvider<T>(plugins: [RequestHandlingPlugin(),// networkLoggerPlugin])provider.request(target) { result inswitch result {case let .success(response):// let json = try? response.mapString()// let responseObject = try? response.mapJSON()// JhLog( responseObject ?? "" );do {// *********** 這里可以統一處理錯誤碼,彈出提示信息 ***********let resObject = try? response.mapJSON()let responseObject = JSON(resObject ?? "")let code = responseObject["code"].intValuelet msg = String(describing: responseObject["msg"])switch (code) {case 200 :// 數據返回正確success(responseObject)case 401:// 請重新登錄failure!(code,msg)alertLogin(msg)default:// 其他錯誤failureHandle(failure: failure, stateCode: code, message: msg)}}case let .failure(error):let statusCode = error.response?.statusCode ?? 1000let message = "請求出錯,錯誤碼:" + String(statusCode)JhAllLog(message)failureHandle(failure: failure, stateCode: statusCode, message: error.errorDescription ?? message)}}// 錯誤處理 - 彈出錯誤信息func failureHandle(failure: ((Int?, String) ->Void)? , stateCode: Int?, message: String) {Alert.show(type: .error, text: message)failure?(stateCode ,message)}// 登錄彈窗 - 彈出是否需要登錄的窗口func alertLogin(_ title: String?) {// TODO: 跳轉到登錄頁的操作:}}// MARK: - 打印日志// static let networkLoggerPlugin = NetworkLoggerPlugin(verbose: true, cURL: true, requestDataFormatter: { data -> String in// return String(data: data, encoding: .utf8) ?? ""// }) { data -> (Data) in// do {// let dataAsJSON = try JSONSerialization.jsonObject(with: data)// let prettyData = try JSONSerialization.data(withJSONObject: dataAsJSON, options: .prettyPrinted)// return prettyData// } catch {// return data// }// } }

MoyaConfig

// // JhHttpRequest.swift // JhSwiftDemo // // Created by Jh on 2022/2/10. // Moya 配置文件 import Foundation import Moya// MARK: - 1、2需要根據項目進行更改 /**1、配置TargetType協議可以一次性處理的參數- Todo: 根據自己的需要更改,不能統一處理的移除下面的代碼,并在APIManager中實現**/ public extension TargetType { // // 放到APIManager中了 // var baseURL: URL { // return URL(string: "http://xxxxx")! // }var headers: [String : String]? {return nil}var sampleData: Data {return "{}".data(using: String.Encoding.utf8)!} }/**2、公共參數- Todo: 配置公共參數,例如所有接口都需要傳token,version,time等,就可以在這里統一處理- Note: 接口傳參時可以覆蓋公共參數。下面的代碼只需要更改 【private var commonParams: [String: Any]?】**/ extension URLRequest {//TODO:處理公共參數private var commonParams: [String: Any]? {//所有接口的公共參數添加在這里:let header = ["Content-Type": "application/x-www-form-urlencoded","systemType": "iOS","version": "1.0.0","token": getToken(),]return header// 如果不需要傳空// return nil}private func getToken() -> String {return "1"} }//下面的代碼不更改 class RequestHandlingPlugin: PluginType {public func prepare(_ request: URLRequest, target: TargetType) -> URLRequest {var mutateableRequest = requestreturn mutateableRequest.appendCommonParams();} }//下面的代碼不更改 extension URLRequest {mutating func appendCommonParams() -> URLRequest {let request = try? encoded(parameters: commonParams, parameterEncoding: URLEncoding(destination: .queryString))assert(request != nil, "append common params failed, please check common params value")return request!}func encoded(parameters: [String: Any]?, parameterEncoding: ParameterEncoding) throws -> URLRequest {do {return try parameterEncoding.encode(self, with: parameters)} catch {throw MoyaError.parameterEncoding(error)}} }

APIManager

// // APIManager.swift // JhSwiftDemo // // Created by Jh on 2021/12/28. // 接口管理 import Foundation import Moya/// 基礎域名 let kBaseURL = "https://www.fastmock.site/mock/1010b262a743f0b06c565c7a31ee9739/root"enum API {case login(params:Dictionary<String,Any>)// 獲取分頁數據case getPageList(_ page:Int)// 獲取分組分頁數據case getGroupPageList(page:Int)// 獲取聯系人數據case getContact// 獲取微信運行排行榜case getWxMotionTops// 獲取固定數據case getSimpleArrDic///其他接口...case other1(p1: String, p2: Int, p3: String, p4: String)case other2}// MARK: - 補全【MoyaConfig 3:配置TargetType協議可以一次性處理的參數】中沒有處理的參數 extension API: TargetType {//0. 基礎域名,整個項目只用一個,可以寫在MoyaConfig中var baseURL: URL {switch self {case .login:return URL(string:kBaseURL)!default:return URL(string:kBaseURL)!}}//1. 每個接口的相對路徑//請求時的絕對路徑是 baseURL + pathvar path: String {switch self {case .login:return "/login"case .getPageList:return "/mock/pages"case .getGroupPageList:return "/mock/groupPages"case .getContact:return "/mock/contacts"case .getWxMotionTops:return "/mock/wxMotionTops"case .getSimpleArrDic:return "/getSimpleArrDic"case let .other1(p1, p2, _, _):return "/list?id=\(p1)&page=\(p2)"case .other2:return ""}}//2. 每個接口要使用的請求方式var method: Moya.Method {switch self {case.getPageList,.getGroupPageList,.other1,.other2:return .getcase.getContact,.getWxMotionTops,.getSimpleArrDic,.login:return .post}}//3. Task是一個枚舉值,根據后臺需要的數據,選擇不同的http task。var task: Task {var params: [String: Any] = [:]switch self {case .login:return .requestPlaincase let .getPageList(page):params["page"] = pageparams["limit"] = 15params["maxCount"] = 100case let .other1(_, _, p3, p4):params["p3"] = p3params["p4"] = p4default://不需要傳參數的接口走這里return .requestPlain}return .requestParameters(parameters: params, encoding: URLEncoding.default)}}

使用

// Alamofire + Moya + SwiftyJSON JhHttpTool.request(API.getPageList(1)) {[weak self] json inself?.mTextView.text = String(describing: JSON(json))JhAllLog(JSON(json)) } failure: {code, msg inJhLog("code : \(code!)")JhLog("message : \(msg)") }

鏈式封裝Alamofire

鏈式封裝,API可以直接通過一個文件進行管理,里面只放url路徑

// // JhRequest.swift // JhSwiftDemo // // Created by Jh on 2021/12/28. // 鏈式網絡請求工具類:Alamofire + SwiftyJSON import Foundation import Alamofire import SwiftyJSONenum HttpRequestType {case getcase post }public let JhRequest = NetworkKit.shared// Networkkit屬性設置 public class NetworkKit {public static let shared = NetworkKit()typealias SuccessHandlerType = ((JSON) -> Void)typealias FailureHandlerType = ((Int?, String) ->Void)private var requestType: HttpRequestType = .post//請求類型private var url: String? // URLprivate var params: [String: Any]? // 參數private var success: SuccessHandlerType? // 成功的回調private var failure: FailureHandlerType? // 失敗的回調private var httpRequest: Request?}// NetworkKit屬性的設置 extension NetworkKit{/// 設置urlfunc url(_ url: String?) -> Self {self.url = urlreturn self}/// 設置post/get 默認postfunc requestType(_ type:HttpRequestType) -> Self {self.requestType = typereturn self}/// 設置參數func params(_ params: [String: Any]?) -> Self {self.params = paramsreturn self}/// 成功的回調func success(_ handler: @escaping SuccessHandlerType) -> Self {self.success = handlerreturn self}///失敗的回調func failure(handler: @escaping FailureHandlerType) -> Self {self.failure = handlerreturn self}}// NetworkKit請求相關 extension NetworkKit{/// 發起請求 設置好相關參數后再調用func request() -> Void {var dataRequest: DataRequest? // alamofire請求后的返回值// 發起請求if let URLString = url {ProgressHUD.show()let method = requestType == .get ? HTTPMethod.get : HTTPMethod.postdataRequest = Alamofire.request(URLString, method: method, parameters: params)httpRequest = dataRequest}dataRequest?.responseJSON {(response) inProgressHUD.hide()switch response.result {case let .success(response):do {// *********** 這里可以統一處理錯誤碼,彈出提示信息 ***********let responseObject = JSON(response)let code = responseObject["code"].intValuelet msg = String(describing: responseObject["msg"])switch (code) {case 200 :// 數據返回正確self.success?(responseObject)case 401:// 請重新登錄self.failure?(code,msg)alertLogin(msg)default:// 其他錯誤failureHandle(failure: self.failure, stateCode: code, message: msg)}}case let .failure(error):failureHandle(failure: self.failure, stateCode: nil, message: error.localizedDescription)}}// 錯誤處理 - 彈出錯誤信息func failureHandle(failure: FailureHandlerType? , stateCode: Int?, message: String) {Alert.show(type: .error, text: message)failure?(stateCode ,message)}// 登錄彈窗 - 彈出是否需要登錄的窗口func alertLogin(_ title: String?) {// TODO: 跳轉到登錄頁的操作:}}// 取消請求func cancel() {httpRequest?.cancel()}}

使用

// 鏈式網絡請求:Alamofire + SwiftyJSONlet url = kBaseURL + "/getSimpleArrDic"JhRequest.url(url).params([:]).requestType(.post).success { res inJhLog(" ========鏈式網絡請求======== ")JhAllLog(res)JhAllLog(res["code"])}.failure { code, msg inJhLog("code : \(code!)")JhLog("message : \(msg)")}.request()

總結

以上是生活随笔為你收集整理的Swift -《从0到1 - 5》:封装网络请求工具类(Alamofire + Moya + SwiftyJSON)和链式封装的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。