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 type
Create 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 type
Parameters, which are directly supported by the protocol. The class diagram for this section is as follows:
For URLEncoding:
destination
Controls 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.- If the parameter has an array type, how to encode it
arrayEncoding
Attribute control; At the same timeboolEncoding
The property controls how to codeBool
Type.
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 type
Create 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
Alamofire
Two 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:
- for
JSON
Type of output due to system built – inJSONEncoder
It was created to encode this type, so it is the backing for both types of input. - for
key=vale
The system does not support this function. So this part of the implementation is provided by the framework. Specific:- Dictionary type input: directly in
URLEncoding
Class. - Encodable type input: the proponents behind it are
URLEncodedFormEncoder
And it realizes the specific coding process.
- Dictionary type input: directly in
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)