如何在Xcode应用中永久保存照片,重启后不丢失?
解决思路与代码修改方案
问题核心是当前图片仅存储在内存数组imageArray中,应用重启后内存释放导致数据丢失。使用Core Data持久化图片数据即可解决,以下是具体步骤:
1. 创建Core Data实体
打开项目中的.xcdatamodeld文件:
- 添加实体(Entity),命名为
StoredImage - 给实体添加属性(Attribute):
imageData,类型选择Binary Data
2. 修改ViewController代码
2.1 调整属性与初始化
移除全局的imageArray,将其改为ViewController的内部属性,并添加Core Data上下文引用:
class ViewController: UIViewController, PHPickerViewControllerDelegate { @IBOutlet var collectionView: UICollectionView! var imageArray = [UIImage]() private let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext // 原有viewDidLoad代码... }
2.2 添加数据加载方法
在viewDidLoad末尾调用加载Core Data数据的方法,启动时恢复图片:
override func viewDidLoad() { super.viewDidLoad() // 原有布局、代理设置代码... loadImages() } private func loadImages() { let request: NSFetchRequest<StoredImage> = StoredImage.fetchRequest() do { // 从Core Data读取所有存储的图片数据 let storedImages = try context.fetch(request) // 将二进制数据转成UIImage并填充数组 imageArray = storedImages.compactMap { UIImage(data: $0.imageData!) } collectionView.reloadData() } catch { print("读取图片失败: \(error.localizedDescription)") } }
2.3 修改图片选择回调,添加持久化逻辑
在picker(_:didFinishPicking:)方法中,将选中的图片转成二进制数据并保存到Core Data:
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { picker.dismiss(animated: true, completion: nil) let group = DispatchGroup() results.forEach { result in group.enter() result.itemProvider.loadObject(ofClass: UIImage.self) { reading, error in defer { group.leave() } guard let image = reading as? UIImage, error == nil else { return } // 将UIImage转成二进制数据(推荐用pngData避免压缩损失) guard let imageData = image.pngData() else { return } // 创建Core Data实体对象并赋值 let storedImage = StoredImage(context: self.context) storedImage.imageData = imageData // 保存到Core Data do { try self.context.save() // 主线程更新内存数组 DispatchQueue.main.async { self.imageArray.append(image) } } catch { print("保存图片失败: \(error.localizedDescription)") } } } group.notify(queue: .main) { self.collectionView.reloadData() } }
3. 注意事项
- 确保Xcode已自动生成
StoredImage实体类:若未生成,可在Data Model文件中选中实体,在右侧检查器中设置"Codegen"为"Class Definition" - 若图片体积较大,Core Data存储二进制数据可能影响性能,可改为将图片保存到Documents目录,Core Data仅存储文件路径
- 测试时需重启应用验证数据是否保留
内容的提问来源于stack exchange,提问作者Jenni Joo
相关产品推荐
相关产品推荐

