I was interested in opening an app in multiple simulators without having to manually run it via xcode, but there seems to be no straightforward way of doing it. We are devs, we don’t want to go through the hassle of changing simulator each time to try the app in different sizes.
I implemented this using derived data. If there’s already a build for the simulator architecture, just run that build for other simulators.
The following code works with Fastlane installed:
DEFAULT_SIMULATORS = ['iPhone 5s', 'iPhone 8', 'iPhone X', 'iPhone Xʀ']
PROJECT_PATH = # Project path.
SCHEME = ... # (Your scheme)
CONFIGURATION = ... # (usually Debug or Release)
APP_ID = # Your app id. i.e: com.company.app
APP_NAME = # The output name of your app.
platform :ios do
desc "Build the app"
lane :build do
simulator_sdk_path = sh("xcrun --show-sdk-path --sdk iphonesimulator").to_s.strip()
sh("xcodebuild -configuration #{CONFIGURATION} -scheme #{SCHEME} -project #{PROJECT_PATH} -sdk #{simulator_sdk_path} build -UseModernBuildSystem=NO")
end
# Before running this lane, ensure that you built the app in Xcode first.
# Example specifying simulators: fastlane run_multiple_simulators simulators:"iPhone 5s, iPhone 8"
desc 'Run App in multiple simulators'
lane :run_multiple_simulators do |options|
simulators = options[:simulators].nil? ? DEFAULT_SIMULATORS : options[:simulators].split(',').map { |device| device.strip }
derivedDataQuery = sh "xcodebuild -project #{PROJECT_PATH} -scheme #{SCHEME} -showBuildSettings | grep -m 1 \'BUILD_DIR\' | grep -oEi \"\/.*\" | tail -1"
derived_data_path = derivedDataQuery.split.last + "/Debug-iphonesimulator/#{APP_NAME}/"
if !File.exist?(derived_data_path)
UI.error("#{derived_data_path} doesn\'t exist! Building app...")
build
end
# Launch simulator app
sh('open /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app/')
# First boot all simulators because it takes some seconds
simulators.each do |simulator|
begin
sh "xcrun simctl list | grep Booted | grep -w \'#{simulator}\' "
rescue
sh "xcrun simctl boot \'#{simulator}\'"
end
end
# Install and launch the app
simulators.each do |simulator|
sh("xcrun simctl install \'#{simulator}\' #{derived_data_path}")
sh("xcrun simctl launch \'#{simulator}\' #{APP_ID}")
end
end
end
To run it with default simulators:
fastlane run_multiple_simulators
To run it with specific simulators:
fastlane run_multiple_simulators simulators:"iPhone 5s, iPhone 8"
To get a list of available simulators:
xcrun simctl list | grep com.apple.CoreSimulator