You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中UIImage未传入Firebase上传函数的问题排查与修复

问题原因及修复方案

问题现象

从相机胶卷选择照片后能正常在界面展示,但点击「Save Photos」按钮上传至Firebase时,uploadAsJPEG/uploadAsJPEG1x1接收的是空UIImage数组。排查发现执行loadImages时图片能正常添加到数组,但传入ImageStorageService时数组为空。

核心原因

你创建了两个完全独立的OnboardingViewModel实例:

  • TestView中通过@StateObject private var viewModel = OnboardingViewModel()创建了一个实例,上传操作使用的是这个实例的images数组
  • ImageSelectorView中又通过@ObservedObject private var viewModel = OnboardingViewModel()创建了另一个独立实例,选图添加图片的操作是在这个实例的images数组中完成的

两个实例的images数组完全隔离,上传时自然拿不到选中的图片。

修复步骤

1. 修改ImageSelectorView,接收外部传入的ViewModel

将ImageSelectorView内部的ViewModel实例移除,改为从外部传入:

struct ImageSelectorView: View {
    // 移除内部初始化,改为接收外部传入的viewModel
    @ObservedObject var viewModel: OnboardingViewModel
    
    var body: some View {
        NavigationView {
            VStack {
                ZStack {
                    Rectangle()
                        .fill(Color.secondary)
                    
                    Text("Tap To Select Photos")
                        .foregroundColor(.white)
                        .font(.headline)
                }
                .onTapGesture {
                    viewModel.isShowingImagePicker = true
                }
                HStack {
                    ForEach(viewModel.images.indices, id: \.self) { index in
                        ImageView(uiImage: viewModel.images[index])
                    }
                }
            }
            .padding([.horizontal, .bottom])
            .onChange(of: viewModel.inputImage) { _ in
                viewModel.loadImages()
            }
            .sheet(isPresented: $viewModel.isShowingImagePicker) {
                ImagePicker(image: $viewModel.inputImage)
            }
        }
    }
}

2. 在TestView中传入共享的ViewModel

调用ImageSelectorView时,传入TestView自己的ViewModel实例:

struct TestView: View {
    @StateObject private var viewModel = OnboardingViewModel()
    @State private var isUploading = false
    var body: some View {
        VStack {
            // 传入共享的viewModel
            ImageSelectorView(viewModel: viewModel)
            Button(action: {
                Task {
                    isUploading = true
                    await viewModel.uploadAndUpdateImageURLs(email: "test@test.com", images: viewModel.images)
                    isUploading = false
                }
            }, label: {
                Text("Save Photos")
            })
            if isUploading {
                ProgressView()
            }
        }
    }
}

3. 确保OnboardingViewModel符合ObservableObject协议

确认你的OnboardingViewModel类声明了ObservableObject(如果之前没加的话):

@MainActor
class OnboardingViewModel: ObservableObject {
    @Published var images: [UIImage] = []
    @Published var inputImage: UIImage?
    @Published var isShowingImagePicker = false // 补充视图用到的属性
    
    // 原有方法保持不变
    func uploadAndUpdateImageURLs(email: String, images: [UIImage]) async {
        print("uploadAndUpdateImageURLs Reached")
        do {
            let imageURLs = try await ImageStorageService.uploadAsJPEG(images: images, path: "users")
            print("ImageURLs is currently: \(imageURLs)")
            print("Count of imageURLs is: \(imageURLs.count)")
            for imageURL in imageURLs {
                await updateImageURLs(email: email, imageURL: imageURL.absoluteString)
            }
        } catch {
            print("error uploading and updating imageURLs: \(error.localizedDescription)")
        }
    }

    func loadImages() {
        guard let inputImage = inputImage else { return }
        images.append(inputImage)
        print("images array is currently \(images)")
    }
}

这样修改后,选图和上传操作会共享同一个ViewModel实例,images数组的内容就能同步传递到上传方法中了。


内容的提问来源于stack exchange,提问作者Donald Dang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 15:53:11