Write an iOS network request library by yourself - encapsulation interface

Write an iOS network request library by yourself - encapsulation interface

Code example: https://github.com/johnlui/Swift-On-iOS/blob/master/BuildYourHTTPRequestLibrary

Open source project: Pitaya, an HTTP request library suitable for uploading large files: https://github.com/johnlui/Pitaya

In this article, we will try to use a class to encapsulate our previous code, try to add the function of dynamically adding HTTP parameters (params), and then encapsulate a powerful interface.

[[135523]]

Basic package

Basic preparation

Create a new empty Swift file, name it Network.swift, write a Network class in it, and then write a static method request():

  1. class Network{
  2. static func request() {
  3. let session = NSURLSession .sharedSession()
  4. let request = NSURLRequest (URL: NSURL(string: "http://baidu.com")!)
  5. let task = session .dataTaskWithRequest(request, completionHandler: { (data, response, error) - > Void in
  6. println("just wait for 5 seconds!")
  7. sleep(5)
  8. let string = NSString (data: data, encoding: NSUTF8StringEncoding)
  9. println(string)
  10. })
  11. task.resume()
  12. }
  13. }

Modify the button function in ViewController:

  1. @IBAction func mainButtonBeTapped(sender: AnyObject) {
  2. Network.request()
  3. }

Run the project and click the button. The effect is the same as before.

Custom HTTP method and URL

Modify the request() method and pass in the HTTP method and URL:

  1. static func request(method: String, url: String) {
  2. let session = NSURLSession.sharedSession()
  3. let request = NSMutableURLRequest(URL: NSURL(string: url)!)
  4. request.HTTPMethod = method
  5. let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
  6. println( "just wait for 5 seconds!" )
  7. sleep( 5 )
  8. let string = NSString(data: data, encoding: NSUTF8StringEncoding)
  9. println(string)
  10. })
  11. task.resume()
  12. }

Modify the previous function call:

  1. @IBAction func mainButtonBeTapped(sender: AnyObject) {
  2. Network.request( "GET" , url: "http://baidu.com" )
  3. }

Run the project and click the button. The effect is the same as before.

Use closures to handle request results

Functions are first-class citizens in Swift. Closures can be used as function parameters and return values, which is very powerful. Next, we use closures to process the return value of network requests. Modify the request() method and pass in a closure:

  1. static func request(method: String, url: String, callback: (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void) {
  2. let session = NSURLSession.sharedSession()
  3. let request = NSMutableURLRequest(URL: NSURL(string: url)!)
  4. request.HTTPMethod = method
  5. let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
  6. callback(data: data, response: response, error: error)
  7. })
  8. task.resume()
  9. }

Use closures to process results in the previous function call:

  1. @IBAction func mainButtonBeTapped(sender: AnyObject) {
  2. Network.request( "GET" , url: "http://baidu.com" ) { (data, response, error) -> Void in
  3. println( "just wait for 5 seconds!" )
  4. sleep( 5 )
  5. let string = NSString(data: data, encoding: NSUTF8StringEncoding)
  6. println(string)
  7. }
  8. }

Run the project and click the button. The effect is the same as before.

Dynamically add Params

GET method

