5

アプリのバックアップマネージャーを作成しています(iCloud経由)。私はいくつかのテストを行い、基本は機能しました。しかし、数日後には止まりました。NSMetadataQueryバックアップファイルが存在するかどうかを検索するために使用しています。私のバックアップファイルの名前は、たとえばBackup29112011154133.xml、数字がバックアップの日付を表す場所です (形式はddMMyyyyHHmmss)。私はそれをチェックします-viewDidAppear

- (void)viewDidAppear:(BOOL)animated {
    [self checkForRemoteFile];
}

- (void)checkForRemoteFile {
    NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
    if (ubiq) {
        NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
        [query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
        NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K like 'Backup*'",NSMetadataItemFSNameKey];
        [query setPredicate:pred];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishGathering:) name:NSMetadataQueryDidFinishGatheringNotification object:query];
        [query startQuery];
    } else {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"iCloud is unavailable at the moment" message:nil delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
        [alert setTag:TAG_ALERT_NOICLOUD];
        [alert show];
    }
}

- (void)queryDidFinishGathering:(NSNotification *)notif {
    NSMetadataQuery *query = [notif object];
    [query disableUpdates];
    [query stopQuery];
    [self loadRemoteFile:query];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query];
}

- (void)loadRemoteFile:(NSMetadataQuery *)query {
    if ([query resultCount] == 1) {
        canRestore = YES;
        NSMetadataItem *item = [query resultAtIndex:0];
        // parse the backup file
        [self.tableView reloadData];
    } else {
        canRestore = NO;
        modifDate = @"never";
        backupInfoLoaded = YES;
        [self.tableView reloadData];
    }
}

問題は、- (void)queryDidFinishGathering:(NSNotification *)notif決して実行されないことです。そこにブレークポイントと NSLogs イオンを配置しましたが、何も起こりませんでした。

「クエリが収集を開始しました」や「クエリプロセス」など、他の通知も確認しようとしました。「クエリが開始されました」通知のみが投稿されます。

また、iCloud が登録された AppID と権利ファイルが添付されています。

何が起こっているのか、私を助けてくれますか? 多分私は何かを逃しましたか?

4

4 に答える 4

17

まず、startQuery が MaintThread からではなく呼び出された場合、NSMetadataQuery は機能しません。パスごとに述語が失敗する可能性もあります。次のコードは私にとってはうまくいきます。

NSURL *mobileDocumentsDirectoryURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
...
query.predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"%%K like \"%@*\"", [mobileDocumentsDirectoryURL path]], NSMetadataItemPathKey];
[query startQuery];
于 2011-12-01T18:21:53.050 に答える
9

ivarforを作成することで修正されましたNSMetadataQuery

アプリケーションがNSMetadataqueryivarなしでデータを読み取れない理由がわかりません。

于 2011-12-10T13:10:35.150 に答える
2

残念ながら、iCloud と の使用には多くの問題がありましNSMetaDataQueryた。正直なところ、iCloud 関連のすべての質問に対する現時点での最良の情報源は、Apple Developer Forums です。今日、Apple は iOS 5.1 ベータ版をリリースしましたが、リリース ノートにはまだNSMetaDataQueryが正しく機能していないと書かれています。iCloud がまだ正常に機能していないことは非常に残念ですが、残念ながら私たちにできることは何もありません。

于 2011-11-29T16:11:51.450 に答える
1

この問題はまだ解決していません。私はそれを次の分岐にたどることができました:

  • クエリの検索述語を名前キーに限定すると、

例えば

[NSPredicate predicateWithFormat:@"%K like[cd] %@", NSMetadataItemFSNameKey, @"*"]

その後、期待どおりに機能します (4 つのクエリ ライフサイクル通知すべてを投稿します)。

  • ただし、複合述語を試すか、パスを操作しようとすると、

のように

[NSPredicate predicateWithFormat:@"%K BEGINSWITH %@", NSMetadataItemPathKey, [self cloudDocumentsURL].path]

また

[NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:namePred, pathPred, nil]];

その後、最初の通知のみが投稿されます。

私は昨年、複数のテスト用アプリと本番用アプリでこれらの構成可能な変数の文字通り何百もの組み合わせを試しましたが、この仮説に対する反例をまだ見つけていません。

残念ながら、NSMetadataQuery はユビキタス ストアでは機能しません (10.8 以降)。

私の回避策は、クエリから生の結果を取得し、結果をフィルタリングできるバインドされた NSArrayController で主に作業することです。これは、ほとんどの既存のコードの query.results からリファクタリングすることを意味し、(おそらく) パフォーマンス ヒットがありますが、それが私が見つけた唯一の方法です。代替案が欲しいです。

于 2012-10-23T16:41:08.913 に答える