This is the 14th day of my participation in the August More Text Challenge
I spent the last two days reading Moya, a framework for encapsulating network requests based on Alamofire. Here are my reading notes.
RangeExpression
Here is the filter method for filtering network states:
func filter<R: RangeExpression> (statusCodes: R) throws -> Response where R.Bound = = Int {
guard statusCodes.contains(statusCode) else {
throw MoyaError.statusCode(self)}return self
}
Copy the code
RangeExpression is used when representing the range of statusCodes that can be received.
There are several types for representing ranges in Swift:
- Range: The element type requirements are met
Comparable
- Half Range: For example
0.. The < 10
; - Close range: for example
0... 10
;
- Half Range: For example
- Countable ranges, in contrast to ranges, have element types that need to be followed
Strideable
Protocol (integer step size) :- Countably half open range (
CountableRange
) :. Such as0.. The < 10
. - Countably closed range (
CountableClosedRange
) :. Such as0... 10
.
- Countably half open range (
- Partial range: refers to the partial range
.
或..<
The range constructed when used as a pre – or post-operator:.
As a postposition, for exampleCharacter("a")...
.
As a precursor, for example. Character("z")
..<
As a postposition, for example. The < 10
..<
As a precursor, for example10.. <
The eight types above all comply with the RangeExpression protocol.
Label statement — end prematurelyLooping statements
andConditional statements
In the Response class in Moya, there is a code that uses the tag statement:
let jsonData: Data
keyPathCheck: if let keyPath = keyPath {
guard let jsonObject = (try mapJSON(failsOnEmptyData: failsOnEmptyData) as? NSDictionary)?.value(forKeyPath: keyPath) else {
if failsOnEmptyData {
throw MoyaError.jsonMapping(self)}else {
jsonData = data
break keyPathCheck
}
}
if let data = try serializeToData(jsonObject) {
jsonData = data
} else {
// Omit some code}}else {
jsonData = data
}
// Omit the following operations on jsonData
Copy the code
In loops, the break statement is often used to terminate the loop prematurely.
In both Swift loop and conditional statements, the break + label statement can be used to prematurely terminate their execution. The code above is a good example of using the break keyPathCheck in the if condition when the if statement needs to be terminated prematurely and the following is executed. If the break + tag is not used here, subsequent operations on jsonData will have duplicate code.
Using breaks simplifies code, and inevitably makes it harder to read.
To avoid duplicate code, there are other ways:
- Pull out the code and add an instance method;
- Define a method or closure directly inside the method to handle similar logic.
Add a “parent” to an enum
The core Moya class MoyaProvider is defined as follows:
open class MoyaProvider<Target: TargetType> :MoyaProviderType {}Copy the code
When initializing the MoyaProvider, specify the specific type of the generic Target. The TargetType protocol is implemented using the enum type. If we need to split network requests into modules and put them into different enumerations, why should Target be specified?
If we implement the TargetType protocol using a class, we can create a parent class and specify the parent class type. However, enumeration (enum) types cannot be inherited.
Moya’s solution is MultiTarget:
public enum MultiTarget: TargetType {
/// The embedded `TargetType`.
case target(TargetType)
/// Initializes a `MultiTarget`.
public init(_ target: TargetType) {
self = MultiTarget.target(target)
}
// Omit some code
}
Copy the code
The MultiTarget design is very simple. It simply saves the target: TargetType passed in for initialization and implements the TargetType protocol with target. It achieves the polymorphism of the class (I can’t explain MultiTarget’s design pattern) :
MultiTarget
Specific representation by incomingtarget
Is responsible for, similar to how a subclass overrides its parent class;MultiTarget
Similar to the “parent class”, provides a unified interface externally.
If the expression is not accurate, welcome to correct, thank you.
reference
- Swift, advanced
- Swift-label statement