Skip to content

노래 track list를 만들어보자! (part2: List로 보여주기 및 ViewModel적용하기)

강병민 (Byungmin Kang) edited this page Nov 23, 2020 · 1 revision
class TrackListViewModel: ObservableObject {
    @Published var tracks = [Track]()
    
    func fetchTracks() {
        self.tracks = [Track(id: 1, title: "Dyanamite", artist: "방탄소년단", isFavorite: true),
                       Track(id: 2, title: "Blooming", artist: "아이유", isFavorite: false),
                       Track(id: 3, title: "Feel Good", artist: "프로미스나인", isFavorite: true),
                       Track(id: 4, title: "Alone", artist: "Marshmello", isFavorite: false)
        ]
    }
    
    func toggleIsFavorite(for id: Int) {
        if let index = tracks.firstIndex(where: { $0.id == id }) {
            tracks[index].isFavorite.toggle()
        }
    }
    
}

ViewModel에는 buisnesslogic을 담당합니다

fetchTracks를 해서 노래 목록을 가져오고 toggleIsFavorite는 선택된 노래의 "좋아요"를 toogle할수 있습니다

아직 네트워킹은 구현하지 못했기 때문에 dummy data를 넣었습니다.

이 ViewModel의 가장 큰 특징은

class TrackListViewModel: **ObservableObject 와** @Published var tracks = Track 두개입니다

iOS13 부터 적용된 Combine을 이용해서 View와 Model간의 Binding이 가능하게 합니다.

TrackListView는 이 Viewmodel을 갖고있습니다

단 이떄 ViewModel이 업데이트 되었다는것을 SwiftUI에게 알려주기 위해서 @ObservedObject 를 앞에 붙여줍니다.

import SwiftUI

struct TrackListView: View {
    
    @ObservedObject private var viewModel = TrackListViewModel()
    
    var body: some View {
        List {
            ForEach(viewModel.tracks) { track -> TrackCell in
                TrackCell(track: track, didToggleFavorite: {
                    viewModel.toggleIsFavorite(for: track.id)
                })
            }
        }
        .onAppear(perform: {
            viewModel.fetchTracks()
        })
    }
}

struct TrackListView_Previews: PreviewProvider {
    static var previews: some View {
        TrackListView()
    }
}

이렇게하면 toggleIsFavorite 을 할때 Model인 tracks가 업데이트 되고,

TrackListViewModel는 objectWillChange Publisher를 통해서 View에게 알립니다.

Clone this wiki locally