首页 > 解决方案 > ProgressView 未更新

问题描述

将图像上传到 Firebase 存储时,我正在尝试观察进度。控制台中的进度正在更新,但是我的 ProgressView 没有更新。其他一切似乎都按预期工作。知道我做错了什么吗?

class UserManager: ObservableObject  {

@Published var taskProgress: Float = 0.0
let user = Auth.auth().currentUser



func uploadProfilePicture(image: UIImage) {
    
    let uploadRef = FirebaseReferenceManager.storage.reference(withPath: "profile/\(user!.uid)")
    
    guard let imageData = image.jpegData(compressionQuality: 0.75) else {
        return
    }
    
    let uploadMetaData = StorageMetadata.init()
    uploadMetaData.contentType = "image/jpeg"
    
    let taskReference = uploadRef.putData(imageData, metadata: uploadMetaData) { (downloadMetaData, error) in
        if let error = error {
            print(error.localizedDescription)
            return
        } else {
            print("Successfully Uploaded Profile Picture to Firebase Storage")
            let downloadRef = FirebaseReferenceManager.storage.reference(withPath: "profile/\(self.user!.uid)")
            downloadRef.downloadURL { (url, error) in
                
                if let error = error {
                    print(error.localizedDescription)
                    return
                }
                
                FirebaseReferenceManager.root.collection(FirebaseKeys.CollectionPath.users).document(self.user!.uid).setData([FirebaseKeys.UsersFieldPath.photoURL : url!.absoluteString], merge: true)
            }
            
            

        }
    }

    
    taskReference.observe(.progress) { [weak self] (snapshot) in
        DispatchQueue.main.async {
            guard let pctThere = snapshot.progress?.fractionCompleted else {return}
            print(pctThere)
            self?.taskProgress = Float(pctThere)
        }

    }
    taskReference.resume()
    

}

}

在我看来,我把以下

@EnvironmentObject var userManager: UserManager

ProgressView(value: userManager.taskProgress).progressViewStyle(LinearProgressViewStyle())

以下是类的初始化方式:

struct SwiftUIView: View {
@StateObject var userManager = UserManager()

var body: some View {
    
    TabView {
        
        HomeView().tabItem {
            Image("home")
            Text("Home")
            
        }
        

        SearchView().tabItem {
            Image("search")
            Text("Search")
            
        }
        
        DiscoverView().tabItem {
            Image("discover")
            Text("Discover")
            
        }
        
        OrdersView().tabItem {
            Image("calendar")
            Text("Orders")
            
        }
        
        InboxView().tabItem {
            Image("inbox")
            Text("Inbox")
            
        }
    }
    .environmentObject(userManager)
}

}

然后我使用

    @EnvironmentObject var userManager: UserManager

这里是调用 uploadProfilePicture() 的地方:

struct ImagePicker: UIViewControllerRepresentable {

var sourceType: UIImagePickerController.SourceType = .photoLibrary

@Binding var selectedImage: UIImage
@Environment(\.presentationMode) private var presentationMode


func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
    
    let imagePicker = UIImagePickerController()
    imagePicker.delegate = context.coordinator
    imagePicker.allowsEditing = true
    imagePicker.sourceType = sourceType
    
    return imagePicker
}

func makeCoordinator() -> Coordinator {
    Coordinator(self)
}


func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {

}


class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
 
    let parent: ImagePicker
    @ObservedObject private var userManager = UserManager()

 
    init(_ parent: ImagePicker) {
        self.parent = parent
    }
 
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
 
        if let image = info[.editedImage] as? UIImage {
            parent.selectedImage = image
            userManager.uploadProfilePicture(image: image)
        }
        

        parent.presentationMode.wrappedValue.dismiss()
    }
}

}

标签: swiftswiftuifirebase-storage

解决方案


从评论中,我们推断这是一个不同的UserManager例子。这是一个如何将相同实例传递给的示例Coordinator(这是假设 ImagePicker 存在于@EnvironmentObject var userManager: UserManager可用的环境中)。

struct ImagePicker: UIViewControllerRepresentable {
    
    var sourceType: UIImagePickerController.SourceType = .photoLibrary
    
    @Binding var selectedImage: UIImage
    @Environment(\.presentationMode) private var presentationMode
    @EnvironmentObject private var userManager: UserManager //<-- Here
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
        
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = context.coordinator
        imagePicker.allowsEditing = true
        imagePicker.sourceType = sourceType
        
        return imagePicker
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self, userManager: userManager)  //<-- Here
    }
    
    
    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
        
    }
    
    
    class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
        
        let parent: ImagePicker
        let userManager: UserManager
        
        init(_ parent: ImagePicker, userManager: UserManager) {  //<-- Here
            self.parent = parent
            self.userManager = userManager  //<-- Here
        }
        
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            
            if let image = info[.editedImage] as? UIImage {
                parent.selectedImage = image
                userManager.uploadProfilePicture(image: image)
            }
            
            parent.presentationMode.wrappedValue.dismiss()
        }
    }
}

推荐阅读