#100DaysOfSwiftUI Day60 Challengeをやってみる(Step1:データモデル編)

まずは、データモデルを作ります。

Userクラス、Friendクラス実装

JSONファイルをつらつらと眺めながら、Userクラスを作りました。あとで、Friendについても扱う必要が出てくることがわかっているので、合わせてFriendクラスも作成。
JSONファイルには、Tagというデータも見えますが、おそらくFriendと同様に処理できると思うので、無視します。
JSONファイル処理のために、必要になることがわかっているので、CodableをConformするようなクラスにしています。
以下のコードとなりました。

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させてます。

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をここまでやってきた人であれば、何回か見ていると思います。

以下のようなコードになります。

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=[]}”に変更します。

ここまでで、基本的なデータモデルはできたことになります。

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で使っていくうちに、足りないものが出てくる気がしますが、それはおいおいと。

MEMO
Gitリポジトリを作成する設定でプロジェクトを作っているならば、ここで一旦Commitしておくのが良いです。
自分でいろいろと実験したくなっても、簡単に戻れます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です