新建一个类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
这篇文章写的还不错觉得还可以再提炼一下,后期有时间也会发布自己封装的
网友评论