【问题标题】:Sharing a plist file using iCloud使用 iCloud 共享 plist 文件
【发布时间】:2012-01-14 14:24:38
【问题描述】:

我有一个相对简单的应用程序,它将数据保存到位于文档文件夹中的 plist 文件中。数据在启动时加载到 UITableView 中。然后,用户可以编辑、删除或添加记录,任何更改都会保存回 plist 文件。

现在我想使用 iCloud 跨设备共享这些数据(plist 文件)。我查看了文档,我的理解是我需要创建一个 UIDocument 来“管理” plist 文件。

我看过几个 iCloud 教程,但是它们都在 UIDocument 类的属性中存储了一个简单的字符串,而不是整个文件(如 plist)。

如何使用 UIDocument 对象将我的 plist 文件(或任何其他文件)共享到 iCloud?

我是否可以将 plist 文件内容转换为 NSData,然后将其保存在 UIDocument 的属性中?我应该改用使用 NsFileWrapper 吗?

我似乎很难理解 UIDocument/iCloud 的安排。我可能让这件事变得更复杂了。

【问题讨论】:

  • 您找到答案了吗?我正在考虑做同样的事情,我的应用听起来和你的很相似。如果你找到了一个好的教程,请告诉我。
  • 我也在努力做到这一点。我一直在用 NSString 修改教程,但是我无法让第二台设备看到数据。

标签: persistence plist icloud nsfilewrapper uidocument


【解决方案1】:

不确定是否还有人需要解决方案,但我找到了一个很好的方法来解决这个问题。

由于 UIDocument 只接受数据作为 NSData 或 NSFilewrapper,我首先为 NSDictionary 类创建了一个类别,该类从 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 秒。

【讨论】:

    【解决方案2】:

    要将 plist 与 UIDocument 一起使用,您可以继承 UIDocument 并使用声明为 NSMutableDictionary 的 self.myDictionary(您的 plist)覆盖以下 2 个方法。

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

    【讨论】:

    • 这不会创建字典 plist 它会创建一个存档 plist 但足够接近。要创建真正的 plist,请使用 NSPropertyListSerialization,您可以选择 xml 或二进制输出。
    • Mac 和 iOS 之间的存档 plist 也不兼容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    • 2012-07-25
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 2020-06-29
    • 1970-01-01
    相关资源
    最近更新 更多