将照片保存到核心数据

Posted

技术标签:

【中文标题】将照片保存到核心数据【英文标题】:Saving Photos to Core Data 【发布时间】:2013-08-07 16:42:45 【问题描述】:

我想将照片保存到 Core Data。我在互联网上查找并找到了许多关于核心数据的资源,但是我找不到我想要完成的资源。我想使用 Core Data 来保存用户拍摄的图像,然后希望用户选择他想要保存的类别。就好像他正在将图片分类为类别,例如肉类或蔬菜等。为此,我创建了一个名为 photo 的实体,并放置了类别的 6 个属性名称,例如肉类蔬菜。我还没有选择类型。我在想用户选择类别并将其保存为属性。这是问题。我想这样做,但我找不到满足我想做的资源。我也在做使用多个属性的正确想法吗?

【问题讨论】:

【参考方案1】:

向下滚动以将 UIImage 数据存储在核心数据中,但首先要了解一下核心数据属性:您不应该为不同的类别使用多个属性,您应该有一个名为“类别”的属性。这可以是整数或字符串,具体取决于您的实现。我建议使用整数并为它定义一个枚举,如下所示:

typedef NS_ENUM(NSUInteger, MyFoodCategory)
    MyFoodCategoryVegetable = 0,
    MyFoodCategoryMeat = 1,
    MyFoodCategoryFish = 2,
    MyFoodCategorySweet = 3,
;

当您将其打印到视图中时,请执行以下操作:

-(void)setLabelTextForCategory:(MyFoodCategory)category

    switch(category) 
        case MyFoodCategoryVegetable:
            self.categoryLabel.text = @"Vegetable";
            break;
        case MyFoodCategoryMeat:
            self.categoryLabel.text = @"Meat";
            break;
        case MyFoodCategoryFish:
            self.categoryLabel.text = @"Poisson"; //French
            break;
        case MyFoodCategorySweet:
            self.categoryLabel.text = @"Dessert";
            break;
    

这意味着,如果您改变了想为每个类别打印什么测试的想法,那么您只需在此处进行更改,而不必更改核心数据库中的内容。例如,您可以使用本地化来显示不同语言或同一单词的变体。

在核心数据中存储 UIImage 数据

好的,所以回答你的主要问题。我个人会避免将图像数据存储在核心数据中,而是将其保存到磁盘。查看使用 NSFileManager 类或将 UIImage 转换为 NSData 并写入文件,例如

UIImage *image = ...
NSData *imageData = UIImagePNGRepresentation(image); // or use UIImageJPEGRepresentation if it's a jpeg image

NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *fileName = @"imageWhatever1";
NSString *filePath = [documentsPath stringByAppendingPathComponent:fileName];
NSError *writeError = nil;
if (![data writeToFile:filePath options:NSDataWritingAtomic error:&writeError]) 
    NSLog(@"Failed to write file: %@", writeError);

但是,如果您希望将图像直接保存到核心数据,则创建一个名为“imageData”的属性并将属性类型设置为“二进制数据”。然后将 NSData 对象保存到核心数据实体中。当您读取 NSData 对象时,您可以将其转换回 UIImage,如下所示:

UIImage *imageLoadedFromDiskOrCoreData = [UIImage imageWithData:imageData];

【讨论】:

对图像等非标准属性使用自定义NSValueTransformer 也很好。 Apple 甚至在他们的 PhotoLocations 示例应用程序中提供了一个示例实现。 我想让用户使用UIPickerView 选择要保存到哪个类别,但我不能让它工作。对我来说,什么是一个好的起点?【参考方案2】:

没有。这不是一个好办法。现在,每个entity 都有一个six attributes。这将导致为数据库中的每一行创建无用的 5 个属性

除此之外,您可以为您的Category 创建一个enum 并将enum 值存储在您的coreData 中。

这样您就可以在 enum 中添加任意数量的类别以供将来增强,您无需关心您在 coreData 中存储的内容。

就这样。

typedef enum imageType 
     vegetables = 0,
     fruits = 1,
     animals = 2,
     scenaries = 3,
     Nature = 4,
     Home = 5,
     Architecture = 6

你的coreData 实体是这样的。

图像实体

 NSData *imageData;
 NSNumber *typeEnum;

您可以拥有一个包含您的类别名称的数组,并在整个应用程序中使用它来匹配enum 与您的UIPickerView 或其他一些组件中的类别的确切名称。

你的数组可能是这样的。

NSArray *categoryArray = [NSArray arrayWithObjects:@"vegetables", @"fruits", @"animals", @"scenaries", @"Nature", @"Home", @"Architecture", nil];

你可以像这样访问数组对象。

NSString *imageCategory = [categoryArray objectAtIndex:imageType.animals];

【讨论】:

以上是关于将照片保存到核心数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 1 个函数将 2 个属性保存到核心数据(Swift4)

将 UIImage 保存到 Core Data 时出错

如何在 IOS 中保存新令牌照片

将 UIImage 数据保存到 iOS 中的照片库后取回

swift核心数据:保存相机中的图像

核心数据 - 通过 iCloud 保存和共享图像