preface

Recently, when I was migrating Swift3, I met a very embarrassing thing. The Alamofire library supports iOS 9.0 at least, but our project must support iOS 8.0+. In order not to duplicate wheels, I decided to change to a lightweight network loading library

Talk is cheap, show me the code!

Request way

Just supports the following request modes: DELETE GET HEAD OPTIONS PATCH POST PUT

Synchronous request/asynchronous request

Just supports both synchronous and asynchronous requests, and Alamofre supports asynchronous requests, but most requests in our development are also done asynchronously

When we developed with Swift, we tended to avoid synchronous network requests because they would block the main thread, which would affect Cocoa/Cocoa Touch applications to refresh the UI. However, there’s no inherantly using synchronous requests, either. In fact, synchronized code is usually easier to understand.

Var r = Just. Get ()"http://httpbin.org/get", params:["page":) / /..."r" becomes available here
Copy the code

It is also very easy to make an asynchronous request

// Make an asynchronous request Just.get("http://httpbin.org/get", params:["page": 3]) { (r) in   
    // the same "r" is available asynchronously here
}
Copy the code

However, it is important to note that callback for asynchronous requests does not run on the main thread, so if we want to refresh the UI in callback we must use GCD or NSOperationQueue to return to the main thread ourselves

HTTP REQUEST

Although the simple examples above call specific GET/POST request methods, these methods end up calling JustAdaptor, which is a protocol, which shows the power of Swift protocol-oriented development. Show the code:

