Perfect implements a basic JSON codec tool through a series of extensions to Swift's self-built data types. Decoding is based on the extension of Swift string type.
The JSON library of Perfect is open source. Please click here to download and install Perfect's support for Swift JSON:
/PerfectlySoft/Perfect/
Please note that although Perfect's JSON tool is powerful, it is not necessary for your system. Please select the function in the reference tool library as required.
If you need to use this system, please make sure that the PerfectLib library function has declared import at the beginning of your source code:
Import PerfectLib
Encode data into JSON format
You can directly convert the following data types into JSON strings:
String string
Int integer
UInt unsigned integer
Double precision floating-point type
Boolean Boolean type
Any type of array
Dictionary A dictionary with strings as key words.
Optional optional type
Custom types inherited from the JSONConvertibleObject object
Please note that for optional types, only optional types containing any of the above types can be directly converted. For options with a value of nil, the output result of JSON string will be "null".
To realize the encoding of the above variable types, please call the jsonEncodedString () function of the above object. This function is a special extension of Perfect. This function may throw an exception jsonconversionerror. Notconvertible cannot be converted.
for instance
Let scoreArray: [String:Any] = ["first place": 300, "second place": 230.45, "third place": 150].
let encoded = try score array . jsonencodedstring()
The encoding result is the following string:
{"Second place": 230.45, "First place": 300, "Third place": 150}
Decoding JSON data
The jsonDecode () function can decode a string containing data in JSON format. If there is a problem with the format, this function will throw a syntax error exception of jsonconversionerror. Grammatical error.
Let encoded = "{\ "Second place \":230.45, \" First place \":300, \ "Third place \": 150}"
let decoded = try encoded . JSON decode()as? [String: any]
Decoding the above string will generate the following dictionary types:
["Second place": 230.499999, "First place": 300, "Third place": 150]
Since decoding JSON strings may produce arbitrary data values, the most common method is to handle them with JSON objects (dictionaries) or arrays. You need to transform yourself according to the expected type according to the result.
Use the decoded data.
Because the result of decoding is always a [String:Any] dictionary or an [Any] array, you need to convert the data it contains into the expected type, for example:
var firstPlace = 0
Var second position = 0.0
var thirdPlace = 0
Let encoded = "{\ "Second place \":230.45, \" First place \":300, \ "Third place \": 150}"
guard let decoded = try encoded . JSON decode()as? [String:Any] Other {
return
}
for (key,value) in decoded {
Switch key {
Case "first place":
firstPlace = value as! Internationalorganizations (same as international organizations)
Case "second place":
secondPlace = value as! double;twofold
Case "third place":
thirdPlace = value as! Internationalorganizations (same as international organizations)
Default value:
break
}
}
Print ("Top three: \r"+"\ (first place)" +"\r"+ "Second place:"+"(second place)"+"Third place:"+"\ (third place).
The output result is:
Top three:
First place: 300 points
Second place: 230.45 points
Third place: 150 points
Decoding null values from JSON data
Because the null value of JSON is untyped, the system will replace the null value with the JSONConvertibleNull object. For example:
Let jsonString = "{\ "First place \":300," Fourth place \":null, "Second place \":230.45," Third place \": 150} "
if let decoded = try JSON string . JSON decode()as? [String:Any] {
for (key,value) in decoded {
If let the value be? JSONConvertibleNull {
Print ("field \"\(key)\ "empty")
}
}
}
The output is:
The field "fourth bit" is empty.
Objects that can be converted into JSON.
Perfect's JSON transformation tool library provides the coding and decoding functions of custom classes. Just inherit from the JSONConvertibleObject base class, as shown in the following example:
///Inherit from the base class into a custom object that can be converted into JSON format.
Public class jsonconvertibleobject: jsonconvertible {
///Default constructor
public init() {}
///Get JSON key/value
public func setJSONValues(_ values:[String:Any]){ }
///Set object properties according to JSON key/value.
Public function getjsonvalues ()-> [String:Any]{ return[String:Any]()}
///Encode the object as JSON text
public func jsonEncodedString()throws-& gt; String {
return try self.getJSONValues()。 jsonEncodedString()
}
}
Any object that needs to use JSON codec must be registered in the system first. Registration needs to be completed at the beginning of your application. Call JSONDecoding. The RegisterJSondeCode function completes object registration. The function is defined as follows:
Public class JSONDecoding {
///This function returns a new instance for customizing objects based on JSON member data.
public type alias JSONConvertibleObjectCreator =()-& gt; JSONConvertibleObject
Static public func registerJSONDecodable (name: string, creator: JSONConvertibleObjectCreator)
}
The registered object needs a unique name. You also need a creator function to create a new object instance when needed.
When the system encodes the JSONConvertibleObject, the getJSONValues function of the object is called. This function returns a [String:Any] dictionary, which contains all fields and property values used to encode the object. The dictionary must contain a field that declares its object type. The value of this type field must also be the same as the name of the object registration at the beginning of the program. The field corresponding to the attribute value is determined by JSON decoding. ObjectIdentifierKey property.
When the system decodes such an object, the system will first look for the value of JSONDecoding. ObjectIdentifierKey, and then find the previously registered object creator constructor. Then the system will automatically create a new object according to this type and constructor, and call the setjsonvalues (_ values: [string: any]) function to set the value of each field. Calling this function will pass a dictionary containing all decoded data as a parameter. These attribute values will match what was previously returned by the getJSONValues encoding function. In the setJSONValues function, the object restores all properties and data.
The following example shows how to define a custom JSONConvertibleObject object and how to convert it into a JSON string. And then decoded and compared with the original object. Note that in this example, the object directly extracts the attribute value of the named field from the dictionary by calling the getJSONValue function. When the dictionary does not contain the specified field, it is allowed to return the default value.
This example is divided into the following parts.
Category definition
Class user: JSONConvertibleObject {
Static let registerName = "user "
var firstName = " "
var lastName = " "
var age = 0
Override funcsetjsonvalues (_ values: [string: any]) {
Self.firstName = getJSONValue (name: "firstName", from: values, defaultValue: "").
Self.lastName = getJSONValue (name: "lastName", from: values, defaultValue: "").
Self.age = getJSONValue (name: "age", from: values, defaultValue: 0).
}
Override funcgetjsonvalues ()-> [String : Any] {
Return [
JSON decoding . objectidentifier key:user . register name,
"name": name,
"Last name": Last name,
[Age]: Age
]
}
}
Register the defined category information
//Run it once.
JSONDecoding. RegisterJSondeCode (name: User.registerName, creator: {return User()})
Object encoding:
Let User = User ()
user.firstName = "Donnie "
user.lastName = "Darko "
user.age = 17
let encoded = try user . jsonencodedstring()
The coded data is as follows:
{"lastName":"Darko "," age": 17," _jsonobjid":"user "," firstName":"Donnie"}
Object decoding:
guard let user 2 = try encoded . JSON decode()as? Other users {
Error in return //
}
//Verify that the property values are consistent.
XCTAssert(user . first name = = user 2 . first name)
XCTAssert(user . last name = = user 2 . last name)
XCTAssert(user.age == user2.age)
JSON conversion error
During JSON encoding and decoding, the system may throw a JSONConversionError conversion exception, which is defined as follows:
Possible errors and exceptions in JSON encoding and decoding.
Public enumeration jsonversionerror: errorprotocol {
///The object does not support JSON transformation.
Case notConvertible (any)
///The field provided is not a string.
Case invalidKey (any)
///There is a syntax error in JSON text.
Case syntax error
}