アプリの iCloud コンテナでファイルが変更されたときに正しく監視する方法を見つけるために、誰かが私を正しい方向に向けることができますか? 私は自分のコードを、私がレビューした Apple および他の iCloud チュートリアルに基づいていますが、最初のクエリを使用するだけで、iCloud コンテナーの更新を処理するものはありません。私はこれに3週間取り組んできましたが、成功していません。アプリで UIDocument を使用して、アプリの iCloud コンテナーに保存します。UIDocument はドキュメントが追加されても通知を送信しないため、アプリが複数のデバイスで実行されている場合、別の iOS デバイスでアプリを更新することはできません。ドキュメントの変更と削除は、UIDocument UIDocumentStateChangedNotification を監視することで正常に機能します。
アプリがバックグラウンドで起動または再開するときに、最初にクエリを使用して iCloud コンテナーをチェックします。これにより、アプリがアクティブでないときに追加されたドキュメントを含め、デバイス上の iCloud コンテナー内のすべてのファイルを取得できます。NSMetadataQueryDidFinishGatheringNotification がポストされたときにクエリ結果を処理するための更新を無効にしてから、クエリの更新を有効にします。NSMetadataQueryDidUpdateNotification からの更新が投稿されていることを有効にした直後に、1 つまたは 2 つの更新通知を受け取ることがありますが、それだけです。それ以上の更新通知や、iCloud コンテナーに追加されたドキュメントからの通知はありません。
私は、iCloud を使用するためのコードがやや複雑であることを理解しています。誰かが私のコードを調べて修正することは期待していません (参照用に抜粋を提供しました)。アプリの実行中に iCloud コンテナーの変更を追跡する方法の詳細について誰かが教えてくれれば幸いです。
ありがとう、
フレッド
クエリを開始するためのコードの抜粋:
-(void)loadDocument {
// set iCloud URL to nil for local storage to start
NSURL *ubiq = nil;
// if iCloud is selected get the iCloud container URL
if ([_useiCloud isEqualToString:@"YES"]) {
// get the app iCloud container URL
ubiq = DefaultMemoDataController.iCloudContainerURL;
}
// if iCloud URL is available and user chooses to use iCloud, set the query for app memo file names
if (ubiq) {
// adding to see if not creating another query prevents crash resuming from background
if (!self.query) {
self.query = [[NSMetadataQuery alloc] init];
}
// set the scope of the query to look in iCloud documents
[self.query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
// set search to look for a group of file names by setting up a predicate
// use the note file name format for the app
NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K like 'FOLMemo_*'", NSMetadataItemFSNameKey];
// set the query to search with the predicate.
[self.query setPredicate:pred];
// set up a notification when the query is complete because the query is an asynchronous call (off the main queue)
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(queryDidFinishGathering:)
name:NSMetadataQueryDidFinishGatheringNotification
object:self.query];
// start the query.
[self.query startQuery];
// not sure this is needed, but want to make sure same query is started again for updates.
DefaultMemoDataController.query = self.query;
}
}
クエリ完了時のコード
-(void)queryDidFinishGathering:(NSNotification *)notification {
// stop the query while processing the query results to prevent changes while processing
NSMetadataQuery *query = [notification object];
[query disableUpdates];
// not sure is needed but want to make sure resume updates on same query
DefaultMemoDataController.query = query;
// stop looking for query did finish notifications since the query was completed.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSMetadataQueryDidFinishGatheringNotification
object:query];
// start looking for query updates
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(processQueryUpdate:)
name:NSMetadataQueryDidUpdateNotification
object:query];
// load the data from the query
[self loadData:query];
}
クエリを処理するコード:
-(void)loadData:(NSMetadataQuery *)query {
// add all the memos from the query results to the app memos dictionary
for (NSMetadataItem *item in [query results]) {
// get the URL for the memo
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
// load the memo text from the url
FOLMemoDoc *doc = [[FOLMemoDoc alloc] initWithFileURL:url];
// open the note
[doc openWithCompletionHandler:^(BOOL success) {
if (success) {
// add the memo UIDocument object to the memo dictionary
// need temp dictionary since can't change a property dictionary for some reason
NSMutableDictionary * tempDict = [NSMutableDictionary dictionaryWithDictionary:DefaultMemoDataController.masterMemoDictionary];
[tempDict setObject:doc forKey:doc.memoDictionaryKey];
DefaultMemoDataController.masterMemoDictionary = [NSMutableDictionary dictionaryWithDictionary:tempDict];
NSNotification *notice = [NSNotification notificationWithName:kFlashofLightUpdateMemoNotice
object:doc];
[[NSNotificationCenter defaultCenter] postNotification:notice];
} else {
// failed to open document, should probably alert the user
}
}];
}
// enable query updates
[query enableUpdates];
}