如何让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,提问作者Езерский Алексей
相关产品推荐
相关产品推荐

