You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
6.0 KiB

import Flutter
import UIKit
import Foundation
import os.log
/// 代理服务Flutter插件,负责将Flutter调用桥接到原生实现
public class AgentServicePlugin: NSObject, FlutterPlugin {
/// 插件注册方法,Flutter引擎调用
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "com.yunqiinnovation.agent_service", binaryMessenger: registrar.messenger())
let eventChannel = FlutterEventChannel(name: "com.yunqiinnovation.agent_service/events", binaryMessenger: registrar.messenger())
let instance = AgentServicePlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
eventChannel.setStreamHandler(instance.eventHandler)
}
// MARK: - 属性
private let impl = AgentServiceImpl.shared
private lazy var eventHandler = AgentServiceEventHandler(impl: impl)
// MARK: - FlutterPlugin 实现
/// 处理Flutter发来的方法调用
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "startAgentService":
guard let arguments = call.arguments as? [String: Any],
let config = arguments["config"] as? [String: Any] else {
result(FlutterError(code: "INVALID_ARGUMENTS", message: "配置参数不能为空", details: nil))
return
}
let success = impl.initialize(config: config)
result(success)
case "stopAgentService":
let success = impl.dispose()
result(success)
case "startConversation":
impl.startRecognition()
result(true)
case "stopConversation":
impl.stopRecognition()
result(true)
case "processTextInput":
guard let arguments = call.arguments as? [String: Any],
let text = arguments["text"] as? String else {
result(FlutterError(code: "INVALID_ARGUMENTS", message: "文本不能为空", details: nil))
return
}
let speakResponse = arguments["speakResponse"] as? Bool ?? false
let success = impl.processTextInput(text, speakResponse: speakResponse)
result(success)
case "processImageInput":
guard let arguments = call.arguments as? [String: Any],
let imagePath = arguments["imagePath"] as? String else {
result(FlutterError(code: "INVALID_ARGUMENTS", message: "图片路径不能为空", details: nil))
return
}
let text = arguments["text"] as? String ?? ""
let speakResponse = arguments["speakResponse"] as? Bool ?? false
let success = impl.processImageInput(imagePath: imagePath, text: text, speakResponse: speakResponse)
result(success)
case "speakText":
guard let arguments = call.arguments as? [String: Any],
let text = arguments["text"] as? String else {
result(FlutterError(code: "INVALID_ARGUMENTS", message: "文本不能为空", details: nil))
return
}
let success = impl.speakText(text)
result(success)
case "stopTts":
let success = impl.stopTts()
result(success)
case "clearChatHistory":
let success = impl.clearChatHistory()
result(success)
case "interruptCurrentResponse":
let success = impl.interruptCurrentResponse()
result(success)
case "dispose":
let success = impl.dispose()
result(success)
default:
result(FlutterMethodNotImplemented)
}
}
}
/// 代理服务事件处理器,负责将原生事件传递给Flutter
class AgentServiceEventHandler: NSObject, FlutterStreamHandler {
private let impl: AgentServiceImpl
private var eventSink: FlutterEventSink?
private let logger = OSLog(subsystem: "com.yunqiinnovation.agent_service", category: "AgentServiceEventHandler")
init(impl: AgentServiceImpl) {
self.impl = impl
super.init()
}
/// 监听开始时调用
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
self.eventSink = events
// 添加实现的事件监听器
impl.addListener(self)
return nil
}
/// 监听取消时调用
func onCancel(withArguments arguments: Any?) -> FlutterError? {
impl.removeListener(self)
self.eventSink = nil
return nil
}
}
// 扩展事件处理器以实现AgentServiceListener接口
extension AgentServiceEventHandler: AgentServiceListener {
func onEvent(eventName: String, data: [String: Any]) {
// 确保在主线程上调用
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
// 将事件数据格式化为与Android版本一致的格式
let eventData: [String: Any] = [
"event": eventName,
"data": data
]
// 转换为JSON字符串发送,与Android版本保持一致
do {
let jsonData = try JSONSerialization.data(withJSONObject: eventData, options: [])
if let jsonString = String(data: jsonData, encoding: .utf8) {
self.eventSink?(jsonString)
} else {
os_log("无法创建JSON字符串", log: self.logger, type: .error)
}
} catch {
os_log("JSON序列化失败: %{public}@", log: self.logger, type: .error, error.localizedDescription)
}
}
}
}