2011-12-07 46 views
7

我有一個relativley簡單的應用程序,它將數據保存到位於文檔文件夾中的plist文件。數據在啓動時加載到UITableView中。然後用戶可以編輯,刪除或添加記錄,並將所有更改保存回plist文件。使用iCloud共享plist文件

現在我想通過使用iCloud的設備共享這些數據(plist文件)。我看過文檔,我的理解是我需要創建一個UIDocument來「管理」plist文件。

我已經看過幾個iCloud教程,但是他們都在Uidocument類的屬性中存儲了一個簡單的字符串,而不是整個文件(如plist)。

如何使用UIDocument對象將我的plist文件(或任何其他文件)分享給iCloud?

我會將plist文件內容轉換爲NSData,然後將其保存在UIDocument的屬性中?我應該使用NsFileWrapper嗎?

我似乎很難在UIDocument/iCloud安排中纏住我的頭。我可能會讓它變得更加複雜,但事實確實如此。

+0

您是否找到了答案?我正在做同樣的事情,我的應用聽起來和你的非常相似。如果你找到一個好的教程,請讓我知道。 – Jackson

+0

我也試圖做到這一點。我一直在用NSString修改教程,但我無法讓第二個設備看到數據。 – zambono

+0

同上。 +1到海報 – autodidakto

回答

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; 
} 
+0

這不會創建一個字典plist它創建一個檔案plist,但足夠接近。要創建一個真正的plist,請使用NSPropertyListSerialization,您可以選擇xml或二進制輸出。 – malhal

+0

另外,歸檔plists在Mac和iOS之間不兼容。 – malhal

7

不知道是否有人仍然需要一個解決方案,但我發現一個很好的方式來得到這個工作。

由於UIDocument只接受數據作爲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容器。

加載您的plist從iCloud中添加到您的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秒才能更新。