Files
iOS/Sources/Shared/Intents/PerformActionIntentHandler.swift
Bruno Pantaleão Gonçalves 13ac4e4a87 Making API connection optional given activeURL is now optional as well (#3169)
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->

## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->

## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->

## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#

## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
2024-11-18 15:07:18 +01:00

69 lines
2.4 KiB
Swift

import Foundation
import Intents
import PromiseKit
import Realm
class PerformActionIntentHandler: NSObject, PerformActionIntentHandling {
func handle(
intent: PerformActionIntent,
completion: @escaping (PerformActionIntentResponse) -> Void
) {
guard let result = intent.action?.asActionWithUpdated() else {
completion(.init(code: .failure, userActivity: nil))
return
}
guard let server = Current.servers.server(for: result.action) else {
completion(.init(code: .failure, userActivity: nil))
return
}
firstly {
Current.api(for: server)?
.HandleAction(actionID: result.action.ID, source: .SiriShortcut) ??
.init(error: HomeAssistantAPI.APIError.noAPIAvailable)
}.done {
completion(.success(action: result.updated))
}.catch { error in
completion(.failure(error: error.localizedDescription))
}
}
func resolveAction(
for intent: PerformActionIntent, with completion:
@escaping (IntentActionResolutionResult) -> Void
) {
if let result = intent.action?.asActionWithUpdated() {
Current.Log.info("using action \(String(describing: result.updated.identifier))")
completion(.success(with: result.updated))
} else {
Current.Log.info("asking for value")
completion(.needsValue())
}
}
func provideActionOptions(
for intent: PerformActionIntent,
with completion: @escaping ([IntentAction]?, Error?) -> Void
) {
let actions = Current.realm(objectTypes: [Action.self]).objects(Action.self)
.sorted(byKeyPath: #keyPath(Action.Position))
let performActions = Array(actions.map { IntentAction(action: $0) })
Current.Log.info { () -> String in
"providing " + performActions.map { action -> String in
(action.identifier ?? "?") + " (" + action.displayString + ")"
}.joined(separator: ", ")
}
completion(Array(performActions), nil)
}
func provideActionOptionsCollection(
for intent: PerformActionIntent,
with completion: @escaping (INObjectCollection<IntentAction>?, Error?) -> Void
) {
provideActionOptions(for: intent) { actions, error in
completion(actions.flatMap { .init(items: $0) }, error)
}
}
}