Skip to content

Commit

Permalink
refactor: rewrite of Device Service
Browse files Browse the repository at this point in the history
  • Loading branch information
okwasniewski committed Sep 10, 2024
1 parent b397cae commit 4d27a98
Show file tree
Hide file tree
Showing 18 changed files with 809 additions and 624 deletions.
28 changes: 28 additions & 0 deletions MiniSim.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@
76BF0ADF2C8E01B3003BE568 /* CustomCommandService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76BF0ADE2C8E01B3003BE568 /* CustomCommandService.swift */; };
76BF0AE12C8E027D003BE568 /* DeviceConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76BF0AE02C8E027D003BE568 /* DeviceConstants.swift */; };
76BF0AE32C8E041C003BE568 /* CustomCommandServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76BF0AE22C8E041C003BE568 /* CustomCommandServiceTests.swift */; };
76BF0AE62C8E0F83003BE568 /* Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76BF0AE52C8E0F83003BE568 /* Actions.swift */; };
76BF0AE82C8E1077003BE568 /* ActionFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76BF0AE72C8E1077003BE568 /* ActionFactory.swift */; };
76BF0AEA2C905A94003BE568 /* AppleUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76BF0AE92C905A94003BE568 /* AppleUtils.swift */; };
76BF0AEC2C905C37003BE568 /* AndroidDeviceService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76BF0AEB2C905C37003BE568 /* AndroidDeviceService.swift */; };
76BF0AEE2C905C43003BE568 /* IOSDeviceService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76BF0AED2C905C43003BE568 /* IOSDeviceService.swift */; };
76BF0AF02C9061E8003BE568 /* DeviceDiscoveryService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76BF0AEF2C9061E8003BE568 /* DeviceDiscoveryService.swift */; };
76BF0AF22C907033003BE568 /* DeviceServiceFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76BF0AF12C907032003BE568 /* DeviceServiceFactory.swift */; };
76C1396A2C849A3F006CD80C /* MenuIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76C139692C849A3F006CD80C /* MenuIcons.swift */; };
76E4451229D4391000039025 /* Onboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76E4451129D4391000039025 /* Onboarding.swift */; };
76E4451429D4403F00039025 /* NSNotificationName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76E4451329D4403F00039025 /* NSNotificationName.swift */; };
Expand Down Expand Up @@ -184,6 +191,13 @@
76BF0ADE2C8E01B3003BE568 /* CustomCommandService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomCommandService.swift; sourceTree = "<group>"; };
76BF0AE02C8E027D003BE568 /* DeviceConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceConstants.swift; sourceTree = "<group>"; };
76BF0AE22C8E041C003BE568 /* CustomCommandServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomCommandServiceTests.swift; sourceTree = "<group>"; };
76BF0AE52C8E0F83003BE568 /* Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actions.swift; sourceTree = "<group>"; };
76BF0AE72C8E1077003BE568 /* ActionFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionFactory.swift; sourceTree = "<group>"; };
76BF0AE92C905A94003BE568 /* AppleUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppleUtils.swift; sourceTree = "<group>"; };
76BF0AEB2C905C37003BE568 /* AndroidDeviceService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AndroidDeviceService.swift; sourceTree = "<group>"; };
76BF0AED2C905C43003BE568 /* IOSDeviceService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IOSDeviceService.swift; sourceTree = "<group>"; };
76BF0AEF2C9061E8003BE568 /* DeviceDiscoveryService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceDiscoveryService.swift; sourceTree = "<group>"; };
76BF0AF12C907032003BE568 /* DeviceServiceFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceServiceFactory.swift; sourceTree = "<group>"; };
76C139692C849A3F006CD80C /* MenuIcons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuIcons.swift; sourceTree = "<group>"; };
76E4451129D4391000039025 /* Onboarding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Onboarding.swift; sourceTree = "<group>"; };
76E4451329D4403F00039025 /* NSNotificationName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSNotificationName.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -317,11 +331,18 @@
55CDB0762B1B6D06002418D7 /* Terminal */,
76F269832A2A375900424BDA /* CustomErrors */,
7645D4BD2982A1B100019227 /* DeviceService.swift */,
76BF0AEB2C905C37003BE568 /* AndroidDeviceService.swift */,
76BF0AED2C905C43003BE568 /* IOSDeviceService.swift */,
76BF0AE92C905A94003BE568 /* AppleUtils.swift */,
7699511C2C845B1900462287 /* DeviceParser.swift */,
76F04A10298A5AE000BF9CA3 /* ADB.swift */,
76B70F832B0D5AB4009D87A4 /* Shell.swift */,
76BF0ADE2C8E01B3003BE568 /* CustomCommandService.swift */,
76BF0AE02C8E027D003BE568 /* DeviceConstants.swift */,
76BF0AE52C8E0F83003BE568 /* Actions.swift */,
76BF0AE72C8E1077003BE568 /* ActionFactory.swift */,
76BF0AEF2C9061E8003BE568 /* DeviceDiscoveryService.swift */,
76BF0AF12C907032003BE568 /* DeviceServiceFactory.swift */,
);
path = Service;
sourceTree = "<group>";
Expand Down Expand Up @@ -634,14 +655,18 @@
76630F0E29BDE7EB00FB64F9 /* ParametersTable.swift in Sources */,
7677999829C25894009030F8 /* OnboardingPager.swift in Sources */,
52B363EC2AEC10A3006F515C /* ParametersTableForm.swift in Sources */,
76BF0AEC2C905C37003BE568 /* AndroidDeviceService.swift in Sources */,
7630B2682985C4CF00D8B57D /* About.swift in Sources */,
76BF0AF02C9061E8003BE568 /* DeviceDiscoveryService.swift in Sources */,
7699511D2C845B1900462287 /* DeviceParser.swift in Sources */,
76630F0C29BDD0C000FB64F9 /* Devices.swift in Sources */,
767C761F29B26ED3009B9AEC /* AccessibilityElement.swift in Sources */,
7610992F2A3F95D90067885A /* NSScriptCommand+utils.swift in Sources */,
4AFACC762AD73D7900EC369F /* NSMenuItem+ConvenienceInit.swift in Sources */,
76F269872A2A39D100424BDA /* Variables.swift in Sources */,
76BF0AF22C907033003BE568 /* DeviceServiceFactory.swift in Sources */,
764BA3EB2A5AD43F003A78AF /* LaunchDeviceCommand.swift in Sources */,
76BF0AE62C8E0F83003BE568 /* Actions.swift in Sources */,
7630B2732986C68000D8B57D /* PaneIdentifier.swift in Sources */,
7630B2662985C44A00D8B57D /* Preferences.swift in Sources */,
7625140B2992B46D0060A225 /* Pasteboard+utils.swift in Sources */,
Expand All @@ -654,6 +679,7 @@
76AC9AF62A0EA82C00864A8B /* CustomCommands.swift in Sources */,
76489D5C29BFCA330070EF03 /* OnboardingItem.swift in Sources */,
7645D5012982E6FA00019227 /* main.swift in Sources */,
76BF0AEA2C905A94003BE568 /* AppleUtils.swift in Sources */,
76F2A914299050F9002D4EF6 /* UserDefaults+Configuration.swift in Sources */,
76059BF72AD449DC0008D38B /* OnboardingHeader.swift in Sources */,
763121902A12B45000EE7F48 /* CustomCommandFormViewModel.swift in Sources */,
Expand All @@ -675,9 +701,11 @@
7630B26D2986B4FD00D8B57D /* KeyboardShortcuts.swift in Sources */,
76059BF52AD4361C0008D38B /* SetupPreferences.swift in Sources */,
7684FAAF29D202F500230BB0 /* AndroidHomeError.swift in Sources */,
76BF0AE82C8E1077003BE568 /* ActionFactory.swift in Sources */,
76C1396A2C849A3F006CD80C /* MenuIcons.swift in Sources */,
55CDB0782B1B6D24002418D7 /* TerminalApps.swift in Sources */,
9B225A9C2C7E360D002620BA /* DeviceType.swift in Sources */,
76BF0AEE2C905C43003BE568 /* IOSDeviceService.swift in Sources */,
7645D4BE2982A1B100019227 /* DeviceService.swift in Sources */,
765ABF382A8BECD900A063CB /* ExecuteCommand.swift in Sources */,
);
Expand Down
20 changes: 6 additions & 14 deletions MiniSim/AppleScript Commands/ExecuteCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,13 @@ class ExecuteCommand: NSScriptCommand {
guard let menuItem = SubMenuItems.Tags(rawValue: rawTag) else {
return nil
}
let actionExecutor = ActionExecutor()
actionExecutor.execute(
device: device,
commandTag: menuItem,
itemName: commandName
)

switch platform {
case .android:
DeviceService.handleAndroidAction(
device: device,
commandTag: menuItem,
itemName: commandName
)
case .ios:
DeviceService.handleiOSAction(
device: device,
commandTag: menuItem,
itemName: commandName
)
}
return nil
}
}
11 changes: 1 addition & 10 deletions MiniSim/AppleScript Commands/GetDevicesCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,7 @@ class GetDevicesCommand: NSScriptCommand {
}

