新建一個類Network
importUIKit
//NSURLSession的使用過程:
//
//構造NSURLRequest
//確定URL
//確定HTTP方法(GET、POST等)
//添加特定的HTTP頭
//填充HTTP Body
//驅動session.dataTaskWithRequest方法,開始請求
//(5)設置SSL證書鋼釘。在我們調用HTTPS協議的時候,事先把SSL證書存到App本地,然后在每次請求的時候都進行一次驗證,避免中間人攻擊(Man-in-the-middle attack)。同時,這個功能也是我們使用自簽名證書時候必須的,因為系統默認會拒絕我們自己簽名的不受信任的證書,導致連接失敗。
// MARK:提供的各種調用接口:GET,POST,文件上傳
classNetwork:NSObject{
//不帶參數的get請求
/*
請求方法的URL? ? url: get
callback閉包[data:請求成功的數據,
response:拿到數據的解析回應,
error:請求錯誤]
NetworkManager()一個初始化URL、params、http、files文件的類
fire()使用一個統一的方法來驅動上面三個function(),完成請求:
*/
staticfuncget(url:String, callback: (data:NSData!, response:NSURLResponse!, error:NSError!) ->Void) {
letmanager =NetworkManager(url: url, method:"GET", callback: callback)
manager.fire()
}
//帶參數的get請求
/*
請求方法的URL? ? url: get
請求參數params:dictionary
callback閉包[data:請求成功的數據,
response:拿到數據的解析回應,
error:請求錯誤]
NetworkManager()一個初始化URL、params、http、files文件的類
fire()使用一個統一的方法來驅動上面三個function(),完成請求:
*/
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()
}
//不帶參數的post請求
/*
請求方法的URL? ? url: post
callback閉包[data:請求成功的數據,
response:拿到數據的解析回應,
error:請求錯誤]
NetworkManager()一個初始化URL、params、http、files文件的類
fire()使用一個統一的方法來驅動上面三個function(),完成請求:
*/
staticfuncpost(url:String, callback: (data:NSData!, response:NSURLResponse!, error:NSError!) ->Void) {
letmanager =NetworkManager(url: url, method:"POST", callback: callback)
manager.fire()
}
//帶參數的post請求
/*
請求方法的URL? ? url: post
請求參數params:dictionary
callback閉包[data:請求成功的數據,
response:拿到數據的解析回應,
error:請求錯誤]
NetworkManager()一個初始化URL、params、http、files文件的類
fire()使用一個統一的方法來驅動上面三個function(),完成請求:
*/
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的接口
/*
提供請求方法類型method: String
請求方法的URL? ? url: String
callback閉包[data:請求成功的數據,
response:拿到數據的解析回應,
error:請求錯誤]
NetworkManager()一個初始化URL、params、http、files文件的類
fire()使用一個統一的方法來驅動上面三個function(),完成請求:
*/
staticfuncrequest(method:String, url:String, callback: (data:NSData!, response:NSURLResponse!, error:NSError!) ->Void) {
letmanager =NetworkManager(url: url, method: method, callback: callback)
manager.fire()
}
//MARK:帶參數不帶files
/*
提供請求方法類型method: String
請求方法的URL? ? url: String
請求方法的參數params: Dictionary
callback閉包[data:請求成功的數據,
response:拿到數據的解析回應,
error:請求錯誤]
NetworkManager()一個初始化URL、params、http、files文件的類
fire()使用一個統一的方法來驅動上面三個function(),完成請求:
*/
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:不帶參數帶files
/*
提供請求方法類型method: String
請求方法的URL? ? url: String
請求文件files:array
callback閉包[data:請求成功的數據,
response:拿到數據的解析回應,
error:請求錯誤]
NetworkManager()一個初始化URL、params、http、files文件的類
fire()使用一個統一的方法來驅動上面三個function(),完成請求:
*/
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:帶參數和files的接口
/*
提供請求方法類型method: String
請求方法的URL? ? url: String
請求方法的參數params: Dictionary
請求文件files:array
callback閉包[data:請求成功的數據,
response:拿到數據的解析回應,
error:請求錯誤]
NetworkManager()一個初始化URL、params、http、files文件的類
fire()使用一個統一的方法來驅動上面三個function(),完成請求:
*/
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的擴展
extensionString{
varnsdata:NSData{
returnself.dataUsingEncoding(NSUTF8StringEncoding)!
}
}
// MARK:定義的文件格式
structFile {
letname:String!
leturl:NSURL!
init(name:String, url:NSURL) {
self.name= name
self.url= url
}
}
// MARK: -新建一個NetworkManager類,將URL、params、files等設為成員變量,讓他們在構造函數中初始化:
classNetworkManager:NSObject,NSURLSessionDelegate{//證書實現NSURLSessionDelegate的協議
//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增加兩個成員變量實現ssl證書檢查代理方法干預網絡請求
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對象
self.session=NSURLSession(configuration:NSURLSession.sharedSession().configuration, delegate:self, delegateQueue:NSURLSession.sharedSession().delegateQueue)
}
//ssl增加設置ssl函數
funcaddSSLPinning(LocalCertData data:NSData, SSLValidateErrorCallBack: (()->Void)? =nil) {
self.localCertData= data
self.sSLValidateErrorCallBack= SSLValidateErrorCallBack
}
//ssl實現證書代理方法,介入網絡請求
@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:使用一個統一的方法來驅動上面三個function,完成請求:
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:將請求任務執行
funcfireTask() {
task=session.dataTaskWithRequest(request, completionHandler: { (data, response, error) ->Voidin
self.callback(data: data, response: response, error: error)
})
task.resume()
}
// MARK:從Alamofire偷了三個函數
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
}
}
主界面測試:
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請求成功")
})
Network.post(url, params: ["post":"POST Network"], callback: { (data, response, error) ->Voidin
letstring =NSString(data: data, encoding:NSUTF8StringEncoding)as!String
print("POST 2請求成功"+ string)
})
Network.get(url, callback: { (data, response, error) ->Voidin
print("GET 1請求成功")
})
Network.get(url, params: ["get":"POST Network"], callback: { (data, response, error) ->Voidin
letstring =NSString(data: data, encoding:NSUTF8StringEncoding)as!String
print("GET 2請求成功"+ string)
})
Network.request("GET", url: url, params: ["get":"Request Network"]) { (data, response, error) ->Voidin
letstring =NSString(data: data, encoding:NSUTF8StringEncoding)as!String
print("Request請求成功"+ string)
}
}
}
來一張測試圖:
May there be enough clouds in your life to make a beautiful sunset...
原文: http://www.cnblogs.com/linxiu-0925/p/5761040.html
這篇文章寫的還不錯覺得還可以再提煉一下,后期有時間也會發布自己封裝的