7

ドキュメントフォルダーにあるplistファイルにデータを保持する比較的シンプルなアプリがあります。データは、起動時に UITableView に読み込まれます。その後、ユーザーはレコードを編集、削除、または追加でき、変更はすべて plist ファイルに保存されます。

ここで、iCloud を使用してデバイス間でこのデータ (plist ファイル) を共有したいと考えています。私はドキュメントを見て、plistファイルを「管理」するためにUIDocumentを作成する必要があることを理解しています。

いくつかのiCloudチュートリアルを見てきましたが、それらはすべて、ファイル全体(plistなど)ではなく、UIDocumentクラスのプロパティ内に単純な文字列を保存します。

UIDocument オブジェクトを使用して、plist ファイル (またはその他のファイル) を iCloud で共有するにはどうすればよいですか?

plist ファイルの内容を NSData に変換し、それを UIDocument のプロパティに保存しますか? 代わりに NsFileWrapper を使用する必要がありますか?

UIDocument/iCloud の配置に頭を悩ませているようです。私はおそらくこれを実際よりも複雑にしています。

4

2 に答える 2

7

誰かがまだその解決策を必要としているかどうかはわかりませんが、これを機能させるための良い方法を見つけました.

UIDocument はデータを NSData または NSFilewrapper としてのみ受け入れるため、最初に NSData から NSDictionary を返す NSDictionary クラスのカテゴリを作成しました。カテゴリの 2 つのファイルを次に示します。

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

ソース

このカテゴリを 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 秒かかることに注意してください。

于 2012-10-06T12:50:40.033 に答える
1

UIDocument で plist を使用するには、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;
}
于 2012-03-08T04:30:26.110 に答える