-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathContents.swift
More file actions
118 lines (97 loc) · 3.12 KB
/
Contents.swift
File metadata and controls
118 lines (97 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*:
# JSONCodable
Hassle-free JSON encoding and decoding in Swift
`JSONCodable` is made of two seperate protocols `JSONEncodable` and `JSONDecodable`.
`JSONEncodable` generates `Dictionary`s (compatible with `NSJSONSerialization`) and `String`s from your types while `JSONDecodable` creates structs (or classes) from compatible `Dictionary`s (from an incoming network request for instance)
*/
import JSONCodable
/*:
Here's some data models we'll use as an example:
*/
struct User {
let id: Int
let name: String
var email: String?
var company: Company?
var friends: [User] = []
}
struct Company {
let name: String
var address: String?
}
/*:
## JSONEncodable
We'll add conformance to `JSONEncodable`. You may also add conformance to `JSONCodable`.
*/
extension User: JSONEncodable {
func toJSON() throws -> AnyObject {
return try JSONEncoder.create({ (encoder) -> Void in
try encoder.encode(id, key: "id")
try encoder.encode(name, key: "full_name")
try encoder.encode(email, key: "email")
try encoder.encode(company, key: "company")
try encoder.encode(friends, key: "friends")
})
}
}
extension Company: JSONEncodable {}
/*:
The default implementation of `func toJSON()` inspects the properties of your type using reflection. (Like in `Company`.) If you need a different mapping, you can provide your own implementation (like in `User`.)
*/
/*:
## JSONDecodable
We'll add conformance to `JSONDecodable`. You may also add conformance to `JSONCodable`.
*/
extension User: JSONDecodable {
init(object: JSONObject) throws {
let decoder = JSONDecoder(object: object)
id = try decoder.decode("id")
name = try decoder.decode("full_name")
email = try decoder.decode("email")
company = try decoder.decode("company")
friends = try decoder.decode("friends")
}
}
extension Company: JSONDecodable {
init(object: JSONObject) throws {
let decoder = JSONDecoder(object: object)
name = try decoder.decode("name")
address = try decoder.decode("address")
}
}
/*:
Simply provide the implementations for `init?(JSONDictionary: JSONObject)`. As before, you can use this to configure the mapping between keys in the `Dictionary` to properties in your structs and classes.
*/
/*:
## Test Drive
You can open the console and see the output using `CMD + SHIFT + Y` or ⇧⌘Y.
Let's work with an incoming JSON Dictionary:
*/
let JSON = [
"id": 24,
"full_name": "John Appleseed",
"email": "john@appleseed.com",
"company": [
"name": "Apple",
"address": "1 Infinite Loop, Cupertino, CA"
],
"friends": [
["id": 27, "full_name": "Bob Jefferson"],
["id": 29, "full_name": "Jen Jackson"]
]
]
print("Initial JSON:\n\(JSON)\n\n")
/*:
We can instantiate `User` using one of provided initializers:
- `init(JSONDictionary: JSONObject)`
- `init?(JSONString: String)`
*/
let user = try! User(object: JSON)
print("Decoded: \n\(user)\n\n")
/*:
And encode it to JSON using one of the provided methods:
- `func JSONEncode() throws -> AnyObject`
- `func JSONString() throws -> String`
*/
let dict = try! user.toJSON()
print("Encoded: \n\(dict as! JSONObject)\n\n")