Let’s take a look at the request parameters in Alamofire. We are most familiar with using dictionaries to pass parameters, as follows:

let parameters: [String: Any] = ["a": 1."b": true]
AF.request("https://httpbin.org/get", parameters: parameters)
Copy the code

In fact, we can also pass it by model. But only if the model follows the Encodable protocol, as follows:

let parameters = struct { a: 1."b": true }
AF.request("https://httpbin.org/get", parameters: parameters)
Copy the code

Both ways are essentially insensitive to the caller. Here’s the story behind it.

Parameter format supported by Alamofire

A dictionary type

Support the use ofA dictionary typeCreate a request as follows:

1, 2 are needed to be studied today; 3 is the interceptor, see this article for details.

Parameters is an alias for a dictionary:

public typealias Parameters = [String: Any]
Copy the code

The encoder of this type is ParameterEncoding. It is responsible for placing Parameters of type into the request appropriately. ParameterEncoding is a protocol:

/// encoder to encode parameters to URLRequest.
/// Note: the argument is a dictionary type.
public protocol ParameterEncoding {
    func encode(_ urlRequest: URLRequestConvertible.with parameters: Parameters?). throws -> URLRequest
}
Copy the code

The protocol requires only a method that accepts URLRequestConvertible and dictionary arguments and needs to return URLRequest. The function of this method is clear: it is responsible for processing the URLRequest using the dictionary parameters passed in and returning the results. Anything that does this is called ParameterEncoding.

URLRequestConvertible represents a type convertible into URLRequest from which URLRequest can be obtained.

We can passA dictionary typeParameters, which are directly supported by the protocol. The class diagram for this section is as follows:

For URLEncoding:

  1. destinationControls where parameters are placed in the request. The default is automatic judgment based on the request method,[.get, .head, .delete]Put the parameters in the QUERY of the URL and the other methods in the httpBody.
  2. If the parameter has an array type, how to encode itarrayEncodingAttribute control; At the same timeboolEncodingThe property controls how to codeBoolType.

For JSONEncoding, it simply places the parameters in the Body of the request. Why, you ask? JSONEncoding changes the encoding argument to Data, which can only be transmitted through body, and sets the content-Type.

Encoding type

Support the use ofEncoding typeCreate a request as follows:

Parameters is actually a generic type. The encoder for this type of parameter is ParameterEncoder, which is also a protocol:

/// encoder to encode parameters to URLRequest.
/// Note: This method is generic, and the parameters are required to be encodable types.
public protocol ParameterEncoder {
    func encode<Parameters: Encodable> (_ parameters: Parameters? .into request: URLRequest) throws -> URLRequest
}
Copy the code

AlamofireTwo encoders are also implemented by default. As follows:

The design here is similar to that in the previous section, so I won’t go into details.

further

For the two parameter formats, their processing flow is roughly as follows:

Starting with the parameters in both formats and ending with the output in both formats, we can see:

  1. forJSONType of output due to system built – inJSONEncoderIt was created to encode this type, so it is the backing for both types of input.
  2. forkey=valeThe system does not support this function. So this part of the implementation is provided by the framework. Specific:
    1. Dictionary type input: directly inURLEncodingClass.
    2. Encodable type input: the proponents behind it areURLEncodedFormEncoderAnd it realizes the specific coding process.

conclusion

Today we learned the story behind processing request parameters in Alamofire. In summary, support for Encodable type parameters. Speaking of which, dictionaries are also supported for Encodable. Why is this type available in isolation? (Comment section discussion is welcome)