Under the GET method, params is directly attached to the end of the URL after being url-encoded and sent to the server. Modify the request() method and pass in a params dictionary:

  1. static func request(method: String, url: String, params: Dictionary = Dictionary(), callback: (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void) {
  2. ... ...
  3. }

To process params, we steal the params processing function from Alamofire. If it is a GET method, then add the processed params to the end of the URL. The complete code of the Network class is as follows:

  1. class Network{
  2. static func request(method: String, url: String, params: Dictionary = Dictionary(), callback: (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void) {
  3. let session = NSURLSession.sharedSession()
  4.  
  5. var newURL = url
  6. if method == "GET" {
  7. newURL += "?" + Network().buildParams(params)
  8. }
  9.  
  10. let request = NSMutableURLRequest(URL: NSURL(string: newURL)!)
  11. request.HTTPMethod = method
  12.  
  13. let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
  14. callback(data: data, response: response, error: error)
  15. })
  16. task.resume()
  17. }
  18.  
  19. // Three functions stolen from Alamofire  
  20. func buildParams(parameters: [String: AnyObject]) -> String {
  21. var components: [(String, String)] = []
  22. for key in sorted(Array(parameters.keys), [(String, String)] {
  23. var components: [(String, String)] = []
  24. if let dictionary = value as? [String: AnyObject] {
  25. for (nestedKey, value) in dictionary {
  26. components += queryComponents( "\(key)[\(nestedKey)]" , value)
  27. }
  28. } else   if let array = value as? [AnyObject] {
  29. for value in array {
  30. components += queryComponents( "\(key)" , value)
  31. }
  32. } else {
  33. components.extend([(escape(key), escape( "\(value)" ))])
  34. }
  35.  
  36. return components
  37. }
  38. func escape(string: String) -> String {
  39. let legalURLCharactersToBeEscaped: CFStringRef = ":&=;+!@#$()',*"  
  40. return CFURLCreateStringByAddingPercentEscapes(nil, string, nil, legalURLCharactersToBeEscaped, CFStringBuiltInEncodings.UTF8.rawValue) as String
  41. }
  42. }

Modify the previous function call:

  1. @IBAction func mainButtonBeTapped(sender: AnyObject) {
  2. Network.request( "GET" , url: "http://pitayaswift.sinaapp.com/pitaya.php" , params: [ "get" : "Network" ]) { (data, response, error) -> Void in
  3. let string = NSString(data: data, encoding: NSUTF8StringEncoding)
  4. println(string)
  5. }
  6. }

http://pitayaswift.sinaapp.com/pitaya.php is the server code I deployed for testing, which will directly return ooxx in ?get=ooxx. Run the project and click the button to see the effect:

POST method

There are several protocols to choose from under the POST method. There is no file upload here, so we use the simpler application/x-www-form-urlencoded method to send the request. Add some code to the request() method:

  1. static func request(method: String, url: String, params: Dictionary = Dictionary(), callback: (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void) {
  2. let session = NSURLSession.sharedSession()
  3.  
  4. var newURL = url
  5. if method == "GET" {
  6. newURL += "?" + Network().buildParams(params)
  7. }
  8.  
  9. let request = NSMutableURLRequest(URL: NSURL(string: newURL)!)
  10. request.HTTPMethod = method
  11.  
  12. if method == "POST" {
  13. request.addValue( "application/x-www-form-urlencoded" , forHTTPHeaderField: "Content-Type" )
  14. request.HTTPBody = Network().buildParams(params).dataUsingEncoding(NSUTF8StringEncoding)
  15. }
  16.  
  17. let task = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
  18. callback(data: data, response: response, error: error)
  19. })
  20. task.resume()
  21. }

Modify the previous function call:

  1. @IBAction func mainButtonBeTapped(sender: AnyObject) {
  2. Network.request( "POST" , url: "http://pitayaswift.sinaapp.com/pitaya.php" , params: [ "post" : "Network" ]) { (data, response, error) -> Void in
  3. let string = NSString(data: data, encoding: NSUTF8StringEncoding)
  4. println(string)
  5. }
  6. }

Use POST to send a request, and the server will also return the value of the key post. Run the project and click the button. The result is the same as the previous GET method.

At this point, the interface encapsulation is completed!

<<:  Three steps to write an iOS network request library yourself

>>:  Write an iOS network request library yourself - reduce coupling

Recommend

New Media Operations丨Operator Cases, Essential Collection Tools

A good idea or activity. It does not necessarily ...

What is channel operation?

Channel , we all know that channel has a synonym:...

What? Turner and Monet paintings can also be used to study air pollution!

Perhaps you will say: Shouldn’t air be colorless ...

How to screen mini program development companies?

As the title says, WeChat mini programs are very ...

Flowers and bees are a perfect match. What tools do they use to collect nectar?

A bee lands on a flower to collect nectar (Photo/...

This formula teaches you how to create popular screen-sweeping cases!

On the Internet, we should regard advertising con...

The era of smart TV aggregation may come with more than 100 million users

As an important output screen for home entertainm...