Open6

IOSアプリで所持NFT一覧を確認できるアプリを作りたい!

飯泉一馬(いいずみかずま)飯泉一馬(いいずみかずま)

SwiftUIのアーキテクチャにはMVVMとTCAというのが存在するらしい
MVVM(Model View ViewModel)
メリット:SwiftUI以前のデファクト、多くのIOSアプリはこの形式に則ってるらしい
デメリット;SwiftUI登場で、ViewModelの存在が疑われてる、状態管理が大規模になると弱い

TCA(The Compatible Architecture)
メリット:状態管理に強い
デメリット:学習コスト高い

飯泉一馬(いいずみかずま)飯泉一馬(いいずみかずま)

とりあえず、今回は小規模のアプリなので、MVVMにする。

Model

import SwiftUI

struct NftResponse: Codable {
    var ownedNfts: [Nft]
}

struct Nft: Codable {
    var title: String
}

Modelの役割

使用する構造体の変数群を設定する

細かいメモ

Codable
プロトコルという呼び方をしているが、インターフェイスに近いのだと思う。
encodeとdecodeを手軽にできるようになっているらしい

飯泉一馬(いいずみかずま)飯泉一馬(いいずみかずま)

Model View

import SwiftUI

class NftViewModel: ObservableObject {
    @Published var ownedNfts: [Nft] = []
    private let baseURL = "" // APIのエンドポイント
    
    func fetchEvents() {
        guard let url = URL(string: baseURL) else { return }
        
        URLSession.shared.dataTask(with: url) { data, _, _ in
            if let data = data, let response = try? JSONDecoder().decode(NftResponse.self, from: data) {
                DispatchQueue.main.async {
                    self.ownedNfts = response.ownedNfts
                }
            }
        }.resume()
    }
}

@Published
@Publishedは、外部のstructに対して変更の監視と再描画を行う際に必要になるプロパティラッパーのようです。@Stateに変更しても良いかと思ったのですが、chatGPTに怒られました(笑)

guard
guardは特定の条件が満たされなかった際にすぐに早期退出するべきに使用されます。

guard 条件 else {
    // 条件がfalseの場合に実行されるコード
    return // またはbreak, throw, continueなど
}
飯泉一馬(いいずみかずま)飯泉一馬(いいずみかずま)

View

import SwiftUI

struct NftListView: View {
    @StateObject var viewModel = NftViewModel()
    
    var body: some View {
        NavigationView {
            List(viewModel.ownedNfts, id: \.title) { event in
                Text(event.title)
            }
            .navigationBarTitle("Nft Titles", displayMode: .inline)
            .onAppear(perform: viewModel.fetchEvents)
        }
    }
}
List(viewModel.ownedNfts, id: \.title) { nft in
                Text(nft.title)
            }

ts/jsのマップ構文見たいなイメージ、第一引数に配列変数、第二引数はidとなっている、でその中を配列の個数分回るようなイメージ

onAppear
中のperformの処理が事前に行われて随時、画面が更新される仕組み、このコードで言うと、viewModel.fetchEventsが行われる。