如何将Firebase Storage图片加载到个人资料页UIImageView并持久展示
问题核心原因
你当前仅在用户选图上传的瞬时给UIImageView赋值了图片,没有实现页面加载时的图片读取逻辑,页面切换重新渲染后没有数据源赋值,自然会重置为初始状态。
先修复现有代码的两处隐患
- 上传文件名格式错误:你当前拼接的路径多了一个多余的
+号,最终生成的文件名是{uid}+.png,后续拉取时路径对应不上会拉不到资源 imagePickerControllerDidCancel方法写在了didFinishPickingMediaWithInfo的作用域内,无法正常被调用,要移到extension的根层级
修复后的选图上传代码:
extension ProfileViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { let selectedImage: UIImage? if let edited = info[.editedImage] as? UIImage { selectedImage = edited } else if let original = info[.originalImage] as? UIImage { selectedImage = original } else { selectedImage = nil } guard let image = selectedImage, let imageData = image.pngData(), let uid = Auth.auth().currentUser?.uid else { picker.dismiss(animated: true) return } // 赋值当前页面的头像 profileimage.image = image // 上传到Storage,路径修正为正确的{uid}.png storage.child("images/\(uid).png").putData(imageData, metadata: nil) { _, error in if let error = error { print("头像上传失败: \(error.localizedDescription)") } } picker.dismiss(animated: true) } // 取消选图方法移到正确位置 func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { picker.dismiss(animated: true) } }
两种实现头像持久展示的方案
方案1:每次进入个人资料页拉取云端头像(推荐,多设备同步数据一致)
在ProfileViewController的viewWillAppear生命周期方法中加入拉取逻辑,每次页面显示时自动拉取当前用户的头像:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) guard let uid = Auth.auth().currentUser?.uid else { return } // 对应你上传的Storage路径 let avatarRef = storage.child("images/\(uid).png") // 下载最大10M的头像,可根据需求调整大小阈值 avatarRef.getData(maxSize: 10 * 1024 * 1024) { [weak self] data, error in guard let self = self, let data = data, error == nil else { // 拉取失败显示默认头像 self?.profileimage.image = UIImage(named: "default_avatar") return } // 主线程更新UI DispatchQueue.main.async { self.profileimage.image = UIImage(data: data) } } }
方案2:本地缓存头像(加载更快,适合无多设备同步需求的场景)
上传成功后同时把头像存在本地沙盒,下次进页优先读本地缓存:
// 保存图片到本地沙盒的工具方法 func saveImageToLocal(image: UIImage, uid: String) { guard let data = image.pngData() else { return } let filePath = NSTemporaryDirectory() + "\(uid)_avatar.png" try? data.write(to: URL(fileURLWithPath: filePath)) } // 从本地读取图片的工具方法 func getLocalAvatar(uid: String) -> UIImage? { let filePath = NSTemporaryDirectory() + "\(uid)_avatar.png" guard let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else { return nil } return UIImage(data: data) }
上传成功后调用saveImageToLocal存储,viewWillAppear时优先调用getLocalAvatar读取,读取不到再走云端拉取逻辑即可。
内容的提问来源于stack exchange,提问作者newbycoder
相关产品推荐
相关产品推荐

