iOS/Sources/Extensions/Watch/WatchCommunicatorService.swift
Bruno Pantaleão Gonçalves 2c838a1c70
Improvements for Apple Watch Assist (#2839)
<!-- 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-07-10 10:32:33 +02:00

65 lines
2.6 KiB
Swift

import Communicator
import Foundation
import Shared
struct ImmediateCommunicatorServiceObserver {
weak var delegate: (any ImmediateCommunicatorServiceDelegate)?
}
protocol ImmediateCommunicatorServiceDelegate: AnyObject {
func didReceiveChatItem(_ item: AssistChatItem)
func didReceiveTTS(url: URL)
func didReceiveError(code: String, message: String)
}
final class ImmediateCommunicatorService {
static var shared = ImmediateCommunicatorService()
private var observers: [ImmediateCommunicatorServiceObserver] = []
func addObserver(_ observer: ImmediateCommunicatorServiceObserver) {
observers.append(observer)
}
func removeObserver(_ observerDelegate: ImmediateCommunicatorServiceDelegate) {
observers.removeAll { $0.delegate === observerDelegate }
}
func evaluateMessage(_ message: ImmediateMessage) {
guard let messageId = InteractiveImmediateResponses(rawValue: message.identifier) else {
Current.Log.error("Received communicator message that cant be mapped to messages responses enum")
return
}
switch messageId {
case .assistSTTResponse:
guard let content = message.content["content"] as? String else {
Current.Log.error("Received assistSTTResponse without content")
return
}
observers.forEach({ $0.delegate?.didReceiveChatItem(AssistChatItem(content: content, itemType: .input)) })
case .assistIntentEndResponse:
guard let content = message.content["content"] as? String else {
Current.Log.error("Received assistIntentEndResponse without content")
return
}
observers.forEach({ $0.delegate?.didReceiveChatItem(AssistChatItem(content: content, itemType: .output)) })
case .assistTTSResponse:
guard let audioURLString = message.content["mediaURL"] as? String,
let audioURL = URL(string: audioURLString) else {
Current.Log.error("Received assistTTSResponse without valid media URL")
return
}
observers.forEach({ $0.delegate?.didReceiveTTS(url: audioURL) })
case .assistError:
guard let code = message.content["code"] as? String,
let message = message.content["message"] as? String else {
Current.Log.error("Received assistError without valid code/message")
return
}
observers.forEach({ $0.delegate?.didReceiveError(code: code, message: message) })
default:
break
}
}
}