Public protocol JustAdaptor {func request(_ method: HTTPMethod, // request method URLString: String, // request address params: [String: Data: [String: Any], // Request parameters use dictionary style data: [String: Any], // Request parameters such as form data json: Any? Headers: [String: String], // Headers: [String: String], // The dictionary style of request header information files: [String: HTTPFile], // Upload files auth: Credentials? , // Authentication information cookies: [String: String], // Request cookie redirects: Bool, // Whether redirect timeout: Double is allowed? URLQuery: String? , // requestBody: Data? AsyncProgressHandler: TaskProgressHandler? AsyncCompletionHandler: ((HTTPResult) -> Void)? -> HTTPResult init(session: URLSession? , defaults: JustSessionDefaults?) }Copy the code

Simple Request

A simple GET request:

// No arguments Just. Get ("http://httpbin.org/get"){ (r) in// Just. Get ()"http://httpbin.org/get", params:["page": 3]) { (r) in// asynchronous request result}Copy the code

POST request A simple POST request:

Just.post("http://httpbin.org/post") { (r) in// asynchronous request result}Copy the code

There are many other ways of requesting that I won’t go into detail.

Cancel the request

There are both open requests and cancel requests

r.cancel()
Copy the code

More complex requests

If you want to send form data, you can use the data argument:

// The content-type header is added to application/x-form-www-encoded Just. Post ("http://httpbin.org/post", data:["firstName":"Barry"."lastName":"Allen"])
Copy the code

JSON data is the same

// The request body is JSON encoded // content-type'application/json'
Just.post("http://httpbin.org/post", json:["firstName":"Barry"."lastName":"Allen"])
Copy the code

Redirect

By default,Just follows the redirect Settings of the server. You can also control this behavior with allowRedirect

// redirects
Just.get("http://httpbin.org/redirect/2").isRedirect // false
// no redirects
Just.get("http://httpbin.org/redirect/2", allowRedirects:false).isRedirect // true
Copy the code

You can also set permanent Redirect

// permanent redirect
Just.get("http://httpbin.org/status/301", allowRedirects:false).isPermanentRedirect // true
// non permanent redirect
Just.get("http://httpbin.org/status/302", allowRedirects:false).isPermanentRedirect // false
Copy the code

FILES

Uploading files with Just is also simple

import Foundation

let elonPhotoURL = Bundle.main.url(forResource: "elon", withExtension: "jpg")!
let uploadResult = Just.post("http://httpbin.org/post", files:["elon": .url(elonPhotoURL, nil)]) // <== that's it
print(uploadResult.text ?? "")
Copy the code

In this case, the file is specified with an NSURL. Alternatively, a file can be an operation file data or just a string. But in both cases, a file name is required.

let someData = "Marco".data(using: String.Encoding.utf8)! 

if let text = Just.post(
    "http://httpbin.org/post",
    files:[
        "a":.data("marco.text", someData, nil), // a file of type Data"b":.text("polo.txt"."Polo"Nil) // a String file]).text {print(text)
}
Copy the code

You could do that;

if let json = Just.post(
    "http://httpbin.org/post",
    data:["lastName":"Musk"], // Parameter files:["elon":.url(elonPhotoURL, nil)] // file).json as? [String:AnyObject] {print(json["form"]???? [:]) // lastName:Muskprint(json["files"]???? [:]) // elon }Copy the code

LINK HEADERS

Many HTTP API headers add self-description to the API, such as Github’s paging API:

let gh = Just.head("https://api.github.com/users/dduan/repos?page=1&per_page=5")
gh.headers["link"]
 // <https://api.github.com/user/75067/repos?page=2&per_page=5>; rel="next", <https://api.github.com/user/75067/repos?page=9&per_page=5>; rel="last"
Copy the code

Just is easier to parse link headers:

gh.links["next"] / ["rel": "next"."url":"https://api.github.com/user/75067/repos?page=2&per_page=5"]
gh.links["last"] / ["rel": "last"."url":"https://api.github.com/user/75067/repos?page=9&per_page=5"]
Copy the code

COOKIE

If you want the server to return cookies you can do this:

// returns an NSHTTPCookie
Just.get("http://httpbin.org/cookies/set/name/elon", allowRedirects:false).cookies["name"]
Copy the code

Make a request with a cookie

Just.get("http://httpbin.org/cookies", cookies:["test":"just"]) // ok
Copy the code

AUTHENTICATION

If the request is authenticated by basic or digest authentication, provide the user name and password using an authentication parameter tuple

Just.get("http://httpbin.org/basic-auth/flash/allen", auth:("flash"."allen")) // ok
Copy the code

TIMEOUT

You can also set the timeout

Just.get("http://httpbin.org/delay/5", the timeout: 0.2). "reasonCopy the code

UPLOAD AND DOWNLOAD PROGRESS

Uploading and downloading files is also easy

Just.post(
    "http://httpbin.org/post",
    files:["large file":.text("or"."pretend this is a large file", nil)],
    asyncProgressHandler: { p inType // mode.upload or.download p.byte processed // Current size p.byte ExpectedToProcess // Total size p.cent // percentage}) {rin
    // finished
}
Copy the code

CUSTOMIZATION / ADVANCED USAGE

If you want to change some of the default Settings of Just, use JustSessionDefaults to customize the write customization

letmyJustDefaults = JustSessionDefaults( // NSJSONSerialization reading options JSONReadingOptions: . MutableContainers, // NSJSONSerialization writing options JSONWritingOptions:. PrettyPrinted, // headers:"OH":"MY"], // Multipart post request boundary:"Ju5tH77P15Aw350m3", // NSURLCredential persistence option credentialPersistence:. None, // en(de)codingfor HTTP body
    encoding: String.Encoding.utf8         
)
Copy the code

Use:

let just = JustOf<HTTP>(defaults: myJustDefaults)
just.post("http://httpbin.org/post").request? .allHTTPHeaderFields? ["OH"]????""
Copy the code

HTTP RESULT

The result of the HTTP request is placed in a single object Show the code:

public final class HTTPResult : NSObject {
  public final var content: Data?
  public var response: URLResponse?
  public var error: Error?
  public var request: URLRequest? { returntask? .originalRequest } public var task: URLSessionTask? public var encoding = String.Encoding.utf8 public var JSONReadingOptions = JSONSerialization.ReadingOptions(rawValue: 0) public var ok: Bool {returnstatusCode ! = nil && ! (statusCode! >= 400 && statusCode! < 600) } public var json: Any? {return content.flatMap {
      try? JSONSerialization.jsonObject(with: $0, options: JSONReadingOptions)
    }
  }

  public var statusCode: Int? {
    return(self.response as? HTTPURLResponse)? .statusCode } ......Copy the code

The ok or statusCode attributes are used to determine whether the request was successful

r.ok
r.statusCode
Copy the code

Other Descriptions:

R.healers // Response headers r.tent // Response body as NSData? r.text // response body as text? r.json // response body parsed by NSJSONSerielization r.url // the URL, as URL r.isRedirect // is this a redirect responseCopy the code

conclusion

Because my knowledge is short, there are mistakes in the article also hope to point out.