スウィフト3:あなたのモデルをあなたのアプリケーションから値型(構造体)にしたいとします。しかし、Core Data/Realmを使用してモデルを永続化することもできます。これは、クラスを作成する必要があります。 JSON(JSONの逆シリアル化とシリアライゼーションの両方をサポートする構造体とクラスが必要です)を使用して、構造体をクラスとその逆に変換できます。プロトコルの初期イニシャライザで望ましくない可変プロパティが必要です
あなたはJSONの直列化復元を記述する必要はありません(と同様に直列化のために、私はここに、逆シリアル化に焦点を当てています)2つの場所ではなく、プロトコルに入れて直列化復元を使用している場合、それはきちんとしたことはないでしょう、そのあなたの構造体とクラスの両方を使用します。
構造体を使用して、JSONモデルに不変フィールドを持たせて、すべてのプロパティがlet
の定数になるようにします。しかし、デシリアライズを実装したを使用しても、このAFAIKは許可されません。
次のコード例は、に動作しますが、それは理由コード内のコメントに記載されているすべての不要な要件(UR)の、醜いです。
struct JSON {
let json: [String: Any]
func value<Value>(_ key: String) throws -> Value {
guard let value = json[key] as? Value else { throw NSError() }
return value
}
}
protocol JSONDeserializable {
init(json: JSON) throws
}
protocol UserModel: JSONDeserializable {
var username: String { get set } // Unwanted requirement (UR) #1: property needs "set" so that it can be initialized within protocol
init() // UR2: needs empty init, because of default implementation of `init(json: JSON)` in `extension UserModel`
}
extension UserModel {
init(json: JSON) throws {
self.init() // UR3: Needs to call this otherwise compilation error: `'self' used before chaining to another self.init requirement`
username = try json.value("username")
}
}
struct UserStruct: UserModel {
// UR4: property cannot be `let`, beause of `set` in protocol.
var username: String = "" // UR5: Property have to have default value because of it being a empty init
init() {}
}
final class UserClass: NSObject, UserModel {
// UR6: analogue with UR4
var username: String = "" // UR7: analogue with UR5
}
let json: JSON = JSON(json: ["username": "Sajjon"])
let u1 = try UserStruct(json: json)
let u2 = try UserClass(json: json)
print(u1.username) // prints "Sajjon"
print(u2.username) // prints "Sajjon"
これを達成する別の方法が、不要な要件を少なくしていますか?または、URがゼロの最適解?
'init()'の代わりに 'UserModel'に' init(username:String) 'を指定するだけです。 – Hamish
提案をお寄せいただきありがとうございます。私は@Hamishという質問を更新してコードを繰り返しました... – Sajjon
'struct'sを使う利点は、この場合にはデフォルトのmemberwise initialiserに頼ることができるということです。 'UserStruct'の初期化子です。 – Hamish