From the this-may-only-be-useful-to-me department, I recently did the stereotypical programmer thing. I procrastinated from doing what I should be doing by instead automating something that bothered me.
One of the many perks of SwiftUI is how easy it is to preview your designs/layouts. In fact, you can even do so across multiple devices:
struct SomeView: View {
var body: some View {
Text("Hello, world")
}
}
struct SomeViewPreviews: PreviewProvider {
static var previews: some View {
Group {
SomeView()
.previewProvider("iPhone 13 Pro")
SomeView()
.previewProvider("iPhone SE (2nd generation)")
}
}
}
The above code would present you with two renders of SomeView
: one shown on
an iPhone 13 Pro, and one on an iPhone SE.
The problem with this, however, is you need to know the exact right
incantation of device name in order to please Xcode/SwiftUI. For some
devices, like iPhone 13 Pro
, that’s pretty straightforward. For others,
like iPhone SE (2nd generation)
, it’s less so.
The good news is, you can get a list of installed simulators on your machine using this command:
xcrun simctl list devices available
It occurred to me, if I can easily query Xcode for the list of installed
simulators, surely I can then convert that list into a Swift enum
or
equivalent that I can use from my code? Hell, I can even auto-generate
this enum
every time I build, in order to make sure I always have the
latest-and-greatest list for my particular machine available.
Enter installed-simulators
. It’s a small Swift command-line app
that does exactly that. When run, without any parameters, it spits out
a file called Simulators.swift
. That file looks like this:
import SwiftUI
enum Simulator {
static let iPhone8 = PreviewDevice(rawValue: "iPhone 8")
static let iPhone8Plus = PreviewDevice(rawValue: "iPhone 8 Plus")
/* ...and so on, and so on... */
}
That makes it super easy to test your SwiftUI views by device, without having to worry about the precisely correct name of the device you’re thinking of:
struct SomeViewPreviews: PreviewProvider {
static var previews: some View {
Group {
SomeView()
.previewProvider(Simulator.iPhone13Pro)
SomeView()
.previewProvider(Simulator.iPhoneSE2ndgeneration)
}
}
}
Naturally, I prefer this over the alternative.
Since I’m so used to wielding a hammer, I wrote this as a Swift command-line app rather than a Perl script. Sorry, John. Also, I know effectively nothing about releasing apps of any sort for macOS, so goodness knows if this will work on anyone else’s desk but mine.
Nevertheless, I’ve open-sourced it, and you can find it — as well as some more robust instructions — over at Github.