当前位置: 首页 > 科技观察

自己写一个iOS网络请求库-封装接口

时间:2023-03-20 20:54:04 科技观察

代码示例:https://github.com/johnlui/Swift-On-iOS/blob/master/BuildYourHTTPRequestLibrary开源项目:Pitaya,适合大文件上传的HTTP请求库:https://github.com/johnlui/Pitaya在本文中,我们将尝试使用一个类来封装我们之前的代码,并尝试添加动态添加HTTP参数(params)的功能,然后封装一个强大的界面。基础封装准备新建一个Swift空文件,命名为Network.swift,在里面写一个Network类,然后写一个静态方法request():classNetwork{staticfuncrequest(){letsession=NSURLSession.sharedSession()letrequest=NSURLRequest(URL:NSURL(string:"http://baidu.com")!)lettask=session.dataTaskWithRequest(request,completionHandler:{(data,response,error)->Voidinprintln("justwaitfor5seconds!")sleep(5)letstring=NSString(data:data,encoding:NSUTF8StringEncoding)println(string)})task.resume()}}修改ViewController中的按钮函数:@IBActionfuncmainButtonBeTapped(sender:AnyObject){Network.request()}运行项目,点击按钮,效果和之前一样。自定义HTTP方法和URL修改request()方法,传入HTTP方法和URL:staticfuncrequest(method:String,url:String){letsession=NSURLSession.sharedSession()letrequest=NSMutableURLRequest(URL:NSURL(string:url)!)request.HTTPMethod=methodlettask=session.dataTaskWithRequest(request,completionHandler:{(data,response,error)->Voidinprintln("justwaitfor5seconds!")sleep(5)letstring=NSString(data:data,encoding:NSUTF8StringEncoding)println(string)})task.resume()}修改之前的函数调用:@IBActionfuncmainButtonBeTapped(sender:AnyObject){Network.request("GET",url:"http://baidu.com")}运行project,点击按钮,效果和之前一样。使用闭包来处理请求结果函数是Swift中的一等公民。闭包可以作为函数的参数和返回值,非常强大。下面我们使用闭包来处理网络请求的返回值。修改request()方法,传入一个闭包:staticfuncrequest(method:String,url:String,callback:(data:NSData!,response:NSURLResponse!,error:NSError!)->Void){letsession=NSURLSession.sharedSession()letrequest=NSMutableURLRequest(URL:NSURL(string:url)!)request.HTTPMethod=methodlettask=session.dataTaskWithRequest(request,completionHandler:{(data,response,error)->Voidincallback(data:data,response:response,error:error)})task.resume()}使用闭包处理上一个函数调用的结果:@IBActionfuncmainButtonBeTapped(sender:AnyObject){Network.request("GET",url:"http://baidu.com"){(data,response,error)->Voidinprintln("justwaitfor5seconds!")sleep(5)letstring=NSString(data:data,encoding:NSUTF8StringEncoding)println(string)}}运行项目,点击按钮,效果和之前一致一样。动态增加ParamsGET方法在GET方法下,params直接附加到URL的末尾,经过url编码后发送给服务器。修改request()方法,传入一个params的字典:staticfuncrequest(method:String,url:String,params:Dictionary=Dictionary(),callback:(data:NSData!,response:NSURLResponse!,error:NSError!)->Void){...}为了处理参数,我们从Alamofire窃取了他的参数处理函数。如果是GET方法,则将处理后的参数添加到URL中。Network类的完整代码如下:classNetwork{staticfuncrequest(method:String,url:String,params:Dictionary=Dictionary(),callback:(data:NSData!,response:NSURLResponse!,error:NSError!)->Void){letsession=NSURLSession.sharedSession()varnewURL=urlifmethod=="GET"{newURL+="?"+Network().buildParams(params)}letrequest=NSMutableURLRequest(URL:NSURL(string:newURL)!)request.HTTPMethod=methodlettask=session.dataTaskWithRequest(request,completionHandler:{(data,response,error)->Voidincallback(data:data,response:response,error:error)})task.resume()}//从Alamofire偷了三个函数funcbuildParams(参数:[String:AnyObject])->String{varcomponents:[(String,String)]=[]forkeyinsorted(Array(parameters.keys),[(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.extend([(escape(key),escape("\(value)"))])}returncomponents}funcescape(string:String)->String{letlegalURLCharactersToBeEscaped:CFStringRef=":&=;+!@#$()',*"returnCFURLCreateStringByAddingPercentEscapes(nil,string,nil,legalURLCharactersToBeEscaped,CFStringBuiltInEncodings.UTF8.rawValue)asString}}修改之前的函数调用:@IBActionfuncmainButtonBeTapped(sender:AnyObject){Network.request("GET",url:"http://pitayaswift.sinaapp.com/pitaya.php",params:["get":"Network"]){(data,response,error)->Voidinletstring=NSString(data:data,encoding:NSUTF8StringEncoding)println(string)}}http://pitayaswift.sinaapp.com/pitaya.php是我测试部署的服务端代码,直接返回?get=ooxxinooxx运行项目,点击按钮查看效果:POST方式POST方式下有几种协议可以选择,这里没有文件上传,我们使用更简单的application/x-www-form-urlencoded方式发送请求客人。request()方法增加一些代码:staticfuncrequest(method:String,url:String,params:Dictionary=Dictionary(),callback:(data:NSData!,response:NSURLResponse!,error:NSError!)->Void){letsession=NSURLSession.sharedSession()varnewURL=urlifmethod=="GET"{newURL+="?"+Network().buildParams(params)}letrequest=NSMutableURLRequest(URL:NSURL(string:newURL)!)request.HTTPMethod=methodifmethod=="POST"{request.addValue("application/x-www-form-urlencoded",forHTTPHeaderField:"Content-Type")request.HTTPBody=Network().buildParams(params).dataUsingEncoding(NSUTF8StringEncoding)}lettask=session.dataTaskWithRequest(request,completionHandler:{(data,response,error)->Voidincallback(data:data,response:response,error:error)})task.resume()}修改前面的函数调用:@IBActionfuncmainButtonBeTapped(sender:AnyObject){Network.request("POST",url:"http://pitayaswift.sinaapp.com/pitaya.php",params:["post":"Network"]){(data,response,error)->Voidinletstring=NSString(data:data,encoding:NSUTF8StringEncoding)println(string)}}使用POST发送请求,服务器返回key作为post的值运行项目,点击按钮,结果与前面GET方法的结果一致。至此,接口封装完成!