You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 01:55:23