核心数据 - 将实体保存为 pList / 字典

3

我有一个非常简单的应用程序,其中包含一个与自身存在循环关系的CoreData实体。我想将此数据用作另一个应用程序中的plist。

关系在父类侧为“对一”,在子类侧为“对多”。

基本上是一个树形结构,顶部有一个物品,然后是该对象的子项、子对象的子项等...

我希望从这个数据创建一个具有实体结构及其关系的字典/ pList。(这有意义吗?)

到目前为止,在其他答案的帮助下,我可以获得所有对象的plist(但都在同一“级别”上),或者获得最终父对象的plist(但子关系会出错)。

这是我尝试获取数据并将其保存到桌面的方法:

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:ENTITY_NAME];
    request.resultType = NSDictionaryResultType;

    NSError *fetchError = nil;
    NSArray *results = [self.databaseDocument.managedObjectContext executeFetchRequest:request error:&fetchError];

    NSLog(@"%@", results);

    NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *path = [caches stringByAppendingPathComponent:@"/../../../../../../../../Desktop/my.plist"];
    [results writeToFile:path atomically:NO];

目前只有三个对象。一个主对象,一个该对象的子对象,以及一个该子对象的子对象。

这给了我一个plist数组,其中包含三个对象。

如果我包含一个谓词来仅获取没有父级的对象,就像这样:

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:ENTITY_NAME];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"parent == nil"];
    request.predicate = predicate;

    NSError *fetchError = nil;
    NSArray *results = [self.databaseDocument.managedObjectContext executeFetchRequest:request error:&fetchError];

    NSLog(@"%@", results);

    Item *mainItem = [results lastObject];

    NSArray *keys = [[[mainItem entity] attributesByName] allKeys];
    NSDictionary *dict = [mainItem dictionaryWithValuesForKeys:keys];

    NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSString *path = [caches stringByAppendingPathComponent:@"/../../../../../../../../Desktop/my.plist"];
    [dict writeToFile:path atomically:NO];

这个命令可以给我一个目录,但不包括它的子项。
有人能解释一下如何获得像我的实体结构化的plist吗?换句话说,只有一个目录,其中包含所有子目录,并且每个子目录的子项都在该子目录中,依此类推...

父子关系中的递归深度是否任意? - FluffulousChimp
@NSBum 是的,它可以无限进行下去。 - Bertie
@NSBum 但实际上只能达到大约6或7个级别。 - Bertie
1个回答

3

也许有更好的方法将您的Core Data实体导出到plist中,同时保留关系的分层结构 - 我愿意接受教育。我会像这样递归地处理它们:(这完全没有经过测试 - 仅用于说明目的 - 还有我不完全确定您希望plist如何结构化等。)

- (void)processEntity:(NSManagedObject *)object forMutableArray:(NSMutableArray *)mutableArray {
    NSMutableDictionary *entityInfo = [NSMutableDictionary new];

    // populate entityInfo with your object's properties
    // however you are doing that now...


    //  if this object has children - process them
    NSMutableArray *childArray = [NSMutableArray new];
    for( id child in object.children ) {
        [self processEntity:child forMutableArray:childArray];
    }

    [entityInfo setObject:childArray forKey:@"children"];
    [mutableArray addObject:entityInfo];
}

所以,您可以通过迭代顶级对象(即没有父级的对象)并在processEntity:forMutableArray:中处理它们来开始该过程。

我必须出门,所以还没有尝试过这个,但是当我回到电脑旁时,我会再联系你的。我认为可能有一种方法可以在不出错的情况下获取顶层对象,并且这将自动填充我的plist。我对核心数据非常陌生。 - Bertie
非常好用!感谢您的帮助,而且速度也很快。我本来打算接下来开始这个方向,但这真的真的帮了我很多。如果没有您的帮助,我可能需要很长时间才能缩小到这个范围。 - Bertie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接