我有一个iOS应用程序,它使用一个简单的UIDocument模型和一个内容字段用于iCloud存储.我检索文档列表以使用NSMetadataQuery填充UITableView.我希望在此表的顶部显示新文档,但默认排序似乎是旧的 - >新的.
我知道如果我在文档中有自定义日期字段,我可以在该字段上使用NSSortDescriptor对查询进行排序,但我的问题是是否可以按照通过UIDocument iCloud存储创建的文件的内在修改日期进行排序?或者还有另一种首选方法吗?
我正在使用UIManagedDocuments来管理iCloud中的文件.设置之后NSMetadataQuery如此:
iCloudQuery = [[NSMetadataQuery alloc] init];
[iCloudQuery setSearchScopes:
[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
[iCloudQuery setPredicate:
[NSPredicate predicateWithFormat:@"%K like %@", NSMetadataItemFSNameKey, @"DocumentMetadata.plist"]];
Run Code Online (Sandbox Code Playgroud)
我遇到了一个奇怪的问题 - 当我的文档没有文件扩展名(例如@"NewDocument2")或公共扩展名时.txt,元数据查询正确地找到了DocumentMetadata.plist文件.但是,当使用我的自定义文件扩展名时,查询永远不会找到任何内容......不是在查询开始时,也不是在我添加新文档时.
在我看来,查询可能是看到我的文档及其自定义文件扩展名,并没有意识到它实际上是一个目录(无论如何都是文件包),因此不会查找内部查找DocumentMetadata.plist文件.但是,我在应用程序中声明了我的自定义UTI info.plist.
也许我已经错误地宣布了我的UTI?我遵循Apple的指导原则(在基于文档的iOS应用程序编程指南和统一类型标识符概述中)创建它,但似乎有些不对劲.
编辑:在"导出的UTI"中info.plist,我的类型设置为符合"com.apple.package".
编辑: 我仍然在努力解决这个问题.我现在正在通过不使用文件扩展名来解决它.
使用自定义文件扩展名时,我正在处理iCloud元数据查询结果,DocumentMetadata.plist文件肯定在文件包中,但元数据查询无法看到它.枚举查询结果时,以下内容将打印到日志中:
<iCloud Container URL>/Documents/
<iCloud Container URL>/Documents/New%20Document.spdoc/
<iCloud Container URL>/Documents/New%20Document.spdoc/DocumentMetadata.plist
<iCloud Container URL>/Documents/New%20Document.spdoc/StoreContent.nosync/
<iCloud Container URL>/Documents/New%20Document.spdoc/StoreContent.nosync/(A%20Document%20Being%20Saved%20By%20<AppName>%202)/
<iCloud Container URL>/Documents/New%20Document.spdoc/StoreContent.nosync/(A%20Document%20Being%20Saved%20By%20<AppName>)/
<iCloud Container URL>/Documents/New%20Document.spdoc/StoreContent.nosync/.persistentStore_SUPPORT/
<iCloud Container URL>/Documents/New%20Document.spdoc/StoreContent.nosync/.persistentStore_SUPPORT/_EXTERNAL_DATA/
<iCloud Container URL>/Documents/New%20Document.spdoc/StoreContent.nosync/persistentStore
Run Code Online (Sandbox Code Playgroud)
("CoreDataLogs"目录中还有一堆文件,但为了简洁起见,我没有在这里显示它们). …
对于我正在编写的iCloud插件,我将iCloud管理器类订阅到这些iCloud NSMetaDataQuery观察器:
// Add a predicate for finding the documents
NSString* filePattern = [NSString stringWithFormat:@"*.%@", @"*"];
self.metadataQuery = [[NSMetadataQuery alloc] init];
// Before starting to query, it is required to set the search scope.
arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
// It is also required to set a search predicate.
[self.metadataQuery setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE %@", NSMetadataItemFSNameKey, filePattern]];
// Listen for the second phase live-updating
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(queryDidReceiveNotification:) name:NSMetadataQueryDidUpdateNotification object:nil];
// Listen for the first phase gathering
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(queryIsDoneGathering:) name:NSMetadataQueryDidFinishGatheringNotification
object:nil];
[self.metadataQuery startQuery]; …Run Code Online (Sandbox Code Playgroud) 我正在为我的应用程序(通过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 …Run Code Online (Sandbox Code Playgroud) 为了监控 iCloud 容器中的文件更改,我注册了
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(processiCloudUpdates:)
name:NSMetadataQueryDidUpdateNotification
object:nil];
Run Code Online (Sandbox Code Playgroud)
理想情况下,每当我收到已进行更新的消息时,我都会打开每个 UIDoc 并检查设置是否已更改。NSMetadataQueryDidUpdateNotification如果只调用一次就可以了。然而,它被触发了几次(我没有忘记等等removeObserver,并且有几个实例正在运行),因此每次触发更新通知时加载所有文件将变得非常不切实际(如果我有 5 个文件并且这被调用了 4 次,我会快速连续打开 20 个 UIDoc)。例如,如果我更新一个文件(并且我的无处不在的容器中只有一个文件),就会发生这种情况:
2012-07-05 10:51:39.565 Meernotes[7842:707] ... NSMetadataQuery update
2012-07-05 10:51:42.468 Meernotes[7842:707] ... NSMetadataQuery update
2012-07-05 10:51:45.216 Meernotes[7842:707] ... NSMetadataQuery update
2012-07-05 10:51:47.036 Meernotes[7842:707] ... NSMetadataQuery update
Run Code Online (Sandbox Code Playgroud)
有没有其他方法可以确定文件何时更改?NSFileVersion 也没有多大帮助。
我有一个iOS应用程序,可以在iCloud中存储文件.当我启动应用程序时,我想确定以前的设备是否已经上传了任何文件.我启动了第一台设备并将文件添加到iCloud(我可以在Mac上的Mobile Documents文件夹中看到它们).然后我在第二个设备上启动应用程序并尝试使用以下NSMetadataQuery来查看是否已上载任何文件,但它返回0结果.如果我继续运行该查询,大约8-10秒后它会返回结果.
iCloudQuery = [[NSMetadataQuery alloc] init];
iCloudQuery.searchScopes = @[NSMetadataQueryUbiquitousDataScope];
NSString *filePattern = [NSString stringWithFormat:@"*.%@", @"txt"];
iCloudQuery.predicate = [NSPredicate predicateWithFormat:@"%K LIKE %@", NSMetadataItemFSNameKey, filePattern];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(iCloudQueryDidFinishGathering:) name:NSMetadataQueryDidFinishGatheringNotification object:iCloudQuery];
[iCloudQuery startQuery];
Run Code Online (Sandbox Code Playgroud)
当我收到通知时,resultCount为0表示查询
- (void)iCloudQueryDidFinishGathering:(NSNotification *)notification
{
NSMetadataQuery *query = [notification object];
[query disableUpdates];
[query stopQuery];
NSLog(@"Found %d results from metadata query", query.resultCount);
}
Run Code Online (Sandbox Code Playgroud)
如果文件存在于iCloud中,NSMetadataQuery是否应该返回resultCount,即使它尚未下载?有没有办法测试一个文件是否存在,而不是尝试超过和15-30秒后超时?
我目前正在构建一个 mac 应用程序,将来应该能够在 OS X 上终止和启动应用程序。
为此,我需要找到一种方法来获取机器上所有已安装应用程序的列表。
我已经做了很多研究,并决定使用 Spotlight 和 NSMetadataQuery 来获取列表。
我找到了有关上述主题的这篇文章,并开始在 Swift 2.2(该项目的首选武器)中实现该功能。通过一些翻译,我能够让它工作,代码现在成功构建和运行。但是,在运行时,我似乎遇到了查询本身的问题:
<NSMetadataQuery: 0x6080000e3880> is being deallocated without first calling -stopQuery. To avoid race conditions, you should first invoke -stopQuery on the run loop on which -startQuery was called
Run Code Online (Sandbox Code Playgroud)
这是我目前使用的代码。
public func doSpotlightQuery() {
query = NSMetadataQuery()
let predicate = NSPredicate(format: "kMDItemKind ==[c] %@", "Application")
let defaultNotificationCenter = NSNotificationCenter()
defaultNotificationCenter.addObserver(self, selector: #selector(queryDidFinish(_:)), name: NSMetadataQueryDidFinishGatheringNotification, object: nil)
query.predicate = predicate
query.startQuery()
}
public func queryDidFinish(notification: NSNotification) …Run Code Online (Sandbox Code Playgroud) 我知道在iOS上,您只能使用NSMetadataQueryiCloud文件。但是,根据Apple的指南,仍然可以NSMetadataItem通过使用以下命令手动搜索所需的文件来获得FileWrapper:
iOS允许在iCloud中搜索元数据以查找与文件相对应的文件。它仅提供用于文件元数据查询
NSMetadataQuery和的Objective-C界面,并且NSMetadataItem仅支持搜索iCloud的搜索范围。与台式机不同,无法使用元数据类搜索iOS应用程序的沙箱。为了搜索应用程序的沙箱,您将需要使用
NSFileManager该类以递归方式遍历沙箱文件系统中的文件。找到匹配的文件后,您可以按照所需的方式访问该文件。您还可以使用NSMedatataItem该类来检索该特定文件的元数据。
但是,我找不到NSMetadataItem从iOS沙箱上的本地文件获取的方法。您可以NSMetadataItem从文件URL 初始化,但这仅在macOS上可用。FileManager似乎也没有NSMetadataItem要从中检索的API 。
如何NSMetadataItem在iOS应用沙箱上获取本地文件?
我正在构建一个具有打开新截图的功能的应用程序.我想使用Mac App Store分发它.不幸的是,它需要沙盒.
为了找到新的屏幕截图,我运行了一个NSMetaDataQuery.它会返回一些条目,但遗憾的是我无法获取他们的URL,因为它们位于桌面上(在我的应用程序的沙箱中).
我怎样才能解决这个问题 ?
这是一些代码
query = [[NSMetadataQuery alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryUpdated:) name:NSMetadataQueryDidStartGatheringNotification object:query];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryUpdated:) name:NSMetadataQueryDidUpdateNotification object:query];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryUpdated:) name:NSMetadataQueryDidFinishGatheringNotification object:query];
[query setDelegate:self];
[query setPredicate:[NSPredicate predicateWithFormat:@"kMDItemIsScreenCapture = 1"]];
[query startQuery];
Run Code Online (Sandbox Code Playgroud)
numberOfScreenshots = [query resultCount];
[self uploadToAmazonS3:[[[query results]objectAtIndex:([query resultCount]-1)]valueForAttribute:NSMetadataItemURLKey]];
Run Code Online (Sandbox Code Playgroud)
谢谢
有没有办法以编程方式访问 MacOS 上单个文件的元数据?
我知道苹果提供了NSMetadataQuery,但它似乎只允许在特定文件夹中搜索与某些参数匹配的文件。实际上我不想搜索所有匹配的文件,而是检查特定文件是否匹配。
有没有办法或唯一的解决方案是分析查询结果并查看我的文件是否在其中?
By default NSMetaDataQuery results notifications are received on the main thread. It seems you have to call query.startQuery on the main thread, but you can use [query.setOperationQueue:] to set the queue to which results notifications will be sent.
Ideally I want a background thread to be receiving these results and processing them and depending on what files are found, I will set variables or post notifications to the main thread.
What I don't understand is how I create the operational …
我正在尝试创建NSMetadataQuery一个谓词。在某个时候,我可能希望收集iCloud可能在另一点上所有图像的所有视频。我什么也不想,只要搜索视频或搜索图像。不能同时使用。
我创建了以下代码:
CFStringRef whatToFilter = kUTTypeImage;
if (self.filterType == kKindVideo) {
whatToFilter = kUTTypeVideo;
}
NSPredicate *predType = [NSPredicate predicateWithFormat:@"(%K == %@)", NSMetadataItemContentTypeKey, whatToFilter];
NSMetadataQuery *newQuery = [[NSMetadataQuery alloc] init];
[newQuery setSearchScopes:@[NSMetadataQueryUbiquitousDocumentsScope]];
newQuery.predicate = predType;
Run Code Online (Sandbox Code Playgroud)
一旦添加此谓词,newQuery结果将为零。
此查询的正确语法是什么?不要告诉我谓词也不适用于NSMetadataQuery,因为sort也不起作用。
nsmetadataquery ×12
icloud ×6
ios ×6
macos ×3
nspredicate ×3
objective-c ×3
metadata ×2
sandbox ×2
cocoa ×1
foundation ×1
icloud-drive ×1
ios5 ×1
iphone ×1
spotlight ×1
swift ×1
uidocument ×1