XCResource is a tool that allows you to efficiently and safely manage resources (localized strings, fonts, and other files) in Xcode projects. By automating code generation, it reduces typos and runtime errors.
- Generates type-safe Swift code for localized strings, fonts, and other files.
- Supports Swift Package Manager for easy integration.
- Enables customized code generation using configuration files.
- Easily executable via Swift Package Plugin.
dependencies: [
.package(url: "https://github.com/nearfri/XCResource.git", from: "<version>"),
// OR
.package(url: "https://github.com/nearfri/XCResource-plugin.git", from: "<version>"),
],Recommendation: Use XCResource-plugin to take advantage of the precompiled binary executable.
Add an xcresource.json file to your project. The plugin reads this file and generates Swift code every time it runs.
Supported paths for the configuration file:
${PROJECT_DIR}/xcresource.json${PROJECT_DIR}/.xcresource.json${PROJECT_DIR}/Configs/xcresource.json${PROJECT_DIR}/Scripts/xcresource.json
xcresource provides multiple subcommands. Among them, xcstrings2swift parses a String Catalog (.xcstrings) and generates LocalizedStringResource constants.
xcstrings2swift.mp4
{
"commands": [
{
"commandName": "xcstrings2swift",
"catalogPath": "Sources/Resources/Resources/Localizable.xcstrings",
"bundle": ".atURL(Bundle.module.bundleURL)",
"swiftFilePath": "Sources/Resources/ResourceAccess/LocalizedStringResource+.swift"
}
]
}public extension LocalizedStringResource {
/// \"\\(arg1)\" will be deleted.\
/// This action cannot be undone.
static func alertDeleteFile(_ arg1: String) -> Self {
.init("alert_delete_file",
defaultValue: """
\"\(arg1)\" 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))
}
}(Function names and parameter names can be customized if they match the localization key and function signature.)
Text(.commonDone)fonts2swift generates Swift code for fonts.
fonts2swift.mp4
{
"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)files2swift generates Swift code for files such as 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)| Command | Description |
|---|---|
xcstrings2swift |
Scans .xcstrings file and generates code. |
fonts2swift |
Scans font directory and generates code. |
files2swift |
Scans directory for matching files and generates code. |
xcassets2swift |
Scans .xcassets directory and generates code. |
This repository includes an example of using the plugin.
graph TD
subgraph Plugin
P["Generate Resource Code<br/><i>plugin</i>"]
end
subgraph Executable
CLI["xcresource<br/><i>executableTarget</i>"]
end
subgraph Command
CMD["XCResourceCommand<br/><i>target</i>"]
end
subgraph "Core Modules"
LOC["LocStringResourceGen"]
FONT["FontResourceGen"]
FILE["FileResourceGen"]
ASSET["AssetResourceGen"]
UTIL["XCResourceUtil"]
end
subgraph "External Dependencies"
AP["ArgumentParser<br/><i>swift-argument-parser</i>"]
SS["SwiftSyntax<br/>SwiftParser<br/>SwiftSyntaxBuilder<br/>SwiftRefactor<br/><i>swift-syntax</i>"]
ST["StrixParsers<br/><i>Strix</i>"]
end
P --> CLI
CLI --> CMD
CMD --> AP
CMD --> LOC
CMD --> FONT
CMD --> FILE
CMD --> ASSET
CMD --> UTIL
LOC --> SS
LOC --> ST
LOC --> UTIL
FONT --> UTIL
FILE --> UTIL
ASSET --> UTIL
style P fill:#e8f5e9,stroke:#4caf50,color:#000000
style CLI fill:#fff3e0,stroke:#ff9800,color:#000000
style CMD fill:#e3f2fd,stroke:#2196f3,color:#000000
style LOC fill:#fce4ec,stroke:#e91e63,color:#000000
style FONT fill:#f3e5f5,stroke:#9c27b0,color:#000000
style FILE fill:#f3e5f5,stroke:#9c27b0,color:#000000
style ASSET fill:#f3e5f5,stroke:#9c27b0,color:#000000
style UTIL fill:#fffde7,stroke:#fbc02d,color:#000000
style AP fill:#eceff1,stroke:#607d8b,color:#000000
style SS fill:#eceff1,stroke:#607d8b,color:#000000
style ST fill:#eceff1,stroke:#607d8b,color:#000000
For more information about the plugin, check the documentation on Swift Package Index.
- XCResource Documentation
- Getting Started
- Advanced
XCResource is distributed under the MIT license. For more details, see the LICENSE file.