Skip to content

Commit

Permalink
Added support for nested decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewcheok committed Sep 22, 2015
1 parent 2e95f3d commit 99fd634
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Demo/Demo/User.swift
Expand Up @@ -26,7 +26,7 @@ extension User: JSONCodable {
email = try JSONDictionary.decode("email")
company = try JSONDictionary.decode("company")
friends = try JSONDictionary.decode("friends")
website = try JSONDictionary.decode("website", transformer: JSONTransformers.StringToNSURL)
website = try JSONDictionary.decode("website.url", transformer: JSONTransformers.StringToNSURL)
}
catch {
print(error)
Expand Down
3 changes: 2 additions & 1 deletion Demo/Demo/ViewController.swift
Expand Up @@ -26,7 +26,8 @@ class ViewController: UIViewController {
"friends": [
["id": 27, "full_name": "Bob Jefferson"],
["id": 29, "full_name": "Jen Jackson"]
]
],
"website": ["url": "http://johnappleseed.com"]
]

print("Initial JSON:\n\(JSON)\n\n")
Expand Down
2 changes: 1 addition & 1 deletion JSONCodable.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'JSONCodable'
s.version = '1.0.0'
s.version = '1.1.0'
s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.10'
s.license = { :type => 'MIT', :file => 'LICENSE' }
Expand Down
37 changes: 27 additions & 10 deletions JSONCodable/JSONDecodable.swift
Expand Up @@ -65,10 +65,27 @@ public extension Array where Element: JSONDecodable {
// Dictionary convenience methods

public extension Dictionary where Value: AnyObject {
private func get(key: Key) -> AnyObject? {
guard let keyString = key as? String else {
return nil
}
let keys = keyString.componentsSeparatedByString(".")

return keys.reduce(self as? AnyObject) {
value, key in

guard let dict = value as? [String: AnyObject] else {
return nil
}

return dict[key]
}
}

// TODO: validate array elements
// optional array of decodables
public func decode<Element: JSONDecodable>(key: Key) throws -> [Element]? {
if let y = self[key] {
if let y = get(key) ?? self[key] {
guard let x = y as? [[String : AnyObject]] else {
throw JSONDecodableError.ArrayTypeExpectedError(key: key as! String, elementType: y.dynamicType)
}
Expand All @@ -79,7 +96,7 @@ public extension Dictionary where Value: AnyObject {

// required array of decodables
public func decode<Element: JSONDecodable>(key: Key) throws -> [Element] {
guard let y = self[key] else {
guard let y = get(key) ?? self[key] else {
return []
}
guard let x = y as? [[String : AnyObject]] else {
Expand All @@ -90,7 +107,7 @@ public extension Dictionary where Value: AnyObject {

// optional array of scalars
public func decode<Element: JSONCompatible>(key: Key) throws -> [Element]? {
if let y = self[key] {
if let y = get(key) ?? self[key] {
guard let x = y as? [Element] else {
throw JSONDecodableError.IncompatibleTypeError(key: key as! String, elementType: y.dynamicType, expectedType: [Element].self)
}
Expand All @@ -101,7 +118,7 @@ public extension Dictionary where Value: AnyObject {

// required array of scalars
public func decode<Element: JSONCompatible>(key: Key) throws -> [Element] {
guard let y = self[key] else {
guard let y = get(key) ?? self[key] else {
throw JSONDecodableError.MissingTypeError(key: key as! String)
}
guard let x = y as? [Element] else {
Expand All @@ -112,7 +129,7 @@ public extension Dictionary where Value: AnyObject {

// optional decodable
public func decode<Type: JSONDecodable>(key: Key) throws -> Type? {
if let y = self[key] {
if let y = get(key) ?? self[key] {
guard let x = y as? [String : AnyObject] else {
throw JSONDecodableError.DictionaryTypeExpectedError(key: key as! String, elementType: y.dynamicType)
}
Expand All @@ -123,7 +140,7 @@ public extension Dictionary where Value: AnyObject {

// required decodable
public func decode<Type: JSONDecodable>(key: Key) throws -> Type {
guard let y = self[key] else {
guard let y = get(key) ?? self[key] else {
throw JSONDecodableError.MissingTypeError(key: key as! String)
}
guard let x = y as? [String : AnyObject] else {
Expand All @@ -137,12 +154,12 @@ public extension Dictionary where Value: AnyObject {

// optional scalar
public func decode<Type: JSONCompatible>(key: Key) throws -> Type? {
return self[key] as? Type
return (get(key) ?? self[key]) as? Type
}

// required scalar
public func decode<Type: JSONCompatible>(key: Key) throws -> Type {
guard let y = self[key] else {
guard let y = get(key) ?? self[key] else {
throw JSONDecodableError.MissingTypeError(key: key as! String)
}
guard let x = y as? Type else {
Expand All @@ -153,7 +170,7 @@ public extension Dictionary where Value: AnyObject {

// optional transformable
public func decode<DecodedType, EncodedType>(key: Key, transformer: JSONTransformer<EncodedType, DecodedType>) throws -> DecodedType? {
if let y = self[key] {
if let y = get(key) ?? self[key] {
guard let x = y as? EncodedType else {
throw JSONDecodableError.IncompatibleTypeError(key: key as! String, elementType: y.dynamicType, expectedType: EncodedType.self)
}
Expand All @@ -168,7 +185,7 @@ public extension Dictionary where Value: AnyObject {

// required transformable
public func decode<DecodedType, EncodedType>(key: Key, transformer: JSONTransformer<EncodedType, DecodedType>) throws -> DecodedType {
guard let y = self[key] else {
guard let y = get(key) ?? self[key] else {
throw JSONDecodableError.MissingTypeError(key: key as! String)
}
guard let x = y as? EncodedType else {
Expand Down
2 changes: 1 addition & 1 deletion Supporting Files/Info.plist
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<string>1.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
Binary file added logo.sketch
Binary file not shown.

0 comments on commit 99fd634

Please sign in to comment.