@@ -1003,6 +1003,62 @@ class TestJSONEncoder : XCTestCase {
1003
1003
XCTAssertEqual ( result. dict. count, 0 )
1004
1004
}
1005
1005
1006
+ func test_decodingWithSuperclassSpecialization( ) throws {
1007
+ class Animal : Codable {
1008
+ let name : String
1009
+ init ( name: String ) {
1010
+ self . name = name
1011
+ }
1012
+ }
1013
+ class Cat : Animal {
1014
+ let isDomestic : Bool
1015
+ private enum CodingKeys : String , CodingKey {
1016
+ case isDomestic
1017
+ }
1018
+ init ( name: String , isDomestic: Bool ) {
1019
+ self . isDomestic = isDomestic
1020
+ super. init ( name: name)
1021
+ }
1022
+ required init ( from decoder: Decoder ) throws {
1023
+ let container = try decoder. container ( keyedBy: CodingKeys . self)
1024
+ isDomestic = try container. decode ( Bool . self, forKey: . isDomestic)
1025
+ try super. init ( from: container. superDecoder ( ) )
1026
+ }
1027
+ override func encode( to encoder: Encoder ) throws {
1028
+ var container = encoder. container ( keyedBy: CodingKeys . self)
1029
+ try container. encode ( isDomestic, forKey: . isDomestic)
1030
+ try super. encode ( to: container. superEncoder ( ) )
1031
+ }
1032
+ }
1033
+
1034
+ let myCat = Cat ( name: " Maru " , isDomestic: true )
1035
+ let myPet : Animal = myCat
1036
+ let petData : Data
1037
+ do {
1038
+ petData = try JSONEncoder ( ) . encode ( myPet)
1039
+ }
1040
+ catch {
1041
+ XCTFail ( " Failed to encode the object: \( error) " )
1042
+ return
1043
+ }
1044
+
1045
+ let decodedPet : Animal
1046
+ do {
1047
+ decodedPet = try JSONDecoder ( ) . decode ( type ( of: myPet) , from: petData)
1048
+ }
1049
+ catch {
1050
+ XCTFail ( " Failed to decode the object: \( error) " )
1051
+ return
1052
+ }
1053
+
1054
+ guard let decodedCat = decodedPet as? Cat else {
1055
+ XCTFail ( " The decoded animal is not a cat " )
1056
+ return
1057
+ }
1058
+ XCTAssertEqual ( decodedCat. isDomestic, myCat. isDomestic)
1059
+ XCTAssertEqual ( decodedCat. name, myCat. name)
1060
+ }
1061
+
1006
1062
// MARK: - Helper Functions
1007
1063
private var _jsonEmptyDictionary : Data {
1008
1064
return " {} " . data ( using: . utf8) !
0 commit comments