Add bundle parameter to define if resource should be load from Bundle.main (app) or Bundle.module (SPM package) Reviewed-on: #19
23 KiB
ResgenSwift
ResgenSwift is a package, fully written in Swift, to help you automatize ressource update and generation.
🧐 For all commands, see samples files in
SampleFiles
and useresgen-swift help
andresgen-swift help <subcommand>
for detailed help.
Fonts
Font generator generates an extension of UIFont
and Font
(or custom classes). It also prints content of UIAppFonts
from your project .plist
. If project .plist
is specified, it will update UIAppFonts
content of all .plist
.
iOS required to use the real name of the font, this name can be different from its filename. To get the real name, it uses fc-scan
. So, be sure that your $PATH
variable contains path of fc-scan
.
USAGE:
swift run -c release ResgenSwift fonts [-f] <input-file> --extension-output-path <extension-output-path> \
[--static-members <static-members>] \
[--visibility <visibility>] \
[--extension-name <extension-name>] \
[--extension-name-ui-kit <extension-name-ui-kit>] \
[--extension-suffix <extension-suffix>] \
[--info-plist-paths <info-plist-paths>]
ARGUMENTS:
<input-file> Input files where fonts ared defined.
OPTIONS:
-f, -F Should force generation
--static-members <static-members>
Tell if it will generate static properties or methods (default: false)
--visibility <visibility>
Visibility of extension and properties. Possibles values: public, private, package, internal. Default is internal (default: internal)
--extension-output-path <extension-output-path>
Path where to generate the extension.
--extension-name <extension-name>
Extension name. If not specified, it will generate an Font extension. (default: Font)
--extension-name-ui-kit <extension-name-ui-kit>
Extension name. If not specified, no extension will be generated.
--extension-suffix <extension-suffix>
Extension suffix. Ex: MyApp, it will generate {extensionName}+FontsMyApp.swift
--info-plist-paths <info-plist-paths>
Info.plist paths (array). Will be used to update UIAppFonts content
--version Show the version.
-h, --help Show help information.
Example
swift run -c release ResgenSwift fonts -f "./Fonts/fonts.txt" \
--extension-output-path "./Fonts/Generated" \
--static-members true \
--visibility "public" \
--extension-name "AppFont" \
--extension-name-ui-kit "UIAppFont" \
--extension-suffix "GreatApp" \
--info-plist-paths "./path/one/to/Info.plist ./path/two/to/Info.plist"
Colors
Colors generator generates colorsets in specified xcassets and an extension of Color
(or a custom class) associated to those colorsets. If the extension name is not specified, no extension will be generated.
USAGE:
swift run -c release ResgenSwift colors [-f] <input-file> \
--style <style> \
--xcassets-path <xcassets-path> \
[--static-members <static-members>] \
[--visibility <visibility>] \
[--asset-bundle <asset-bundle>] \
[--extension-output-path <extension-output-path>] \
[--extension-name <extension-name>] \
[--extension-name-ui-kit <extension-name-ui-kit>] \
[--extension-suffix <extension-suffix>]
ARGUMENTS:
<input-file> Input files where colors ared defined.
OPTIONS:
-f, -F Should force generation
--style <style> Color style to generate: light for light colors only, or all for dark and light colors (values: light, all)
--xcassets-path <xcassets-path>
Path of xcassets where to generate colors
--static-members <static-members>
Tell if it will generate static properties or not (default: false)
--visibility <visibility>
Visibility of extension and properties. Possibles values: public, private, package, internal. Default is internal (default: internal)
--asset-bundle <asset-bundle>
Bundle where the asset are generated (default: main)
--extension-output-path <extension-output-path>
Path where to generate the extension.
--extension-name <extension-name>
SwiftUI extension name. If not specified, no extension will be generated.
--extension-name-ui-kit <extension-name-ui-kit>
UIKit extension name. If not specified, no extension will be generated.
--extension-suffix <extension-suffix>
Extension suffix. Ex: MyApp, it will generate {extensionName}+ColorsMyApp.swift
--version Show the version.
-h, --help Show help information.
Example
swift run -c release ResgenSwift colors -f "./Colors/colors.txt" \
--style all \
--xcassets-path "./Colors/colors.xcassets" \
--static-members true \
--visibility internal \
--asset-bundle "main" \
--extension-output-path "./Colors/Generated/" \
--extension-name "AppColor \
--extension-name-ui-kit "UIAppColor" \
--extension-suffix "GreatApp"
⚠️ Option
extensionOutputPath
will require anextensionName
orextensionNameUIKit
to generate extension files. Passing anextensionName
orextensionNameUIKit
withoutextensionOutputPath
will not generate any extension file.
Strings
Strings command allows to generate strings
files along with extensions to access those strings easily. It can do it 2 ways: Twine and Stringium. It is not recommended to use Twine except on legacy projects or while migrating to ResgenSwift, because it use https://github.com/openium/twine. Using Stringium is recommended because it does not required external dependency and allow more customisation.
Twine (not recommended)
USAGE:
swift run -c release ResgenSwift strings twine [-f] <input-file> \
--output-path <output-path> \
--langs <langs> \
--default-lang <default-lang> \
--extension-output-path <extension-output-path>
ARGUMENTS:
<input-file> Input files where strings ared defined.
OPTIONS:
-f, -F Should force generation
--output-path <output-path>
Path where to strings file.
--langs <langs> Langs to generate.
--default-lang <default-lang>
Default langs.
--extension-output-path <extension-output-path>
Path where to generate the extension.
--version Show the version.
-h, --help Show help information.
Example
swift run -c release ResgenSwift strings twine -f "./Twine/strings.txt" \
--output-path "./Twine/Generated" \
--langs "fr en en-us" \
--default-lang "en" \
--extension-output-path "./Twine/Generated"
Stringium (recommended)
USAGE:
swift run -c release ResgenSwift strings stringium [-f] <input-file> \
--output-path <output-path> \
--langs <langs> \
--default-lang <default-lang> \
[--tags <tags>] \
[--static-members <static-members>] \
[--xc-strings <xc-strings>] \
[--visibility <visibility>] \
[--asset-bundle <asset-bundle>] \
[--extension-output-path <extension-output-path>] \
[--extension-name <extension-name>] \
[--extension-suffix <extension-suffix>]
ARGUMENTS:
<input-file> Input files where strings are defined.
OPTIONS:
-f, -F Should force generation
--output-path <output-path>
Path where to find the .xcStrings file or the lproj folders.
--langs <langs> Langs to generate.
--default-lang <default-lang>
Default langs.
--tags <tags> Tags to generate. (default: ios iosonly iosOnly notranslation)
--static-members <static-members>
Generate static properties. False by default (default: false)
--xc-strings <xc-strings>
Tell if it will generate xcStrings file or lproj file. True by default (default: true)
--visibility <visibility>
Visibility of extension and properties. Possibles values: public, private, package, internal. Default is internal (default: internal)
--asset-bundle <asset-bundle>
Bundle where the asset are generated (default: main)
--extension-output-path <extension-output-path>
Path where to generate the extension.
--extension-name <extension-name>
Extension name. If not specified, no extension will be generated.
--extension-suffix <extension-suffix>
Extension suffix: {extensionName}+{extensionSuffix}.swift
--version Show the version.
-h, --help Show help information.
Example
swift run -c release ResgenSwift strings stringium -f "./Strings/strings.txt" \
--output-path "./Strings/Generated" \
--langs "fr en en-us" \
--default-lang "en \
--tags "ios iosonly iosOnly notranslation" \
--static-members true \
--xc-strings true \
--visibility "package" \
--asset-bundle "module" \
--extension-output-path "./Strings/Generated" \
--extension-name "AppString \
--extension-suffix "GreatApp"
⚠️ Option
extensionOutputPath
will require anextensionName
orextensionNameUIKit
to generate extension files. Passing anextensionName
orextensionNameUIKit
withoutextensionOutputPath
will not generate any extension file.
Tags
Tags is also a subcommand of Strings
. Input files are formatted the same way. Tags will generate properties which return exactly what is specified in the input file. It was designed to be used for analytics purpose and to be shared with any other platform to have the same analytics keys.
USAGE:
swift run -c release ResgenSwift strings tags [-f] <input-file> \
--extension-output-path <extension-output-path> \
[--lang <lang>] \
[--visibility <visibility>] \
[--static-members <static-members>] \
[--extension-name <extension-name>] \
[--extension-suffix <extension-suffix>]
ARGUMENTS:
<input-file> Input files where tags ared defined.
OPTIONS:
-f, -F Should force generation
--lang <lang> Lang to generate. ("ium" by default) (default: ium)
--visibility <visibility>
Visibility of extension and properties. Possibles values: public, private, package, internal. Default is internal (default: internal)
--extension-output-path <extension-output-path>
Path where to generate the extension.
--static-members <static-members>
Tell if it will generate static properties or not (default: false)
--extension-name <extension-name>
Extension name. If not specified, it will generate a Tag extension. (default: Tags)
--extension-suffix <extension-suffix>
Extension suffix. Ex: MyApp, it will generate {extensionName}+Tag{extensionSuffix}.swift
--version Show the version.
-h, --help Show help information.
Example
swift run -c release ResgenSwift strings tags -f "./Tags/tags.txt" \
--extension-output-path "./Tags/Generated" \
--lang "ium" \
--visibility "public" \
--static-members true \
--extension-name "AppTags" \
--extension-suffix "GreatApp"
⚠️ If extension name is not set or is
Tags
, it will generate the following typealiastypealias Tags = String
.
Analytics
Analytics will generate all you need to analyze UX with Matomo or Firebase Analytics. Input files are formatted in YAML. This command will generate a manager for each target and an AnalyticsManager. This is this one you will need to use. And it will generate a method for all tags you have declared in the YAML file. Next, you will need to use the configure()
method of AnalyticsManager and if you want to use matomo to set up the siteId
and the url
of the site.
USAGE:
swift run -c release ResgenSwift analytics [-f] <input-file> \
--target <target> \
--output-file <output-file> \
[--static-members <static-members>] \
[--visibility <visibility>]
ARGUMENTS:
<input-file> Input files where tags ared defined.
OPTIONS:
-f, -F Should force generation
--target <target> Target(s) analytics to generate. ("matomo" | "firebase")
--output-file <output-file>
Where to generate the analytics manager (path with filename)
--static-members <static-members>
Tell if it will generate static properties or not (default: false)
--visibility <visibility>
Visibility of extension and properties. Possibles values: public, private, package, internal. Default is internal (default: internal)
--version Show the version.
-h, --help Show help information.
Example
swift run -c release ResgenSwift analytics -f "./Tags/analytics.yml" \
--target "matomo firebase" \
--output-file "./Analytics/Generated/AppAnalytics+GreatApp.swift" \
--static-members false \
--visibility "public"
YAML
- id: s1_def_one
name: s1 def one _TITLE_
path: s1_def_one/_TITLE_
action: Tap
category: User
tags: ios,droid
comments:
parameters:
- name: title
type: String
replaceIn: name,path
id
: name of the method (method name will be composed oflog
+Event|Screen
+id
)name
: name of the tagpath
(optional with firebase) : needed for matomo but not with firebase (log screen)action
(optional with firebase) : needed for matomo but not with firebase (log event)category
(optional with firebase) : needed for matomo but not with firebase (log event)tags
: which platform targetcomments
(optional)parameters
(optional)
Parameters
You can use parameters in generate methods.
name
: name of the parametertype
: type of the parameter (Int, String, Bool, Double)value
: value of the parameterdefaultValue
: defaultValue of the parameterreplaceIn
(optional)
Value
If you want to send another parameter with a static value. For example, you want to send to which screen the event is triggered. You can add the parameter 'screenName' for example and its 'value' is 'Home'. With this, you do not need to specify the value in the function call.
DefaultValue
If you want ta add a parameter in the call of the function but you want to make it optionnal with a default value you need to use this property.
Example:
events:
id: id_of_tag
name: _TITLE_
tags: ios,droid
parameters:
- name: title
type: String
defaultValue: someTitle
The generated method will be:
logIdOfTag(title: String = "someTitle")
Replace in
This is section is equivalent of %s | %d | %f | %@
. You can put the content of the parameter in name, path, action, category.
You need to put _
+ NAME OF THE PARAMETER
+ _
in the target and which target you want in the value of replaceIn
. (name need to be in uppercase).
You can't use value
and replaceIn
in thge same time.
Example:
events:
id: id_of_tag
name: _TITLE_
tags: ios,droid
parameters:
- name: title
type: String
replaceIn: name
In this sample, we want to add the parameter title
in the field name
. So, we need to place _TITLE_
in the field name
.
The generated method will be:
logIdOfTag(title: String)
You can also want to replace a parameter in an other parameter. You can do this with the replaceIn
property. The condition is that the parameter which will use the replaceIn
need to have the value
property
Example:
events:
id: id_of_tag
name: title
tags: ios,droid
parameters:
- name: something
type: String
value: test _TEXT_
- name: text
type: String
replaceIn: something
Images
Images generator will generate images assets along with extensions to access those images easily. If the extension name is not specified, no extension will be generated.
USAGE:
resgen-swift images [-f] [-F] <input-file> \
--xcassets-path <xcassets-path> \
[--static-members <static-members>] \
[--visibility <visibility>] \
[--asset-bundle <asset-bundle>] \
[--extension-output-path <extension-output-path>] \
[--extension-name <extension-name>] \
[--extension-name-ui-kit <extension-name-ui-kit>] \
[--extension-suffix <extension-suffix>]
ARGUMENTS:
<input-file> Input files where strings ared defined.
OPTIONS:
-f Should force script execution
-F Regenerate all images
--xcassets-path <xcassets-path>
Xcassets path where to generate images.
--static-members <static-members>
Tell if it will generate static properties or not (default: false)
--visibility <visibility>
Visibility of extension and properties. Possibles values: public, private, package, internal. Default is internal (default: internal)
--asset-bundle <asset-bundle>
Bundle where the asset are generated (default: main)
--extension-output-path <extension-output-path>
Path where to generate the extension.
--extension-name <extension-name>
SwiftUI extension name. If not specified, no extension will be generated.
--extension-name-ui-kit <extension-name-ui-kit>
UIKit extension name. If not specified, no extension will be generated.
--extension-suffix <extension-suffix>
Extension suffix. Ex: MyApp, it will generate {extensionName}+Image{extensionSuffix}.swift
--version Show the version.
-h, --help Show help information.
Example
swift run -c release ResgenSwift images -F "./Images/images.txt" \
--xcassets-path "./Images/app.xcassets" \
--static-members false \
--visibility "public" \
--asset-bundle "module" \
--extension-output-path "./Images/Generated" \
--extension-name "AppImage" \
--extension-name-ui-kit "UIAppImage" \
--extension-suffix "GreatApp"
⚠️ Option
extensionOutputPath
will require anextensionName
orextensionNameUIKit
to generate extension files. Passing anextensionName
orextensionNameUIKit
withoutextensionOutputPath
will not generate any extension file.
⚠️ Svg images will be copied in the assets and rendered as "Original", however if those images are not rendered correctly you can force the png generation by adding the key word "png" like this: id arrow_back 15 ? png
All at once
Another command exists to generate all ressources at the same time: generate
. It use the following commands: Fonts
, Colors
, Strings/Stringium
, Strings/Tags
, Images
.
All parameters can be specified in a configuration file in Yaml
:
Order of configuration types does not matter. Order them to fit your needs.
---
colors:
-
inputFile: String
style: String
xcassetsPath: String
extensionOutputPath: String
extensionName: String?
extensionNameUIKit: String?
extensionSuffix: String?
staticMembers: Bool?
visiblity: String?
assetBundle: String?
fonts:
-
inputFile: String
extensionOutputPath: String
extensionName: String?
extensionNameUIKit: String?
extensionSuffix: String?
staticMembers: Bool?
visiblity: String?
infoPlistPaths: [String]
images:
-
inputFile: String
xcassetsPath: String
extensionOutputPath: String
extensionName: String?
extensionNameUIKit: String?
extensionSuffix: String?
staticMembers: Bool?
visiblity: String?
assetBundle: String?
strings:
-
inputFile: String
outputPath: String
langs: String
defaultLang: String
extensionOutputPath: String
extensionName: String?
extensionSuffix: String?
staticMembers: Bool?
visiblity: String?
assetBundle: String?
xcStrings: Bool?
tags:
-
inputFile: String
lang: String
extensionOutputPath: String
extensionName: String?
extensionSuffix: String?
staticMembers: Bool?
visiblity: String?
analytics:
-
inputFile: String
target: String
outputFile: String
visibility: String?
staticMembers: Bool?
Multiple configurations
In some case, you may need to have 2 colors files in your projects. You will need 2 colors configurations. Every configuration type is an array and can contains as many configurations as you need.
Sample for 2 colors configurations:
...
colors:
-
inputFile: String
style: String
xcassetsPath: String
extensionOutputPath: String
extensionName: String?
extensionNameUIKit: String?
extensionSuffix: String?
staticMembers: Bool?
visiblity: String?
assetBundle: String?
-
inputFile: String
style: String
xcassetsPath: String
extensionOutputPath: String
extensionName: String?
extensionNameUIKit: String?
extensionSuffix: String?
staticMembers: Bool?
visiblity: String?
assetBundle: String?
...
No configuration
In some case, you may not need to generate tags for example. You must specified tags
as an empty array :
...
tags: []
...
File architecture
ResgenSwift generate extension of classes. Those classes must exists in your project. You can create them yourself OR you can let ResgenSwift create them by specifying what you want. Do as follow:
architecture:
property: R *(required but not used)*
classname: R
path: ./path/to/generate
children:
- property: images
classname: R2Image
- property: strings
classname: R2String
- property: fonts
classname: R2Font
- property: images
classname: R2Image
- property: uikit
classname: R2UI
children:
- property: images
classname: R2UIImage
- property: fonts
classname: R2UIFont
- property: images
classname: R2UIImage
This will generate a file named as the architecture classname: R.swift
. Based on the previous architecture, it will generate:
class R: Sendable {
static let images = R2Image()
static let strings = R2String()
static let fonts = R2Font()
static let images = R2Image()
static let uikit = R2UI()
}
class R2Image: Sendable {}
class R2String: Sendable {}
class R2Font: Sendable {}
class R2Image: Sendable {}
class R2UI: Sendable {
let images = R2UIImage()
let fonts = R2UIFont()
let images = R2UIImage()
}
class R2UIImage: Sendable {}
class R2UIFont: Sendable {}
class R2UIImage: Sendable {}
Usage
swift run -c release ResgenSwift generate path/to/configuration.yml --project-directory ${PROJECT_DIR}
⚠️ Every path in
configuration.yml
will be prepended by content of--project-directory
if they are relative path (not starting with/
)
Binary usage
Installation
Run make install
. Binary will be install in /usr/local/bin
.
Usage:
resgen-swift generate path/to/configuration.yml --project-directory ${PROJECT_DIR}
Man page
Commands parameters and details can be find by running resgen-swift --help
. If you prefer, a man page is also available. Run man resgen-swift
. Man page is installed on make install
but you can install manually by running make create-and-install-man-file
.
Uninstallation
To uninstall ResgenSwift: make uninstall
.