swift 動(dòng)手寫(xiě)網(wǎng)絡(luò)請(qǐng)求封裝(仿照了一個(gè)大神的)不用導(dǎo)入第三方

新建一個(gè)類(lèi)Network

importUIKit

//NSURLSession的使用過(guò)程:

//

//構(gòu)造NSURLRequest

//確定URL

//確定HTTP方法(GET、POST等)

//添加特定的HTTP頭

//填充HTTP Body

//驅(qū)動(dòng)session.dataTaskWithRequest方法灰署,開(kāi)始請(qǐng)求

//(5)設(shè)置SSL證書(shū)鋼釘判帮。在我們調(diào)用HTTPS協(xié)議的時(shí)候,事先把SSL證書(shū)存到App本地溉箕,然后在每次請(qǐng)求的時(shí)候都進(jìn)行一次驗(yàn)證晦墙,避免中間人攻擊(Man-in-the-middle attack)。同時(shí)肴茄,這個(gè)功能也是我們使用自簽名證書(shū)時(shí)候必須的晌畅,因?yàn)橄到y(tǒng)默認(rèn)會(huì)拒絕我們自己簽名的不受信任的證書(shū),導(dǎo)致連接失敗寡痰。

// MARK:提供的各種調(diào)用接口:GET,POST,文件上傳

