2

iCloud をサポートしていない UIDocument ベースのアプリがあります。ユーザーはドキュメントを作成し、アプリのドキュメント ディレクトリに保存できます。

また、いくつかの「サンプル」ドキュメントを作成し、それらをアプリのバンドルに渡しました。ユーザーが自分のドキュメントを開くのと同じ方法でサンプル ドキュメントを開くことができるようにします。

NSArray *samplesContent = [[NSBundle mainBundle] URLsForResourcesWithExtension:@"doco" subdirectory:@"Samples"];

for (NSURL *sampleURL in samplesContent) {
    Doco *doco = [[Doco alloc] initWithFileURL:sampleURL];
    [doco disableEditing];

    [doco openWithCompletionHandler:^(BOOL success) {
        if (success) {
            [self.docos addObject:doco];

            if (self.docos.count >= samplesContent.count) {
                [self.tableView reloadData];
            }
        } else DLog(@"Failed to open %@", [sampleURL pathExtension]);
     }];
}

私が見ているのはこれです:

  1. viewDidLoadでは、 docs 配列にサンプル ドキュメントが取り込まれ、アプリの初回起動時に tableView に表示されます。ここでは問題はありません。すべてがスムーズで快適です。
  2. 次に、次のコードを使用してビューから戻り、開いているすべてのドキュメントを閉じます。

    int count = 0;
    
    for (Doco *doco in self.docos) {
        if (doco.documentState == UIDocumentStateNormal) {
            [doco closeWithCompletionHandler:nil];
            count++;
        }
    }
    
    DLog(@"Closed %i docs", count);
    
  3. ビューを再度開くと、ドキュメントの配列が再び入力され、tableView が再入力されるはずですが、何も起こりません。

URL が同じファイルを指しており、有効であるにもかかわらず、以下の完了ハンドラーが呼び出されることはありません。

[doco openWithCompletionHandler:^(BOOL success) {}

ドキュメントに保存されているユーザー生成ドキュメントではこの問題は発生していないため、読み取り専用バンドルで呼び出されて失敗する自動保存と関係があると思います

しかし、私はこの部分で立ち往生しています。どんな助けでも大歓迎です。

4

2 に答える 2

2

この問題はすでに特定されていますが、アプリのバンドルにサンプル ドキュメントを含めることは珍しくないため、いくつかの簡単な解決策を説明する価値があると思います。

問題は、サンプル ドキュメントが閉じられたときに変更を保存しようとしているのに、読み取り専用アプリ バンドルで保存が成功しないことです。

ここには2つの主な解決策があると思います:

  1. サンプル ドキュメントを Documents ディレクトリにコピーします。このディレクトリでは、他のドキュメントと同様に扱うことができ、正常に保存できます (サンプル ドキュメントに対するユーザーの編集を保存する場合は、この方法を使用します)。

  2. ドキュメントが保存されないようにします (読み取り専用のサンプル ドキュメントの場合)。

そこで、いくつかの簡単な例を...


1. サンプル ドキュメントを Documents ディレクトリにコピーします。

最初の起動時 (または実際にサンプル ドキュメントを「更新」するたびに) を使用NSFileManagerして、ファイルを所定の場所にコピーします。

- (void)refreshSampleDocuments
{
    NSArray *sampleFromURLs = [[NSBundle mainBundle] URLsForResourcesWithExtension:@"doc" subdirectory:@"Samples"];

    for (NSURL *sampleFromURL in sampleFromURLs) {

        NSString *sampleFilename = [sampleFromURL lastPathComponent];
        NSURL *sampleToURL = [[self documentsDirectoryURL] URLByAppendingPathComponent:sampleFilename];

        // ...
        // Do some checks to make sure you won't write over any user documents!
        // ....

        NSError *error;
        BOOL copySuccessful = [[NSFileManager defaultManager] copyItemAtURL:sampleFromURL toURL:sampleToURL error:&error];

        if (!copySuccessful) {
            // Handle error...
        }
    }
}

2. サンプル文書が保存されないようにする

このアプローチは (読み取り専用ドキュメントの場合) はるかに単純であり、ドキュメント内で発生する可能性のある更新を防止しようとするよりも簡単です。

でがcloseWithCompletionHandler:呼び出されると、ドキュメント ファイルを閉じる前に確実に保存するために呼び出されます。これは、保存が必要かどうかを決定するために呼び出されます。したがって、が返された場合、自動保存メカニズムを呼び出しても、変更は書き出されません。UIDocumentautosaveWithCompletionHandler:hasUnsavedChangeshasUnsavedChangesNO

(NB を手動で呼び出すsaveToURL:forSaveOperation:completionHandler:と、戻り値に関係なく、保存が強制されhasUnsavedChangesます。)

したがって、サブクラスでは、ドキュメントが読み取り専用の場合UIDocumentにオーバーライドhasUnsavedChangesして戻ります。NO

@interface MyDocument : UIDocument

@property(nonatomic, getter = isReadOnly) BOOL readOnly;

@end


@implementation MyDocument

- (BOOL)hasUnsavedChanges
{
    return [self isReadOnly] ? NO : [super hasUnsavedChanges];
}

@end

于 2014-08-17T08:26:34.343 に答える
2

UIDocument が更新されると、閉じるときに変更を保存しようとします。は読み取り専用バンドルから読み込まれたためUIDocument、更新されないようにする必要がありました。それ以外の場合は、クローズ ブロックが返されsuccess=NO、ドキュメントが閉じられません...

于 2012-06-30T03:39:30.127 に答える