Summary of Swift progress

Preface:

The last article analyzed the characteristics of the Mirror, as well as view the composition of the Mirror from the source point of view, according to the characteristics of the Mirror to think about a question, what can the long Mirror do? That brings us to Json parsing and Error handling, the subject of this article

Json parsing

Basic Json parsing

We define a LGTeacher class and then parse t through a test method

Analysis:

  • The mirror successfully reads the property name and value of the object, which can be stored and output using a dictionary

  • Each attribute is treated as an object by default, and mirror.children is used to determine whether the current object has an attribute. This ensures that all children are read with complete hierarchy information

  • Recursion is actually the use of stack properties, directly or indirectly call itself to achieve the requirements of the level of reading, recursion needs to have clear termination conditions

JSON parsing encapsulation

The Json parsing above is for a single class. If you want to use a generic class, you wrap the Json parsing, extract the Json parsing protocol, and then provide a default implementation to make the class comply with the protocol

CustomJSONMap{func jsonMap() -> Any} CustomJSONMap{func jsonMap() -> Any} Any{let mirror = mirror (reflecting: self) Mirror.children. IsEmpty else {return self} var keyValue: [String: Any] = [:] // For children in mirror.children {if let value = children.value as? CustomJSONMap {if let keyName = children.label {// Recursive keyValue[keyName] = value.jsonmap ()}else{print("key is nil")} }else{print(" current -\(children. Value) exception ")}} return keyValue}} class LGTeacher: CustomJSONMap {var name = "LGCat" var t = LGTeacher() print(t.jsonmap ())Copy the code

Abnormal printing:

If let value = children. Value as? CustomJSONMap is false. The subproject does not comply with the CustomJSONMap protocol, so it cannot be printed

Adjust the code so that the child nodes also comply with the CustomJSONMap protocol

Json package code, it can be seen that the object can be automatically parsed, but in the case of error I developed to the expected effect, so how to handle the error message Mirror scheme? See the analysis below

Error handling

The Error protocol is provided in Swift to identify the situation in which an Error occurs in the current application, as defined below:

public protocol Error {
}
Copy the code

Error is an empty protocol with no implementation, which means you can follow the protocol and then customize the Error type. So whether it’s our struct, Class, enum, we can follow this Error to indicate an Error.

So next, use enum to parse the JSON encapsulated above to modify its error handling.

Define a custom Error enumeration of an enumeration type to comply with the Error protocol, replacing the default implementation of print with an enumeration type

// Define error type enum JSONMapError: Error{case emptyKey case notConformProtocol} protocol CustomJSONMap {func jsonMap() -> Any} //2, provide a default implementation of extension CustomJSONMap{func jsonMap() -> Any{let mirror = mirror (reflecting: self) Mirror.children. IsEmpty else {return self} var keyValue: [String: Any] = [:] // For children in mirror.children {if let value = children.value as? CustomJSONMap {if let keyName = children.label {// Recursive keyValue[keyName] = value.jsonmap ()}else{return JSONMapError.emptyKey } }else{ return JSONMapError.notConformProtocol } } return keyValue } }Copy the code

With the jsonMap method in the above code, the return value is of type Any, but the JSONMapError protocol does not know what the return value is, so how to tell the difference? How do you throw an error? In this case, we can use the throw keyword to recursively call the jsonMap method, so we need to add the try keyword before the recursive call. The complete error expression is as follows:

Extension CustomJSONMap{func jsonMap() throws -> Any{let mirror = mirror (reflecting: self) // Recursive terminating conditions guard! Mirror.children. IsEmpty else {return self} var keyValue: [String: Any] = [:] // For children in mirror.children {if let value = children.value as? CustomJSONMap {if let keyName = children.label {// Recursive keyValue[keyName] = try value.jsonmap ()}else{throw JSONMapError.emptyKey } }else{ throw JSONMapError.notConformProtocol } } return keyValue } } var t = LGTeacher() print(try t.jsonMap())Copy the code

Reference: “Keywords throw and REthrows for Swift values”

How errors are handled in SWIFT

A: try

The easiest way to use the try keyword is to throw it to someone else (up, to the upper function). There are two things to note when using the try keyword:

  • try?Returns aOptional type, there are only two outcomes:

A: Either success, return the specific dictionary value

B: Either an error, but it doesn’t care what kind of error it is, returns nil

  • try!Use yourabsoluteConfident that this line of code is correct, this line of codeabsoluteNo errors will occur.

Second way: the do… catch

The answer can be found in the keywords throw and REthrows for Swift values

LocalizedError agreement

If Error alone is not enough to express more detailed Error information, you can use the LocalizedError protocol, which is defined as follows:

This protocol complies with the Error protocol, adding an extension to the JSONMapError enumeration, complies with the LocalizedError protocol, and can print more detailed Error messages

Extension JSONMapError: LocalizedError{var errorDescription: String? {switch self {case. emptyKey: return "key is empty "case. notConformProtocol: return" no "}}}Copy the code

CustomNSError agreement

CustomNSError is equivalent to NSError in OC

Specific code implementation:

//CustomNSError = NSError extension JSONMapError: CustomNSError{var errorCode: Int{switch self {case.emptyKey: return 404 case .notConformProtocol: return 504 } } }Copy the code

conclusion

  • The basic protocol for handling Error information in Swift is Error protocol, wherein LocalizedError and CustomNSError comply with Error protocol

  • The methods for handling error messages are do… Catch and try methods

  • To return normal values and error information at the same time, use the throw keyword together. Throw keyword must be added before the return value arrow of the method; otherwise, the throw keyword will report an error

  • Do not use try! If you are not confident that the code is working. Method to process exception information

  • In the use of a try? There are only two outcomes of nil or success