我认为这个问题与 iMessage "app" 的含义更相关——它实际上是一个扩展,而不是一个真正的应用程序。没有初始 VC,因此没有真正的Bundle.main 可以访问。
我的一个(可能很快第二个)应用程序有一个照片编辑扩展程序 - 基本上就是我一直所说的与 Apple 应用程序的“外壳连接”。你要么真的有一个“什么都不做”的应用程序连接到他们的一个应用程序,要么你有一个独立的应用程序共享代码与扩展。
我共享代码的解决方案是使用框架目标。是的,第三个项目。 (应用程序、扩展程序、共享代码。)我发现了一种我认为应该适合您的技术 - 基本上,对于图像、脚本(我的应用程序使用 .cikernel 文件),您将它们添加到框架项目中,然后在函数调用中返回您需要的内容。
您可以根据需要框架目标来简化此操作。 YMMV。基本情况是这样的:
- 在 Xcode 中的某个地方有一个“Bundle Identifier”。类似于 *"com.company.projectname"。
- 将您的文件放入一个文件夹中,也许在您的桌面上。向此文件夹添加一个名为 ".bundle" 的扩展名。 macOS 会给你一个警告,接受它。您真正要做的就是创建捆绑包。
- 将其拖到您的 Xcode 项目中。
- 获取此捆绑包的代码以及其中的文件。 (我不确定这里是否需要一个框架 - 尝试先将它拖到您的“MessagesExtension”目标中。
假设您有希望在项目、扩展程序等之间共享的图像。将它们移动到一个名为“images”的文件夹中,并在最后用“.bundle”重命名该文件夹,最后将其拖到您的 Xcode 项目中,您几乎需要添加此功能:
public func returnImage(_ named:String) -> UIImage {
let myBundle = Bundle.init(identifier: "com.company.project")
let imagePath = (myBundle?.path(forResource: "images", ofType: "bundle"))! + "/" + named
let theImage = UIImage(contentsOfFile: imagePath)
return theImage!
}
对于你想要的文本文件:
public func returnKernel(_ named:String) -> String {
let myBundle = Bundle.init(identifier: "com.company.project")
let kernelPath = (myBundle?.path(forResource: "cikernels", ofType: "bundle"))! + "/" + named + ".cikernel"
do {
return try String(contentsOfFile: kernelPath)
}
catch let error as NSError {
return error.description
}
}
用法,用于名为“Camera.png”的图像,该图像是名为“images.bundle”的捆绑包的一部分:
let cameraImage = returnImage("Camera")
由于我不使用 SQLite 文件,我没有确切的代码,但我认为这应该可以。请记住将“com.company.project”更改为您拥有的捆绑标识符。