UTMIntent.swift 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. //
  2. // Copyright © 2025 osy. All rights reserved.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. import AppIntents
  17. @available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
  18. protocol UTMIntent: AppIntent {
  19. associatedtype T : IntentResult
  20. var data: UTMData { get }
  21. var vmEntity: UTMVirtualMachineEntity { get }
  22. func perform(with vm: any UTMVirtualMachine, boxed: VMData) async throws -> T
  23. }
  24. @available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
  25. @available(*, deprecated)
  26. extension UTMIntent {
  27. static var openAppWhenRun: Bool { true }
  28. }
  29. @available(iOS 26, macOS 26, tvOS 26, watchOS 26, visionOS 26, *)
  30. extension UTMIntent {
  31. static var supportedModes: IntentModes { [.background, .foreground(.dynamic)] }
  32. }
  33. @available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
  34. extension UTMIntent {
  35. @MainActor
  36. func perform() async throws -> T {
  37. guard let vm = data.virtualMachines.first(where: { $0.id == vmEntity.id }), vm.isLoaded else {
  38. throw UTMIntentError.virtualMachineNotFound
  39. }
  40. do {
  41. return try await perform(with: vm.wrapped!, boxed: vm)
  42. } catch {
  43. throw UTMIntentError.localizedError(error)
  44. }
  45. }
  46. }
  47. @available(iOS 16, macOS 13, tvOS 16, watchOS 9, *)
  48. enum UTMIntentError: Error, CustomLocalizedStringResourceConvertible {
  49. case localizedError(Error)
  50. case virtualMachineNotFound
  51. case unsupportedBackend
  52. case inputHandlerNotAvailable
  53. var localizedStringResource: LocalizedStringResource {
  54. switch self {
  55. case .localizedError(let wrapped):
  56. return "\(wrapped.localizedDescription)"
  57. case .virtualMachineNotFound:
  58. return "Virtual machine not found."
  59. case .unsupportedBackend:
  60. return "Operation not supported by the backend."
  61. case .inputHandlerNotAvailable:
  62. return "Input handler not available."
  63. }
  64. }
  65. }