【问题标题】:Persist Array of Images Swift持久化图像数组 Swift
【发布时间】:2015-09-25 21:46:34
【问题描述】:
我希望能够通过SwiftyUserDefaults 保存包含 UIImages 的数组 cardImages。
期望的行为
这是确切的期望行为:
通过 SwiftyUserDefault 库将 UIImage 数组保存到 NSUserDefaults
稍后检索图像
代码这被精简为非常少的代码
var newPhotoKey = DefaultsKey<NSArray>("image")//Setting up the SwiftyUserDefaults Persisted Array
cardImages = [(UIImage(named: "MyImageName.jpg")!)] //This array contains the default value, and will fill up with more
Defaults[theKeyForStoringThisArray] = cardImages //This is the persisted array in which the array full of images should be stored. WHERE THE ERROR HAPPENS
var arrayToRetreiveWith = Defaults[theKeyForStoringThisArray] as! [UIImage] //To Retreive
错误
我收到以下错误:
尝试设置非属性列表对象(
", {300, 300}"
) 作为关键图像的 NSUserDefaults/CFPreferences 值
*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“尝试插入非属性列表对象(
", {300, 300}"
) 用于关键图像'
谢谢!
【问题讨论】:
标签:
arrays
swift
nsuserdefaults
【解决方案1】:
错误信息实际上很清楚。 UIImage 不是属性列表,因此您需要先将其更改为行数据。我将在下面举个例子,但仅供参考,不建议使用 NSUserDefaults 保存像图像这样的大数据。我会使用 NSFileManager 并将其放在用户文档目录中。无论如何
var newPhotoKey = DefaultsKey<NSArray>("image")
cardImages = [(UIImage(named: "MyImageName.jpg")!)]
var cardImagesRowdataArray: NSData = []
for image in cardImages {
let imageData = UIImageJPEGRepresentation(image, 1.0)
cardImagesRowdataArray.append(imageData)
}
Defaults[theKeyForStoringThisArray] = cardImagesRowdataArray
var arrayToRetreiveWith = Defaults[theKeyForStoringThisArray] as! [NSData]
// here you can use UIImage(data: data) to get it back
如果你不坚持使用SwiftyUserDefaults,你可以将它保存在用户文档目录中,这里是如何做到的
func saveImage(image: UIImage){
if let imageData = UIImageJPEGRepresentation(image, 1.0) {
let manager = NSFileManager()
if let docUrl = manager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first{
let uniqueName = NSDate.timeIntervalSinceReferenceDate()
let url = docUrl.URLByAppendingPathComponent("\(uniqueName).jpg")
imageData.writeToURL(url, atomically: true)
}
}
}
【解决方案2】:
用户默认值必须是属性列表。 property list 是
- 一个字符串(
String 或NSString),
-
NSData,
- 一个日期 (
NSDate),
- 一个数字 (
NSNumber),
- 一个布尔值(也叫
NSNumber),
- 一组属性列表,
- 或一个字典,其键是字符串,其值是属性列表。
UIImage 不是这些,因此UIImage 不是属性列表,也不能是属性列表的一部分。
您需要将图像转换为NSData 以将其存储在用户默认值中。由于UIImage 除了原始像素数据之外还包含一些属性(如scale 和imageOrientation),所以将UIImage 转换为NSData 而不会丢失的最简单方法是creating an archive:
let cardImage: UIImage? = someImage()
let cardImageArchive: NSData = NSKeyedArchiver.archivedDataWithRootObject(cardImage!)
现在您可以将cardImageArchive 存储在更大的属性列表中,您可以将其存储为用户默认值。
稍后,当您需要从数据中重新创建图像时,请执行以下操作:
let cardImageArchive: NSData = dataFromUserDefaults()
let cardImage: UIImage = NSKeyedUnarchiver.unarchiveObjectWithData(cardImageArchive) as! UIImage