This repository has been archived by the owner on Feb 2, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
`DecoderType` is a new protocol that better encapsulates the idea of decoding an object from a given `JSON`. It allows for two abilities that `JSONDecodable` did not: 1) Multiple decoders for the same type can be defined. This is illustrated by the two `NSDate` decoders provided by Alexander. 2) The decoder type is separate from the type being decoded. `JSONDecodable` is now deprecated.
- Loading branch information
Showing
6 changed files
with
144 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// | ||
// DecoderType.swift | ||
// Alexander | ||
// | ||
// Created by Caleb Davenport on 11/18/15. | ||
// Copyright © 2015 Hodinkee. All rights reserved. | ||
// | ||
|
||
public protocol DecoderType { | ||
typealias Value | ||
static func decode(JSON: Alexander.JSON) -> Value? | ||
} | ||
|
||
extension JSON { | ||
public func decode<T: DecoderType>(decoder: T.Type) -> T.Value? { | ||
return decode(T.decode) | ||
} | ||
|
||
public func decodeArray<T: DecoderType>(decoder: T.Type) -> [T.Value]? { | ||
return decodeArray(T.decode) | ||
} | ||
} | ||
|
||
public struct NSTimeIntervalDecoder: DecoderType { | ||
public typealias Value = NSTimeInterval | ||
public static func decode(JSON: Alexander.JSON) -> Value? { | ||
return JSON.object as? NSTimeInterval | ||
} | ||
} | ||
|
||
public struct NSDateTimeIntervalSince1970Decoder: DecoderType { | ||
public typealias Value = NSDate | ||
public static func decode(JSON: Alexander.JSON) -> Value? { | ||
return NSTimeIntervalDecoder.decode(JSON).flatMap({ NSDate(timeIntervalSince1970: $0) }) | ||
} | ||
} | ||
|
||
public struct NSDateTimeIntervalSinceReferenceDateDecoder: DecoderType { | ||
public typealias Value = NSDate | ||
public static func decode(JSON: Alexander.JSON) -> Value? { | ||
return NSTimeIntervalDecoder.decode(JSON).flatMap({ NSDate(timeIntervalSinceReferenceDate: $0) }) | ||
} | ||
} | ||
|
||
public struct NSURLDecoder: DecoderType { | ||
public typealias Value = NSURL | ||
public static func decode(JSON: Alexander.JSON) -> Value? { | ||
return JSON.stringValue.flatMap({ NSURL(string: $0) }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// | ||
// UserDecoderTests.swift | ||
// Alexander | ||
// | ||
// Created by Caleb Davenport on 11/18/15. | ||
// Copyright © 2015 Hodinkee. All rights reserved. | ||
// | ||
|
||
import XCTest | ||
import Alexander | ||
|
||
final class UserDecoderTests: XCTestCase { | ||
func testDecodeValidUser() { | ||
let user = User(ID: "1", name: "Caleb") | ||
let object = [ "id": user.ID, "name": user.name ] | ||
let JSON = Alexander.JSON(object: object) | ||
guard let decodedUser = JSON.decode(UserDecoder) else { | ||
XCTFail() | ||
return | ||
} | ||
|
||
XCTAssertEqual(decodedUser.ID, user.ID) | ||
XCTAssertEqual(decodedUser.name, user.name) | ||
} | ||
|
||
func testDecodeValidUsersArray() { | ||
let users = [ | ||
User(ID: "1", name: "Caleb"), | ||
User(ID: "2", name: "Jon") | ||
] | ||
let object = [ | ||
"users": [ | ||
[ "id": users[0].ID, "name": users[0].name ], | ||
[ "id": users[1].ID, "name": users[1].name ] | ||
] | ||
] | ||
let JSON = Alexander.JSON(object: object) | ||
guard let decodedUsers = JSON["users"]?.decodeArray(UserDecoder) where decodedUsers.count == 2 else { | ||
XCTFail() | ||
return | ||
} | ||
|
||
XCTAssertEqual(decodedUsers.count, 2) | ||
|
||
XCTAssertEqual(decodedUsers[0].ID, users[0].ID) | ||
XCTAssertEqual(decodedUsers[0].name, users[0].name) | ||
|
||
XCTAssertEqual(decodedUsers[1].ID, users[1].ID) | ||
XCTAssertEqual(decodedUsers[1].name, users[1].name) | ||
} | ||
} | ||
|
||
struct User { | ||
var ID: String | ||
var name: String | ||
} | ||
|
||
struct UserDecoder: DecoderType { | ||
typealias Value = User | ||
static func decode(JSON: Alexander.JSON) -> Value? { | ||
guard let ID = JSON["id"]?.stringValue, let name = JSON["name"]?.stringValue else { | ||
return nil | ||
} | ||
return User(ID: ID, name: name) | ||
} | ||
} |