我有一个relativley简单应用程序,它将数据保存到位于文档文件夹中的plist文件中。数据在启动时加载到UITableView中。然后,用户可以编辑,删除或添加记录,任何更改都会保存回plist文件。
现在我想使用iCloud跨设备共享此数据(plist文件)。我查看了文档,我的理解是我需要创建一个UIDocument来“管理”plist文件。
我查看了几个iCloud教程,但是它们都在UIDocument类的属性中存储了一个简单的字符串,而不是整个文件(如plist)。
如何使用UIDocument对象将我的plist文件(或任何其他文件)与iCloud共享?
我会将plist文件内容转换为NSData,然后将其保存在UIDocument的属性中吗?我应该使用NsFileWrapper吗?
我似乎很难绕着UIDocument / iCloud安排我的脑袋。我可能会让它变得更加复杂,然而它确实如此。
答案 0 :(得分:7)
不确定是否有人仍需要解决方案,但我找到了一种很好的方法让它发挥作用。
由于UIDocument只接受Data作为NSData或NSFilewrapper,我首先为NSDictionary类创建了一个Category,它从NSData返回一个NSDictionary。这是类别的两个文件:
的NSDictionary + DictFromData.h:
#import <Foundation/Foundation.h>
@interface NSDictionary (DictFromData)
+ (id)dictionaryWithData:(NSData *)data;
- (id)initWithData:(NSData *)data;
@end
和NSDictionary + DictFromData.m
#import "NSDictionary+DictFromData.h"
@implementation NSDictionary (DictFromData)
+ (id)dictionaryWithData:(NSData *)data {
return [[[NSDictionary alloc] initWithData:data] autorelease];
}
- (id)initWithData:(NSData *)data {
NSString *tmp = nil;
self = (NSDictionary *)[NSPropertyListSerialization
propertyListFromData:data
mutabilityOption:NSPropertyListImmutable
format:NULL
errorDescription:&tmp];
NSAssert1(tmp == nil,@"Error in plist: %@",tmp);
return [self retain];
}
@end
(source)
如果您现在在UIDocument子类中导入此类别,则可以轻松地将Plist文件加载并保存到iCloud容器中。
要从iCloud加载您的Plist,请将其添加到您的UIDocument子类(属性内容是NSDictionary):
- (BOOL)loadFromContents:(id)contents
ofType:(NSString *)
typeName error:(NSError **)outError {
if ([contents length] > 0){
self.contents = [NSDictionary dictionaryWithData:contents];
} else {
self.contents = nil;
}
// call some Methods to handle the incoming NSDictionary
// maybe overwrite the old Plist file with the new NSDictionary
return YES;
}
要将数据保存回iCloud,请添加以下内容:
- (id)contentsForType:(NSString *)typeName error:(NSError **)outError {
NSData * plistData = [[[NSData alloc]initWithContentsOfFile:YOUR_PLIST_FILE]autorelease];
return plistData;
}
如果您现在致电:
[myUIDocument updateChangeCount:UIDocumentChangeDone];
YOUR_PLIST_FILE正在同步。请记住,您的iCloud容器需要大约10-15秒才能更新。
答案 1 :(得分:1)
要使用带有UIDocument的plist,您可以继承UIDocument并使用声明为NSMutableDictionary的self.myDictionary(您的plist)覆盖以下两个方法。
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError **)outError
{
if ([contents length] > 0)
{
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:(NSData *)contents];
NSMutableDictionary *dataDictionary = [unarchiver decodeObjectForKey:@"data"];
self.myDictionary = dataDictionary;
[unarchiver finishDecoding];
[unarchiver release];
}
else
{
self.myDictionary = [NSMutableDictionary dictionary];
}
return YES;
}
- (id)contentsForType:(NSString *)typeName error:(NSError **)outError
{
NSMutableData *data = [[[NSMutableData alloc] init] autorelease];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
if( !self.myDictionary )
{
self.myDictionary = [NSMutableDictionary dictionary];
}
[archiver encodeObject:self.myDictionary forKey:@"data"];
[archiver finishEncoding];
[archiver release];
return data;
}