Skip to content

Instantly share code, notes, and snippets.

@rhysforyou
Created October 2, 2019 01:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rhysforyou/9e3a6efdb0ee503ea8592e1e2106cecd to your computer and use it in GitHub Desktop.
Save rhysforyou/9e3a6efdb0ee503ea8592e1e2106cecd to your computer and use it in GitHub Desktop.
#!/usr/bin/swift
import Foundation
struct Device: Codable {
enum State: String, Codable {
case shutdown = "Shutdown"
case booted = "Booted"
}
let state: State
let isAvailable: Bool
let name: String
let udid: String
}
struct DeviceList: Codable {
enum CodingKeys: String, CodingKey {
case devicesByPlatform = "devices"
}
let devicesByPlatform: [String: [Device]]
var devices: [Device] {
return devicesByPlatform.values.reduce(into: [], { $0.append(contentsOf: $1) })
}
var iOSDevices: [Device] {
let devicesByiOSPlatform = devicesByPlatform.filter { $0.key.contains("iOS") }
return devicesByiOSPlatform.values.reduce(into: [], { $0.append(contentsOf: $1) })
}
}
/// Thrown when the output of a process can't be converted into a unicode string
struct BadOutputError: Error {
let data: Data
}
extension Process {
/// Creates a process to execute `xcrun`.
///
/// - Parameter args: The arguments to pass to `xcrun`.
@discardableResult func xcrun(_ args: String...) throws -> String {
self.launchPath = "/usr/bin/xcrun"
self.arguments = args
let pipe = Pipe()
self.standardOutput = pipe
self.launch()
self.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
guard let output = String(data: data, encoding: .utf8) else {
throw BadOutputError(data: data)
}
return output
}
/// Executes `xcrun simctl list devices`
@discardableResult func xcrunListDevices() throws -> DeviceList {
let json = try xcrun("simctl", "list", "devices", "-j")
let decoder = JSONDecoder()
return try! decoder.decode(DeviceList.self, from: json.data(using: .utf8)!)
}
/// Executes `xcrun simctl status_bar` on the specified device.
///
/// - Parameter device: The device for which status bar values should be overridden.
@discardableResult func xcrunFixStatusBar(_ device: Device) throws -> String {
return try self.xcrun(
"simctl", "status_bar", device.udid, "override",
"--time", "9:41",
"--dataNetwork", "wifi",
"--wifiMode", "active",
"--wifiBars", "3",
"--cellularMode", "active",
"--cellularBars", "4",
"--batteryState", "charged",
"--batteryLevel", "100"
)
}
}
let deviceList = try Process().xcrunListDevices()
let bootediOSDevices = deviceList.iOSDevices.filter({ $0.state == .booted })
guard !bootediOSDevices.isEmpty else {
print("⚠️ No devices currently booted")
exit(0)
}
print("Fixing status bars...")
for device in bootediOSDevices {
try Process().xcrunFixStatusBar(device)
print("✅ Fixed \(device.name)")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment