怠慢プログラマーの備忘録

怠慢でナマケモノなプログラマーの備忘録です。

今更だけどCodableにハマったところ(備忘録)

※色々省略しています。

struct Hoge: EntityProtcol, Codable {
    
    let uid: String
    let hogeName: String
    let firstHoges1: [String: String?]
    let secondHoges1: [String: String?]  
    let thirdHoges1: [String: String?]
    
    init(uid: String,
         hogeName: String,
         firstHoges1: [String: String?],
         secondHoges1: [String: String?],
         thirdHoges1: [String: String?]) {
        
        self.uid = uid
        self.hogeName = hogeName
        self.firstHoges1 = firstHoges1
        self.secondHoges1 = secondHoges1
        self.thirdHoges1 = thirdHoges1
    }
    
    static func deserialize<T: EntityProtcol>(document: [String: Any]) -> T {
        let json = try! JSONSerialization.data(withJSONObject: document, options: [])
        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        return try! decoder.decode(JSSchoolExamEntity.self, from: json) as! T
    }
}

Firestoreからfetchする際にいつも通りデコードしていました。

問題1: 末尾の数字はsnakeにしてくれない

first_hoge_1 というKeyの場合 convertFromSnakeCase でコンバートしても first_hoge1 にしかなりません。

問題2: Key値の頭文字が数字

そもそもそんなKeyにするな問題はわかります。 しかし1st_hoge_1みたいなのに遭遇してしまった場合の対処策です。

このような時はCodingKeyを使用します。

enum CodingKeys: String, CodingKey {
        case uid
        case hogeName = "hoge_name"
        case firstHoges1 = "1st_hoge_1"
        case secondHoges1 = "2nd_hoge_1"
        case thirdHoges1 = "3rd_hoge_1"
    }

上記のコードをstruct内に放り込むだけです。

確かCodableがでた直後にこれは把握していたはずだけど備忘録として。

全体のコードが下記になります。

truct Hoge: EntityProtcol, Codable {
    
    let uid: String
    let hogeName: String
    let firstHoges1: [String: String?]
    let secondHoges1: [String: String?]  
    let thirdHoges1: [String: String?]
    
    init(uid: String,
         hogeName: String,
         firstHoges1: [String: String?],
         secondHoges1: [String: String?],
         thirdHoges1: [String: String?]) {
        
        self.uid = uid
        self.hogeName = hogeName
        self.firstHoges1 = firstHoges1
        self.secondHoges1 = secondHoges1
        self.thirdHoges1 = thirdHoges1
    }

    enum CodingKeys: String, CodingKey {
        case uid
        case hogeName = "hoge_name"
        case firstHoges1 = "1st_hoge_1"
        case secondHoges1 = "2nd_hoge_1"
        case thirdHoges1 = "3rd_hoge_1"
    }
    
    static func deserialize<T: EntityProtcol>(document: [String: Any]) -> T {
        let json = try! JSONSerialization.data(withJSONObject: document, options: [])
        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        return try! decoder.decode(JSSchoolExamEntity.self, from: json) as! T
    }
}

詳細! Swift iPhoneアプリ開発入門ノート iOS12 + Xcode 10対応

詳細! Swift iPhoneアプリ開発入門ノート iOS12 + Xcode 10対応