classNetwork:NSObject{

//不帶參數(shù)的get請(qǐng)求

/*

請(qǐng)求方法的URL? ? url: get

callback閉包[data:請(qǐng)求成功的數(shù)據(jù),

response:拿到數(shù)據(jù)的解析回應(yīng),

error:請(qǐng)求錯(cuò)誤]

NetworkManager()一個(gè)初始化URL抗楔、params棋凳、http、files文件的類(lèi)

fire()使用一個(gè)統(tǒng)一的方法來(lái)驅(qū)動(dòng)上面三個(gè)function()连躏,完成請(qǐng)求:

*/

staticfuncget(url:String, callback: (data:NSData!, response:NSURLResponse!, error:NSError!) ->Void) {

letmanager =NetworkManager(url: url, method:"GET", callback: callback)

manager.fire()

}

//帶參數(shù)的get請(qǐng)求

/*

請(qǐng)求方法的URL? ? url: get

請(qǐng)求參數(shù)params:dictionary

callback閉包[data:請(qǐng)求成功的數(shù)據(jù),

response:拿到數(shù)據(jù)的解析回應(yīng),

error:請(qǐng)求錯(cuò)誤]

NetworkManager()一個(gè)初始化URL剩岳、params、http入热、files文件的類(lèi)

fire()使用一個(gè)統(tǒng)一的方法來(lái)驅(qū)動(dòng)上面三個(gè)function()拍棕,完成請(qǐng)求:

*/

staticfuncget(url:String, params:Dictionary, callback: (data:NSData!, response:NSURLResponse!, error:NSError!) ->Void) {

letmanager =NetworkManager(url: url, method:"GET", params: params, callback: callback)

manager.fire()

}

//不帶參數(shù)的post請(qǐng)求

/*

請(qǐng)求方法的URL? ? url: post

callback閉包[data:請(qǐng)求成功的數(shù)據(jù),

response:拿到數(shù)據(jù)的解析回應(yīng),

error:請(qǐng)求錯(cuò)誤]

NetworkManager()一個(gè)初始化URL、params勺良、http绰播、files文件的類(lèi)

fire()使用一個(gè)統(tǒng)一的方法來(lái)驅(qū)動(dòng)上面三個(gè)function(),完成請(qǐng)求:

*/

staticfuncpost(url:String, callback: (data:NSData!, response:NSURLResponse!, error:NSError!) ->Void) {

letmanager =NetworkManager(url: url, method:"POST", callback: callback)

manager.fire()

}

//帶參數(shù)的post請(qǐng)求

/*

請(qǐng)求方法的URL? ? url: post

請(qǐng)求參數(shù)params:dictionary

callback閉包[data:請(qǐng)求成功的數(shù)據(jù),

response:拿到數(shù)據(jù)的解析回應(yīng),

error:請(qǐng)求錯(cuò)誤]

NetworkManager()一個(gè)初始化URL尚困、params蠢箩、http、files文件的類(lèi)

fire()使用一個(gè)統(tǒng)一的方法來(lái)驅(qū)動(dòng)上面三個(gè)function()事甜,完成請(qǐng)求:

*/

staticfuncpost(url:String, params:Dictionary, callback: (data:NSData!, response:NSURLResponse!, error:NSError!) ->Void) {

letmanager =NetworkManager(url: url, method:"POST", params: params, callback: callback)

manager.fire()

}

//MARK:不帶params和files的接口

/*

提供請(qǐng)求方法類(lèi)型method: String

請(qǐng)求方法的URL? ? url: String

callback閉包[data:請(qǐng)求成功的數(shù)據(jù),

response:拿到數(shù)據(jù)的解析回應(yīng),

error:請(qǐng)求錯(cuò)誤]

NetworkManager()一個(gè)初始化URL谬泌、params、http讳侨、files文件的類(lèi)

fire()使用一個(gè)統(tǒng)一的方法來(lái)驅(qū)動(dòng)上面三個(gè)function()呵萨,完成請(qǐng)求:

*/

staticfuncrequest(method:String, url:String, callback: (data:NSData!, response:NSURLResponse!, error:NSError!) ->Void) {

letmanager =NetworkManager(url: url, method: method, callback: callback)

manager.fire()

}

//MARK:帶參數(shù)不帶files

/*

提供請(qǐng)求方法類(lèi)型method: String

請(qǐng)求方法的URL? ? url: String

請(qǐng)求方法的參數(shù)params: Dictionary

callback閉包[data:請(qǐng)求成功的數(shù)據(jù),

response:拿到數(shù)據(jù)的解析回應(yīng),

error:請(qǐng)求錯(cuò)誤]

NetworkManager()一個(gè)初始化URL、params跨跨、http潮峦、files文件的類(lèi)

fire()使用一個(gè)統(tǒng)一的方法來(lái)驅(qū)動(dòng)上面三個(gè)function(),完成請(qǐng)求:

*/

staticfuncrequest(method:String, url:String, params:Dictionary, callback: (data:NSData!, response:NSURLResponse!, error:NSError!) ->Void) {

letmanager =NetworkManager(url: url, method: method, params: params, callback: callback)

manager.fire()

}

//MARK:不帶參數(shù)帶files

/*

提供請(qǐng)求方法類(lèi)型method: String

請(qǐng)求方法的URL? ? url: String

請(qǐng)求文件files:array

callback閉包[data:請(qǐng)求成功的數(shù)據(jù),

response:拿到數(shù)據(jù)的解析回應(yīng),

error:請(qǐng)求錯(cuò)誤]

NetworkManager()一個(gè)初始化URL勇婴、params忱嘹、http、files文件的類(lèi)

fire()使用一個(gè)統(tǒng)一的方法來(lái)驅(qū)動(dòng)上面三個(gè)function()耕渴,完成請(qǐng)求:

*/

staticfuncrequest(method:String, url:String, files:Array, callback: (data:NSData!, response:NSURLResponse!, error:NSError!) ->Void) {

letmanager =NetworkManager(url: url, method: method, files: files, callback: callback)

manager.fire()

}

//MARK:帶參數(shù)和files的接口

/*

提供請(qǐng)求方法類(lèi)型method: String

請(qǐng)求方法的URL? ? url: String

請(qǐng)求方法的參數(shù)params: Dictionary

請(qǐng)求文件files:array

callback閉包[data:請(qǐng)求成功的數(shù)據(jù),

response:拿到數(shù)據(jù)的解析回應(yīng),

error:請(qǐng)求錯(cuò)誤]

NetworkManager()一個(gè)初始化URL拘悦、params、http橱脸、files文件的類(lèi)

fire()使用一個(gè)統(tǒng)一的方法來(lái)驅(qū)動(dòng)上面三個(gè)function()础米,完成請(qǐng)求:

*/

staticfuncrequest(method:String, url:String, params:Dictionary, files:Array, callback: (data:NSData!, response:NSURLResponse!, error:NSError!) ->Void) {

letmanager =NetworkManager(url: url, method: method, params: params, files: files, callback: callback)

manager.fire()

}

}

// MARK: - nsdata屬性是string的擴(kuò)展

extensionString{

varnsdata:NSData{

returnself.dataUsingEncoding(NSUTF8StringEncoding)!

}

}

// MARK:定義的文件格式

structFile {

letname:String!

leturl:NSURL!

init(name:String, url:NSURL) {

self.name= name

self.url= url

}

}

// MARK: -新建一個(gè)NetworkManager類(lèi),將URL添诉、params屁桑、files等設(shè)為成員變量,讓他們?cè)跇?gòu)造函數(shù)中初始化:

