如何设计CoreData来存储复杂数据

时间:2016-02-16 05:06:10

标签: ios json swift dictionary core-data

我需要使用CoreData在本地将来自API调用的一些数据存储为JSON。

问题是,JSON对我来说太复杂了,无法在CoreData中处理。我将JSON作为带有4个密钥的Dictionary,这4个密钥再次保留Dictionary个,DictionaryArray和{{1} }}的

现在,我真的不知道应该如何为这个要求设计实体和属性,但是我试图这样做,我做的是,我创建了一个实体(比如XYZ),这个实体有4个关系(一个一个到4个其他实体,这四个实体只是我在JSON文件中得到的四个Dictionary。我将这些DictionaryArray存储为可转换类型。这有点令人困惑,对吧?那么让我把JSON数据放在这里

Dictionary

我的方法是否正常还是需要纠正?或者我需要以完全不同的方式实现它。请帮帮我,谢谢

3 个答案:

答案 0 :(得分:5)

问题是您正在尝试根据JSON的结构创建CoreData实体。您应该根据JSON表示的对象以及它们之间的关系来创建实体。

您的问题并没有真正提供有关数据模型意图的足够信息,以便我给您一个确切的答案,但很可能将这些数据存储为一堆可转换的词典并非如此。最好的答案。使用可转换属性意味着不能查询这些值,并且您没有明确的列表应该包含在这些词典中。这意味着每当您访问数据时,您将有大量if let语句检查字典中的字符串类型值。相反,每个值都应映射到CoreData实体上的属性。

我要问的第一件事是,这些outerKey词典是否代表我的基础对象的属性和值,或者每个outerKey是否真的代表了自己的与根对象有关系的模型对象。如果它们是一个对象的属性,则只需阅读JSON并将值映射到实体上的属性。如果没有,那么你应该创建多个实体并创建你当前正在做的关系,但是你应该为这些实体上的每个值创建属性。

对于嵌套数组和词典,您可能还想创建具有关系的其他实体。

请记住,您的CoreData模型应该反映对象及其相互关联的方式。除非JSON恰好代表正确的结构,否则它不应只反映JSON的结构。

示例

因为我不知道你的数据真正代表什么,这对你的应用程序来说可能不是一个完美的结构,但是假设你的JSON意味着这就是我要来的实体用。

- RootEntity
  - outerKey1: OuterKey1 // one to one
  - outerKey2: OuterKey2 // one to one
  - outerKey3: OuterKey3 // one to one
  - outerKey4: OuterKey4 // one to one

- OuterKey1
  - someKey: String
  - disableAutoFill: Bool
  - disableABC: Bool
  - disableXYZ: Bool
  - disableThis: Bool
  - disableThat: Bool
  - disableBla: Bool
  - disableBlaBla: Bool
  - disableBlaBlaBlaBla: Bool
  - disableBlaBlaBlaBlaBlaBla: Bool

- OuterKey2
  - someKey: [SomeKeyEntity] // one to many
  - enabled: Bool

- SomeKeyEntity
  - markPath: Bool
  - title: String
  - urlString: String

- OuterKey3
  - gatewayIP: String
  - gatewayPort: Int
  - gatewayRoutingURLs: [String] // This can be a transformable `Array`, unless you think you will need to query based on this property later
  - enabled: Bool

- OuterKey4
  - someCategories: [SomeCategoriesEntity] // one to many
  - defaultURL: String
  - enabled: Bool
  - exceptionURLs: [String] // This can be a transformable `Array`, unless you think you will need to query based on this property later
  - filterURLs: [String] // This can be a transformable `Array`, unless you think you will need to query based on this property later
  - filteringFlag: Bool

希望有所帮助!

答案 1 :(得分:1)

是的,你不想按照自己的方式去做,完全忽略了这一点。您可以消化所有这些并构建正确的对象模型,或者只是将JSON保存到文件系统,然后只需在需要时重新加载并从中获取所需的数据。 有各种基于JSON的解析器可以让你做以下事情:

BOOL autofillDisabled = [jsonFile boolFor:@"outerkey.disableAutoFill"];

这将直接使用JSON作为您的数据存储。如果你真的需要根据这些数据建立一个对象模型,祝你好运。

哈,j / k。我已经解决了这个问题的一种方法(虽然从来没有使用过这种随机形成的json。在你获得根字典,并对数据有所了解以及如何使用它之后,构建一个简单的对象级联系统来深入研究数据。

例如,从这里开始:

@interface ParseOperation : NSObject
+ (void) updateObject:(id)object fromDictionary:(NSDictionary *)aDict;
@end

然后,您将继续创建每个对象的内容:

@implementation SomeOperation // Which is a subclass of ParseOperation

+ (void) updateObject:(SomeObject *)object fromDictionary:(NSDictionary *)aDict
{
    object.caption = [ParseObject stringForTag:@"caption" in:aDict];
    object.status = [ParseObject stringForTag:@"status" in:aDict];
    object.event = [ParseObject stringForTag:@"event" in:aDict];
}

然后只需创建您的驱动程序机制:

    identifier = [ParseOperation stringForTag:@"SomeObject" in:dict];
    SomeObject * object = (SomeObject *)[self object:NSStringFromClass([SomeObject class]) withIdentifier:identifier];
    object.identifier = identifier;
    [SomeOperation updateObject:object fromDictionary:dict];

这样做的实用方法是,您可以轻松处理JSON的复杂性,例如:

id check = [aDict objectForKey:@"subArray"];
// This is a mapping file you create, replacing "subArray" with your object's key
NSString * objectKey = [mapping objectForKey:@"object"];
if([check isKindOfClass:[NSMutableArray class]])
{
    NSArray * array = (NSArray *)check;
    for(NSDictionary * dict in array)
    {
        NSString * identifier = [ParseOperation stringForTag:identifierKey in:dict];
        ManagedObject * object = [self object:objectKey withIdentifier:identifier];

        NSString * operation = [NSString stringWithFormat:@"%@Operation", objectKey];
        Class operationClass = NSClassFromString(operation);
        [operationClass updateObject:object fromDictionary:dict];
    }
}

答案 2 :(得分:0)

我真的不知道它会对你有所帮助,但是为了存储这种复杂的数据我更喜欢使用KISS XML API保存基于XML的保存(它易于使用)并在需要时解析它

您的xml文件可能看起来像

<RootEntity>    
     <OuterKey1>
           <someKey> String </someKey>
           <disableAutoFill> Bool</disableAutoFill>  //and so on
     </OuterKey1>
     <OuterKey2>
           <someKey> String </someKey>
           <disableAutoFill> Bool</disableAutoFill>  //and so on
     </OuterKey2>  
</RootEntity>