Swiftpack.co - brightdigit/SimulatorServices as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by brightdigit.
brightdigit/SimulatorServices 1.1.0-beta.2
Swift Interface into simctl
⭐️ 4
🕓 5 weeks ago
iOS macOS watchOS tvOS macCatalyst
.package(url: "https://github.com/brightdigit/SimulatorServices.git", from: "1.1.0-beta.2")



Control the simulator... in Swift

SwiftPM Twitter GitHub GitHub issues GitHub Workflow Status

Codecov CodeFactor Grade codebeat badge Code Climate maintainability Code Climate technical debt Code Climate issues Reviewed by Hound

Table of Contents


SimulatorServices provides an easy to use API for managing, querying, and accessing simulators on your Mac.


Apple Platforms

  • Xcode 13.3 or later
  • Swift 5.5.2 or later
  • iOS 14 / watchOS 6 / tvOS 14 / macOS 12 or later deployment targets


  • Ubuntu 18.04 or later
  • Swift 5.5.2 or later


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.


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(
            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](https://raw.github.com/brightdigit/SimulatorServices/main/)) { paths, path in
    // essential this does a compactMap on results
    if let 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:

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:

Great Simulator Apps

Also take a look at these great app which take advantage of what simctl can do:


This code is distributed under the MIT license. See the LICENSE file for more info.


Stars: 4
Last commit: 5 weeks ago
Advertisement: IndiePitcher.com - Cold Email Software for Startups

Release Notes

5 weeks ago

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics