在核心数据中存储UIColor对象

时间:2014-05-23 17:22:35

标签: ios core-data uicolor

我想将一个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进行交互。

非常感谢您的帮助!

5 个答案:

答案 0 :(得分:29)

您的属性应为Transformable类型。默认值转换器(NSKeyedUnarchiveFromDataTransformerName)可以转换符合NSCoding的任何对象。

  1. 将属性标记为" Tranformable"。
  2. 可选:将值变换器名称设置为" NSKeyedUnarchiveFromDataTransformerName"。如果不这样做,无论如何都会默认为此。
  3. Like so

    您无需做任何其他事情。请记住,您无法将可转换属性与谓词匹配或按谓词排序。它们几乎只是存储 - 值变换器将对象值转换为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)
相关问题