iCloud: возможно ли использовать KVS для пользовательских объектов?
Я пытаюсь обернуть голову вокруг хранилища iCloud. Я прочитал Руководство по дизайну iCloud и некоторые вопросы здесь, на SO. Вот мой сценарий:
У меня есть класс, который имеет только NSMutableArray
... эта коллекция содержит мои собственные объекты, которые все придерживаются NSCoding
и сохранение локально работает отлично. Этот класс является MasterList и имеет свойство masterList, блестящий - я знаю:-p. Когда я посмотрел, как начать внедрять iCloud, я подумал, что KVS будет отличным решением, поскольку объем данных очень мал. Когда я пытался это сделать, я продолжал получать:
[NSUbiquitousKeyValueStore setObject:forKey:]: Attempt to insert non-property value <my custom objects>...
После просмотра причин, по-видимому, вы можете хранить только скалярные и P-List типы с KVS. Поэтому я перешел к использованию UIDocument
и я борюсь с этим.
Нижняя линия -
Для пользовательских объектов, вы должны использовать UIDocument
, или можно ли использовать КВС?
а также
Если я должен использовать UIDocument
Кто-нибудь из вас читал учебник, который был простым по своей природе (может быть, хранил несколько реквизитов и загружал их обратно, может быть, в примере проекта?), который заставил его щелкнуть вас?
Ниже мой код для использования KVS, если это вообще помогает. Не производство или что-то, просто пытаясь заставить его работать:
//Load it
+(MasterList *)decodeMasterList:(MasterList *)objectToDecode
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSURL *dataFile = [self pathForDocumentsFile:kFilePathAllLists];
NSString *filePath = [dataFile path];
objectToDecode = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
//First time runnign the app :-)
if (!objectToDecode) objectToDecode = [[MasterList alloc] init];
if ([defaults boolForKey:kIsUsingiCloud])
{
objectToDecode.masterList = [[[NSUbiquitousKeyValueStore defaultStore] arrayForKey:kiCloudPath] mutableCopy];
//If we just started and nothing is there
if (!objectToDecode.masterList)
{
objectToDecode.masterList = [[NSMutableArray alloc] initWithObjects:[CustomList new], nil];
}
}
return objectToDecode;
}
//Save it
+(BOOL)encodeMasterList:(MasterList *)objectToEncode
{
@try
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults boolForKey:kIsUsingiCloud])
{
[[NSUbiquitousKeyValueStore defaultStore] setArray:objectToEncode.masterList forKey:kiCloudPath];
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
}
NSURL *dataFile = [FileSystemHelper pathForDocumentsFile:kFilePathAllLists];
NSString *filePath = [dataFile path];
[NSKeyedArchiver archiveRootObject:objectToEncode toFile:filePath];
}
@catch (NSException *exception)
{
return NO;
}
return YES;
}
1 ответ
Это правда, что хранилище значений ключей может содержать только типы списков свойств. Но вы упомянули объекты в вашем массиве все соответствуют NSCoding
так что это не главная проблема. Вам просто нужно подать заявку NSCoding
конвертировать ваши объекты в / из NSData
и сохранить это.
Кодировать используя
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:myObject];
Декодировать используя
NSData *data = // from key-value store
MyClass *myObject = [NSKeyedUnarchiver unarchiveObjectWithData:data];
Однако, если вы используете UIDocument
хранилище значений ключей, вероятно, не лучший путь. Вы также можете хранить и синхронизировать документы непосредственно в iCloud через NSFileManager
а также NSMetadataQuery
, Apple предоставляет довольно хорошую документацию по этому вопросу, и она будет синхронизировать документ на месте, вместо того, чтобы требовать от вас преобразования его туда-сюда. Плюс, конечно, хранилище значений ключей имеет очень низкий предел общего размера, в то время как документы ограничены только емкостью учетной записи iCloud пользователя.