SwiftFrame is a command line application for composing and laying out screenshots. Here's an example from the sample app.
The easiest way to get SwiftFrame is via Mint:
$ mint install kayak/SwiftFrame
This is an experimental feature of SPM and might not work as expected. To install SwiftFrame via SPM, follow these steps:
- clone the repository (e.g.
git clone https://github.com/kayak/SwiftFrame
) - change into the directory:
cd SwiftFrame
- run
swift package experimental-install
(make sure your$PATH
includes$HOME/.swiftpm/bin
)
However, if you'd like you can also build SwiftFrame from source. To do this clone the repository and run the install.sh
script. This will compile a binary and install it into usr/local/bin/swiftframe
.
- clone the repository (e.g.
git clone https://github.com/kayak/SwiftFrame
) - change into the directory:
cd SwiftFrame
- run the install script:
sh install.sh
To use SwiftFrame, you need to pass it a configuration file (which is a JSON or YAML file):
swiftframe path/to/your/config/file --verbose
You can use the --help
flag to print SwiftFrame's documentation out. The following flags are available
Prints additional information during processing and rendering. This will also ask you to confirm the processed config file before SwiftFrame starts rendering
Pauses after parsing the config file to let you verify the contents
Outputs the whole image canvas into the output directories before slicing it up into the correct screenshot sizes. Helpful for troubleshooting
Disables any colored output. Useful when running in CI
Disables clearing the output directories before writing images to them
The format of the configuration file is specified as following (indent levels represent nesting levels within the file):
stringsPath
: a path to a folder with.strings
files, prefixed with the corresponding locale (e.g.en.strings
)maxFontSize
: the maximum font point size to use. SwiftFrame will be always try to render the text at the largest point size that fits within the bounding rectangle. If the determined point size is larger thanmaxFontSize
, the latter will be usedoutputPaths
: an array of paths to where SwiftFrame should output the finished screenshots. This is an array in case you want to render the files into multiple directories at the same time. (Note: screenshots will be placed into subfolders organized by locale within these paths)fontFile
: a path to a font fileformat
: the output format of the screenshots, can bepng
,jpeg
orjpg
textColor
: a RGB color in Hex format (e.g.#FFF
) to use for titleslocales
: optional a regular expression that can be used to exclude (or include) certain locales during rendering. To only includefr
andde
locale for example, use"fr|de"
. To excluderu
andfr
, use something like"^(?!ru|fr$)\\w*$"
deviceData
: an array containing device specific data about screenshot and text coordinates (this way you can frame screenshots for more than one device per config file)outputSuffixes
: an array of suffixes to apply to the output files in addition to the locale identifier and index. Multiple suffixes can be used to render the same screenshots for different target devices (for example 2nd and 3rd 12.9 inch iPad Pro)screenshots
: a folder path containing a subfolder for each locale, which in turn contains all the screenshots for that devicenumberOfSlices
: how many slices the output image should be divided into. SwiftFrame will automatically calculate the slice width based on this value, the width of the template file and gap width if anytemplateFile
: an image file that will be rendered above the screenshots to overlay device frames (e.g. seeExample/Template Files/iPhone X/TemplateFile.png
) Note: places where screenshots should go need to be transparentgapWidth
: optional (default: 0) a gap width in pixels that will be skipped after every screenshot that is sliced from the template filescreenshotData
: an array containing further information about screenshot coordinatesscreenshotName
: the file name (just name, not path) to the screenshot file to renderzIndex
: optional, use this to avoid wrong rendering order if two screenshots need to overlap each other for examplebottomLeft
,bottomRight
,topLeft
andtopRight
: the corners of the screenshot to render. Note that screenshots can be rotated in 3D, so the corners of the resulting don't have to form 90 degree anglesx
: The x coordinate of the corner point, relative to the left edgey
: the y coordinate of the corner point, relative to the top or bottom edge
textData
: an array containing further information about text titles coordinates and its layoutidentifier
: the key that SwiftFrame should look for in the.strings
file for a certain titlecolorOverride
: optional, a color in Hex format to use specifically for this titlealignment
: information about text alignmenthorizontal
: the horizontal text alignment in CSS style (left
,right
,center
,justify
ornatural
)vertical
: the vertical text alignment in (top
,center
,bottom
)
customFontPath
: optional, a path to a font file to use specifically for this titlegroupIdentifier
: optional, an identifier for a text group (see below)topLeft
andbottomRight
: the bounding coordinate points of the text (as of right now, it's not possible to have rotated text)x
: The x coordinate of the corner point, relative to the left edgey
: the y coordinate of the corner point, relative to the top or bottom edge
textGroups
: optional, an array of text groups which you can use to force multiple titles to use the same font sizeidentifier
: the identifier of the text groupmaxFontSize
: the maximum font point size titles with this group ID should be using (overrides the globalmaxFontSize
)
To run the example, either install the CLI (see above) and run swiftframe Example/example.config --verbose
or directly via swift run swiftframe Example/example.config --verbose
SwiftFrame also provides a subcommand to quickly setup the folder structure needed to get started with SwiftFrame. To scaffold, use the following command:
swiftframe scaffold "en" "de" --path path/of/your/desired/swiftframe/scaffold
After the subcommand scaffold
you specify all the locales that you want to create folders/files for. After that you need to specify the path where you want the scaffold to be created.
This flag will create directories with lowercased names
With this flag SwiftFrame will not create sample files for each locale/device. Otherwise a sample .strings
file and some README.md
files will be written in the folders to help you get started
Will print some additional information, for example how many folders and files were created
We offer rudimentary markup support for your strings with HTML tags such as <b>
, <i>
or <u>
. In order to use this, please make sure the font file you pass in uses the .ttc format, is installed on your computer and has all the versions you need.
Fastlane's frameit is an awesome tool but we have, unfortunately, found it to be too limitting for our own needs. At the time of writing this, the following reasons drove us towards implementing a stand-alone solution:
- No 3D placement of screenshots or support for multiple titles/screenshot in one framed image
- Long titles could not properly be forced onto more than one line in frameit. The font size just shrinks until the text fits onto a single line which usually produces small text and different font sizes for every screenshot.
- Due to the multitude of brands and locales that we support, we had to offload frameit to our build server since running it locally and on demand turned out to be too slow.
- The fact that frameit was built on top of imagemagick seemingly made it hard to easily address any of the above with a pull request.