do {
switch (platform, deviceType) {
case (.android, .physical):
return try self.encode(DeviceService.getAndroidPhysicalDevices())
case (.android, .virtual):
return try self.encode(DeviceService.getAndroidEmulators())
case (.ios, .physical):
return try self.encode(DeviceService.getIOSPhysicalDevices())
case (.ios, .virtual):
return try self.encode(DeviceService.getIOSSimulators())
}
return try self.encode(DeviceServiceFactory.getDeviceDiscoveryService(platform: platform).getDevices(type: deviceType))

Check warning on line 24 in MiniSim/AppleScript Commands/GetDevicesCommand.swift

View workflow job for this annotation

GitHub Actions / lint

Line Length Violation: Line should be 120 characters or less; currently it has 131 characters (line_length)
} catch {
scriptErrorNumber = NSInternalScriptError
return nil
Expand Down
8 changes: 4 additions & 4 deletions MiniSim/AppleScript Commands/LaunchDeviceCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@ class LaunchDeviceCommand: NSScriptCommand {

do {
var devices: [Device] = []
try devices.append(contentsOf: DeviceService.getIOSDevices())
try devices.append(contentsOf: DeviceService.getAndroidDevices())
try devices.append(contentsOf: DeviceServiceFactory.getDeviceDiscoveryService(platform: .ios).getDevices())
try devices.append(contentsOf: DeviceServiceFactory.getDeviceDiscoveryService(platform: .android).getDevices())

Check warning on line 21 in MiniSim/AppleScript Commands/LaunchDeviceCommand.swift

View workflow job for this annotation

GitHub Actions / lint

Line Length Violation: Line should be 120 characters or less; currently it has 123 characters (line_length)

guard let device = devices.first(where: { $0.name == deviceName }) else {
scriptErrorNumber = NSInternalScriptError
return nil
}

if device.booted {
DeviceService.focusDevice(device)
device.focus()
return nil
}

DeviceService.launch(device: device) { _ in }
try? device.launch()
return nil
} catch {
scriptErrorNumber = NSInternalScriptError
Expand Down
39 changes: 19 additions & 20 deletions MiniSim/Menu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import UserNotifications

class Menu: NSMenu {

Check warning on line 12 in MiniSim/Menu.swift

View workflow job for this annotation

GitHub Actions / lint

Type Body Length Violation: Type body should span 250 lines or less excluding comments and whitespace: currently spans 254 lines (type_body_length)
public let maxKeyEquivalent = 9
let actionExecutor = ActionExecutor()

var devices: [Device] = [] {
didSet {
Expand Down Expand Up @@ -71,7 +72,7 @@ class Menu: NSMenu {

func updateDevicesList() {
let userDefaults = UserDefaults.standard
DeviceService.getAllDevices(
DeviceServiceFactory.getAllDevices(
android: userDefaults.enableAndroidEmulators && userDefaults.androidHome != nil,
iOS: userDefaults.enableiOSSimulators
) { devices, error in
Expand All @@ -93,30 +94,28 @@ class Menu: NSMenu {
.forEach(safeRemoveItem)
}

@objc private func androidSubMenuClick(_ sender: NSMenuItem) {
guard let tag = SubMenuItems.Tags(rawValue: sender.tag) else { return }
guard let device = getDeviceByName(name: sender.parent?.title ?? "") else { return }
@objc private func subMenuClick(_ sender: NSMenuItem) {
guard let tag = SubMenuItems.Tags(rawValue: sender.tag) else { return }
guard let device = getDeviceByName(name: sender.parent?.title ?? "") else { return }

DeviceService.handleAndroidAction(device: device, commandTag: tag, itemName: sender.title)
}

@objc private func IOSSubMenuClick(_ sender: NSMenuItem) {
guard let tag = SubMenuItems.Tags(rawValue: sender.tag) else { return }
guard let device = getDeviceByName(name: sender.parent?.title ?? "") else { return }

DeviceService.handleiOSAction(device: device, commandTag: tag, itemName: sender.title)
actionExecutor.execute(
device: device,
commandTag: tag,
itemName: sender.title
)
}

@objc private func deviceItemClick(_ sender: NSMenuItem) {
guard let device = getDeviceByName(name: sender.title), device.type == .virtual else { return }

if device.booted {
DeviceService.focusDevice(device)
return
}

DeviceService.launch(device: device) { error in
if let error {
DispatchQueue.global().async {
if device.booted {
device.focus()
return
}
do {
try device.launch()
} catch {
NSAlert.showError(message: error.localizedDescription)
}
}
Expand Down Expand Up @@ -242,7 +241,7 @@ class Menu: NSMenu {
let subMenu = NSMenu()
let platform = device.platform
let deviceType = device.type
let callback = platform == .android ? #selector(androidSubMenuClick) : #selector(IOSSubMenuClick)
let callback = #selector(subMenuClick)
let actionsSubMenu = createActionsSubMenu(
for: SubMenuItems.items(platform: platform, deviceType: deviceType),
isDeviceBooted: device.booted,
Expand Down
7 changes: 6 additions & 1 deletion MiniSim/MiniSim.swift
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ class MiniSim: NSObject {
return
}

DeviceService.clearDerivedData { amountCleared, error in
AppleUtils.clearDerivedData { amountCleared, error in
guard error == nil else {
NSAlert.showError(message: error?.localizedDescription ?? "Failed to clear derived data.")
return
Expand All @@ -186,6 +186,11 @@ class MiniSim: NSObject {
}
}

static func showSuccessMessage(title: String, message: String) {
UNUserNotificationCenter.showNotification(title: title, body: message)
NotificationCenter.default.post(name: .commandDidSucceed, object: nil)
}

private var mainMenu: [NSMenuItem] {
MainMenuActions.allCases.map { item in
NSMenuItem(
Expand Down
97 changes: 46 additions & 51 deletions MiniSim/Model/Device.swift
Original file line number Diff line number Diff line change
@@ -1,34 +1,29 @@
//
// Device.swift
// MiniSim
//
// Created by Oskar Kwaśniewski on 25/01/2023.
//
import Foundation

struct Device: Hashable, Codable {
var name: String
var version: String?
var identifier: String?
var booted: Bool
var platform: Platform
var type: DeviceType
var name: String
var version: String?
var identifier: String?
var booted: Bool
var platform: Platform
var type: DeviceType

var displayName: String {
switch platform {
case .ios:
if let version {
return "\(name) - (\(version))"
}
return name
var displayName: String {
switch platform {
case .ios:
if let version {
return "\(name) - (\(version))"
}
return name

case .android:
return name
}
case .android:
return name
}
}

enum CodingKeys: String, CodingKey {
case name, version, identifier, booted, platform, displayName, type
}
enum CodingKeys: String, CodingKey {
case name, version, identifier, booted, platform, displayName, type
}

init(
name: String,
Expand All @@ -38,32 +33,32 @@ struct Device: Hashable, Codable {
platform: Platform,
type: DeviceType
) {
self.name = name
self.version = version
self.identifier = identifier
self.booted = booted
self.platform = platform
self.type = type
}
self.name = name
self.version = version
self.identifier = identifier
self.booted = booted
self.platform = platform
self.type = type
}

init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
version = try values.decode(String.self, forKey: .version)
identifier = try values.decode(String.self, forKey: .identifier)
booted = try values.decode(Bool.self, forKey: .booted)
platform = try values.decode(Platform.self, forKey: .platform)
type = try values.decode(DeviceType.self, forKey: .type)
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
version = try values.decode(String.self, forKey: .version)
identifier = try values.decode(String.self, forKey: .identifier)
booted = try values.decode(Bool.self, forKey: .booted)
platform = try values.decode(Platform.self, forKey: .platform)
type = try values.decode(DeviceType.self, forKey: .type)
}

func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
try container.encode(version, forKey: .version)
try container.encode(identifier, forKey: .identifier)
try container.encode(booted, forKey: .booted)
try container.encode(platform, forKey: .platform)
try container.encode(displayName, forKey: .displayName)
try container.encode(type, forKey: .type)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
try container.encode(version, forKey: .version)
try container.encode(identifier, forKey: .identifier)
try container.encode(booted, forKey: .booted)
try container.encode(platform, forKey: .platform)
try container.encode(displayName, forKey: .displayName)
try container.encode(type, forKey: .type)
}
}
Loading

0 comments on commit 4d27a98

Please sign in to comment.