Swift中Firebase Storage多图片上传进度获取方法咨询
Hey there! I get where you're coming from—when dealing with multiple uploads, it's easy to mix up where to attach the progress observer. The key thing to remember is that progress tracking happens on the individual upload task, not the StorageReference itself.
Let me break this down for you:
1. Track Progress for Each Individual Upload
Every time you initiate an upload (using putData or putFile), Firebase returns a StorageUploadTask object. This is what you'll use to observe progress for that specific image.
Here's a practical example of uploading multiple images and tracking each one's progress:
// Assume you have an array of image data or file URLs let imageDataArray: [Data] = [/* your image data here */] let storage = Storage.storage() let baseStorageRef = storage.reference().child("user_uploads") // Loop through each image to create and monitor upload tasks for (imageIndex, imageData) in imageDataArray.enumerated() { let imageRef = baseStorageRef.child("image_\(imageIndex).png") let uploadTask = imageRef.putData(imageData, metadata: nil) // Attach progress observer to this specific task let progressHandle = uploadTask.observe(.progress) { snapshot in guard let progress = snapshot.progress else { return } let percentComplete = Double(progress.completedUnitCount) / Double(progress.totalUnitCount) print("Image \(imageIndex + 1) progress: \(String(format: "%.1f", percentComplete * 100))%") // Update your UI here (e.g., a progress bar for this image) } // Clean up observer when the task finishes (success or failure) uploadTask.observe(.success) { _ in uploadTask.removeObserver(withHandle: progressHandle) } uploadTask.observe(.failure) { _ in uploadTask.removeObserver(withHandle: progressHandle) } }
2. Track Combined Total Progress Across All Uploads
If you want a single progress bar showing overall progress for all uploads, you'll need to aggregate progress values from each task:
var totalCompletedBytes: Int64 = 0 var totalTotalBytes: Int64 = 0 let uploadDispatchGroup = DispatchGroup() for (imageIndex, imageData) in imageDataArray.enumerated() { uploadDispatchGroup.enter() let imageRef = baseStorageRef.child("image_\(imageIndex).png") let uploadTask = imageRef.putData(imageData, metadata: nil) // Add this task's total bytes to the overall total if let taskTotalBytes = uploadTask.progress?.totalUnitCount { totalTotalBytes += taskTotalBytes } let progressHandle = uploadTask.observe(.progress) { snapshot in guard let progress = snapshot.progress else { return } // Calculate how much this task has advanced since last update let taskCompleted = progress.completedUnitCount let previousTaskCompleted = totalCompletedBytes % progress.totalUnitCount totalCompletedBytes += (taskCompleted - previousTaskCompleted) // Compute overall percentage let overallPercent = Double(totalCompletedBytes) / Double(totalTotalBytes) print("Total upload progress: \(String(format: "%.1f", overallPercent * 100))%") // Update your combined progress UI here } // Clean up and mark task as completed in the dispatch group uploadTask.observe(.success) { _ in uploadTask.removeObserver(withHandle: progressHandle) uploadDispatchGroup.leave() } uploadTask.observe(.failure) { _ in uploadTask.removeObserver(withHandle: progressHandle) uploadDispatchGroup.leave() } } // Optional: Run code when all uploads finish uploadDispatchGroup.notify(queue: .main) { print("All images uploaded successfully!") }
Key Clarification
The StorageReference.observe(_:options:changeHandler:) method you encountered is for KVO observing reference properties (like metadata changes), not upload progress. Progress tracking is exclusively tied to the StorageUploadTask object returned when you start an upload.
Hope this clears up the confusion! Let me know if you hit any specific snags.
内容的提问来源于stack exchange,提问作者Daibaku

