mirror of
https://github.com/somegeekintn/SimDirs.git
synced 2026-06-29 05:29:30 +00:00
82 lines
3 KiB
Swift
82 lines
3 KiB
Swift
//
|
|
// SimModel.swift
|
|
// SimDirs
|
|
//
|
|
// Created by Casey Fleser on 5/24/22.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
enum SimError: Error {
|
|
case deviceParsingFailure
|
|
case invalidApp
|
|
}
|
|
|
|
class SimModel: ObservableObject {
|
|
var deviceTypes : [SimDeviceType]
|
|
@Published var runtimes : [SimRuntime]
|
|
let timer = DispatchSource.makeTimerSource()
|
|
let updateInterval = 1.0
|
|
|
|
init() {
|
|
let simctl = SimCtl()
|
|
|
|
do {
|
|
let runtimeDevs : [String : [SimDevice]]
|
|
|
|
deviceTypes = try simctl.readAllDeviceTypes()
|
|
runtimes = try simctl.readAllRuntimes()
|
|
runtimeDevs = try simctl.readAllRuntimeDevices()
|
|
for (runtimeID, devices) in runtimeDevs {
|
|
do {
|
|
let runtimeIdx = try runtimes.indexOfMatchedOrCreated(identifier: runtimeID)
|
|
|
|
runtimes[runtimeIdx].setDevices(devices, from: deviceTypes)
|
|
}
|
|
catch {
|
|
print("Warning: Unable to create placeholder runtime from \(runtimeID)")
|
|
}
|
|
}
|
|
runtimes.sort()
|
|
beginMonitor()
|
|
}
|
|
catch {
|
|
fatalError("Failed to initialize data model:\n\(error)")
|
|
}
|
|
}
|
|
|
|
func beginMonitor() {
|
|
timer.setEventHandler {
|
|
guard let runtimeDevs : [String : [SimDevice]] = try? SimCtl().readAllRuntimeDevices() else { return }
|
|
|
|
// Device updating
|
|
for (runtimeID, newDevices) in runtimeDevs {
|
|
guard let runtime = self.runtimes.first(where: { $0.identifier == runtimeID }) else { continue }
|
|
let newDevIDs = newDevices.map { $0.udid }
|
|
let curDevIDs = runtime.devices.map { $0.udid }
|
|
let updates = runtime.updatedDevices(from: newDevices)
|
|
let deleteIDs = curDevIDs.filter { !newDevIDs.contains($0) }
|
|
let inserts = newDevices.filter { !curDevIDs.contains($0.udid) }
|
|
let changes : (upd: Bool, del: Bool, ins: Bool) = (!updates.isEmpty, !deleteIDs.isEmpty, !inserts.isEmpty)
|
|
|
|
if changes != (false, false, false) {
|
|
DispatchQueue.main.async {
|
|
guard let runtimeIdx = self.runtimes.firstIndex(of: runtime) else { return }
|
|
|
|
if changes.upd {
|
|
self.runtimes[runtimeIdx].applyDeviceUpdates(updates)
|
|
}
|
|
if changes.del {
|
|
self.runtimes[runtimeIdx].devices.removeAll(where: { deleteIDs.contains($0.udid) })
|
|
}
|
|
if changes.ins {
|
|
self.runtimes[runtimeIdx].devices.append(contentsOf: inserts)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
timer.schedule(deadline: DispatchTime.now(), repeating: updateInterval)
|
|
timer.resume()
|
|
}
|
|
}
|