3.3 为 Swift 包打包资源
3 分钟阅读
原文链接: https://docs.swift.org/latest/documentation/packagemanagerdocs/bundlingresources/
2.5 为 Swift 包打包资源
把资源文件加入 Swift 包,并在代码中访问它们。
概述
如果你在 Package.swift 文件中声明了 // swift-tools-version: 5.3 或更高版本,就可以在 Swift 包中把资源与源代码一起打包。例如,Swift 包可以包含资源目录(asset catalog)、测试夹具等。
添加资源文件
包管理器会把目标源代码目录中发现的非源代码文件当作该目标范围内的资源。例如,MyLibrary 目标的资源默认位于 Sources/MyLibrary。为了便于把资源与源文件区分开,建议为资源新建并使用一个子文件夹。例如,把所有资源文件放进名为 Resources 的目录,这样所有资源文件就位于 Sources/MyLibrary/Resources。
显式声明或排除资源
要添加编译器不会自动处理的资源,就在包清单中显式把它声明为资源。如果你用 Xcode 构建包,它会自动处理许多种类的资源。
例如,要把文件 text.txt 作为资源包含进来,先把它放进 Sources/MyLibrary/Resources,然后把这个文件名加入目标的资源列表,显式声明它是包资源:
| |
上面的例子使用 process(_:localization:) 来标明该资源。显式声明资源时,需要选择一条规则来决定 Swift 如何处理该资源文件,可选项包括:
Process 规则:大多数情况下使用 process(_:localization:)。它要求编译器根据你为该包构建的平台,对该类资源施以已知的处理。例如 Xcode 可能针对支持相关优化的平台优化图片文件。如果把 process 规则应用于某个目录路径,Xcode 会递归地把该规则应用于目录中的所有文件。如果没有针对该资源的特殊处理,编译器会把资源原样复制到资源包的顶层目录。
Copy 规则:有些 Swift 包需要资源文件保持原样,或者需要保留特定的目录结构。使用 copy(_:) 函数应用这条规则,把资源原样复制到资源包的顶层。如果传给 copy 规则的是目录路径,编译器会保留该目录的结构。
如果某个文件位于目标的文件夹内,而你不想把它作为包资源,就把它传给目标构造器的 exclude 参数。例如,假设源代码目录中有一个名为 instructions.md 的文件,仅供本地使用、不打算打包进去,就使用 exclude:
| |
一般来说,避免把非资源文件放进目标的源代码文件夹。如果确实做不到,就不要逐个排除文件,而是把所有要排除的文件放进一个目录,再把该目录路径加入排除列表。Swift Package Manager 会对目标的 Sources 目录中它不认识的文件给出警告。
在代码中访问资源
如果目标包含资源,编译器会创建一个资源包,并为每个模块在 Bundle 上创建一个内部的静态扩展来访问它。用这个扩展来定位包资源。例如,下面这段代码可以取得与包一起打包的 property list 文件的 URL:
| |
重要:访问资源时始终使用
Bundle.module。 包不应对资源的确切位置做任何假设。
如果你想让包资源对依赖该 Swift 包的应用可用,就为它声明一个公开常量。例如,下面这段代码把 property list 文件暴露给使用该 Swift 包的应用:
| |