classNetworkManager:NSObject,NSURLSessionDelegate{//證書(shū)實(shí)現(xiàn)NSURLSessionDelegate的協(xié)議

//todo? boundary是我們自己指定的文件間隔符栏赴。

letboundary ="PitayaUGl0YXlh"

letmethod:String!

letparams:Dictionary

letcallback: (data:NSData!, response:NSURLResponse!, error:NSError!) ->Void

// add files

varfiles:Array

varsession:NSURLSession!

leturl:String!

varrequest:NSMutableURLRequest!

vartask:NSURLSessionTask!

//ssl增加兩個(gè)成員變量實(shí)現(xiàn)ssl證書(shū)檢查代理方法干預(yù)網(wǎng)絡(luò)請(qǐng)求

varlocalCertData:NSData!

varsSLValidateErrorCallBack: (() ->Void)?

// add files

init(url:String, method:String, params:Dictionary =Dictionary(), files:Array =Array(), callback: (data:NSData!, response:NSURLResponse!, error:NSError!) ->Void) {

self.url= url

self.request=NSMutableURLRequest(URL:NSURL(string: url)!)

self.method= method

self.params= params

self.callback= callback

// add files

self.files= files

super.init()

//ssl自定義nsurlsession對(duì)象

self.session=NSURLSession(configuration:NSURLSession.sharedSession().configuration, delegate:self, delegateQueue:NSURLSession.sharedSession().delegateQueue)

}

//ssl增加設(shè)置ssl函數(shù)

funcaddSSLPinning(LocalCertData data:NSData, SSLValidateErrorCallBack: (()->Void)? =nil) {

self.localCertData= data

self.sSLValidateErrorCallBack= SSLValidateErrorCallBack

}

//ssl實(shí)現(xiàn)證書(shū)代理方法,介入網(wǎng)絡(luò)請(qǐng)求

@objcfuncURLSession(session:NSURLSession, didReceiveChallenge challenge:NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition,NSURLCredential?) ->Void) {

ifletlocalCertificateData =self.localCertData{

ifletserverTrust = challenge.protectionSpace.serverTrust,

certificate =SecTrustGetCertificateAtIndex(serverTrust,0),

remoteCertificateData:NSData=SecCertificateCopyData(certificate) {

iflocalCertificateData.isEqualToData(remoteCertificateData) {

letcredential =NSURLCredential(forTrust: serverTrust)

challenge.sender?.useCredential(credential, forAuthenticationChallenge: challenge)

completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, credential)

}else{

challenge.sender?.cancelAuthenticationChallenge(challenge)

completionHandler(NSURLSessionAuthChallengeDisposition.CancelAuthenticationChallenge,nil)

self.sSLValidateErrorCallBack?()

}

}else{

NSLog("Get RemoteCertificateData or LocalCertificateData error!")

}

}else{

completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential,nil)

}

}

//MARK:使用一個(gè)統(tǒng)一的方法來(lái)驅(qū)動(dòng)上面三個(gè)function蘑斧,完成請(qǐng)求:

funcfire() {

buildRequest()

buildBody()

fireTask()

}

//MARK:確定URL、http方法、添加特定的http頭

funcbuildRequest() {

ifself.method=="GET"&&self.params.count>0{

self.request=NSMutableURLRequest(URL:NSURL(string:url+"?"+buildParams(self.params))!)

}

request.HTTPMethod=self.method

// ? Content-Type

ifself.files.count>0{

request.addValue("multipart/form-data; boundary="+self.boundary, forHTTPHeaderField:"Content-Type")

}elseifself.params.count>0{

request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField:"Content-Type")

}

}

//MARK:填充HTTP Body

funcbuildBody() {

letdata =NSMutableData()

ifself.files.count>0{

ifself.method=="GET"{

NSLog("\n\n------------------------\nThe remote server may not accept GET method with HTTP body. But Pitaya will send it anyway.\n------------------------\n\n")

}

for(key, value)inself.params{

data.appendData("--\(self.boundary)\r\n".nsdata)

data.appendData("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".nsdata)

data.appendData("\(value.description)\r\n".nsdata)

}

forfileinself.files{

data.appendData("--\(self.boundary)\r\n".nsdata)

data.appendData("Content-Disposition: form-data; name=\"\(file.name)\"; filename=\"\(NSString(string: file.url.description).lastPathComponent)\"\r\n\r\n".nsdata)

ifleta =NSData(contentsOfURL: file.url) {

data.appendData(a)

data.appendData("\r\n".nsdata)

}

}

data.appendData("--\(self.boundary)--\r\n".nsdata)

}elseifself.params.count>0&&self.method!="GET"{

data.appendData(buildParams(self.params).nsdata)

}

request.HTTPBody= data

}

//MARK:將請(qǐng)求任務(wù)執(zhí)行

funcfireTask() {

task=session.dataTaskWithRequest(request, completionHandler: { (data, response, error) ->Voidin

self.callback(data: data, response: response, error: error)

})

task.resume()

}

// MARK:從Alamofire偷了三個(gè)函數(shù)

