Issue #559
public class GetDestinations {
public init() {}
public func getAvailable(workflow: Workflow) throws -> [Destination] {
let processHandler = DefaultProcessHandler(filter: { $0.starts(with: "name=") })
let string = try CommandLine().runBash(
workflow: workflow,
program: "xcrun simctl",
arguments: [
"list",
"devices",
"-j"
],
processHandler: processHandler
)
guard let data = string.data(using: .utf8) else {
throw PumaError.invalid
}
let response: Response = try JSONDecoder().decode(Response.self, from: data)
let devicesWithOS: [DeviceWithOS] = response.devices.flatMap({ key, value in
return value.map({ DeviceWithOS(device: $0, os: key) })
})
let destinations: [Destination] = try devicesWithOS
.filter({ withOS in
return withOS.device.isAvailable
})
.compactMap({ withOS in
guard
let platform = self.platform(withOS: withOS),
let os = try self.os(withOS: withOS)
else {
return nil
}
var destination = Destination(
name: withOS.device.name,
platform: platform,
os: os
)
destination.id = withOS.device.udid
return destination
})
return destinations
}
func findId(workflow: Workflow, destination: Destination) throws -> String? {
let availableDestinations = try self.getAvailable(workflow: workflow)
return availableDestinations.first(where: { $0 == destination })?.id
}
// MARK: - Private
private func platform(withOS: DeviceWithOS) -> String? {
let list: [String] = [
Destination.Platform.iOS,
Destination.Platform.watchOS,
Destination.Platform.macOS,
Destination.Platform.tvOS,
]
return list.first(where: { withOS.os.contains($0) })
}
// com.apple.CoreSimulator.SimRuntime.iOS-13-2
private func os(withOS: DeviceWithOS) throws -> String? {
guard let string = try withOS.os.matches(pattern: #"(-\d+)+"#).first else {
return nil
}
return string.dropFirst().replacingOccurrences(of: "-", with: ".")
}
}
private struct Response: Decodable {
let devices: [String: [Device]]
}
private struct Device: Decodable {
let state: String
let name: String
let udid: String
let isAvailable: Bool
}
private struct DeviceWithOS {
let device: Device
let os: String
}