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

How much does it cost to find an African to record a birthday blessing video?

In recent days, photos and videos of African blac...

How much does it cost to make a small program?

Nowadays, mini programs are becoming more and mor...

World Hate Cilantro Day丨Does cilantro smell good or bad to you?

Science Fiction Network, February 24 (Xu Mingyang...

Kitchen air conditioning is really not an IQ tax

Kitchen air conditioning is a rather unfamiliar c...

What should you do to plan an event that will go viral on WeChat Moments?

How to create an event that will go viral on WeCh...

Xiaohongshu KOL promotion: the secret of note ranking and weight algorithm!

Two months have passed since Xiaohongshu’s big pu...

Tips to make Tik Tok videos popular, how to make short videos popular?

Tips to make Tik Tok videos popular, how to make ...

A strange sight on the streets of Beijing: Mushrooms are smoking!

Review expert: Ji Hongzeng, PhD candidate in Powe...

Guide to submitting new apps to the App Store for review in Apple iOS 9

In the tenth lecture, we mentioned the details th...