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.

500 lines
16 KiB

import Flutter
import UIKit
@main
@objc class AppDelegate: FlutterAppDelegate {
private var classicBluetoothHelper: ClassicBluetoothHelper?
private var mediaButtonHelper: Any?
// 添加Azure语音服务辅助类
private var azureAsrHelper: Any?
private var azureTtsHelper: Any?
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// 初始化蓝牙辅助类
classicBluetoothHelper = ClassicBluetoothHelper()
// 立即初始化蓝牙,不要等待Flutter调用
classicBluetoothHelper?.initBluetooth()
// 仅在iOS 13.0及以上版本初始化媒体按钮辅助类和Azure语音服务辅助类
if #available(iOS 13.0, *) {
mediaButtonHelper = BluetoothMediaButtonHelper()
// 稍后在方法通道注册时初始化Azure语音服务辅助类
}
// 建立Flutter方法通道
registerMethodChannel()
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
private func registerMethodChannel() {
let controller = window?.rootViewController as? FlutterViewController
guard let controller = controller else {
NSLog("AppDelegate: FlutterViewController 不可用")
return
}
// 注册经典蓝牙通道
let classicChannel = FlutterMethodChannel(
name: "com.deep_voice.classic_bluetooth",
binaryMessenger: controller.binaryMessenger
)
classicChannel.setMethodCallHandler { [weak self] (call, result) in
guard let self = self else {
result(FlutterError(code: "UNAVAILABLE", message: "AppDelegate实例不可用", details: nil))
return
}
switch call.method {
case "isBluetoothEnabled":
result(self.classicBluetoothHelper?.isBluetoothEnabled() ?? false)
case "getConnectedHeadsetDevices":
// 获取已连接的耳机设备
self.classicBluetoothHelper?.getConnectedHeadsetDevices { devices, error in
if let error = error {
result(FlutterError(code: "GET_DEVICES_FAILED", message: error, details: nil))
} else {
result(devices)
}
}
case "startBluetoothDeviceMonitoring":
// 启动蓝牙设备监控
self.classicBluetoothHelper?.initBluetooth()
result(true)
default:
result(FlutterMethodNotImplemented)
}
}
// 注册蓝牙事件通道
let classicEventChannel = FlutterEventChannel(
name: "com.deep_voice.classic_bluetooth_events",
binaryMessenger: controller.binaryMessenger
)
// 创建事件处理器
let bluetoothEventHandler = BluetoothStreamHandler(bluetoothHelper: self.classicBluetoothHelper!)
classicEventChannel.setStreamHandler(bluetoothEventHandler)
// 仅在iOS 13.0及以上版本注册媒体按钮通道和Azure语音服务通道
if #available(iOS 13.0, *) {
// 注册媒体按钮方法通道
registerMediaButtonChannels(controller: controller)
// 注册Azure ASR方法通道
registerAzureAsrChannels(controller: controller)
// 注册Azure TTS方法通道
registerAzureTtsChannels(controller: controller)
}
}
// 注册媒体按钮通道
@available(iOS 13.0, *)
private func registerMediaButtonChannels(controller: FlutterViewController) {
guard let mediaButtonHelper = mediaButtonHelper as? BluetoothMediaButtonHelper else {
return
}
// 注册媒体按钮方法通道
let mediaButtonChannel = FlutterMethodChannel(
name: "com.deep_voice.bluetooth_media_button",
binaryMessenger: controller.binaryMessenger
)
mediaButtonChannel.setMethodCallHandler { [weak self, weak mediaButtonHelper] (call, result) in
guard let _ = self, let mediaButtonHelper = mediaButtonHelper else {
result(FlutterError(code: "UNAVAILABLE", message: "媒体按钮辅助实例不可用", details: nil))
return
}
switch call.method {
case "startButtonListening":
let success = mediaButtonHelper.startButtonListening()
result(success)
case "stopButtonListening":
let success = mediaButtonHelper.stopButtonListening()
result(success)
default:
result(FlutterMethodNotImplemented)
}
}
// 注册媒体按钮事件通道
let mediaButtonEventChannel = FlutterEventChannel(
name: "com.deep_voice.bluetooth_media_button_events",
binaryMessenger: controller.binaryMessenger
)
// 创建媒体按钮事件处理器
let mediaButtonEventHandler = MediaButtonStreamHandler(mediaButtonHelper: mediaButtonHelper)
mediaButtonEventChannel.setStreamHandler(mediaButtonEventHandler)
}
// 注册Azure ASR通道
@available(iOS 13.0, *)
private func registerAzureAsrChannels(controller: FlutterViewController) {
// 注册Azure ASR方法通道
let azureAsrChannel = FlutterMethodChannel(
name: "com.deep_voice.azure_asr",
binaryMessenger: controller.binaryMessenger
)
// 初始化Azure ASR辅助类
azureAsrHelper = AzureAsrHelper { [weak self] eventName, eventData in
// 推送事件到Flutter
self?.sendAsrEvent(eventName: eventName, eventData: eventData)
}
// 设置ASR方法处理器
azureAsrChannel.setMethodCallHandler { [weak self] (call, result) in
guard let self = self,
let asrHelper = self.azureAsrHelper as? AzureAsrHelper else {
result(FlutterError(code: "UNAVAILABLE", message: "Azure ASR辅助实例不可用", details: nil))
return
}
switch call.method {
case "initialize":
guard let args = call.arguments as? [String: Any],
let key = args["subscriptionKey"] as? String,
let region = args["region"] as? String else {
result(FlutterError(code: "INVALID_ARGS", message: "初始化参数无效", details: nil))
return
}
let languages = args["supportedLanguages"] as? [String]
let success = asrHelper.initialize(speechSubscriptionKey: key, serviceRegion: region, supportedLanguages: languages)
result(success)
case "recognizeOnce":
let success = asrHelper.recognizeOnce()
result(success)
case "startContinuousRecognition":
let success = asrHelper.startContinuousRecognition()
result(success)
case "stopContinuousRecognition":
let success = asrHelper.stopContinuousRecognition()
result(success)
case "isContinuousRecognitionActive":
let isActive = asrHelper.isContinuousRecognitionActive()
result(isActive)
case "dispose":
asrHelper.dispose()
result(true)
default:
result(FlutterMethodNotImplemented)
}
}
// 注册Azure ASR事件通道
let azureAsrEventChannel = FlutterEventChannel(
name: "com.deep_voice.azure_asr_events",
binaryMessenger: controller.binaryMessenger
)
// 创建ASR事件处理器
let asrStreamHandler = AsrStreamHandler()
azureAsrEventChannel.setStreamHandler(asrStreamHandler)
}
// 注册Azure TTS通道
@available(iOS 13.0, *)
private func registerAzureTtsChannels(controller: FlutterViewController) {
// 注册Azure TTS方法通道
let azureTtsChannel = FlutterMethodChannel(
name: "com.deep_voice.azure_tts",
binaryMessenger: controller.binaryMessenger
)
// 初始化Azure TTS辅助类
azureTtsHelper = AzureTtsHelper { [weak self] eventName, eventData in
// 推送事件到Flutter
self?.sendTtsEvent(eventName: eventName, eventData: eventData)
}
// 设置TTS方法处理器
azureTtsChannel.setMethodCallHandler { [weak self] (call, result) in
guard let self = self,
let ttsHelper = self.azureTtsHelper as? AzureTtsHelper else {
result(FlutterError(code: "UNAVAILABLE", message: "Azure TTS辅助实例不可用", details: nil))
return
}
switch call.method {
case "initialize":
guard let args = call.arguments as? [String: Any],
let key = args["subscriptionKey"] as? String,
let region = args["region"] as? String else {
result(FlutterError(code: "INVALID_ARGS", message: "初始化参数无效", details: nil))
return
}
let language = args["language"] as? String ?? "zh-CN"
let success = ttsHelper.initialize(speechSubscriptionKey: key, serviceRegion: region, language: language)
result(success)
case "setVoice":
guard let args = call.arguments as? [String: Any],
let voiceName = args["voiceName"] as? String else {
result(FlutterError(code: "INVALID_ARGS", message: "语音名称参数无效", details: nil))
return
}
let success = ttsHelper.setVoice(voiceName: voiceName)
result(success)
case "setSpeechParams":
guard let args = call.arguments as? [String: Any] else {
result(FlutterError(code: "INVALID_ARGS", message: "语音参数无效", details: nil))
return
}
let rate = args["rate"] as? Int ?? 0
let pitch = args["pitch"] as? Int ?? 0
let volume = args["volume"] as? Int ?? 100
let success = ttsHelper.setSpeechParams(rate: rate, pitch: pitch, volume: volume)
result(success)
case "speakText":
guard let args = call.arguments as? [String: Any],
let text = args["text"] as? String else {
result(FlutterError(code: "INVALID_ARGS", message: "文本参数无效", details: nil))
return
}
let success = ttsHelper.speakText(text: text)
result(success)
case "stopSpeaking":
let success = ttsHelper.stopSpeaking()
result(success)
case "isSpeaking":
let isSpeaking = ttsHelper.isSpeaking()
result(isSpeaking)
case "dispose":
ttsHelper.dispose()
result(true)
default:
result(FlutterMethodNotImplemented)
}
}
// 注册Azure TTS事件通道
let azureTtsEventChannel = FlutterEventChannel(
name: "com.deep_voice.azure_tts_events",
binaryMessenger: controller.binaryMessenger
)
// 创建TTS事件处理器
let ttsStreamHandler = TtsStreamHandler()
azureTtsEventChannel.setStreamHandler(ttsStreamHandler)
}
// 存储ASR事件
private var _cachedAsrEvent: [String: Any]?
// 发送ASR事件
@available(iOS 13.0, *)
private func sendAsrEvent(eventName: String, eventData: [String: Any]) {
// 调整格式:将event改为type,并将data的内容提升到顶层
var eventMap = eventData
eventMap["type"] = eventName
_cachedAsrEvent = eventMap
NotificationCenter.default.post(
name: Notification.Name("AzureAsrEvent"),
object: nil,
userInfo: eventMap
)
}
// 存储TTS事件
private var _cachedTtsEvent: [String: Any]?
// 发送TTS事件
@available(iOS 13.0, *)
private func sendTtsEvent(eventName: String, eventData: [String: Any]) {
// 调整格式:将event改为type,并将data的内容提升到顶层
var eventMap = eventData
eventMap["type"] = eventName
_cachedTtsEvent = eventMap
NotificationCenter.default.post(
name: Notification.Name("AzureTtsEvent"),
object: nil,
userInfo: eventMap
)
}
}
// 蓝牙事件流处理器
class BluetoothStreamHandler: NSObject, FlutterStreamHandler, BluetoothEventHandler {
private let bluetoothHelper: ClassicBluetoothHelper
private var eventSink: FlutterEventSink?
init(bluetoothHelper: ClassicBluetoothHelper) {
self.bluetoothHelper = bluetoothHelper
super.init()
// 设置事件处理器
bluetoothHelper.setEventHandler(self)
}
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
NSLog("BluetoothStreamHandler: 开始监听蓝牙事件")
self.eventSink = events
return nil
}
func onCancel(withArguments arguments: Any?) -> FlutterError? {
NSLog("BluetoothStreamHandler: 取消监听蓝牙事件")
eventSink = nil
return nil
}
// 实现BluetoothEventHandler协议
func sendEvent(_ event: [String: Any]) {
NSLog("BluetoothStreamHandler: 接收到蓝牙事件: \(event)")
DispatchQueue.main.async { [weak self] in
self?.eventSink?(event)
}
}
}
// 媒体按钮事件流处理器
@available(iOS 13.0, *)
class MediaButtonStreamHandler: NSObject, FlutterStreamHandler, MediaButtonEventHandler {
private let mediaButtonHelper: BluetoothMediaButtonHelper
private var eventSink: FlutterEventSink?
init(mediaButtonHelper: BluetoothMediaButtonHelper) {
self.mediaButtonHelper = mediaButtonHelper
super.init()
// 设置事件处理器
mediaButtonHelper.setEventHandler(self)
}
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
NSLog("MediaButtonStreamHandler: 开始监听媒体按钮事件")
self.eventSink = events
return nil
}
func onCancel(withArguments arguments: Any?) -> FlutterError? {
NSLog("MediaButtonStreamHandler: 取消监听媒体按钮事件")
eventSink = nil
return nil
}
// 实现MediaButtonEventHandler协议
func sendEvent(_ event: [String: Any]) {
NSLog("MediaButtonStreamHandler: 收到按钮事件 \(event)")
DispatchQueue.main.async { [weak self] in
self?.eventSink?(event)
}
}
}
// ASR事件流处理器
@available(iOS 13.0, *)
class AsrStreamHandler: NSObject, FlutterStreamHandler {
private var eventSink: FlutterEventSink?
private var notificationObserver: Any?
deinit {
if let observer = notificationObserver {
NotificationCenter.default.removeObserver(observer)
}
}
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
self.eventSink = events
// 注册通知观察者
notificationObserver = NotificationCenter.default.addObserver(
forName: Notification.Name("AzureAsrEvent"),
object: nil,
queue: .main) { [weak self] notification in
if let userInfo = notification.userInfo as? [String: Any] {
self?.eventSink?(userInfo)
}
}
return nil
}
func onCancel(withArguments arguments: Any?) -> FlutterError? {
eventSink = nil
// 移除通知观察者
if let observer = notificationObserver {
NotificationCenter.default.removeObserver(observer)
notificationObserver = nil
}
return nil
}
}
// TTS事件流处理器
@available(iOS 13.0, *)
class TtsStreamHandler: NSObject, FlutterStreamHandler {
private var eventSink: FlutterEventSink?
private var notificationObserver: Any?
deinit {
if let observer = notificationObserver {
NotificationCenter.default.removeObserver(observer)
}
}
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
self.eventSink = events
// 注册通知观察者
notificationObserver = NotificationCenter.default.addObserver(
forName: Notification.Name("AzureTtsEvent"),
object: nil,
queue: .main) { [weak self] notification in
if let userInfo = notification.userInfo as? [String: Any] {
self?.eventSink?(userInfo)
}
}
return nil
}
func onCancel(withArguments arguments: Any?) -> FlutterError? {
eventSink = nil
// 移除通知观察者
if let observer = notificationObserver {
NotificationCenter.default.removeObserver(observer)
notificationObserver = nil
}
return nil
}
}