iCloud:是否可以将KVS用于自定义对象?

时间:2014-04-02 01:46:34

标签: ios objective-c icloud uidocument

我正试图围绕iCloud存储。我已经阅读了iCloud Design Guide以及有关SO的一些问题。这是我的情景:

我有一个只有NSMutableArray的类...该集合包含我的自定义对象,这些对象都遵循NSCoding并且本地保存完美。那个类是MasterList,有属性masterList,很棒 - 我知道:-p。当我看到如何开始实施iCloud时,我认为KVS会很棒,因为我的数据占用空间非常小。当我尝试这个时,我不断得到:

[NSUbiquitousKeyValueStore setObject:forKey:]: Attempt to insert non-property value <my custom objects>...

在看到原因后,似乎你只能用KVS存储标量和P-List类型。所以我开始使用UIDocument并且正在努力解决它。

底线 -

对于自定义对象,您是否必须使用UIDocument,还是可以使用KVS?

如果我必须使用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 个答案:

答案 0 :(得分:1)

键值存储只能保存属性列表类型。但是你提到数组中的对象都符合NSCoding,因此不是主要的问题。您只需要应用NSCoding将对象转换为NSData或从NSData *data = [NSKeyedArchiver archivedDataWithRootObject:myObject]; 转换,然后存储。

使用

进行编码
NSData *data = // from key-value store
MyClass *myObject = [NSKeyedUnarchiver unarchiveObjectWithData:data];

使用

解码
UIDocument

然而如果您使用NSFileManager,则键值存储可能不是最好的方法。您还可以通过NSMetadataQuery和{{1}}直接在iCloud中存储和同步文档。 Apple提供了相当好的文档,它可以就地同步文档,而不是要求你来回转换它。此外,键值存储的总大小限制非常低,而文档仅受用户的iCloud帐户容量的限制。