Сериализация пользовательского объекта в PLIST

Я хочу иметь возможность взять объект и записать все его свойства в PLIST. Я дошел до этого:

// Get the properties of the parent class
NSMutableArray *contentViewPropertyNames = [self propertyNamesOfObject:[contentView superclass]];

// Add the properties of the content view class
[contentViewPropertyNames addObjectsFromArray:[self propertyNamesOfObject:contentView]];

// Get the values of the keys for both the parent class and the class itself
NSDictionary *keyValuesOfProperties = [contentView dictionaryWithValuesForKeys:contentViewPropertyNames];

// Write the dictionary to a PLIST
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pathAndFileName = [documentsDirectory stringByAppendingPathComponent:[dataFileName stringByAppendingString:@".plist"]];

[keyValuesOfProperties writeToFile:pathAndFileName atomically:YES];

Все хорошо, за исключением того, что я не могу записать это в PLIST, потому что он содержит некоторые свойства, несовместимые с PLIST, поэтому writeToFile:atomically: терпит неудачу и возвращает NO.

Есть ли хороший способ сериализовать только те свойства, которые можно преобразовать в PLIST, или изменить базовый класс моих объектов, чтобы это работало?

Я понимаю, что могу архивировать в двоичный файл без проблем с NSCoding, однако мне нужно иметь возможность передавать выходные данные между приложением MacOS и приложением iOS, поэтому мне нужно использовать промежуточный, независимый от платформы формат.

Конечно, я мог полностью упустить суть, если у меня есть, пожалуйста, скажите, и, как всегда, любая помощь полезна.

С наилучшими пожеланиями

Дэйв

P.S.

Вот мой метод получения имен свойств объекта:

- (NSMutableArray *)propertyNamesOfObject:(id)object {
    NSMutableArray *propertyNames = nil;
    unsigned int count, i;
    objc_property_t *properties = class_copyPropertyList([object class], &count);

    if (count > 0) {
        propertyNames = [[[NSMutableArray alloc] init] autorelease];

        for(i = 0; i < count; i++) {
            objc_property_t property = properties[i];
            const char *propName = property_getName(property);
            if(propName) {
                NSString *propertyName = [NSString stringWithCString:propName encoding:NSUTF8StringEncoding];
                [propertyNames addObject:propertyName];
            }
        }
    }
    free(properties);

    return propertyNames;
}

person Magic Bullet Dave    schedule 04.10.2012    source источник


Ответы (1)


Посмотрите, сможете ли вы применить эту функцию, которую я недавно написал в похожей ситуации:

// Property list compatible types: NSString, NSData, NSArray, or NSDictionary */
- (BOOL)isPlistCompatibleDictionary:(NSDictionary *)dict {
    NSSet *plistClasses = [NSSet setWithObjects:[NSString class], [NSData class],
        [NSArray class], [NSDictionary class], [NSDate class], 
        [NSNumber class], nil];

    BOOL compatible = YES;
    NSArray *keys = [dict allKeys];
    for (id key in keys) {
        id obj = [dict objectForKey:key];
        if (![plistClasses containsObject:[obj class]]) {
            NSLog(@"not plist compatible: %@", [obj class]);
            compatible = NO;
            break;
        }
    }

    return compatible;
}
person Jere Käpyaho    schedule 04.10.2012
comment
Отлично выглядит Джере. Я попробую и дам вам знать, как у меня дела. Дэйв. - person Magic Bullet Dave; 05.10.2012
comment
Подход выглядит хорошо, однако по какой-то причине все мои классы obj сообщаются как __NSCFString, а не их правильные типы, поэтому проверка совместимости возвращает NO для каждого ключа. Любые идеи? - person Magic Bullet Dave; 05.10.2012
comment
Хм, любая помощь в этом? stackoverflow.com/questions/393873 / - person Jere Käpyaho; 05.10.2012