文章目录
- 一、Mac 中 Spotlight 的使用
- 1、调用/打开 Spotlight
- 2、执行搜索
- 3、Spotlight 设置
- 二、Mac 上的 Spotlight 开发
- 1、关于 Spotlight
- 2、使用 NSMetadataQuery 搜索示例
- 三、mds 和 fsevents
- 四、命令行访问 Spotlight
- 五、Core Spotlight Framework
- 六、Spotlight 插件
- 相关资料
一、Mac 中 Spotlight 的使用
可见官方 《macOS 使用手册》:在 Mac 上使用“聚焦”搜索
https://support.apple.com/zh-cn/guide/mac-help/mchlp1008/mac
本文基于 macOS 11.2
1、调用/打开 Spotlight
一般在菜单栏右上角会有 放大镜图标, 点击图标将在屏幕正中出现搜索窗口,如下:
如果菜单右上角没有,也可以在 系统偏好设置 – 程序坞与菜单栏 中,勾选设置显示
2、执行搜索
在输入框中输入内容,就会出现相关搜索结果:
以下是使用 Alfred(v4.0.5) 的搜索结果
3、Spotlight 设置
你可以在 系统偏好设置 – 聚焦 中设置搜索结果
(搜索结果的文件类型) 和 隐私
(不希望搜索结果展示的文件夹)
二、Mac 上的 Spotlight 开发
1、关于 Spotlight
官网对 Spotlight 的介绍如下:
Search for files and other items on the local device, and index your app’s content for searching.
Spotlight 用于搜索本地的文件或其他项目,也可以给你的应用内容添加 index 来搜索。
Spotlight 主要由 Foundation 框架的下面元素实现:
-
Queries
NSMetadataQuery
A query that you perform against Spotlight metadata.NSMetadataQueryDelegate
An interface that enables the delegate of a metadata query to provide substitute results or attributes.
-
Items
NSMetadataItem
The metadata associated with a file.
其他相关API
- HISearchWindow ( Carbon framework.)
- MDQuery (CoreServices 中的 metadata framework )
Spotlight 的历史和兼容性
- Spotlight 是在 macOS Tiger(10.4) 时引入的。
- 在Leopard中,Spotlight已经无缝地整合进了Finder。
- 从iOS 3.0开始,Spotlight被移植到了iOS。在iOS中,用户用手指滑向主屏幕画面左侧就可以打开类似的窗口。
2、使用 NSMetadataQuery 搜索示例
以下代码简单示例搜索 UTI 为 public.jpeg 类型的文件:
@interface AppDelegate ()
@property (nonatomic, strong) NSMetadataQuery *query;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
[self getSoftwaresFromMetaData];
}
- (void)getSoftwaresFromMetaData{
self.query = [[NSMetadataQuery alloc] init];
self.query.searchScopes = [NSArray arrayWithObject:NSMetadataQueryLocalComputerScope];
NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:@"kMDItemContentType == 'public.jpeg'"];
[self.query setPredicate:searchPredicate];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(mdQueryNote:)
name:nil
object:self.query];
// 按照文件显示名正序排列
NSSortDescriptor *sortKeys = [[NSSortDescriptor alloc] initWithKey:(id)kMDItemPath ascending:YES];
[self.query setSortDescriptors:[NSArray arrayWithObject:sortKeys]];
[self.query startQuery];
}
- (void)mdQueryNote:(NSNotification *)note {
NSLog(@"mdQueryNote: %@", [note name]);
if ([[note name] isEqualToString:NSMetadataQueryDidFinishGatheringNotification]) {
[self.query stopQuery];
NSLog(@"resultCount : %ld",self.query.resultCount);
NSUInteger i=0;
for (i=0; i < [self.query resultCount]; i++) {
NSMetadataItem *theResult = [self.query resultAtIndex:i];
NSString *path = [theResult valueForAttribute:NSMetadataItemPathKey];
NSLog(@"path : %@", path);
}
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSMetadataQueryDidFinishGatheringNotification
object:self.query];
self.query=nil;
}
}
部分打印结果如下
mdQueryNote: NSMetadataQueryDidStartGatheringNotification
mdQueryNote: NSMetadataQueryGatheringProgressNotification
mdQueryNote: NSMetadataQueryGatheringProgressNotification
mdQueryNote: NSMetadataQueryGatheringProgressNotification
mdQueryNote: NSMetadataQueryGatheringProgressNotification
mdQueryNote: NSMetadataQueryDidFinishGatheringNotification
resultCount : 82980
path : /usr/share/doc/cups/images/smiley.jpg
path : 。。。/ipptool/color.jpg
path : /System/Library/Desktop Pictures/Reflection 1.jpg
path : /System/Library/Desktop Pictures/Reflection 2.jpg
path : /System/Library/Desktop Pictures/Reflection 3.jpg
...
关于 UTI 可参考文章:https://blog.csdn.net/lovechris00/article/details/113091912?spm=1001.2014.3001.5502
如果想搜索 app 类型文件,将 public.jpeg
替换为 com.apple.application-bundle
即可。
三、mds 和 fsevents
Spotlight 背后的核心力量是一个索引服务器 mds
,mds在 MetaData
框架中,而这个框架是 CoreServices.framework
的一部分。
mds 文件路径:
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Support/mds
- mds是一个没有GUI的后台服务程序。
- 每当有任何文件操作(创建、修改和删除)发生时,内核都会通知这个后台服务程序。这个通知机制称为
fsevents
。 - 当mds收到通知时,mds会通过工作进程
mdworker
将各种元数据信息导入数据库。 - mdworker进程可以加载一个具体的 Spotlight Importer (Spotlight导入器)从文件中提取元数据信息。
- 系统提供的导入器位于
/System/Library/Spotlight
目录;
用户提供的导入器位于/Library/Spotlight
目录。 - 和QuickLook类似,这些导入器都是实现了固定API的插件(在Xcode中选择MetaData Importer项目模板时可以创建出API框架)。
四、命令行访问 Spotlight
在命令行可以通过以下命令访问Spotlight:
- mdutil:管理元数据数据库
- mdfind:发出spotlight查询
- mdimport:配置和测试spotlight插件
- mdls:列出文件的元数据属性
- mdcheckschema:验证元数据的布局(译者注:这个工具在10.8中移除了)
- mddiagnose:Lion引入的新功能,这个工具能对spotlight子系统(mds和mdworker)以及系统上的附加数据进行完整的诊断。
另外一个文档稀少的特性是通过在一些路径创建特定的文件控制Spotlight(即mds)的行为。
例如,在一个目录中创建一个.metadata_never_index
隐藏文件可以防止这个目录被索引(最初是为可移动媒体设计的)。
使用示例
$ mdfind -name "a.png" # 根据文件名查找
$ mdfind "kMDItemContentType = 'public.jpeg'" # 根据 uti 查找
五、Core Spotlight Framework
根据官网对于 Core Spotlight 框架的描述:
Index your app so users can search the content from Spotlight and Safari.
主要是用于 给你的应用中的内容添加索引,来让 Spotlight 和 Safari 更好的调用。
使用可参考:https://blog.csdn.net/mengxiangyue/article/details/46585159
六、Spotlight 插件
- 让 Mac 上的 Spotlight 更强大:Flashlight 拓展插件
https://sspai.com/post/27734 - Spotlight 插件 SpotlightFinder(开源)
https://github.com/jcavar/SpotlightFinder
相关资料
- 《macOS 使用手册》:在 Mac 上使用“聚焦”搜索
https://support.apple.com/zh-cn/guide/mac-help/mchlp1008/mac - Spotlight
https://developer.apple.com/documentation/foundation/spotlight?language=objc - Framework:Core Spotlight
https://developer.apple.com/documentation/corespotlight?language=objc - Human Interface Guidelines:Search and Spotlight
https://developer.apple.com/design/human-interface-guidelines/macos/system-capabilities/search-and-spotlight/
伊织 2021-03-01