0

パッケージスタイルのドキュメントを作成するツールがあります。NSDocumentを使用して実装され、次のNSDocumentメソッドをオーバーライドします。

- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName
                              error:(NSError **)outError;

- (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper
                    ofType:(NSString *)typeName
                     error:(NSError **)outError;

バージョン管理下にあるドキュメントを保存する場合を除いて、これはすべて素敵です。(.svnディレクトリは保存されませんなど)

私のドキュメントをsvnでうまく再生させるための良いレシピはどこかにありますか?

4

2 に答える 2

3

-fileWrapperOfType:error:が呼び出されるたびに新しいファイルラッパーを作成することで、コードが機能すると思います。これは便利ですが、パッケージ内のディスクに存在する可能性のある追加のファイルは無視されます。

したがって、代わりに、ディスク上の既存のコンテンツを参照するファイルラッパーを作成/使用することから始めた場合はどうでしょうか。そのラッパーをドキュメントの現在の状態に一致するように変更し、結果を返します。そのラッパーがディスクに書き出されるとき、svnファイルは適切に維持されるべきです。

于 2010-08-24T22:56:33.507 に答える
1

これがマイクの答えに基づいた私の解決策です!

私のドキュメントパッケージはバンドルであり、通常の階層構造になっています…したがって、保存中に変更するディレクトリは4つあります。

  1. 保存すると、新しいトップレベル(My.bundle)が作成されます
  2. コンテンツディレクトリが変更されました(My.bundle/Contents)
  3. Resourcesディレクトリが変更されました(My.bundle/Contents/Resources)
  4. ローカライズされたリソースが更新されます(My.bundle/Contents/Resources/en.lproj)

レシピは、これらの各ディレクトリの内容を保持するために、ドキュメントクラスに変更可能な辞書スロットを追加することから始まります。

@interface LMDocument : NSDocument {
@private
    // All this is for preserving SCM artifacts across saves…
    NSMutableDictionary * bundleWrappers;
    NSMutableDictionary * contentsWrappers;
    NSMutableDictionary * resourcesWrappers;
    NSMutableDictionary * localizedWrappers;
}

新しいドキュメントを作成するとき、これらは空の辞書として始まります。

- (id)init;
{
    if ((self = [super init]) != nil) {
        bundleWrappers = [[NSMutableDictionary alloc] initWithCapacity:0];
        contentsWrappers = [[NSMutableDictionary alloc] initWithCapacity:0];
        resourcesWrappers = [[NSMutableDictionary alloc] initWithCapacity:0];
        localizedWrappers = [[NSMutableDictionary alloc] initWithCapacity:0];
    }
    return self;
}

既存のドキュメントを読み取る場合は、これらを関連するfileWrapperコンテンツの変更可能なコピーに置き換えます。

- (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper
                     ofType:(NSString *)typeName
                      error:(NSError **)outError;
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    bundleWrappers = [[fileWrapper fileWrappers] mutableCopy];
    contentsWrappers = [[[bundleWrappers objectForKey:@"Contents"] fileWrappers] mutableCopy];
    resourcesWrappers = [[[contentsWrappers objectForKey:@"Resources"] fileWrappers] mutableCopy];
    localizedWrappers = [[[resourcesWrappers objectForKey:@"en.lproj"] fileWrappers] mutableCopy];
    NSFileWrapper * infoPlistWrapper = [contentsWrappers objectForKey:@"Info.plist"];
    [contentsWrappers removeObjectForKey:@"Info.plist"]; // Replaced during save…
    // …
    NSMutableDictionary * localizedWrappersCopy = [localizedWrappers mutableCopy];
    [localizedWrappers enumerateKeysAndObjectsUsingBlock:^(id key,
                                                           id obj,
                                                           BOOL * stop)
     {
         if (mumble) { // If it's a file that will be replaced during save…
             [localizedWrappersCopy removeObjectForKey:key]; // Replaced during save…
             // …
         }
     }];
    localizedWrappers = localizedWrappersCopy;
    [pool drain];
    return YES;
}

そして最後に、ドキュメントを保存するときは、入念に準備された辞書を使用してください。

- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName
                               error:(NSError **)outError;
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSFileWrapper * localizedWrapper =
    [[NSFileWrapper alloc] initDirectoryWithFileWrappers:localizedWrappers];
    [resourcesWrappers setObject:localizedWrapper
                          forKey:@"en.lproj"];
    NSFileWrapper * resourcesWrapper =
    [[NSFileWrapper alloc] initDirectoryWithFileWrappers:resourcesWrappers];
    [contentsWrappers setObject:resourcesWrapper
                         forKey:@"Resources"];
    NSFileWrapper * contentsWrapper =
    [[NSFileWrapper alloc] initDirectoryWithFileWrappers:contentsWrappers];
    // …
    for (id item in mumble) {
        NSString * filename = [item filename];
        NSData * data = [item data];
        [localizedWrapper addRegularFileWithContents:data
                                   preferredFilename:filename];
    }
    [contentsWrapper addRegularFileWithContents:[self infoPlistData]
                              preferredFilename:@"Info.plist"];
    [pool drain];
    [bundleWrappers setObject:contentsWrapper
                       forKey:@"Contents"];
    NSFileWrapper * bundleWrapper =
    [[[NSFileWrapper alloc] initDirectoryWithFileWrappers:bundleWrappers] autorelease];
    return bundleWrapper;
}

これで、パッケージドキュメントが編集されると、アプリケーションは、SCMアーティファクトや「その他の」ローカリゼーションなど、バンドルに追加しなかったファイルをすべて保持します。

于 2010-08-25T01:09:27.973 に答える