In previous posts, I have defined a “scene” in the context of my project as a module consisting of three files: a coordinator, a view, and a view model.
As I develop my app, I plan on introducing several more scenes. However, it can be cumbersome to create three new files every time I need to add a feature. Then, I have to write boilerplate for all three, every time. It wastes so much time that could be better used for actually developing the features.
This is where a scene generation script becomes particularly handy.
Here’s the concept:
- I’ll create a template scene, complete with all three components, each of which has boilerplate code.
- I’ll create a shell script with a function that takes a scene name as a parameter.
- I’ll configure the script to make a copy of all three template components.
- I’ll configure the script to rename each new file according to the provided scene name.
- I’ll configure the script to place the generated files into a new folder in the Scenes directory of my project.
So in practice, all I have to do is open a terminal, cd into my project’s directory, and execute the following line:
sh generate_scene.sh MyFeatureName
And then I’ll have a MyFeatureNameCoordinator, a MyFeatureNameView, and a MyFeatureNameViewModel.
Let’s jump into that script.
First, I’ll create a new file in the root directory of the project and name it generate_scene.sh
Then I’ll open that file and add the following code:
#!/bin/bash
# Base directory for scenes
BASE_DIR="./BKSwifty/Source/Scenes"
# Check if a scene name was provided
if [ -z "$1" ]; then
echo "Error: No scene name provided."
echo "Usage: $0 <SceneName>"
exit 1
fi
SCENE_NAME="$1"
SCENES_DIR="${BASE_DIR}/${SCENE_NAME}"
TEMPLATES_DIR="${BASE_DIR}/Template"
# Create a directory for the new scene
if ! mkdir -p "$SCENES_DIR"; then
echo "Failed to create directory '$SCENES_DIR'. Check permissions or disk space."
exit 1
fi
# Function to create files from templates
create_file_from_template() {
local template_file=$1
local output_file=$2
if [ ! -f "$template_file" ]; then
echo "Template file $template_file does not exist."
exit 1
fi
sed "s/Template/${SCENE_NAME}/g" "$template_file" > "$output_file"
echo "Created $output_file"
}
# Create Coordinator, View, and ViewModel files from templates
create_file_from_template "$TEMPLATES_DIR/TemplateCoordinator.swift" "$SCENES_DIR/${SCENE_NAME}Coordinator.swift"
create_file_from_template "$TEMPLATES_DIR/TemplateView.swift" "$SCENES_DIR/${SCENE_NAME}View.swift"
create_file_from_template "$TEMPLATES_DIR/TemplateViewModel.swift" "$SCENES_DIR/${SCENE_NAME}ViewModel.swift"
echo "Scene files for '$SCENE_NAME' created in '$SCENES_DIR'."
And that’s it!
There is still the issue of including those files in the Xcode project, but that’s as simple as dragging and dropping them into the appropriate directory.
I’ll write another post soon on how to set up the project for XcodeGen to skip that manual step of dragging and dropping. XcodeGen is a very powerful tool that can be used to automatically regenerate our Xcode project file. But for now, we’re in a good place.
In my next post, I’ll explore setting up and using environment variables for dependency injection with minimal boilerplate.
Full code:
Leave a Reply