我想将一个UIColor对象作为属性存储在Core Data实体上,然后检索它并以与我在该实体上执行其他属性相同的方式使用它。
在我的研究中,虽然文献看起来很稀疏,但我发现this post说该属性应该被指定为“可转换”,并且应该使用NSKeyedArchiver
手动转换数据。使用NSKeyedUnarchiver
出来。
但是,我发现a more recent post说所有必要的是将UIColor保存为CD中的Transformable属性,生成一个Managed Object子类,并像其他属性一样使用。
Apple docs themselves详细介绍了如何在NSColor
上存储和检索UIColor
个对象,而不是(我能找到)。但是,它听起来像归档/取消归档在CD中自动处理。也许。我被这条线弄糊涂了:
如果您在Xcode中使用模型编辑器,请在属性的“类型”弹出窗口中选择“可变换”,然后在“值变换器名称”文本字段中键入名称。
我认为他们正在谈论属性的名称,但我不确定,特别是因为它警告明确指定变换器可能引起的问题:
重要说明:虽然默认转换器是NSKeyedUnarchiveFromDataTransformerName指定的转换器,但实际上反向使用此转换器。如果明确指定默认转换器,Core Data将“以错误的方向”使用它。
我已经达到了这样的程度:我有一个名为“color”的新的可转换属性(没有命名变换器)并且生成了一个包含新“color”属性(类型id)的新子类文件。
我只是简单地困惑。有人可以给我一些关于如何从这里开始的明确指导吗?
如果重要的话,我正在使用MagicalRecord与Core Data进行交互。
非常感谢您的帮助!
答案 0 :(得分:29)
您的属性应为Transformable类型。默认值转换器(NSKeyedUnarchiveFromDataTransformerName)可以转换符合NSCoding的任何对象。
您无需做任何其他事情。请记住,您无法将可转换属性与谓词匹配或按谓词排序。它们几乎只是存储 - 值变换器将对象值转换为NSData,这是在商店中持久存储的内容。当属性故障触发时,Core Data使用另一个方向的转换器从NSData转到您的对象类型。
答案 1 :(得分:6)
另一种选择, Swift 3
extension UIColor {
class func color(withData data:Data) -> UIColor {
return NSKeyedUnarchiver.unarchiveObject(with: data) as! UIColor
}
func encode() -> Data {
return NSKeyedArchiver.archivedData(withRootObject: self)
}
}
<强>用法强>
var myColor = UIColor.green
// Encoding the color to data
let myColorData = myColor.encode() // This can be saved into coredata/UserDefaulrs
let newColor = UIColor.color(withData: myColorData) // Converting back to UIColor from Data
答案 2 :(得分:1)
为了将UIColor保存到核心数据,您需要分离红色,蓝色和绿色值。然后,在创建代码中,获取RGB值并使用获取的结果创建UIColor对象。这比听起来容易,并且您不必提供任何NSKeyArchiver / Unarchiver或NSUserDefaults的工作。
在数据模型中,在颜色实体中,创建三个属性:float类型的红色,绿色和蓝色。然后为颜色实体子类化NSManagedObject。 (如果你之前使用核心数据应该听起来很熟悉。)但是,这不是一个关于如何使用核心数据的问题,所以我要去做。
为了论证,我们将生成一个随机颜色并将其保存到核心数据(您可以将RGB值设置为您想要的任何颜色)。
首先在您要使用它的任何类的实现文件中创建float类型的三个属性。
@property (nonatomic) float randomRedColor;
@property (nonatomic) float randomBlueColor;
@property (nonatomic) float randomGreenColor;
设置保存到核心数据的方法,每个RGB值至少包含3个float类型的参数。请记住,实体属性必须是对象而不是基本类型,因此在设置key的值时将浮点值包装在NSNumber中。
-(void) withColors:(float)redColor withBlue:(float)blueColor withGreen:(float)greenColor{
//set up NSManagedObjectContext/EntityDescription/ManagedObject (core data)
self.randomRedColor = redColor;
self.randomBlueColor = blueColor;
self.randomGreenColor = greenColor;
[newCategory setValue:[NSNumber numberWithFloat:redColor] forKey:@"red"];
[newCategory setValue:[NSNumber numberWithFloat:blueColor] forKey:@"blue"];
[newCategory setValue:[NSNumber numberWithFloat:greenColor] forKey:@"green"];
//save new objects (core data)
无论你打算在哪里调用这个方法,你都会创建三个带有随机值的浮点数,并将它们传递给:(我喜欢在数据源中设置所有这些,所以不要担心我的sharedInstance。如果您不熟悉单例模式,请不要担心,我只是调用方法并将随机生成的值作为参数传递。)
float red = (arc4random()%256/256.0);
float blue = (arc4random()%256/256.0);
float green = (arc4random()%256/256.0);
[[DataSource sharedInstance] withColors:red withBlue:blue withGreen:green];
现在只需导入Color NSManagedObject的头文件并创建Color NSManagedObject属性,在这种情况下我们将其称为* color:
@property (nonatomic, strong) Color *color
假设任何阅读此内容的人都知道如何执行获取请求,我们现在将使用在我们的Color实体的子类化时提供的* red * blue和* green属性。
float red = [self.category.red floatValue];
float green = [self.category.green floatValue];
float blue = [self.category.blue floatValue];
剩下的就是将检索到的值存储在UIColor对象中:
UIColor *randomRGBColor = [[UIColor alloc] initWithRed:red green:green blue:blue alpha:1.0];
现在你已经完成了。您已成功存储UIColor对象。我希望这有帮助!
答案 3 :(得分:0)
以上答案为我指明了正确的方向,但要求已不断发展。搜索“使用Transformable在CoreData中保存UIColor和数组”以查看更多信息。
我能够使用上述答案和我发现堆栈溢出的文章通过iCloud将可转换字段添加到核心数据中。
答案 4 :(得分:0)
您可以使用 SwifterSwift hexString将字符串保存到coredata,然后按如下所示进行检索
let str = UIColor.white.hexString
let color = UIColor(hexString:str)