6

ドキュメントでいっぱいのローカルフォルダをリモートのiCloudフォルダにアップロードしようとしています。このメソッドを作成して、ローカルフォルダー内のファイルの配列をループし、それらがすでに存在するかどうかを確認し、存在しない場合はiCloudにアップロードします。注-このコードは、メインスレッドではなくバックグラウンドスレッドで実行されています。

//Get the array of files in the local documents directory
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSArray *localDocuments = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:nil];

//Compare the arrays then upload documents not already existent in iCloud
for (int item = 0; item < [localDocuments count]; item++) {
    //If the file does not exist in iCloud, upload it
     if (![[iCloud previousQueryResults] containsObject:[localDocuments objectAtIndex:item]]) {
          NSLog(@"Uploading %@ to iCloud...", [localDocuments objectAtIndex:item]);
          //Move the file to iCloud
          NSURL *destinationURL = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil] URLByAppendingPathComponent:[NSString stringWithFormat:@"Documents/%@",[localDocuments objectAtIndex:item]]];
          NSError *error;
          NSURL *directoryURL = [[NSURL alloc] initWithString:[documentsDirectory stringByAppendingPathComponent:[localDocuments objectAtIndex:item]]];
          BOOL success = [[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:directoryURL destinationURL:destinationURL error:&error];
          if (success == NO) {
              //Determine Error
              NSLog(@"%@",error);
          }
     } else {
          ...
     } }

このコードを実行すると、Forループは正常に機能します(NSLogステートメントを使用してアップロードしているファイルを見つけます)。ローカルに保存されていて、まだiCloudにないすべてのファイルがアップロードを開始することになっています。Forループが終了したら、developer.icloud.comを使用して現在iCloudにあるドキュメントを確認します。iCloudにローカルにアップロードされた多くのファイルのうち、1つのファイル(私のアプリが作成し続けるが決して使用しないsqliteファイル)のみ。forループを使用するときに1つのファイルしかアップロードしないのはなぜですか?

同じコードを使用して(Forループなしで)個々のファイルをアップロードすると、それらはiCloudに完全にアップロードされます。Forループがファイルのアップロードを妨げるのはなぜですか?これは、最後のプロセス/行の実行が終了するのを待たずに、Forループがコードの次の行に続くことと関係がありますか?何が起きてる?

編集:通常、(Forループを使用せずに)大きなファイルをiCloudにアップロードすると、iCloud開発サイトでファイルがほぼ瞬時にアップロードを保留していることがわかります。私はWiFiを介してすべてをテストしていて、しばらく待っていましたが、何も表示されません(sqliteファイルを除く)。

編集:私はまた、別のメソッドでiCloudの可用性をチェックし、iCloudが利用可能な場合はこのメソッドの呼び出しを許可します。また、ドキュメントを読み、AppleのWebサイトでWWDCビデオを視聴したことも確認しましたが、それらは複雑で、私がやろうとしていることについて多くの説明を提供していません。

編集:上記のコードを修正した後(エラー機能を追加)、ログに次のエラーメッセージが表示されます:

Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be completed. (Cocoa error 512.)" UserInfo=0x1f5dd070 {NSUnderlyingError=0x208ad9b0 "The operation couldn’t be completed. (LibrarianErrorDomain error 2 - No source URL specified.)"}

これにより、ファイルの1つが正常にアップロードされ、他のファイルはアップロードされないため、事態はさらに混乱します。

4

1 に答える 1

6

OK、その最後の編集は役に立ちます。エラーは、(コード内の)ソースURLdirectoryURLが欠落していることを示しています-おそらくそれがであるためnilです。なぜだろうnil?あなたがそれを間違って作成しているからです。を使用していて-[NSURL initWithString:]、ドキュメントには次のように書かれています。

この文字列は、RFC 2396で説明されているURL形式に準拠している必要があります。このメソッドは、RFC1738および1808に従ってURLStringを解析します。

URLではなくファイルパスを渡しています。NSURL有効なURLとして認識されないものを渡すと、通常はを返しますnil。とにかくファイルURLを頻繁に生成するように見えNSURLますが、ここでは失敗が予想される動作です。私の知る限り、ファイル名にスペースが含まれていなくても機能するようですが、それは文書化されておらず、信頼できるものでもありません。

あなたがすべきことはdirectoryURL、ファイルパスを受け入れるものを使用するように初期化する行を変更することです。何かのようなもの:

NSURL *directoryURL = [NSURL fileURLWithPath:[documentsDirectory stringByAppendingPathComponent:[localDocuments objectAtIndex:item]]];

また、万が一の場合に備えて、そうでdirectoryURLはないことを確認してください。nil

于 2013-01-17T22:38:19.580 に答える