我需要为我用Swift编写的应用程序编写一个Spotlight导入程序,我指的是苹果官方的Writing a Spotlight Importer指南。
这看起来很简单,但是创建一个Spotlight导入器项目会创建一个Objective-C实现的默认设置。(我过去用过很多次)但是我为我的应用程序编写的所有内容都是Swift,所以我真的很想也用Swift编写导入程序,以避免在语言之间切换,这样我就可以分享一些我已经完成的阅读文件的代码。
首先,是否可以使用Swift而不是Objective-C来编写Spotlight导入器?如果可以,我应该从哪里开始(例如,如果我从Objective-C开始,我应该怎么做才能切换到Swift)?
3条答案
按热度按时间i86rm4rw1#
我花了点时间才让它起作用。
我没有将Swift代码添加到mdimporter,而是导入了一个已经为我的应用设置好的嵌入式框架。
除了main.c和GetMetadataForFile.m之外,我删除了所有示例代码。在后一个示例中,我导入了我的框架,其中所有功能现在都作为Swift代码驻留。
生成的mdimporter将添加到应用程序。在文件检查器中,将位置设置为相对于生成产品。
然后,应用程序添加mdimporter,并执行复制文件构建阶段。
以下内容需要添加到运行搜索路径构建设置中,因为我们要链接到应用的嵌入式框架。
如果您在构建应用时遇到无法找到框架模块的编译器错误(具体取决于工作区的设置方式),您可能需要修改应用的Scheme。
1.在此序列中添加Build目标:
1.框架项目
1.应用程序项目
将所有逻辑放在一个框架中的额外好处是,它可以在Playground中原型化和验证,比调试mdimporter插件容易一百万倍。
xwbd5t1u2#
是的,可以完全 * 在Swift中编写Spotlight导入程序!
我刚刚在这里发表了一篇文章:https://github.com/foxglove/MCAPSpotlightImporter
下面是一篇关于实施过程的详细博客文章:https://foxglove.dev/blog/implementing-a-macos-search-plugin-for-robotics-data
困难的部分是实现一个与CFPlugIn架构兼容的插件。(MDImporter特定的逻辑相对最少。)CFPlugIn API基于Microsoft的COM,而Apple的文档已有近20年的历史。
插件应该是一个符合特定内存布局的内存块--具体来说,块中的第一个值必须是指向所请求接口(对于MDImporter,这是
MDImporterInterfaceStruct
或MDImporterURLInterfaceStruct
)或基本IUnknown接口的虚函数表(vtable)的指针。我想把Swift代码组织成一个类,但是你不能控制Swift类示例的内存布局,所以我创建了一个“wrapper”内存块来保存vtable和一个指向类示例的unsafe指针,这个类有一个
static func allocate()
,它使用UnsafeMutablePointer来分配wrapper块,在其中创建和存储类示例,并且初始化vtable。vtable实现标准的COM基本接口(IUnknown)函数(
QueryInterface
、AddRef
和Release
),方法是从 Package 器中获取类示例,并在示例上调用queryInterface()
、addRef()
和release()
方法。(或ImporterImportData
)。不幸的是,在我的测试中,Spotlight似乎没有将指向 Package 器结构体的正确指针作为ImporterImportURLData
的第一个参数传递,因此不可能调用类示例上的方法,因此,实际导入文件属性的函数必须是全局函数,由于这个原因,我无法使插件实现成为一个可以与任何接口一起使用的更通用的类-它必须与具体的全球进口商职能挂钩。我鼓励您查看完整的on GitHub源代码,但为了不只是提供链接,下面是核心功能:
最后,我创建了一个
@objc
类,它将allocate
函数公开给Obj-C,在Obj-C中,我可以从main.m
调用它,并从工厂函数返回指向 Package 器块的指针,这是必要的,因为我不想使用不稳定的@_cdecl
属性将Swift函数直接公开给插件加载器。x一个一个一个一个x一个一个二个x
有关详细信息,请参见my blog post。
9wbgstp73#
由于苹果引入了Swift作为一种语言,它与任何现有的Objective-C项目完美兼容,我建议你从任何对你来说更容易的东西开始。
如果你最了解Swift,那么没有什么能阻止你使用它--无论你想做什么项目。如果你想学习一个为Objective-C编写的教程,而且还没有为Swift更新,我想你有 * 两个选择 *(我个人建议现在选择第二个选项):
1.现在就用Swift从头开始编写相同的逻辑(几乎所有在Objective-C中可以实现的东西在Swift中也可以实现)。为此,你需要理解Objective-C的基础知识以及Swift中相应的语法和特性。
1.从Objective-C开始学习教程,并在开始时让事情变得更简单(不需要真正理解教程的细节)。然后利用Swift代码与Objective-C代码混合匹配的巨大可能性,根据您的需要定制代码或使用您自己预先存在的类扩展代码。
更具体地说,关于第二个备选方案:
如果你想编写新的类只需要使用Swift --你完全可以在Swift中使用所有用Objective-C编写的东西,反之亦然。如果你觉得你需要修改已经用Objective-C编写的类,你有以下选择:用一个 * 新的Swift类 * 扩展用Objective-C编写的类,*在Swift 中重写该特定文件,或者直接编辑Objective-C文件。
要了解更多**如何将Swift代码与Objective-C混合搭配,我推荐阅读苹果official documentation。这是苹果工程师为开发人员编写的免费iBook“使用Swift与可可和Objective-C”的一部分。
不幸的是,苹果似乎确实提供了一个Spotlight导入器的模板,目前只针对Objective-C。不知道为什么--我看不出有什么能阻止他们支持Swift。我们可能应该用苹果的Bug Reporter报告这个,以强调人们实际上是在要求这个。
希望我没有忽略任何东西,否则我的回答将毫无意义。
UPDATE(request)以下是有关从何处开始实施第一种方法的一些步骤:
我希望这能帮助你入门,而且足够具体。我试着自己做必要的修改,以便在Swift中提供一个示例项目,但不幸的是,我无法在有限的时间内让它工作。你可能需要考虑公开提供你的代码(例如在GitHub上发布一个链接),以防你决定自己移植它,这样其他人也可以从中受益。
祝你好运!