web-dev-qa-db-ja.com

Swift 4のCodableからプロパティを除外する方法

Swfit 4の新しいEncodable/Decodableプロトコルは、JSON(デ)シリアライゼーションを非常に快適にします。ただし、エンコードするプロパティとデコードするプロパティをきめ細かく制御する方法はまだ見つかりません。

付随するCodingKeys enumからプロパティを除外すると、プロセスからプロパティが完全に除外されることに気付きましたが、よりきめ細かい制御を行う方法はありますか?

62
RamwiseMatt

エンコード/デコードするキーのリストは、CodingKeysと呼ばれるタイプによって制御されます。コンパイラーはこれを合成できますが、いつでもオーバーライドできます。

プロパティnicknameをエンコード/デコードしたくないとしましょう。

struct Person: Codable {
    var firstName: String
    var lastName: String
    var nickname: String?

    private enum CodingKeys: String, CodingKey {
        case firstName
        case lastName
    }
}

これにより、エンコード時のnicknameが除外されますおよびデコード。


非対称にする(つまり、エンコードするがデコードしない、またはその逆)場合は、encode(with encoder: )およびinit(from decoder: )の独自の実装を提供する必要があります。

struct Person: Codable {
    var firstName: String
    var lastName: String

    // Since fullName is a computed property, it's excluded by default
    var fullName: String {
        return firstName + " " + lastName
    }

    private enum CodingKeys: String, CodingKey {
        case firstName
        case lastName
        case fullName
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        firstName = try container.decode(String.self, forKey: .firstName)
        lastName = try container.decode(String.self, forKey: .lastName)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(firstName, forKey: .firstName)
        try container.encode(lastName, forKey: .lastName)
        try container.encode(fullName, forKey: .fullName)
    }
}
118
Code Different

プロトコル(およびその拡張機能)をAssociatedObjectと共に使用して、イメージ(またはCodableから除外する必要があるプロパティ)プロパティを設定および取得しました。

これにより、独自のエンコーダーとデコーダーを実装する必要がなくなります

コードは次のとおりです。簡単にするために関連するコードを保持します。

protocol SCAttachmentModelProtocol{
    var image:UIImage? {get set}
    var anotherProperty:Int {get set}
}
extension SCAttachmentModelProtocol where Self: SCAttachmentUploadRequestModel{
    var image:UIImage? {
        set{
            //Use associated object property to set it
        }
        get{
            //Use associated object property to get it
        }
    }
}
class SCAttachmentUploadRequestModel : SCAttachmentModelProtocol, Codable{
    var anotherProperty:Int
}

これで、Imageプロパティにアクセスするたびに、プロトコル(SCAttachmentModelProtocol)を確認するオブジェクトで使用できます。

0
infiniteLoop

これはcan実行できますが、最終的には非常にnSwiftyになり、さらにnJSONyになります。 #idsの概念はHTMLで一般的ですが、JSONの世界に転送されることはめったにありません良いこと =(TM)。

いくつかのCodable構造体は、再帰的ハッシュを使用して再構成する場合、つまりJSONの配列がrecipeの配列のみを含む場合、ingredientsファイルを適切に解析できます。 (1つまたは複数)ingredient_infoを含む。そうすれば、パーサーは最初にネットワークをつなぎ合わせるのに役立ち、単純なトラバーサル構造を介していくつかのバックリンクを提供するだけで済みます本当に必要な場合。これにはJSONandのデータ構造を徹底的に作り直す必要があるため、考えてみてください。あなたがそれを受け入れられると思うなら、コメントで私に教えてください、それから私はそれをさらに詳述することができます、しかし状況によっては、あなたはそれらのいずれかを変える自由にないかもしれません。

0
Patru

構造内の多数のプロパティセットからいくつかのプロパティのデコードを除外する必要がある場合は、それらをオプションプロパティとして宣言します。オプションをアンラップするコードは、CodingKey列挙型で多くのキーを記述するよりも少ないです。

0