成功获取请求后..无法使用组合订阅者.sink将数据转换为ViewModel Published var

问题描述 投票:0回答:0
  • 我正在从免费 API 获取数据到 @published var.. 成功
  • 然后在 ViewModel 中,我订阅了 @published var 并尝试 .sink 到我的 ViewModel @published var 中......但它不起作用!我认为这是我调用这 2 个函数时的时间错误的原因
  • 我使用的是 OMDb 免费 API,到目前为止它运行良好

显示问题的更短示例代码:

带有@published var 和 fetch 函数的 DataManager

class DataManager {

static let instance = DataManager()

let apiKey: String = "c2e5cb16"

@Published var fetchedSPIDERMAN: SearchModel = SearchModel(search: nil, totalResults: nil, response: nil)
var cancelFetchAllSelections = Set<AnyCancellable>()

private init() {
    fetchSpiderman()
}

func fetchSpiderman() {
    guard let url = URL(string: "https://www.omdbapi.com/?apikey=\(apiKey)&s=spider") else { return print("MY ERROR: BAD URL") }
    
    NetworkingManager.download(url: url)
        .decode(type: SearchModel.self, decoder: JSONDecoder())
        .sink(receiveCompletion: NetworkingManager.handleCompletion,
               receiveValue: { [weak self] (moviesDownloaded) in
            self?.fetchedSPIDERMAN = moviesDownloaded
            print("fetchedSPIDER")
        })
        .store(in: &cancelFetchAllSelections)
}

}

ViewModel 与其他@published var 和 func .sink

class ViewModel: ObservableObject {

let dataService = DataManager.instance

var selectionForSpiderman: [MovieModel] = []
@Published var cancellables = Set<AnyCancellable>()


init() {
}

func sinkToSelectionForSpiderman(){
    dataService.$fetchedSPIDERMAN
        .receive(on: DispatchQueue.main)
        .sink { [weak self] (fetchedMovieModel) in
            if let unwrappedFetchedMovieModel = fetchedMovieModel.search {
                self?.selectionForSpiderman = unwrappedFetchedMovieModel
            }else {
                print("MY ERROR: CANT SINK SPIDERMAN")
            }
        }
        .store(in: &cancellables)
}

} !!! 在控制台中,它显示打印(“我的错误:无法击沉蜘蛛侠”),您可以在 VIEWMODEL 屏幕截图中看到 !!!

带有 .onApear 的 HomeView 调用 vm.sinkToSelectionSpiderman()

struct HomeView: View {

@StateObject var vm: ViewModel = ViewModel()

let randomUrl: String = "https://media.istockphoto.com/id/525982128/cs/fotografie/agresivita-koček.jpg?s=1024x1024&w=is&k=20&c=y632ynYYyc3wS5FuPBgnyXeBNBC7JmjQNwz5Vl_PvI8="


var body: some View {
    ScrollView(.horizontal, showsIndicators: true) {
        HStack(spacing: 0) {
            ForEach(vm.selectionForSpiderman) { selection in
                VStack(alignment: .leading, spacing: 12) {
                    AsyncImage(url: URL(string: selection.poster ?? randomUrl)) { returnedImage in
                        switch returnedImage {
                        case .empty:
                            ProgressView()
                        case .success (let image):
                            image
                                .resizable()
                                .frame(width: 200,
                                       height: 120,
                                       alignment: .leading)
                                .background(Color.red)
                                .scaledToFill()
                                .cornerRadius(10)
                                .shadow(color: Color.white.opacity(0.2), radius: 5, x: 0, y: 5)
                        case .failure (_):
                            Image(systemName: "xmark")
                        default:
                            Image(systemName: "xmark")
                        }
                    }
                    
                    Text(selection.title ?? "NA")
                        .foregroundColor(Color.white)
                        .font(.system(.headline, design: .rounded, weight: .medium))
                        .padding(.leading, 12)
                }.frame(maxWidth: 210)
            }
            .accentColor(Color.white)
        }
    }
    .onAppear {
        vm.sinkToSelectionForSpiderman()
    }
}

}

我的模型通常与其他 Fetch 函数一起工作。

主要问题是: 我很确定我需要在 Fetch func 之后调用 .sink func ...但是如果 .onAppear 代码块在 Fetch func 完成之前执行并且有时间将数据发送给订阅者 .sink func?

有趣的事实: 一旦它实际在 Canvas 的 scrollView 中显示了数据:不幸的是,DD 只是一次,再也不会了。也许 API 很慢

我试图查看 SwiftUI 中的计时如何工作以及何时调用哪个函数,但它太具体了,我没有找到答案。如果你知道我可以研究这类东西的任何资源,请告诉我!! :)

networking swiftui viewmodel fetch-api
© www.soinside.com 2019 - 2024. All rights reserved.