SimulatorServices allows you to execute subcommands to simctl directly in Swift while offering an easy to use API for parsing and passing arguments.
Usage
SimulatorServices uses the SimCtl object to pass subcommands. Each subcommand objects takes custom arguments or property and can parse the standard output into an easy to use Swift object. There are currently two supported subcommands: GetAppContainers and List.
Listing Simulators
The List subcommand gives you the ability pull the list of devices, device types, runtimes, and device pairs. For instances let’s say you want to pull all your available devices which are booted:
let simctl = SimCtl()
let list = try await simctl.run(List())
let devices = list.devices.values
.flatMap { $0 }
.filter{$0.state == "Booted"}
For more details on the properties available, check out the documentation on SimulatorList.
In this instance, we can take this a step further and find app container directories for these different simulator devices.
Getting App Containers
With our list of device simulators, we can use the GetAppContainer subcommand to find specific paths. In this case, let’s find the data directory of our app com.BrightDigit.Jojo.watchkitapp:
let jojoSimulatorDataDirPaths: [Path] = await withTaskGroup(of: Path?.self) { taskGroup in
for device in devices {
taskGroup.addTask {
do {
return try await simctl.run(
GetAppContainer(
appBundleIdentifier: "com.BrightDigit.Jojo.watchkitapp",
container: .data,
// use the udid of the device to indicate which simulator to pull from
simulator: .id(device.udid)
)
)
// if the data is missing that means that device does not contain that app container
} catch GetAppContainer.Error.missingData {
return nil
} catch {
return nil
}
}
}
return await taskGroup.reduce(into: [Path]()) { paths, path in
// essential this does a compactMap on results
if let path {
paths.append(path)
}
}
}
For more details on arguments available, check out the documentation on List.
Yeah but where’s…?
While now this package only supports two subcommands, however there are two ways more subcommands can be supported:
add an issue and it will be implemented in the future by the organizers
For details on how to implement a new Subcommand, check out the code on the existing commands and take a look at the documentation of the Subcommand protocol.
Learn more about simctl
There are some great articles out there regarding the intracacies of simctl. I highly recommend these articles which helped me in building this package:
SimulatorServices
Control the simulator… in Swift
Table of Contents
Introduction
SimulatorServices provides an easy to use API for managing, querying, and accessing simulators on your Mac.
Requirements
Apple Platforms
Linux
Installation
Use the Swift Package Manager to install this library via the repository url:
Use version up to
1.0.1
.What does Simulator Services provide?
SimulatorServices allows you to execute subcommands to
simctl
directly in Swift while offering an easy to use API for parsing and passing arguments.Usage
SimulatorServices uses the
SimCtl
object to pass subcommands. Each subcommand objects takes custom arguments or property and can parse the standard output into an easy to use Swift object. There are currently two supported subcommands:GetAppContainers
andList
.Listing Simulators
The
List
subcommand gives you the ability pull the list of devices, device types, runtimes, and device pairs. For instances let’s say you want to pull all your available devices which are booted:For more details on the properties available, check out the documentation on
SimulatorList
.In this instance, we can take this a step further and find app container directories for these different simulator devices.
Getting App Containers
With our list of device simulators, we can use the
GetAppContainer
subcommand to find specific paths. In this case, let’s find the data directory of our appcom.BrightDigit.Jojo.watchkitapp
:For more details on arguments available, check out the documentation on
List
.Yeah but where’s…?
While now this package only supports two subcommands, however there are two ways more subcommands can be supported:
Subcommand
For details on how to implement a new
Subcommand
, check out the code on the existing commands and take a look at the documentation of theSubcommand
protocol.Learn more about
simctl
There are some great articles out there regarding the intracacies of
simctl
. I highly recommend these articles which helped me in building this package:Great Simulator Apps
Also take a look at these great app which take advantage of what
simctl
can do:License
This code is distributed under the MIT license. See the LICENSE file for more info.