XCResource
A plugin to generate Swift code for String Catalog (xcstrings), fonts, and other resources.
Install / Use
/learn @nearfri/XCResourceREADME
XCResource
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.
Features
1. Type-Safe Resource Code Generation
- Generates type-safe Swift code for localized strings, fonts, and other files.
2. Flexible Configuration and Integration
- Supports Swift Package Manager for easy integration.
- Enables customized code generation using configuration files.
- Easily executable via Swift Package Plugin.
Getting Started
1. Adding XCResource to Your Project
Add to 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>"),
],
Recommendation: Use XCResource-plugin to take advantage of the precompiled binary executable.
Create a Configuration File (xcresource.json)
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
2. Managing Localized Strings
xcresource provides multiple subcommands. Among them, xcstrings2swift parses a String Catalog (.xcstrings) and generates LocalizedStringResource constants.
https://github.com/user-attachments/assets/16073e8f-9ad9-4e9c-b945-d542efd656f7
Configuration (xcresource.json)
{
"commands": [
{
"commandName": "xcstrings2swift",
"catalogPath": "Sources/Resources/Resources/Localizable.xcstrings",
"bundle": ".atURL(Bundle.module.bundleURL)",
"swiftFilePath": "Sources/Resources/ResourceAccess/LocalizedStringResource+.swift"
}
]
}
Generated Code
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.)
Usage
Text(.commonDone)
3. Font Code Generation
fonts2swift generates Swift code for fonts.
https://github.com/user-attachments/assets/ae09a571-3ee8-450e-84c2-39341fe203d2
Configuration (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"
}
]
}
Generated Code
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)
}
Usage
Font.custom(.openSansBold, size: 16)
4. File Code Generation
files2swift generates Swift code for files such as JSON.
Configuration (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"
}
]
}
Generated Code
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)
}
Usage
LottieView(.hello)
Commands
| 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. |
Example
This repository includes an example of using the plugin.
Architecture
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
Documentation
For more information about the plugin, check the documentation on Swift Package Index.
- XCResource Documentation
- Getting Started
- Advanced
License
XCResource is distributed under the MIT license. For more details, see the LICENSE file.
