如何在 SwiftUI 视图中显示项目之前更新 Firebase 存储 URL

问题描述 投票:0回答:1

我正在从 Firebase 检索练习列表并对其进行过滤。之后,我需要发出另一个异步请求来解析视频 URL 并更新它(请参阅下面的代码)。问题是练习在 URL 解析之前返回到视图。怎么解决?

import Combine
import FirebaseStorage
import Foundation

class ExerciseViewModel<DS: DataService>: ObservableObject where DS.Item == Exercise {
    @Published var exercises: [Exercise] = []

    private let dataService: DS
    private let storage = Storage.storage(url: "someURL")

    private var cancellables = Set<AnyCancellable>()

    init(dataService: DS, idArray: [String]) {
        self.dataService = dataService
        dataService.getData()
            .sink { error in
                print("Exercises request failed: \(String(describing: error))")
            } receiveValue: { [weak self] data in
                Task {
                    self?.exercises =
                        await self?.filterExercises(exercises: data, by: idArray) ?? []
                }
            }
            .store(in: &cancellables)
    }

    private func filterExercises(exercises: [Exercise], by idArray: [String]) async -> [Exercise] {

        var filteredExercises = exercises.filter { idArray.contains($0.id ?? "") }
        filteredExercises.forEach {
            var exercise = $0
            Task {
                do {
                    exercise.videoUrl = try await self.storage.reference().child(
                        "video/\(exercise.video ?? "")"
                    ).downloadURL().absoluteString
                    print("Video URL resolved: \(exercise.videoUrl ?? "")")
                } catch { print("Error resolving video URL: \(error)") }

            }
        }

        return filteredExercises
    }
}
swift firebase swiftui async-await firebase-storage
1个回答
0
投票

更新了代码以使其正常工作:

init(dataService: DS, idArray: [String]) {
    self.dataService = dataService
    dataService.getData()
        .sink { error in
            print("Exercises request failed: \(String(describing: error))")
        } receiveValue: { [weak self] data in
            Task {
                self?.exercises = await self?.filterExercises(exercises: data, by: idArray) ?? []
            }
        }
        .store(in: &cancellables)
}

private func filterExercises(exercises: [Exercise], by idArray: [String]) async -> [Exercise] {
    let filteredExercises = exercises.filter{idArray.contains($0.id ?? "")}
    var result: [Exercise] = []
    for exercise in filteredExercises {
        let videoUrl = await getVideoRef(exercise.video ?? "")
        var updatedExercise = exercise
        updatedExercise.videoUrl = videoUrl
        result.append(updatedExercise)
    }
    return result
        
}

private func getVideoRef(_ video: String) async -> String {
    do {
        let videoURL = try await storage.reference().child("video/\(video)").downloadURL().absoluteString
        return videoURL
    } catch { return "" }
}
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.