新建一個(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ā)布自己封裝的