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.
227 lines
8.4 KiB
227 lines
8.4 KiB
import Flutter
|
|
import UIKit
|
|
import AVFoundation
|
|
|
|
/// 代理服务插件,负责连接Flutter端与原生服务
|
|
public class AgentServicePlugin: NSObject, FlutterPlugin {
|
|
private let TAG = "AgentServicePlugin"
|
|
private var eventSink: FlutterEventSink?
|
|
|
|
// MARK: - 插件注册
|
|
|
|
/// 插件注册方法
|
|
public static func register(with registrar: FlutterPluginRegistrar) {
|
|
let methodChannel = 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: methodChannel)
|
|
eventChannel.setStreamHandler(instance)
|
|
|
|
// 添加监听器
|
|
AgentServiceImpl.shared.addListener(instance)
|
|
|
|
NSLog("\(instance.TAG): 插件已加载")
|
|
}
|
|
|
|
// MARK: - 方法处理
|
|
|
|
/// 处理来自Flutter的方法调用
|
|
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
|
NSLog("\(TAG): 收到方法调用 - \(call.method)")
|
|
|
|
switch call.method {
|
|
case "initialize":
|
|
handleInitialize(call, result: result)
|
|
case "startAgentService":
|
|
handleStartAgentService(call, result: result)
|
|
case "stopAgentService":
|
|
handleStopAgentService(result: result)
|
|
case "startConversation":
|
|
handleStartConversation(result: result)
|
|
case "stopConversation":
|
|
handleStopConversation(result: result)
|
|
case "processTextInput":
|
|
handleProcessTextInput(call, result: result)
|
|
case "speakText":
|
|
handleSpeakText(call, result: result)
|
|
case "stopTts":
|
|
handleStopTts(result: result)
|
|
case "clearChatHistory":
|
|
handleClearChatHistory(result: result)
|
|
case "interruptCurrentResponse":
|
|
handleInterruptCurrentResponse(result: result)
|
|
case "processImageInput":
|
|
handleProcessImageInput(call, result: result)
|
|
case "dispose":
|
|
handleDispose(result: result)
|
|
default:
|
|
result(FlutterMethodNotImplemented)
|
|
}
|
|
}
|
|
|
|
// MARK: - 方法实现
|
|
|
|
private func handleInitialize(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
|
guard let args = call.arguments as? [String: Any],
|
|
let config = args["config"] as? [String: Any] else {
|
|
result(FlutterError(code: "INVALID_ARGUMENTS", message: "参数无效", details: nil))
|
|
return
|
|
}
|
|
|
|
// 初始化AgentServiceImpl
|
|
let success = AgentServiceImpl.shared.initialize(config: config)
|
|
result(success)
|
|
}
|
|
|
|
private func handleStartAgentService(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
|
guard let args = call.arguments as? [String: Any],
|
|
let config = args["config"] as? [String: Any] else {
|
|
result(FlutterError(code: "INVALID_ARGUMENTS", message: "参数无效", details: nil))
|
|
return
|
|
}
|
|
|
|
NSLog("\(TAG): 启动AgentService,配置参数: \(config)")
|
|
|
|
// 初始化AgentServiceImpl
|
|
let success = AgentServiceImpl.shared.initialize(config: config)
|
|
|
|
if success {
|
|
result(true)
|
|
} else {
|
|
result(FlutterError(code: "SERVICE_START_ERROR", message: "AgentService启动失败", details: nil))
|
|
}
|
|
}
|
|
|
|
private func handleStopAgentService(result: @escaping FlutterResult) {
|
|
NSLog("\(TAG): 停止AgentService")
|
|
let success = AgentServiceImpl.shared.dispose()
|
|
result(success)
|
|
}
|
|
|
|
private func handleStartConversation(result: @escaping FlutterResult) {
|
|
NSLog("\(TAG): 开始对话")
|
|
let success = AgentServiceImpl.shared.startRecognition()
|
|
result(success)
|
|
}
|
|
|
|
private func handleStopConversation(result: @escaping FlutterResult) {
|
|
NSLog("\(TAG): 停止对话")
|
|
let success = AgentServiceImpl.shared.stopRecognition()
|
|
result(success)
|
|
}
|
|
|
|
private func handleProcessTextInput(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
|
guard let args = call.arguments as? [String: Any],
|
|
let text = args["text"] as? String else {
|
|
result(FlutterError(code: "INVALID_ARGUMENTS", message: "文本不能为空", details: nil))
|
|
return
|
|
}
|
|
let speakResponse = args["speakResponse"] as? Bool ?? false
|
|
|
|
NSLog("\(TAG): 处理文本输入 - \(text)")
|
|
let success = AgentServiceImpl.shared.processTextInput(text, speakResponse: speakResponse)
|
|
result(success)
|
|
}
|
|
|
|
private func handleSpeakText(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
|
guard let args = call.arguments as? [String: Any],
|
|
let text = args["text"] as? String else {
|
|
result(FlutterError(code: "INVALID_ARGUMENTS", message: "文本不能为空", details: nil))
|
|
return
|
|
}
|
|
|
|
NSLog("\(TAG): 语音合成 - \(text)")
|
|
let success = AgentServiceImpl.shared.speakText(text)
|
|
result(success)
|
|
}
|
|
|
|
private func handleStopTts(result: @escaping FlutterResult) {
|
|
NSLog("\(TAG): 停止语音合成")
|
|
let success = AgentServiceImpl.shared.stopTts()
|
|
result(success)
|
|
}
|
|
|
|
private func handleClearChatHistory(result: @escaping FlutterResult) {
|
|
NSLog("\(TAG): 清除聊天历史")
|
|
let success = AgentServiceImpl.shared.clearChatHistory()
|
|
result(success)
|
|
}
|
|
|
|
private func handleInterruptCurrentResponse(result: @escaping FlutterResult) {
|
|
NSLog("\(TAG): 中断当前响应")
|
|
let success = AgentServiceImpl.shared.interruptCurrentResponse()
|
|
result(success)
|
|
}
|
|
|
|
private func handleProcessImageInput(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
|
guard let args = call.arguments as? [String: Any],
|
|
let imagePath = args["imagePath"] as? String else {
|
|
result(FlutterError(code: "INVALID_ARGUMENTS", message: "图片路径不能为空", details: nil))
|
|
return
|
|
}
|
|
let text = args["text"] as? String ?? ""
|
|
let speakResponse = args["speakResponse"] as? Bool ?? false
|
|
|
|
NSLog("\(TAG): 处理图片输入 - \(imagePath)")
|
|
let success = AgentServiceImpl.shared.processImageInput(imagePath: imagePath, text: text, speakResponse: speakResponse)
|
|
result(success)
|
|
}
|
|
|
|
private func handleDispose(result: @escaping FlutterResult) {
|
|
NSLog("\(TAG): 释放资源")
|
|
|
|
// 移除监听器并释放资源
|
|
AgentServiceImpl.shared.removeListener(self)
|
|
let success = AgentServiceImpl.shared.dispose()
|
|
|
|
result(success)
|
|
}
|
|
|
|
// MARK: - 实例析构
|
|
|
|
deinit {
|
|
// 确保在实例销毁时移除监听器
|
|
AgentServiceImpl.shared.removeListener(self)
|
|
NSLog("\(TAG): 插件已卸载")
|
|
}
|
|
}
|
|
|
|
// MARK: - AgentServiceListener 实现
|
|
extension AgentServicePlugin: AgentServiceListener {
|
|
public func onEvent(eventName: String, data: [String: Any]) {
|
|
guard let eventSink = eventSink else { return }
|
|
|
|
// 将事件转换为JSON字符串
|
|
let eventData: [String: Any] = [
|
|
"event": eventName,
|
|
"data": data
|
|
]
|
|
|
|
do {
|
|
let jsonData = try JSONSerialization.data(withJSONObject: eventData, options: [])
|
|
if let jsonString = String(data: jsonData, encoding: .utf8) {
|
|
// 确保在主线程发送事件到Flutter
|
|
DispatchQueue.main.async {
|
|
eventSink(jsonString)
|
|
}
|
|
}
|
|
} catch {
|
|
NSLog("\(TAG): 错误 - 事件数据序列化失败: \(error.localizedDescription)")
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - FlutterStreamHandler 实现
|
|
extension AgentServicePlugin: FlutterStreamHandler {
|
|
public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
|
self.eventSink = events
|
|
return nil
|
|
}
|
|
|
|
public func onCancel(withArguments arguments: Any?) -> FlutterError? {
|
|
self.eventSink = nil
|
|
return nil
|
|
}
|
|
}
|