まずは、データモデルを作ります。
Userクラス、Friendクラス実装
JSONファイルをつらつらと眺めながら、Userクラスを作りました。あとで、Friendについても扱う必要が出てくることがわかっているので、合わせてFriendクラスも作成。
JSONファイルには、Tagというデータも見えますが、おそらくFriendと同様に処理できると思うので、無視します。
JSONファイル処理のために、必要になることがわかっているので、CodableをConformするようなクラスにしています。
以下のコードとなりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class User: Codable { var id:String var isActive: Bool var name:String var age: Int var company:String var email: String var address:String var about: String var registered: Date var friends:[Friend] } class Friend: Codable{ var id: String var name: String } |
簡単なタイプしか使用していないので、とくに問題なくコンパイルできます。
UserListクラス
複数のUserをリストとして処理する必要があるので、Userの配列を保持するUserListクラスを作ります。
User,Friendと同様にCodableにすると同時に、SwiftUIで使うことを考えて、ObservableObjectにもConformさせてます。
1 2 3 |
class UserList: Codable, ObservableObject { @Published var users:[User] } |
“no initializers”というエラーが出ます。
単純な”init() {}”というinitializerを実装するとこのエラーは消えますが、Encodable, DecodableにConformしていないというエラーに変わります。
CodableというProtocolは、 Decodable&Encodableですので、どちらにもConformしないといけません。
ドキュメントを確認すると、Decodableは、”init(from decoder: Decoder) throws”の実装を要求しています。
Encodableは、”func encode(to encoder: Encoder) throws”の実装を要求しています。
なにを実装しなければいけないかわかりましたので、実装していきます。このあたりは、パターン化されている箇所で、100DaysOfSwiftUIをここまでやってきた人であれば、何回か見ていると思います。
以下のようなコードになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
enum CodingKeys: CodingKey { case users } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) users = try container.decode([User].self, forKey: .users) } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(users, forKey: .users) } |
ちなみに、上記を実装すると、Initializerがすべてのプロパティを初期化していないと怒られますので、”init(){}”を”init(){users=[]}”に変更します。
ここまでで、基本的なデータモデルはできたことになります。
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 |
class UserList: Codable, ObservableObject { @Published var users:[User] init() { users = [] } enum CodingKeys: CodingKey { case users } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) users = try container.decode([User].self, forKey: .users) } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(users, forKey: .users) } } class User: Codable { var id:String var isActive: Bool var name:String var age: Int var company:String var email: String var address:String var about: String var registered: Date var friends:[Friend] } class Friend: Codable{ var id: String var name: String } |
SwiftUIで使っていくうちに、足りないものが出てくる気がしますが、それはおいおいと。
自分でいろいろと実験したくなっても、簡単に戻れます。
Sponsor Link