[iOS]封裝自己所需要的Networking

以前開始學(xué)習(xí)iOS的時候網(wǎng)絡(luò)請求都是直接用AFN,每一次請求都特別繁瑣,最近完善了一下自己寫的請求封裝,分享一下。

以下代碼為Swift版本,如果需要Object-c的可以去我的github(https://github.com/JakeZhucl/CLBaseObject-C)下載

下面是我心里想的封裝需求:
1.添加公共參數(shù)
2.緩存請求的結(jié)果
3.要可以處理tableview, scrollview,collectionview的停止刷新
4.可以加密
5.打印對應(yīng)的請求、參數(shù)、加密參數(shù)和結(jié)果

開始吧

1.既然需要處理公共參數(shù),那就寫一個處理參數(shù)的方法

private class func addPostParameters( parameters : Dictionary<String, Any>?) -> Dictionary<String, Any>{
        
        var newParameters = Dictionary<String,Any>()
        /*這里的內(nèi)容都是公共參數(shù),看需求添加
        newParameters["vid"] = Account.account().vid
        newParameters["user_id"] = Account.account().user_id
        newParameters["app_flag"] = APP_FLAG
        newParameters["device"] = "iOS"
         */
        //版本號
        newParameters["version"] = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String
        //bundleId
        newParameters["bundleid"] = Bundle.main.object(forInfoDictionaryKey: "CFBundleIdentifier")
        //如果沒有參數(shù)傳入就直接返回公共參數(shù),如果有參數(shù)傳入就將參數(shù)字典的東西通過遍歷加到公共參數(shù)返回作為最后的請求參數(shù)
        if parameters == nil {
            return newParameters
        }else{
            for (key,value) in parameters!{
                newParameters[key] = value
            }
            return newParameters
        }
    }

2.緩存我采用的yycache這個第三方庫(主要是這個用習(xí)慣了

let clCache = YYCache(name: "product_name")
//講請求的參數(shù)字典的key變成有序的,為了下一步存儲的時候變成string不會每次都不一樣
let parametersKeys = addParameters.keys.sorted { (num1 , num2) -> Bool in
    return num1 < num2
}

var cacheString = ""
for key in parametersKeys {
    if key != "lat" && key != "lng" {
    cacheString += "\(key)\(String(describing:addParameters[key]))"
        }
}
//這個cacheurl就是請求路徑和請求參數(shù)要放進(jìn)cache的key
let cacheURL =  "\(url)\(cacheString)"

Alamofire.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: nil).response { (response) in
            SVProgressHUD.setDefaultMaskType(.none)
            if (response.error == nil ) {
                if response.data != nil {
                    if isCache {
                        //請求結(jié)束的時候就可以將請求結(jié)果當(dāng)作value,剛剛的url當(dāng)作key存到本地了
                        clCache?.setObject(response.data! as NSData, forKey: cacheURL)
                    }
                }
            }
        }

3.添加自動停止刷新的方法,這個真的非常有用,添加后,在寫tableview、scorllview、collection就完全不用考慮是否會出現(xiàn)忘記寫停止刷新的方法了

//我這里是將請求已經(jīng)全部轉(zhuǎn)換成model了
private class func endRefresh(model : CLNetWorkModel,
                                  scrollview : UIScrollView ,
                                  isCache : Bool){
        if !isCache {
            //后端返回isnull來控制是否最后一頁,所以這邊由isnull控制是否endRefreshing
            if model.isnull == "0" {
                if scrollview.mj_footer != nil {
                    scrollview.mj_footer.endRefreshing()
                }
            }else{
                if scrollview.mj_footer != nil {
                    scrollview.mj_footer.endRefreshingWithNoMoreData()
                }
            }
            
            if scrollview.mj_header != nil {
                scrollview.mj_header.endRefreshing()
            }
        }
    }

4.加密 我公司根據(jù)項(xiàng)目采用des還是aes(不知道為什么,可能是哪個代碼好復(fù)制用哪個吧

//這個isDes是一個屬性 用來控制萬一項(xiàng)目不采用加密的方式就不用去除代碼了(如果你的需求是項(xiàng)目某一個請求不需要加密,那你就再通過函數(shù)的參數(shù)來控制

if isDes {
    parameters["data"] = CLDes.encryptUse(addParameters.CLDictionaryToJsonString())
    print(parameters.CLDictionaryToJsonString())
}else{
    parameters = addParameters
}

好啦。我把全部代碼放上去

//
//  CLNetworkingSwift.swift
//  Created by zcl on 2018/2/6.
//

import UIKit
import Alamofire
import SwiftyJSON
import HandyJSON
import SVProgressHUD
import MJRefresh
import YYCache

class CLNetWorkModel: HandyJSON {
   var data : AnyObject?
   var isnull = "0"
   var ret = "-100"
   var code : String?
   var page = "0"
   required init() {
       
   }
}

class CLNetworkSwift {
   
   enum CLNetWorkType {
       case notReachable
       case unknown
       case wwan
       case ethernetOrWiFi
   }
   static let isDes = true
   
   func networkState(state : @escaping (_ type : CLNetWorkType) ->Void )
       -> Void {
           let networkManager = NetworkReachabilityManager.init(host: YM)
           networkManager?.listener = { status in
               switch status {
               case .notReachable:
                   state(.notReachable)
                   break
               case .unknown:
                   state(.unknown)
                   break
               case .reachable(NetworkReachabilityManager.ConnectionType.wwan):
                   state(.wwan)
                   break
               case .reachable(NetworkReachabilityManager.ConnectionType.ethernetOrWiFi):
                   state(.ethernetOrWiFi)
                   break
               }
           }
           networkManager?.startListening()
   }
   
   /// GET 返回結(jié)果為JSON.
   class func GET(url : String ,
                  parameters : Dictionary<String, Any>? ,
                  successJson success : @escaping (_ success : JSON) -> Void ,
                  fail : @escaping (_ fail : Error) -> Void)  {
       print(url)
       
       print(self.addPostParameters(parameters: parameters).CLDictionaryToJsonString())
       
       Alamofire.request(url, method: .get, parameters: self.addPostParameters(parameters: parameters), encoding: URLEncoding.default, headers: nil).response { (response) in
           
           if (response.error == nil) {
               do {
                   success(try JSON.init(data: response.data!))
               }catch{
                   let error = NSError.init(domain: "網(wǎng)絡(luò)請求失敗,錯誤代碼(-1001)", code: -1001, userInfo: nil)
                   fail(error)
               }
           }else{
               SVProgressHUD.showError(withStatus: response.error?.localizedDescription)
               SVProgressHUD.dismiss(withDelay: 1)
               fail(response.error!)
           }
       }
   }
   
   /// 返回結(jié)果Data.
   class func POST(url : String ,
                   parameters : Dictionary<String, Any>? ,
                   successData success : @escaping (_ successData : Data , _ isCache : Bool) -> Void ,
                   fail : @escaping (_ fail : Error) -> Void,
                   isCache : Bool) {
       
       let clCache = YYCache(name: "yixingcheng")
       
       let addParameters = self.addPostParameters(parameters: parameters)
       
       print(url)
       print(addParameters.CLDictionaryToJsonString())
       
       var parameters = Dictionary<String,Any>()
       if isDes {
           parameters["data"] = CLDes.encryptUse(addParameters.CLDictionaryToJsonString())
           print(parameters.CLDictionaryToJsonString())
       }else{
           parameters = addParameters
       }
       
       let parametersKeys = addParameters.keys.sorted { (num1 , num2) -> Bool in
           return num1 < num2
       }
       
       
       var cacheString = ""
       for key in parametersKeys {
           if key != "lat" && key != "lng" {
               cacheString += "\(key)\(String(describing: addParameters[key]))"
           }
       }
       
       let cacheURL =  "\(url)\(cacheString)"
       
       if isCache {
           if (clCache?.containsObject(forKey: cacheURL))! {
               success(clCache?.object(forKey: cacheURL) as! Data,true)
           }
       }
       
       Alamofire.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: nil).response { (response) in
           SVProgressHUD.setDefaultMaskType(.none)
           if (response.error == nil ) {
               if response.data != nil {
                   if isCache {
                       print(url)
                       clCache?.setObject(response.data! as NSData, forKey: cacheURL)
                   }
                   success(response.data!,false)
               }else{
                   let error = NSError.init(domain: "網(wǎng)絡(luò)請求失敗,錯誤代碼(-1002)", code: -1001, userInfo: nil)
                   SVProgressHUD.showError(withStatus: "網(wǎng)絡(luò)請求失敗,錯誤代碼(-1002)")
                   SVProgressHUD.dismiss(withDelay: 1)
                   fail(error)
               }
           }else{
               SVProgressHUD.showError(withStatus: response.error?.localizedDescription)
               SVProgressHUD.dismiss(withDelay: 1)
               fail(response.error!)
           }
       }
   }
   
   
   /// 返回結(jié)果為JSON和Model.
   ///
   /// - Parameters:
   ///   - url: 路徑
   ///   - parameters: 參數(shù)
   ///   - successDictionary: 字典閉包
   ///   - successModel: 模型閉包
   ///   - fail: 失敗閉包
   class func POST(url : String ,
                   parameters : Dictionary<String, Any>? ,
                   successJsonAndModel success : @escaping (_ success : JSON , _ success : CLNetWorkModel ,_ isCahce : Bool) -> Void ,
                   fail : @escaping (_ fail : Error) -> Void,
                   isCache : Bool) {
       self.POST(url: url, parameters: parameters, successData: { (successData , isCacheData) in
           do {
               var JsonString = try JSON.init(data: successData)
               
               var model : CLNetWorkModel!
               
               if isDes {
                   let decry = JsonString.dictionaryObject
                   let result = CLDes.decryptUse(decry?["data"] as? String)
                   //                    print(result ?? "")
                   model = CLNetWorkModel.deserialize(from: CLDes.decryptUse(decry?["data"] as? String))
                   JsonString = JSON.init(parseJSON: result ?? "")
               }else{
                   model = CLNetWorkModel.deserialize(from: JsonString.dictionaryObject)
               }
               
               
               if model?.ret == "1001" {
                   SVProgressHUD.dismiss()
                   success(JsonString,model, isCacheData)
               }else{
                   print("錯誤接口")
                   print(url)
                   print(model?.code ?? "")
                   
                   SVProgressHUD.showError(withStatus:  model?.code )
                   SVProgressHUD.dismiss(withDelay: 1)
                   
                   let error = NSError.init(domain:  (model?.code ?? "")!
                       , code: Int((model?.ret)!)!, userInfo: nil)
                   fail(error)
               }
           }catch{
               let error = NSError.init(domain: "網(wǎng)絡(luò)請求失敗,錯誤代碼(-1001)", code: -1001, userInfo: nil)
               SVProgressHUD.showError(withStatus: "網(wǎng)絡(luò)請求失敗,錯誤代碼(-1001)")
               SVProgressHUD.dismiss(withDelay: 1)
               fail(error)
           }
       }, fail: { (error) in
           SVProgressHUD.showError(withStatus: error.localizedDescription)
           SVProgressHUD.dismiss(withDelay: 1)
           
           print("請求失敗")
           print(url)
           print(parameters?.CLDictionaryToJsonString() ?? "")
           print(error.localizedDescription)
           
           fail(error)
       }, isCache: isCache)
   }
   
   /// 返回結(jié)果為JSON.
   ///
   /// - Parameters:
   ///   - url: 路徑
   ///   - parameters: 參數(shù)
   ///   - success: 字典閉包
   ///   - fail: 失敗閉包
   class func POST(url : String ,
                   parameters : Dictionary<String, Any>? ,
                   successJson success : @escaping (_ success : JSON,_ isCahce : Bool) -> Void ,
                   fail : @escaping (_ fail : Error) -> Void,
                   isCache : Bool) {
       self.POST(url: url, parameters: parameters, successJsonAndModel: { (successJSON, successModel, isCacheData) in
           success(successJSON, isCacheData)
       }, fail: fail, isCache: isCache)
       
   }
   
   /// 返回結(jié)果為Model.
   ///
   /// - Parameters:
   ///   - url: 路徑
   ///   - parameters: 參數(shù)
   ///   - success: 成功閉包
   ///   - fail: 失敗閉包
   class func POST(url : String,
                   parameters : Dictionary<String,Any>,
                   successModel success : @escaping (_ success : CLNetWorkModel , _ isCahce : Bool) -> Void,
                   fail : @escaping (_ fail : Error)-> Void,
                   isCache : Bool) -> Void {
       self.POST(url: url, parameters: parameters, successJsonAndModel: { (successJson, successModel, isCacheData) in
           success(successModel, isCacheData)
       }, fail: fail,isCache : isCache)
   }
   
   /// 請求結(jié)束停止scorllview的刷新返回參數(shù)為JSON和Model.
   ///
   /// - Parameters:
   ///   - url: 路徑
   ///   - parameters: 參數(shù)
   ///   - success: 成功閉包
   ///   - fail: 失敗閉包
   ///   - scrollView: 需要停止刷新的scrollview、tableview、collectionview
   class func POST(url : String ,
                   parameters : Dictionary<String, Any>?,
                   success : @escaping (_ success : JSON , _ success : CLNetWorkModel , _ isCahce : Bool) -> Void ,
                   fail : @escaping (_ fail : Error) -> Void,
                   scrollView : UIScrollView,
                   isCache : Bool) {
       
       self.POST(url: url, parameters: parameters, successJsonAndModel: { (successJSON, successModel , isCacheData) in
           self.endRefresh(model: successModel, scrollview: scrollView , isCache: isCacheData)
           success(successJSON,successModel, isCacheData)
       }, fail: { (error) in
           self.endRefresh(model: CLNetWorkModel(), scrollview: scrollView, isCache:  false)
           fail(error)
       }, isCache: isCache)
   }
}

//配置處理
extension CLNetworkSwift {
   private class func addPostParameters( parameters : Dictionary<String, Any>?) -> Dictionary<String, Any>{
       
       var newParameters = Dictionary<String,Any>()
       newParameters["vid"] = Account.account().vid
       newParameters["user_id"] = Account.account().user_id
       newParameters["app_flag"] = APP_FLAG
       newParameters["device"] = "iOS"
       newParameters["version"] = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String
       newParameters["bundleid"] = Bundle.main.object(forInfoDictionaryKey: "CFBundleIdentifier")
       newParameters["channel_id"] = UserDefaults.standard.value(forKey: "channel_id")
       
       if parameters == nil {
           return newParameters
       }else{
           for (key,value) in parameters!{
               newParameters[key] = value
           }
           return newParameters
       }
   }
   private class func endRefresh(model : CLNetWorkModel,
                                 scrollview : UIScrollView ,
                                 isCache : Bool){
       if !isCache {
           if model.isnull == "0" {
               if scrollview.mj_footer != nil {
                   scrollview.mj_footer.endRefreshing()
               }
           }else{
               if scrollview.mj_footer != nil {
                   scrollview.mj_footer.endRefreshingWithNoMoreData()
               }
           }
           
           if scrollview.mj_header != nil {
               scrollview.mj_header.endRefreshing()
           }
       }
   }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容