Деинит ViewModel в MVVM с помощью SwiftUI

#ios #mvvm #swiftui

#iOS #mvvm #swiftui

Вопрос:

Я изучаю MVVM с помощью SwiftUI, и у меня проблема с деинициализацией ViewModel. Представление использует ListView для отображения данных из ViewModel. Если я перейду к классу Detail строки ListView, а затем вернусь к ListView, приложение создаст дубликаты данных. Например: если в списке 100 элементов, и я перехожу к подробному просмотру строки списка, а затем возвращаюсь назад, теперь это 200 элементов и так далее. Как это остановить?

Просмотр списка:

 import SwiftUI
import KingfisherSwiftUI

struct ListView: View {

@ObservedObject var viewModel = ListViewModel()
@State private var searchText = ""

var body: some View {
    NavigationView {
        
        VStack {
        SearchBar(text: $searchText)
            .padding(.top, -30)
        
        List(viewModel.itemsList) { item in
            NavigationLink(destination: ListDetail()) {
                
                HStack {
                    
                    KFImage(URL(string: String(item.thumbnailUrl)))
                        .resizable()
                        .frame(width: 80, height: 80)
                        .padding(EdgeInsets(top: 10, leading: 0, bottom: 10, trailing: 0 ))
                    
                }
                
                VStack(alignment: .leading) {
                    Text(item.title)
                        .padding(.top, -10)
                        .padding(.bottom, 10)
                    
                    Text(item.albumTitle)
                        .font(.system(size: 12))
                        .padding(.bottom, 0)
                    
                }
                .padding(.leading, 10)
                .padding(.trailing, 20)
            }
        }
            }
            .onAppear {
                self.viewModel.fetchPhotos()
        }
    }
    }
}
  

ListViewModel:

 import SwiftUI
import Combine

class ListViewModel: ObservableObject {

private let persistenceService = PersistenceService()

@Published var albumsList = [Album]()
@Published var photosList = [Photo]()
@Published var usersList = [User]()
@Published var itemsList = [ListItem]()


func fetchAlbums() {
    albumsList  = persistenceService.fetchAlbums()
}

func fetchPhotos() {
    photosList  = persistenceService.fetchPhotos()
    
    fetchAlbums()
    if albumsList.count > 0 amp;amp; photosList.count > 0 {
        setItemList()
    }
}

func setItemList() {
    
    if albumsList.count > 0 amp;amp; photosList.count > 0 {
        let photo: Photo
        let album: Album
        
        itemsList = photosList.compactMap { photo in
            guard let album = albumsList.first(where: { $0.id == photo.id}) else {
                return nil
            }
            return ListItem(id: album.id, title: photo.title, albumTitle: album.title, thumbnailUrl: photo.thumbnailUrl)
        }
        
        print("Items  (itemsList.count)")
    }
    
}
}
  

Ответ №1:

Одним из способов избежать дублирования данных было бы переместить выборку фотографий из onAppear метода в init . Поэтому вместо

 .onAppear {
    self.viewModel.fetchPhotos()
}
  

сделайте это так

 init() {
    self.viewModel.fetchPhotos()
}