Swift 4从Firebase Storage获取图片失败,报NSURLErrorDomain Code=-999错误
Hey there, let's break down why you're hitting this "-999 cancelled" error and how to fix it. First, let's demystify the error itself: this code means your network request was actively cancelled mid-execution—it's almost never a Firebase or network connectivity issue, but a problem with how your request is tied to your UI elements.
First, Let's Diagnose the Core Issue
Looking at your code, here's the main problem: you're firing off a getData request but not keeping a reference to it. If the imageHolder (say, a UIImageView in a TableView/CollectionView cell) gets reused or destroyed before the request finishes, the system automatically cancels the in-flight request, throwing this exact error. You also aren't handling the error parameter, which hides useful context.
Step 1: Add Proper Error Handling
First, update your code to log meaningful errors and catch edge cases:
func retrieveImagesFromFireBase(downloadUrl: String, imageHolder: UIImageView){ guard !downloadUrl.isEmpty else { return } let storageRef = Storage.storage().reference(forURL: downloadUrl) storageRef.getData(maxSize: 5*1024*1024) { (data, error) in // Handle errors first if let error = error { // Skip logging if we intentionally cancelled the request if (error as NSError).code == NSURLErrorCancelled { return } print("Image fetch failed: \(error.localizedDescription)") print("Error code: \(error._code)") // Set a placeholder image here if needed imageHolder.image = UIImage(named: "profile-placeholder") return } // Safely unwrap data and set the image guard let imageData = data, let profilePic = UIImage(data: imageData) else { imageHolder.image = UIImage(named: "profile-placeholder") return } imageHolder.image = profilePic } }
Step 2: Fix Request Cancellation from UI Reuse (Most Common Fix)
If your imageHolder lives in a reusable cell (TableView/CollectionView), you need to track and cancel pending requests when the cell is reused. Here's how:
- Update your custom cell class to store the active request:
class ProfileCell: UITableViewCell { @IBOutlet weak var profileImageView: UIImageView! // Store the active download task var activeStorageTask: StorageDownloadTask? override func prepareForReuse() { super.prepareForReuse() // Cancel any pending request activeStorageTask?.cancel() activeStorageTask = nil // Reset the image to avoid showing old content profileImageView.image = UIImage(named: "profile-placeholder") } }
- Modify your image fetch function to attach the task to the cell:
func retrieveImagesFromFireBase(downloadUrl: String, for cell: ProfileCell){ guard !downloadUrl.isEmpty else { cell.profileImageView.image = UIImage(named: "profile-placeholder") return } let storageRef = Storage.storage().reference(forURL: downloadUrl) // Cancel any existing task for this cell cell.activeStorageTask?.cancel() // Start and store the new task cell.activeStorageTask = storageRef.getData(maxSize: 5*1024*1024) { (data, error) in if let error = error { if (error as NSError).code == NSURLErrorCancelled { return } print("Fetch error: \(error.localizedDescription)") cell.profileImageView.image = UIImage(named: "profile-placeholder") return } guard let imageData = data, let profilePic = UIImage(data: imageData) else { cell.profileImageView.image = UIImage(named: "profile-placeholder") return } cell.profileImageView.image = profilePic } }
Step 3: Verify Your Storage URL
Looking at your error log, the URL includes Profile_Image_Of:VgMpm1a3ZaU8kQNXnMhXhhVecdF2—colons are allowed in Firebase Storage filenames, but URL encoding can sometimes cause issues. Instead of passing the full URL, try creating the reference using the file path directly:
// Replace with your actual file path let storageRef = Storage.storage().reference() .child("images_profile") .child("Profile_Image_Of:VgMpm1a3ZaU8kQNXnMhXhhVecdF2")
This avoids any potential URL encoding mishaps.
Final Notes
That -999 error is almost always tied to request cancellation from UI element reuse. By tracking and cancelling pending tasks, you'll eliminate this issue entirely. Don't forget to use placeholder images to improve user experience while images load!
内容的提问来源于stack exchange,提问作者Abdulmoiz Ahmer

