2011-04-11 53 views
4

我正在运行,使我的NSMangedObjectClass配置文件im- /可导出。
我试试this way
如果我在NSArrays中写入关系,导出工作正常,因为NSSet没有实现writeToFileNSManagedObject层次结构导入和导出

- (void) exportProfile:(Profile *)profile toPath:(NSString *)path{ 
//Profile 
NSMutableDictionary *profileDict = [[self.selectedProfile dictionaryWithValuesForKeys:[[[self.selectedProfile entity] attributesByName] allKeys]] mutableCopy]; 
NSMutableArray *views = [NSMutableArray array]; 

//Views 
for (View *view in selectedProfile.views) { 
    NSMutableDictionary *viewDict = [[view dictionaryWithValuesForKeys:[[[view entity] attributesByName] allKeys]] mutableCopy]; 
    NSMutableArray *controls = [NSMutableArray array]; 
     //Much more for-loops 
    [viewDict setObject:controls forKey:@"controls"]; 
    [views addObject:viewDict]; 
} 

[profileDict setObject:views forKey:@"views"]; 

if([profileDict writeToFile:[path stringByStandardizingPath] atomically:YES]) 
    NSLog(@"Saved"); 
else 
    NSLog(@"Not saved"); 
[profileDict release]; 
} 

但是,如果要导入另一侧

- (Profile*) importProfileFromPath:(NSString *)path{ 
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext]; 
Profile *newProfile = [NSEntityDescription insertNewObjectForEntityForName:@"Profile" inManagedObjectContext:context]; 

NSMutableDictionary *profileDict = [NSMutableDictionary dictionaryWithContentsOfFile:[path stringByStandardizingPath]]; 
[newProfile setValuesForKeysWithDictionary:profileDict]; 
} 

我得到一个例外,这并不让我困惑造成档案需要一个NSSet中没有的NSArray。
[__NSCFArray intersectsSet:]: unrecognized selector sent to instance 0x4e704c0 *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[__NSCFArray intersectsSet:]: unrecognized selector sent to instance 0x4e704c0'

所以,我有两个问题:

  • 在一边,我不能写的NSSet到文件。
  • 另一方面是我的Profile类期望NSSet。

所以我试图创建NSSet中的一个类别,它实现将writeToFile

@implementation NSSet(Persistence) 

- (BOOL)writeToFile:(NSString*)path atomically:(BOOL)flag{ 
    NSMutableArray *temp = [NSMutableArray arrayWithCapacity:self.count]; 
    for(id element in self) 
     [temp addObject:element]; 
    return [temp writeToFile:path atomically:flag]; 
} 

+ (id)setWithContentsOfFile:(NSString *)aPath{ 
    return [NSSet setWithArray:[NSArray arrayWithContentsOfFile:aPath]]; 
} 
@end 

但我的功能不会被调用。

有没有其他的方式来写我的NSSet或告诉setValuesForKeysWithDictionary关键“意见”是一个NSArray?

还是一种简单的方法来im-/export ManagedObjects?

+0

什么是例外? – deanWombourne 2011-04-11 15:15:02

+0

'NSSet'有一个实例方法' - (NSArray *)allObjects'和一个类方法'+(id)setWithArray:(NSArray *)array',可以帮助您。 – Joe 2011-04-11 15:22:29

+0

'[__NSCFArray intersectsSet:]:无法识别的选择发送到实例0x4e704c0 ***终止应用程序由于未捕获的异常 'NSInvalidArgumentException',原因:“ - [__ NSCFArray intersectsSet:]:无法识别的选择发送到实例0x4e704c0'' 像我表示Profile需要一个NSSet并且调用NSSet的函数而不是NSArray的方法 – Seega 2011-04-11 15:23:49

回答

2

得到了与嵌套NSDictonarys的问题,所以我说再见的动态方式。 这里是我完整的解决方案,以帮助他人
的ViewController调用IM /导出功能

- (void) exportProfile:(Profile *)profile toPath:(NSString *)path{ 
    //Call the NSManagedobject function to export 
    NSDictionary *profileDict = [self.selectedProfile dictionaryForExport]; 

    if([profileDict writeToFile:[path stringByStandardizingPath] atomically:YES]) 
     NSLog(@"Saved"); 
    else 
     NSLog(@"Not saved"); 
} 

- (void) importProfileFromPath:(NSString *)path{ 
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext]; 
    Profile *newProfile = [NSEntityDescription insertNewObjectForEntityForName:@"Profile" inManagedObjectContext:context]; 

    //load dictonary from file 
    NSMutableDictionary *profileDict = [NSMutableDictionary dictionaryWithContentsOfFile:[path stringByStandardizingPath]]; 
    //call the NSManagedObjects import function 
    [newProfile importWithDictonary:profileDict context:context]; 

    NSError *error = nil; 
    if (![context save:&error]) { 

     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 
} 

NSManagedObject功能我得到了一个层次,所以我把它们放在我的每个NSManagedObjects的

- (void) importWithDictonary:(NSDictionary*)dict context:(NSManagedObjectContext*)context{ 
    self.name = [dict objectForKey:@"name"]; 

    //Relationship 
    for (NSDictionary *view in [dict objectForKey:@"views"]) { 
     View *tempView = [NSEntityDescription insertNewObjectForEntityForName:@"View" inManagedObjectContext:context]; 
     [tempView importWithDictonary:view context:context]; 
     tempView.profile = self; 
     [self addViewsObject:tempView]; 
    } 
} 

- (NSDictionary*) dictionaryForExport{ 
    //propertys 
    NSMutableDictionary *dict = [[[self dictionaryWithValuesForKeys:[[[self entity] attributesByName] allKeys]] mutableCopy] autorelease]; 
    NSURL *objectID = [[self objectID] URIRepresentation]; 
    [dict setObject: [objectID absoluteString] forKey:@"objectID"]; 
    NSMutableArray *views = [NSMutableArray array]; 

    //relationship 
    for (View *view in self.views) { 
     [views addObject:[view dictionaryForExport]]; 
    } 
    [dict setObject:views forKey:@"views"]; 
    return dict; 
} 

不是最美丽的解决方案,但它的工作:)
,我仍然要弄清楚如何避免重复在我的n:m rela tionship

谢谢

+0

导出字典时该语句的任何特定用法? - NSURL * objectID = [[self objectID] URIRepresentation]; – 2012-07-09 18:52:09

1

你可以尝试重写NSManagedObject的setValuesForKeysWithDictionary的默认实现?

看着the documentation你应该只需要在你的子类中实现setValue:forKey:

你应该能够抓住那里的NSSet并在抛出异常之前自己处理它?

[免责声明 - 我从来没有做过这个!]

+0

谢谢,在回家的路上想到这个,明天就会试试。 – Seega 2011-04-11 18:41:33

+0

+1为链接转发 – Seega 2011-04-11 18:48:23