Terminal Setup & Scripts
Introduction
As iOS developers, we spend a significant amount of time in the terminal - whether it’s running builds, managing simulators, or navigating between projects. Yet most of us are still typing the same long commands over and over again. What if I told you that with just a few simple terminal customizations, you could cut your daily command typing by 80% and automate the most tedious parts of iOS development?
In this post, I’ll share my personal terminal setup that I’ve refined over years of iOS development. These aren’t just theoretical productivity hacks - these are the actual aliases, functions, and scripts I use every single day. By the end of this post, you’ll have a toolkit that will make your fellow developers wonder how you work so fast.
Let’s dive in!
Essential iOS Development Aliases
Let’s start with the basics - aliases that replace those long, hard-to-remember commands with short, memorable ones. Add these to your ~/.zshrc
or ~/.bash_profile
:
# Xcode and iOS Development
alias xc='open *.xcworkspace || open *.xcodeproj'
alias xcclean='rm -rf ~/Library/Developer/Xcode/DerivedData'
alias xcdevices='xcrun simctl list devices'
alias xcboot='xcrun simctl boot'
alias xcshutdown='xcrun simctl shutdown all'
alias xcreset='xcrun simctl erase all'
# Build shortcuts
alias build='xcodebuild -workspace *.xcworkspace -scheme'
alias buildclean='xcodebuild clean -workspace *.xcworkspace -scheme'
alias archive='xcodebuild archive -workspace *.xcworkspace -scheme'
# Fastlane shortcuts (if you use Fastlane)
alias fl='fastlane'
alias fltest='fastlane test'
alias flbuild='fastlane build'
# CocoaPods shortcuts
alias pod='bundle exec pod'
alias podup='bundle exec pod update'
alias podclean='bundle exec pod deintegrate && bundle exec pod install'
# Git shortcuts for iOS
alias gitclean='git clean -xfd && git reset --hard HEAD'
alias gitignore='curl -o .gitignore https://www.toptal.com/developers/gitignore/api/swift,xcode,cocoapods'
These aliases alone will save you hundreds of keystrokes per day. But we’re just getting started - this is where things get really interesting.
Powerful Terminal Functions
Aliases are great for simple commands, but functions let you create more sophisticated automation. Here are my favorite iOS development functions that I honestly can’t live without:
Quick Project Setup
# Create a new iOS project structure with common files
ios_project_setup() {
if [ -z "$1" ]; then
echo "Usage: ios_project_setup <project_name>"
return 1
fi
mkdir "$1"
cd "$1"
# Create basic directory structure
mkdir -p Scripts Documentation Assets
# Download .gitignore
curl -s -o .gitignore https://www.toptal.com/developers/gitignore/api/swift,xcode,cocoapods
# Create README
echo "# $1" > README.md
echo "" >> README.md
echo "## Setup" >> README.md
echo "" >> README.md
echo "\`\`\`bash" >> README.md
echo "bundle install" >> README.md
echo "bundle exec pod install" >> README.md
echo "\`\`\`" >> README.md
# Create Gemfile for Fastlane
echo "source 'https://rubygems.org'" > Gemfile
echo "" >> Gemfile
echo "gem 'fastlane'" >> Gemfile
echo "gem 'cocoapods'" >> Gemfile
echo "✅ Project $1 setup complete!"
}
Smart Simulator Management
# Boot the most recent iOS simulator
boot_latest_sim() {
local device_id=$(xcrun simctl list devices available | grep "iPhone" | tail -1 | grep -o "([A-F0-9-]*)" | tr -d "()")
if [ -n "$device_id" ]; then
xcrun simctl boot "$device_id"
echo "✅ Booted simulator: $device_id"
else
echo "❌ No available iPhone simulators found"
fi
}
# Install app on all booted simulators
install_on_all_sims() {
if [ -z "$1" ]; then
echo "Usage: install_on_all_sims <path_to_app>"
return 1
fi
local app_path="$1"
xcrun simctl list devices | grep "Booted" | while read -r line; do
local device_id=$(echo "$line" | grep -o "([A-F0-9-]*)" | tr -d "()")
if [ -n "$device_id" ]; then
xcrun simctl install "$device_id" "$app_path"
echo "✅ Installed on $device_id"
fi
done
}
Let me break down what these functions do, because the simulator management commands can be a bit cryptic:
- `boot_latest_sim()`: This grabs the latest iPhone simulator from your available devices and boots it up. No more manually opening Simulator.app and clicking through menus!
- `install_on_all_sims()`: Ever wanted to test your app on multiple simulator sizes at once? This installs your .app bundle on every currently running simulator. Super handy for screenshot automation or testing across different screen sizes.
Build Log Analysis
# Parse Xcode build logs for errors and warnings
analyze_build_log() {
if [ -z "$1" ]; then
echo "Usage: analyze_build_log <log_file>"
return 1
fi
echo "🔍 Analyzing build log: $1"
echo ""
echo "❌ ERRORS:"
grep -n "error:" "$1" | head -10
echo ""
echo "⚠️ WARNINGS:"
grep -n "warning:" "$1" | head -10
echo ""
echo "📊 SUMMARY:"
echo "Errors: $(grep -c "error:" "$1")"
echo "Warnings: $(grep -c "warning:" "$1")"
}
Project Navigation Scripts
One thing that drives me crazy is navigating between multiple iOS projects. You know the drill - you’re working on three different apps, each in a different folder, and you spend half your time just cd
-ing around trying to remember where everything is. Here’s how I solved it:
Quick Project Switcher
# Add this to your shell config
export IOS_PROJECTS_DIR="$HOME/Developer/iOS"
# Quick project navigation
ios_project() {
if [ -z "$1" ]; then
echo "Available projects:"
ls -1 "$IOS_PROJECTS_DIR" | grep -v ".DS_Store"
return 0
fi
local project_path="$IOS_PROJECTS_DIR/$1"
if [ -d "$project_path" ]; then
cd "$project_path"
# Automatically open in Xcode if requested
if [ "$2" = "open" ]; then
xc
fi
else
echo "❌ Project '$1' not found in $IOS_PROJECTS_DIR"
fi
}
# Add tab completion for projects
_ios_project() {
local projects=($(ls -1 "$IOS_PROJECTS_DIR" 2>/dev/null | grep -v ".DS_Store"))
compadd -a projects
}
compdef _ios_project ios_project
Now you can type ios_project MyApp
to instantly navigate to your project, or ios_project MyApp open
to navigate and open in Xcode.
Advanced Automation Scripts
Automated Testing Script with Notifications
# Run tests and send notification when complete
test_and_notify() {
local scheme="${1:-$(basename $(pwd))}"
local start_time=$(date +%s)
echo "🧪 Running tests for scheme: $scheme"
if fastlane test scheme:"$scheme"; then
local end_time=$(date +%s)
local duration=$((end_time - start_time))
osascript -e "display notification \"Tests passed in ${duration}s\" with title \"✅ $scheme\""
echo "✅ Tests passed in ${duration}s"
else
osascript -e "display notification \"Tests failed\" with title \"❌ $scheme\""
echo "❌ Tests failed"
return 1
fi
}
This one is a game-changer. How many times have you started a test run, then switched to Slack or Twitter while waiting, only to completely forget about it? This function runs your tests and sends you a macOS notification when they’re done. You can even see how long they took right in the notification. No more wondering if your tests are still running or if they finished 10 minutes ago!
Dependency Update Checker
# Check for outdated dependencies
check_dependencies() {
echo "🔍 Checking for outdated dependencies..."
echo ""
if [ -f "Podfile" ]; then
echo "📦 CocoaPods:"
bundle exec pod outdated
echo ""
fi
if [ -f "Package.swift" ]; then
echo "📦 Swift Package Manager:"
swift package show-dependencies --format json | jq -r '.dependencies[] | "\(.identity): \(.requirement)"'
echo ""
fi
if [ -f "Gemfile" ]; then
echo "💎 Ruby Gems:"
bundle outdated
fi
}
Setting Up Your Terminal for Maximum Productivity
To make the most of these scripts, here’s how to set up your terminal:
1. Install Essential Tools
# Install Homebrew if you haven't already
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install essential tools
brew install jq tree bat fzf ripgrep
2. Add to Your Shell Config
Add all the aliases and functions above to your ~/.zshrc
(if using zsh) or ~/.bash_profile
(if using bash):
# Edit your shell config
nano ~/.zshrc
# Reload your config
source ~/.zshrc
3. Create a Scripts Directory
# Create a dedicated directory for your iOS scripts
mkdir -p ~/Scripts/iOS
echo 'export PATH="$PATH:$HOME/Scripts/iOS"' >> ~/.zshrc
Pro Tips for Terminal Efficiency
-
Use
fzf
for fuzzy finding: Installfzf
to quickly search through your command history and file system. -
Set up tab completion: The project switcher above includes tab completion - use this pattern for your other functions too.
-
Create keyboard shortcuts: Map frequently used commands to keyboard shortcuts in your terminal app.
-
Use
bat
instead ofcat
: It provides syntax highlighting and line numbers. -
Leverage
tree
for project structure: Quickly visualize your project structure withtree -I 'Pods|DerivedData'
.
Bonus: Supercharge Your Terminal with Powerlevel10k
Now that we’ve covered all the functional aspects of terminal productivity, let’s talk about making your terminal not just powerful, but beautiful and informative too. I use Powerlevel10k (p10k), which is hands down the best Zsh theme I’ve ever used.
Seriously, I’ve tried probably a dozen different themes over the years, and nothing comes close to p10k. It’s fast, it’s gorgeous, and it shows you exactly the information you need without being cluttered.
What is Powerlevel10k?
Powerlevel10k is a theme for Zsh that provides:
- Lightning fast prompt rendering (100x faster than other themes)
- Rich information at a glance - Git status, current directory, execution time, etc.
- Highly customizable - configure it exactly how you want
- iOS-specific info - Show Swift version, Xcode version, and more
Installation
# Install Powerlevel10k
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k
echo 'source ~/powerlevel10k/powerlevel10k.zsh-theme' >>~/.zshrc
# Restart your terminal and run the configuration wizard
p10k configure
My iOS Developer Configuration
Here’s how I configure p10k for maximum iOS development productivity:
# Add these to your ~/.p10k.zsh file after running p10k configure
# Show Swift version when in Swift projects
typeset -g POWERLEVEL9K_SWIFT_SHOW_ON_COMMAND='swift|xcodebuild|fastlane'
# Show Ruby version (for Fastlane/CocoaPods)
typeset -g POWERLEVEL9K_RBENV_SHOW_ON_COMMAND='bundle|pod|fastlane|gem'
# Show Node version (for React Native or web stuff)
typeset -g POWERLEVEL9K_NODE_VERSION_SHOW_ON_COMMAND='node|npm|yarn|react-native'
# Customize the prompt elements (left side)
typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
dir # Current directory
vcs # Git status
swift_version # Swift version
rbenv # Ruby version (for Fastlane)
command_execution_time # How long the last command took
newline # Line break
prompt_char # The prompt character
)
# Customize the right side
typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(
status # Exit code of last command
background_jobs # Background jobs indicator
time # Current time
)
# Show execution time for commands longer than 3 seconds
typeset -g POWERLEVEL9K_COMMAND_EXECUTION_TIME_THRESHOLD=3
# Git status customization
typeset -g POWERLEVEL9K_VCS_CLEAN_FOREGROUND=76
typeset -g POWERLEVEL9K_VCS_MODIFIED_FOREGROUND=178
typeset -g POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND=014
Why This Matters for iOS Development
With p10k configured like this, your terminal instantly shows you:
- Git status - See if you have uncommitted changes at a glance
- Swift version - Know which Swift version you’re using when switching between projects
- Ruby version - Important for Fastlane and CocoaPods compatibility
- Command execution time - See how long your builds or tests took
- Current directory - Never get lost in your project structure
Pro p10k Tips
-
Instant prompt: p10k has an “instant prompt” feature that shows your prompt immediately, even before zsh fully loads. Enable it with:
echo 'typeset -g POWERLEVEL9K_INSTANT_PROMPT=verbose' >>~/.p10k.zsh
-
Transient prompt: Makes your command history cleaner by simplifying past prompts:
echo 'typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=always' >>~/.p10k.zsh
-
Custom segments: You can create custom segments. Here’s one that shows if you’re in an iOS project:
# Add to ~/.p10k.zsh function prompt_ios_project() { if [[ -n *.xcworkspace(#qN) || -n *.xcodeproj(#qN) ]]; then p10k segment -f 208 -t "📱" fi } # Add ios_project to your POWERLEVEL9K_LEFT_PROMPT_ELEMENTS
The result is a terminal that’s not just functional, but gives you crucial information at a glance. When you’re juggling multiple iOS projects with different Swift versions, Ruby versions, and Git states, this visual feedback is invaluable.
Trust me, once you get used to seeing all this information in your prompt, you’ll never want to go back to a boring terminal again. It’s like having a dashboard for your development environment!
Conclusion
These terminal customizations have literally saved me hours every week. I’m not exaggerating - when you add up all the time saved from not typing long commands, not having to remember complex xcodebuild syntax, and getting instant visual feedback about your project state, it really adds up.
The beauty is that you can start small - pick a few aliases that solve your biggest pain points, then gradually add more as you discover new needs. I didn’t build this setup overnight; it evolved over years of “ugh, I’m tired of typing this same command again.”
The key is to pay attention to the commands you type repeatedly and ask yourself: “Could I automate this?” More often than not, the answer is yes, and it only takes a few minutes to set up.
Start with the aliases and basic functions, then gradually build up your toolkit. Your future self (and your wrists) will thank you!
What terminal shortcuts do you swear by? I’d love to hear about your productivity hacks! Hit me up on Twitter and let me know what I should cover next.