Импорт и экспорт иерархии NSManagedObject

Я пытаюсь сделать свой профиль NSMangedObjectClass не- / экспортируемым.
Я пробую таким образом
Экспорт работает правильно, если я пишу отношения в NSArrays, потому что в NSSet не реализовано writeToFile.

- (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];
}

У меня исключение, это меня не смущает, потому что Profile ожидает 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?

Или простой способ импорта / экспорта управляемых объектов?


person Seega    schedule 11.04.2011    source источник
comment
NSSet имеет метод экземпляра - (NSArray *)allObjects и метод класса + (id)setWithArray:(NSArray *)array, которые могут вам помочь.   -  person Joe    schedule 11.04.2011
comment
[__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 и вызывает функции NSSet, а не методы NSArray   -  person Seega    schedule 11.04.2011
comment
+1: возможно, вы захотите добавить исключение в свой вопрос, чтобы его было легче обнаружить. в противном случае, займитесь проблемой!   -  person Jesse Naugher    schedule 11.04.2011


Ответы (2)


Возникли проблемы с вложенными NSDictonarys, поэтому я попрощался с динамическим способом. Вот мое полное решение, чтобы помочь другим
ViewController вызывать функции im / export

- (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. У меня есть иерархия, поэтому я помещаю их в каждый из своих NSManagedObject.

- (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

Спасибо

person Seega    schedule 12.04.2011
comment
Какое-нибудь конкретное использование этого оператора при экспорте словаря? - NSURL * objectID = [[self objectID] URIRepresentation]; - person Raj Pawan Gumdal; 09.07.2012

Вы можете попробовать переопределить реализацию NSManagedObject по умолчанию setValuesForKeysWithDictionary?

Изучив документацию вам нужно только реализовать setValue: forKey: в ваших подклассах?

Вы должны иметь возможность захватить NSSet и разобраться с ним самостоятельно, прежде чем будет выбрано исключение?

[Отказ от ответственности - я никогда этого не делал!]

person deanWombourne    schedule 11.04.2011
comment
спасибо, думал об этом по дороге домой, завтра попробую. - person Seega; 11.04.2011