swift enum codable
enum에서 codable을 채택하면 바로 안 되고,
1 |
Type 'FileType' does not conform to protocol 'Decodable' |
1 |
Type 'FileType' does not conform to protocol 'Encodable' |
뜨는 상황이 발생한다.
이유는 enum이 rawValue로 String 또는 Int를 채택하지 않아서 그렇다. (json 데이터라고 생각하면 당연한 것 같다.)
별도의 인자가 없는 경우에는 아래와 같이 수동으로(?) 인코딩, 디코딩을 해주면 된다. (사실 그냥, 문제가 없다면 rawValue를 채택하는 게 좋아보인다.)
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 |
enum FileType { case `default` case directory case link } extension FileType: Codable { enum ErrorType: Error { case encoding case decoding } init(from decoder: Decoder) throws { let value = try decoder.singleValueContainer() let decodedValue = try value.decode(String.self) switch decodedValue { case "default": self = .default case "directory": self = .directory case "link": self = .link default: throw ErrorType.decoding } } func encode(to encoder: Encoder) throws { var contrainer = encoder.singleValueContainer() switch self { case .default: try contrainer.encode("default") case .directory: try contrainer.encode("directory") case .link: try contrainer.encode("link") } } } let encoder = JSONEncoder() let decoder = JSONDecoder() let value = FileType.link let encodedData = try! encoder.encode(value) let decodedValue = try! decoder.decode(FileType.self, from: encodedData) |
만약 enum의 case에서 인자를 받았다면 아래의 stackoverflow를 참조하여 codingKey를 이용해서 case 별로 받은 인자를 추가적으로 인코딩, 디코딩해주면 좋을 것 같다. (container(keyedBy: CodingKey.Protocol) 사용.)
https://stackoverflow.com/questions/44580719/how-do-i-make-an-enum-decodable-in-swift-4/44582674