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

以前開始學習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這個第三方庫(主要是這個用習慣了

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ù)要放進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é)果當作value,剛剛的url當作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ù)項目采用des還是aes(不知道為什么屯掖,可能是哪個代碼好復(fù)制用哪個吧

//這個isDes是一個屬性 用來控制萬一項目不采用加密的方式就不用去除代碼了(如果你的需求是項目某一個請求不需要加密玄柏,那你就再通過函數(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)系作者
  • 序言:七十年代末椎咧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子把介,更是在濱河造成了極大的恐慌勤讽,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拗踢,死亡現(xiàn)場離奇詭異地技,居然都是意外死亡,警方通過查閱死者的電腦和手機秒拔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門莫矗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人砂缩,你說我怎么就攤上這事作谚。” “怎么了庵芭?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵妹懒,是天一觀的道長。 經(jīng)常有香客問我双吆,道長眨唬,這世上最難降的妖魔是什么会前? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮匾竿,結(jié)果婚禮上瓦宜,老公的妹妹穿的比我還像新娘。我一直安慰自己岭妖,他們只是感情好临庇,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著昵慌,像睡著了一般假夺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上斋攀,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天已卷,我揣著相機與錄音,去河邊找鬼淳蔼。 笑死悼尾,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的肖方。 我是一名探鬼主播闺魏,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼俯画!你這毒婦竟也來了析桥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤艰垂,失蹤者是張志新(化名)和其女友劉穎泡仗,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體猜憎,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡娩怎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了胰柑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片截亦。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖柬讨,靈堂內(nèi)的尸體忽然破棺而出崩瓤,到底是詐尸還是另有隱情,我是刑警寧澤踩官,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布却桶,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏颖系。R本人自食惡果不足惜嗅剖,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嘁扼。 院中可真熱鬧信粮,春花似錦、人聲如沸偷拔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽莲绰。三九已至,卻和暖如春姑丑,著一層夾襖步出監(jiān)牢的瞬間蛤签,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工栅哀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留震肮,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓留拾,卻偏偏與公主長得像戳晌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子痴柔,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359