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
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)
|
|
}
|
|
}
|
|
}
|
|
}
|