funcbuildParams(parameters: [String:AnyObject]) ->String{

varcomponents: [(String,String)] = []

forkeyinArray(parameters.keys).sort(<) {

letvalue:AnyObject! = parameters[key]

components +=self.queryComponents(key, value)

}

return(components.map{"\($0)=\($1)"}as[String]).joinWithSeparator("&")

}

funcqueryComponents(key:String,_value:AnyObject) -> [(String,String)] {

varcomponents: [(String,String)] = []

ifletdictionary = valueas? [String:AnyObject] {

for(nestedKey, value)indictionary {

components +=queryComponents("\(key)[\(nestedKey)]", value)

}

}elseifletarray = valueas? [AnyObject] {

forvalueinarray {

components +=queryComponents("\(key)", value)

}

}else{

components.appendContentsOf([(escape(key),escape("\(value)"))])

}

returncomponents

}

funcescape(string:String) ->String{

letlegalURLCharactersToBeEscaped:CFStringRef=":&=;+!@#$()',*"

returnCFURLCreateStringByAddingPercentEscapes(nil, string,nil, legalURLCharactersToBeEscaped,CFStringBuiltInEncodings.UTF8.rawValue)asString

}

}

主界面測(cè)試:

importUIKit

classViewController:UIViewController{

overridefuncviewDidLoad() {

super.viewDidLoad()

// Do any additional setup after loading the view, typically from a nib.

letmainBtn =UIButton.init(frame:CGRectMake(200,200,100,50))

mainBtn.backgroundColor=UIColor.redColor()

mainBtn.addTarget(self, action:#selector(mainBtnBeTapped), forControlEvents: .TouchUpInside)

self.view.addSubview(mainBtn)

}

funcmainBtnBeTapped(sender:AnyObject) {

leturl ="http://pitayaswift.sinaapp.com/pitaya.php"

Network.post(url, callback: { (data, response, error) ->Voidin

print("POST 1請(qǐng)求成功")

})

Network.post(url, params: ["post":"POST Network"], callback: { (data, response, error) ->Voidin

letstring =NSString(data: data, encoding:NSUTF8StringEncoding)as!String

print("POST 2請(qǐng)求成功"+ string)

})

Network.get(url, callback: { (data, response, error) ->Voidin

print("GET 1請(qǐng)求成功")

})

Network.get(url, params: ["get":"POST Network"], callback: { (data, response, error) ->Voidin

letstring =NSString(data: data, encoding:NSUTF8StringEncoding)as!String

print("GET 2請(qǐng)求成功"+ string)

})

Network.request("GET", url: url, params: ["get":"Request Network"]) { (data, response, error) ->Voidin

letstring =NSString(data: data, encoding:NSUTF8StringEncoding)as!String

print("Request請(qǐng)求成功"+ string)

}

}

}

來(lái)一張測(cè)試圖:

May there be enough clouds in your life to make a beautiful sunset...

原文: http://www.cnblogs.com/linxiu-0925/p/5761040.html
這篇文章寫(xiě)的還不錯(cuò)覺(jué)得還可以再提煉一下竖瘾,后期有時(shí)間也會(huì)發(fā)布自己封裝的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末沟突,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子捕传,更是在濱河造成了極大的恐慌惠拭,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庸论,死亡現(xiàn)場(chǎng)離奇詭異求橄,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)葡公,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)条霜,“玉大人催什,你說(shuō)我怎么就攤上這事≡姿” “怎么了蒲凶?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)拆内。 經(jīng)常有香客問(wèn)我旋圆,道長(zhǎng),這世上最難降的妖魔是什么麸恍? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任灵巧,我火速辦了婚禮,結(jié)果婚禮上抹沪,老公的妹妹穿的比我還像新娘刻肄。我一直安慰自己,他們只是感情好融欧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布敏弃。 她就那樣靜靜地躺著,像睡著了一般噪馏。 火紅的嫁衣襯著肌膚如雪麦到。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,208評(píng)論 1 299
  • 那天欠肾,我揣著相機(jī)與錄音瓶颠,去河邊找鬼。 笑死董济,一個(gè)胖子當(dāng)著我的面吹牛步清,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼廓啊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼欢搜!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起谴轮,我...
    開(kāi)封第一講書(shū)人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤炒瘟,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后第步,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體疮装,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年粘都,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了廓推。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡翩隧,死狀恐怖樊展,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情堆生,我是刑警寧澤专缠,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站淑仆,受9級(jí)特大地震影響涝婉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蔗怠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一墩弯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蟀淮,春花似錦最住、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至策治,卻和暖如春脓魏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背通惫。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工茂翔, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人履腋。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓珊燎,卻偏偏與公主長(zhǎng)得像惭嚣,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子悔政,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容