XCResource

Swift Swift Version Compatibility Platform Compatibility codecov

XCResource 是一款工具,可帮助你在 Xcode 项目中高效且安全地管理资源(本地化字符串、字体和其他文件)。通过自动化代码生成,它可以减少拼写错误和运行时错误。

功能特性

1. 类型安全的资源代码生成

2. 灵活的配置和集成

入门指南

1. 将 XCResource 添加到你的项目中

添加到 Package.swift

dependencies: [
    .package(url: "https://github.com/nearfri/XCResource.git", from: "<version>"),
    // OR
    .package(url: "https://github.com/nearfri/XCResource-plugin.git", from: "<version>"),
],

推荐:使用 XCResource-plugin 以充分利用预编译的二进制可执行文件。

创建配置文件 (xcresource.json)

在你的项目中添加一个 xcresource.json 文件。插件会读取此文件,并在每次运行时生成 Swift 代码。

配置文件支持的路径

2. 管理本地化字符串

xcresource 提供了多个子命令。其中,xcstrings2swift 解析 String Catalog (.xcstrings) 并生成 LocalizedStringResource 常量。

xcstrings2swift.mp4

配置 (xcresource.json)

{
    "commands": [
        {
            "commandName": "xcstrings2swift",
            "catalogPath": "Sources/Resources/Resources/Localizable.xcstrings",
            "bundle": "atURL:Bundle.module.bundleURL",
            "swiftFilePath": "Sources/Resources/ResourceAccess/LocalizedStringResource+.swift"
        }
    ]
}

生成的代码

public extension LocalizedStringResource {
    /// \"\\(param1)\" will be deleted.\
    /// This action cannot be undone.
    static func alertDeleteFile(_ param1: String) -> Self {
        .init("alert_delete_file",
              defaultValue: """
                \"\(param1)\" will be deleted.
                This action cannot be undone.
                """,
              bundle: .atURL(Bundle.module.bundleURL))
    }
    
    /// Done
    static var commonDone: Self {
        .init("common_done",
              defaultValue: "Done",
              bundle: .atURL(Bundle.module.bundleURL))
    }
}

(如果函数名和参数名与本地化键和函数签名匹配,则可以自定义。)

用法

Text(.commonDone)

3. 字体代码生成

fonts2swift 为字体生成 Swift 代码。

fonts2swift.mp4

配置 (xcresource.json)

{
    "commands": [
        {
            "commandName": "fonts2swift",
            "resourcesPath": "Sources/Resources/Resources",
            "swiftFilePath": "Sources/Resources/ResourceAccess/FontResource.swift",
            "resourceTypeName": "FontResource",
            "resourceListName": "all",
            "transformsToLatin": true,
            "stripsCombiningMarks": true,
            "preservesRelativePath": true,
            "bundle": "Bundle.module",
            "accessLevel": "public"
        }
    ]
}

生成的代码

public struct FontResource: Hashable, Sendable {
    public let fontName: String
    public let familyName: String
    public let style: String
    public let relativePath: String
    public let bundle: Bundle
    ...
}

public extension FontResource {
    static let all: [FontResource] = [
        // Cambria
        .cambriaRegular,
        
        // Open Sans
        .openSansBold,
    ]
}

public extension FontResource {
    // MARK: Cambria
    
    static let cambriaRegular: FontResource = .init(
        fontName: "Cambria",
        familyName: "Cambria",
        style: "Regular",
        relativePath: "Fonts/Cambria.ttc",
        bundle: Bundle.module)
    
    // MARK: Open Sans
    
    static let openSansBold: FontResource = .init(
        fontName: "OpenSans-Bold",
        familyName: "Open Sans",
        style: "Bold",
        relativePath: "Fonts/OpenSans/OpenSans-Bold.ttf",
        bundle: Bundle.module)
}

用法

Font.custom(.openSansBold, size: 16)

4. 文件代码生成

files2swift 为文件(如 JSON)生成 Swift 代码。

配置 (xcresource.json)

{
    "commands": [
        {
            "commandName": "files2swift",
            "resourcesPath": "Sources/Resources/Resources/Lotties",
            "filePattern": "(?i)\\.json$",
            "swiftFilePath": "Sources/Resources/ResourceAccess/LottieResource.swift",
            "resourceTypeName": "LottieResource",
            "preservesRelativePath": true,
            "relativePathPrefix": "Lotties",
            "bundle": "Bundle.module",
            "accessLevel": "public"
        }
    ]
}

生成的代码

public struct LottieResource: Hashable, Sendable {
    public let relativePath: String
    public let bundle: Bundle
    ...
}

extension LottieResource {
    public static let hello: LottieResource = .init(
        relativePath: "Lotties/hello.json",
        bundle: Bundle.module)
}

用法

LottieView(.hello)

命令

命令 描述
xcstrings2swift 扫描 .xcstrings 文件并生成代码。
fonts2swift 扫描字体目录并生成代码。
files2swift 扫描目录以查找匹配的文件并生成代码。
xcassets2swift 扫描 .xcassets 目录并生成代码。

文档

有关插件的更多信息,请查看 Swift Package Index 上的文档。

示例

此仓库包含一个使用该插件的示例

许可

XCResource 在 MIT 许可证下分发。有关更多详细信息,请参阅 LICENSE 文件。