【发布时间】:2013-06-12 19:45:21
【问题描述】:
我正在尝试让我的 OS X 应用程序根据对 iCloud 文档的更改自动更新,但我很难让通知正常工作。具体来说,我得到了一些代码,应该列出我的NSMetadataQuery 的所有结果(只是这样我可以进行一些测试和确认),但它返回 0 结果。尽管事实上我的无处不在的容器中显然有一些东西,因为数据正在从我的 OS X 应用程序成功上传,并在启动时再次成功下载。这就是我现在所拥有的。
CloudDocument.h:
@property (nonatomic, strong) NSMetadataQuery *alertQuery;
CloudDocument.m:
@implementation CloudDocument
@synthesize alertQuery;
-(id)init {
self = [super init];
if (self) {
alertQuery = [[NSMetadataQuery alloc] init];
if (alertQuery) {
// Search the Documents subdirectory only.
[alertQuery setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
// Add a predicate for finding the documents.
NSString *filePattern = @"*";
[alertQuery setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE %@", NSMetadataItemFSNameKey, filePattern]];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidUpdate:) name:NSMetadataQueryDidFinishGatheringNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidUpdate:) name:NSMetadataQueryDidUpdateNotification object:nil];
NSLog(@"Notification created");
[alertQuery startQuery];
}
return self;
}
-(void)queryDidUpdate:(NSNotification *)notification {
[alertQuery disableUpdates];
NSLog(@"Something changed!!! - %@", [notification name]);
// Look at each element returned by the search
// - note it returns the entire list each time this method is called, NOT just the changes
int resultCount = (int)[alertQuery resultCount];
NSLog(@"%i", resultCount);
for (int i = 0; i < resultCount; i++) {
NSMetadataItem *item = [alertQuery resultAtIndex:i];
[self logAllCloudStorageKeysForMetadataItem:item];
}
[alertQuery enableUpdates];
}
- (void)logAllCloudStorageKeysForMetadataItem:(NSMetadataItem *)item {
NSLog(@"LogAll gets called");
NSNumber *isUbiquitous = [item valueForAttribute:NSMetadataItemIsUbiquitousKey];
NSNumber *hasUnresolvedConflicts = [item valueForAttribute:NSMetadataUbiquitousItemHasUnresolvedConflictsKey];
NSNumber *isDownloaded = [item valueForAttribute:NSMetadataUbiquitousItemIsDownloadedKey];
NSNumber *isDownloading = [item valueForAttribute:NSMetadataUbiquitousItemIsDownloadingKey];
NSNumber *isUploaded = [item valueForAttribute:NSMetadataUbiquitousItemIsUploadedKey];
NSNumber *isUploading = [item valueForAttribute:NSMetadataUbiquitousItemIsUploadingKey];
NSNumber *percentDownloaded = [item valueForAttribute:NSMetadataUbiquitousItemPercentDownloadedKey];
NSNumber *percentUploaded = [item valueForAttribute:NSMetadataUbiquitousItemPercentUploadedKey];
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
BOOL documentExists = [[NSFileManager defaultManager] fileExistsAtPath:[url path]];
NSLog(@"isUbiquitous:%@ hasUnresolvedConflicts:%@ isDownloaded:%@ isDownloading:%@ isUploaded:%@ isUploading:%@ %%downloaded:%@ %%uploaded:%@ documentExists:%i - %@", isUbiquitous, hasUnresolvedConflicts, isDownloaded, isDownloading, isUploaded, isUploading, percentDownloaded, percentUploaded, documentExists, url);
}
-(NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
[Data setSyncProgressIndicators:NO];
return [NSKeyedArchiver archivedDataWithRootObject:[Data getAllNotes]];
}
-(BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError {
[Data setSyncProgressIndicators:YES];
NSDictionary *dict = (NSDictionary *)[NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)data];
[Data didReceiveCloudData:dict];
[Data setSyncProgressIndicators:NO];
return YES;
}
+(BOOL)autosavesInPlace {
return YES;
}
@end
我看到的结果是 queryDidUpdate: 在启动时被调用了 2-3 次,全部来自 NSMetadataQueryDidFinishGatheringNotification。问题是,“resultCount”变量始终为 0,因此无论我多久编辑一次云文档,logAllCloudStorageKeysForMetadataItem 都不会被调用,NSMetadataQueryDidUpdateNotification 根本不会被调用。
任何人都可以就搜索返回 0 个结果的原因提供任何建议,尽管显然有一个文件正在来回同步?或者更好的是,你能完全看出代码有什么问题吗?我能做些什么来让NSMetadataQueryDidUpdateNotification 走上正轨并告诉我什么时候对我的文件进行了编辑?顺便说一句,我正在使用以下方法保存文件:
+(NSURL *)notesURL {
NSURL *url = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
return [url URLByAppendingPathComponent:kAllNotes];
}
其中“kAllNotes”=“笔记”。
提前感谢您的帮助!
编辑:请注意,当我说它同步成功时,它并没有因为 NSMetadataQuery 而做。我在其他地方有一个 cloudDoc = [[CloudDocument alloc]initWithContentsOfURL:[self notesURL] ofType:NSPlainTextDocumentType error:nil]; 行加载 CloudDocument,所以我知道那里有一个文档,我知道它正在被应用程序的 iOS 版本更改,但我现在要掌握的 NSMetadataQuery 是只有在那里才能与NSMetadataQueryDidUpdateNotification 一起工作,而且似乎都不能正常工作。
另外,我绝对是个初学者,所以非常非常感谢您提出建议时的代码 sn-ps 和示例!
【问题讨论】:
标签: cocoa nsnotifications nsmetadataquery