Swift uses reflection to serialize custom object data into JSON data

Source: Internet
Author: User
Tags extend json reflection

We know that Apple has launched the SDK's own JSON solution nsjsonserialization from IOS5.0, a very useful JSON generation and resolution tool, and more efficient than other third-party open-source projects.
But there is a limit to using it to generate JSON data: Only Foundation objects can be converted to JSON. That is, the top-level object must be Nsarray or nsdictionary, and all objects must be instances of NSString, NSNumber, Nsarray, Nsdictionary, Nsnull.
So, if we want to turn a custom type of data object into JSON data, nsjsonserialization is powerless.

1, the implementation principle of converting custom objects into JSON data (without the help of the third Third-party)

(1) First of all, we use reflection (Reflection) to recursively iterate over all the attributes in a data object of a custom type, generating a dictionary type of data and returning it.
(2) then use Nsjsonserialization to convert this dictionary type of data into JSON data.

2, for example, we customize one of the contact human

User class
Class User {
var name:string = ""/Name
var nickname:string? Nickname
var age:int? Age
var emails:[string]? Mailing Address
var tels:[telephone]? Phone
}

Phone structure Body
struct Telephone {
var title:string//Phone title
var number:string//Phone number
}

The realization of the function of 3,json string generation

(1) First define a protocol called JSON and extend it to implement the two methods defined in the protocol.
Tojsonmodel (): Converts data to a usable JSON model.
toJSONString (): Converts data into a JSON string (the previous Tojsonmodel () method is called internally).
(2) Extend the optional type (Optional), the custom Class (User, Teletelephone), and the base data type to conform to the JSON protocol.
The Tojsonmodel () method is also overridden for optional types in order to return nil when an optional type value does not exist, and to convert it to a specific type when it exists and to serialize.

Customizing a JSON protocol
Protocol JSON {
Func Tojsonmodel ()-> anyobject?
Func tojsonstring ()-> String?
}

Extended Protocol method
Extension JSON {
converting data to a usable JSON model
Func Tojsonmodel ()-> anyobject? {
Let mirror = Mirror (reflecting:self)
If Mirror.children.count > 0 {
var result: [String:anyobject] = [:]
For case let (label., value) in Mirror.children {
Print ("Properties: \ (label) value: \ (value)")
If let Jsonvalue = value as? JSON {
Result[label] = Jsonvalue.tojsonmodel ()
}
}

return result
}
Return self as? Anyobject
}

Turn data into a JSON string
Func tojsonstring ()-> String? {
Let Jsonmodel = Self.tojsonmodel ()
Using the JSON Library of OC to convert NSData to OC,
Let data:nsdata! = try? Nsjsonserialization.datawithjsonobject (jsonmodel!, Options: [])
NSData converted to NSString print output
Let str = NSString (Data:data, encoding:nsutf8stringencoding)
Return str as String?
}
}

Extend an optional type so that it follows the JSON protocol
Extension Optional:json {
Optional type override Tojsonmodel () method
Func Tojsonmodel ()-> anyobject? {
If let x = self {
If let value = x as? JSON {
Return Value.tojsonmodel ()
}
}
return Nil
}
}

Extend two custom types so that they follow the JSON protocol
Extension User:json {}
Extension Telephone:json {}

Expand Swift's basic data type to conform to the JSON protocol
Extension String:json {}
Extension Int:json {}
Extension Bool:json {}
Extension Dictionary:json {}
Extension Array:json {}

4, test sample

Create a user instance object
Let User1 = User ()
User1.name = "Hangge"
User1.age = 100
User1.emails = ["hangge@hangge.com", "system@hangge.com"]
Add animation
Let Tel1 = telephone (title: "Mobile", Number: "123456")
Let Tel2 = telephone (title: "Company Landline", Number: "001-0358")
User1.tels = [Tel1, Tel2]

Output JSON string
Print (user1.tojsonstring ()!)
See the console output with the following information:
Original: Swift-serializes custom object data into JSON data using reflection

The formatted data is as follows:
{
"Tels": {
"[1]": {
"Number": "001-0358",
"title": "Company Landline"
},
"[0]": {
"Number": "123456",
"title": "Mobile"
}
},
"Age": 100,
"Name": "Hangge",
"Emails": {
"[1]": "System@hangge.com",
"[0]": "Hangge@hangge.com"
}
}

Using third party libraries-Jsonkit


1, new Bridge Street file Bridging-header.h, and set into the compilation parameters
1 #include "JSONKit.h"
2, import the Jsonkit library files into the project (JSONKit.h and JSONKIT.M)
3, the compiler will find the error, this is because the Jsonkit library does not support the OBJECTIVE-C automatic reference counting function caused.
In Build phases-> Compile Sources-> jsonkit.m, double-click Add Comipler flag:-fno-objc-arc. This completes the configuration that does not support automatic reference counting.

Test code:

Import Uikit

Class Viewcontroller:uiviewcontroller {

Override Func Viewdidload () {
Super.viewdidload ()
Testjson ()
}

Override Func didreceivememorywarning () {
Super.didreceivememorywarning ()
}

Func Testjson () {
Swift Dictionary Object
Let user = [
"Uname": "User1",
"Tel": ["mobile": "138", "Home": "010"]
]
Converting to a JSON string using Jsonkit
Let jsonstring = (user as nsdictionary). Jsonstring ()
Print (jsonstring);
Back to Dictionary by string parsing
Print (jsonstring.objectfromjsonstring () as! Nsdictionary)

Using Jsonkit to convert to a nsdata type of JSON data
Let Jsondata = (user as nsdictionary). Jsondata ()
Print (Jsondata);
Back to Dictionary by NSData Reverse parsing
Print (Jsondata.objectfromjsondata () as! Nsdictionary)
}
}

Output results:

{"uname": "User1", "tel": {"Home": "010", "mobile": "138"}}
{
Tel = {
home = 010;
Mobile = 138;
};
uname = user1;
}
<7b22756e 616d6522 3a227573 65723122 2c227465 6c223a7b 22686f6d 65223a22 30313022 2c226d6f 62696c65 223a2231 3338227d 7 D>
{
Tel = {
home = 010;
Mobile = 138;
};
uname = user1;
}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.