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

如何让PhotosPickerItem遵循Codable协议以存入UserDefaults?

保存PhotosPickerItem数组的可行方案

问题背景

无法直接通过Codable或NSCoding序列化PhotosPickerItem,直接存储会报错,但又不想存储图片数据占用过多内存,需要一种轻量的存储方式。

核心思路

PhotosPickerItem自带itemIdentifier属性(类型为String?),这个标识符对应相册中资源的唯一标识,可安全序列化。我们只需要存储这个标识符数组,后续通过标识符重新获取PhotosPickerItem实例即可。

代码实现

1. 定义可序列化的存储模型

import SwiftUI
import PhotosUI

// 可序列化的模型,仅存储照片资源的唯一标识符
struct StoredPhotoIdentifier: Codable {
    let itemIdentifier: String
}

2. 实现存储管理工具类

struct PhotoPickerStorageManager {
    static let defaults = UserDefaults.standard
    private static let storageKey = "savedPhotoPickerIdentifiers"
    
    private init() {}
    
    // 保存标识符数组到UserDefaults
    static func saveIdentifiers(_ identifiers: [StoredPhotoIdentifier]) {
        do {
            let encoder = JSONEncoder()
            let data = try encoder.encode(identifiers)
            defaults.set(data, forKey: storageKey)
        } catch {
            print("保存失败: \(error.localizedDescription)")
        }
    }
    
    // 从UserDefaults读取标识符数组
    static func loadIdentifiers() -> [StoredPhotoIdentifier] {
        guard let data = defaults.data(forKey: storageKey) else { return [] }
        do {
            let decoder = JSONDecoder()
            return try decoder.decode([StoredPhotoIdentifier].self, from: data)
        } catch {
            print("读取失败: \(error.localizedDescription)")
            return []
        }
    }
    
    // 通过标识符恢复PhotosPickerItem实例
    static func restorePickerItems(from identifiers: [StoredPhotoIdentifier]) -> [PhotosPickerItem] {
        return identifiers.compactMap { identifier in
            PhotosPickerItem(itemIdentifier: identifier.itemIdentifier)
        }
    }
}

3. 实际使用示例

// 保存选中的PhotosPickerItem数组
func saveSelectedItems(_ items: [PhotosPickerItem]) {
    let identifiers = items.compactMap { item in
        guard let id = item.itemIdentifier else { return nil }
        return StoredPhotoIdentifier(itemIdentifier: id)
    }
    PhotoPickerStorageManager.saveIdentifiers(identifiers)
}

// 从存储中恢复PhotosPickerItem数组
func loadSavedItems() -> [PhotosPickerItem] {
    let identifiers = PhotoPickerStorageManager.loadIdentifiers()
    return PhotoPickerStorageManager.restorePickerItems(from: identifiers)
}

注意事项

  • 标识符有效性:如果用户在保存后删除了对应相册资源,通过标识符恢复的PhotosPickerItem可能无法正常加载图片,使用时需要处理加载失败的情况。
  • 存储限制:UserDefaults适合存储少量数据,如果需要保存大量照片标识符,建议使用Core Data或文件存储替代。
  • 权限问题:恢复PhotosPickerItem时,依然需要确保App拥有相册访问权限,否则无法正常获取资源。

内容的提问来源于stack exchange,提问作者Езерский Алексей

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 12:52:21