2011-04-11 82 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