From: liangzhenying <867174124@qq.com> Date: Thu, 13 Feb 2025 07:41:24 +0000 (+0800) Subject: 去掉发送等待 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=64bcb5552cf1089c27180e9bb939a051c2fc03c8;p=mirrors%2FIOTBluetooth-iOS.git 去掉发送等待 --- diff --git a/IOTBluetooth/IOTBluetooth/Example/ChatViewController.swift b/IOTBluetooth/IOTBluetooth/Example/ChatViewController.swift index a367ff1..40ccefe 100644 --- a/IOTBluetooth/IOTBluetooth/Example/ChatViewController.swift +++ b/IOTBluetooth/IOTBluetooth/Example/ChatViewController.swift @@ -26,12 +26,12 @@ class ChatViewController: UIViewController{ setupViews() setupChatCallBack() - //设置默认平台 - self.title = MSPlatform.doubao.title + } func setupViews(){ - self.title = "大模型对话" + //设置默认平台 + self.title = MSPlatform.doubao.title self.view.backgroundColor = .white self.navigationItem.rightBarButtonItems = [UIBarButtonItem(title: "切换平台", style: .done, target: self, action: #selector(changePlatform))] @@ -50,6 +50,10 @@ class ChatViewController: UIViewController{ } func setupChatCallBack(){ + IBAiManager.shared.useMode = { [weak self] mode in + guard let self = self else {return} + self.title = mode.title + } IBAiManager.shared.aiResponse = {[weak self] response in print(response.description) guard let self = self else {return} @@ -57,6 +61,7 @@ class ChatViewController: UIViewController{ if let model = list.last,model.reponseId == response.reponseId { list.removeLast() list.append(response) +// IBSpeaker.shared.appendText(response.totalContent) } else{ list.append(response) @@ -66,6 +71,9 @@ class ChatViewController: UIViewController{ tableView.scrollToRow(at: IndexPath(row: list.count - 1, section: 0), at: .none, animated: true) } } + if response.type == 4{ + IBSpeaker.shared.appendText(response.totalContent) + } } } diff --git a/IOTBluetooth/IOTBluetooth/Example/IBSpeaker.swift b/IOTBluetooth/IOTBluetooth/Example/IBSpeaker.swift new file mode 100644 index 0000000..a34681b --- /dev/null +++ b/IOTBluetooth/IOTBluetooth/Example/IBSpeaker.swift @@ -0,0 +1,85 @@ +// +// IBSpeaker.swift +// IOTBluetooth +// +// Created by liangshi on 2025/2/13. +// + +import AVFoundation + +class IBSpeaker: NSObject, AVSpeechSynthesizerDelegate { + static let shared = IBSpeaker() + // MARK: - Properties + private let synthesizer = AVSpeechSynthesizer() + private var textBuffer: String = "" // 用于存储待播放的文字 + private var isPlaying: Bool = false // 是否正在播放 + + // MARK: - Initializer + override init() { + super.init() + synthesizer.delegate = self + } + + // MARK: - Public Methods + + /// 添加文字并开始播放 + func appendText(_ text: String) { + textBuffer += text + + // 如果没有正在播放,则开始播放 + if !isPlaying { + playNextChunk() + } + } + + /// 停止播放并清空缓冲区 + func stop() { + synthesizer.stopSpeaking(at: .immediate) + textBuffer = "" + isPlaying = false + } + + // MARK: - Private Methods + + /// 播放缓冲区中的下一段文字 + private func playNextChunk() { + guard !textBuffer.isEmpty else { + isPlaying = false + return + } + + // 每次播放一段文字(可以根据需要调整) + let chunkSize = textBuffer.count // 每次播放的字符数 + let endIndex = textBuffer.index(textBuffer.startIndex, offsetBy: min(chunkSize, textBuffer.count)) + let chunk = String(textBuffer[.. - - - - - - diff --git a/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBAiManager.swift b/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBAiManager.swift index 9f0e16b..2c3417a 100644 --- a/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBAiManager.swift +++ b/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBAiManager.swift @@ -18,12 +18,26 @@ public class IBAiManager{ public var productKey:String = "" /// chatGptKey public var chatGptKey:String = "" + /// 使用大模型 + public var useMode:((_ result:MSPlatform) -> Void)? + /// 使用大模型 + public var aiResponse:((_ result:IBAiResponse) -> Void)? - public var aiResponse:((_ response:IBAiResponse) -> Void)? + var chatModeMap:[Int:MSPlatform] = [0:.yiyan, + 1:.chatGPT, + 2:.kimi, + 3:.doubao, + 4:.aliyun, + 5:.xunfei, + ] var responseId = "" var reply = "" + var isLogin:Bool{ + return MixSdk.shared.auth.authorized + } + init(){ MixSdk.shared.isDebug = true @@ -31,12 +45,17 @@ public class IBAiManager{ } func aiValid(_ data:Data){ + if !isLogin{ + Logger.log("ai未登录!!!") + login() + } + let result = IBGeneralParser.dataPacket(data) let code = result.int - let desc = ["文心一言","ChatGPT","KIMI","豆包","通义千问","讯飞星火"] - Logger.log("询问模型是否可用:",code >= desc.count ? "未知": desc[code]) + let platform = chatModeMap[code] ?? .doubao + useMode?(platform) let model = IBAiValid() - model.isValid = true + model.isValid = isLogin if code == 1 { model.key = chatGptKey } @@ -46,13 +65,10 @@ public class IBAiManager{ .response { result in } - } func aiRequest(_ data:Data){ let result = IBGeneralParser.dataPacket(data) let code = result.int - let desc = ["文心一言","ChatGPT","KIMI","豆包","通义千问","讯飞星火"] - Logger.log("使用模型:",code >= desc.count ? "未知": desc[code]) IBSender() .ability(IBAbility.aiReady) .parameters([.value(1)]) @@ -61,13 +77,9 @@ public class IBAiManager{ } - var platform = MSPlatform.doubao + let platform = chatModeMap[code] ?? .doubao var key = "" - if code == 0 { - platform = .yiyan - } - else if code == 1 { - platform = .chatGPT + if code == 1 { key = chatGptKey if chatGptKey.isEmpty { Logger.log("请先设置chatGpt Key!") @@ -75,19 +87,9 @@ public class IBAiManager{ // let gptModel = "gpt-4-turbo" // MixSdk.shared.chatGpt.changeModel(model:gptModel ) } - else if code == 2 { - platform = .kimi - } - else if code == 3 { - platform = .doubao - } - else if code == 4 { - platform = .aliyun - } - else if code == 5 { - platform = .xunfei - } + Logger.log("使用模型:",platform.title) MixSdk.shared.setPlatform(platform,key: key) + useMode?(platform) } func fectchAiAudio(){ IBSender() @@ -187,9 +189,13 @@ extension IBAiManager{ } } - - extension IBAiManager{ + func login(){ + let mac = IBBluetooth.shared.currentConnected.macAddress.split(separator: ":").joined().uppercased() + login(deviceId:mac ) { token, error in + + } + } /// 登录 /// - Parameters: /// - deviceId: 设备ID diff --git a/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBReceiveManager.swift b/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBReceiveManager.swift index a326f2a..0e6ef0a 100644 --- a/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBReceiveManager.swift +++ b/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBReceiveManager.swift @@ -5,74 +5,65 @@ // Created by incar on 2024/7/15. // -import Foundation import CoreBluetooth - +import Foundation @objc protocol IBReceiveManagerDelegate { - func receiveManagerDidReceiveFullData(characteristic: CBCharacteristic,_ data:Data) + func receiveManagerDidReceiveFullData( + characteristic: CBCharacteristic, _ data: Data) } -class IBReceiveManager{ - var delegate:IBReceiveManagerDelegate? +class IBReceiveManager { + var delegate: IBReceiveManagerDelegate? static let shared = IBReceiveManager() - + var headData = Data() var lastData = Data() var totalData = Data() - - - func receice(characteristic: CBCharacteristic){ - - + + func receice(characteristic: CBCharacteristic) { + guard let data = characteristic.value else { return } - if(data.count == 2 && data.int == 0){ -// Logger.log("收到0000指令异常") + if data.count == 2 && data.int == 0 { + // Logger.log("收到0000指令异常") return } - - if data.count >= 18,data[0] == 0x72{ + + if data.count >= 18, data[0] == 0x72 { let mark = characteristic.isNotifying ? "Notify Read" : "Read" let uuid = characteristic.uuid.uuidString let pkgTotal = data[3...6].int let dataTotal = data[7...10].int let pkgIndex = data[11...14].int let pkgLen = data[15...16].int - - Logger.log(mark, uuid, "->", "pkgTotal = \(pkgTotal),dataTotal = \(dataTotal),pkgIndex = \(pkgIndex),pkgLen = \(pkgLen)",data.joined(" ")) - -// if data[1] == 0x01,data[2] == 0x34{ -// //ai语音 - if pkgIndex == 1{ - headData = data.prefix(17) - lastData = data.suffix(1) - } - IBBluetooth.shared.deinitTimer() - IBBluetooth.shared.startTimer() - totalData = totalData + data.suffix(from: 17).prefix(pkgLen) - if pkgTotal == pkgIndex{ - Logger.log("total = \(dataTotal),receive = \(totalData.count)") - let fullData = headData + totalData + lastData - didGetFullData(characteristic: characteristic, data: fullData) - } -// } -// else{ -// didGetFullData(characteristic: characteristic, data: data) -// } - } - else{ - Logger.log( data.joined(" ")) + + Logger.log( + mark, uuid, "->", + "pkgTotal = \(pkgTotal),dataTotal = \(dataTotal),pkgIndex = \(pkgIndex),pkgLen = \(pkgLen)", + data.joined(" ")) + if pkgIndex == 1 { + headData = data.prefix(17) + lastData = data.suffix(1) + } + totalData = totalData + data.suffix(from: 17).prefix(pkgLen) + if pkgTotal == pkgIndex { + Logger.log("total = \(dataTotal),receive = \(totalData.count)") + let fullData = headData + totalData + lastData + didGetFullData(characteristic: characteristic, data: fullData) + } + } else { + Logger.log(data.joined(" ")) didGetFullData(characteristic: characteristic, data: data) } } - - func didGetFullData(characteristic: CBCharacteristic,data:Data){ -// Logger.log( data.joined(" ")) - - delegate?.receiveManagerDidReceiveFullData(characteristic: characteristic, data) + + func didGetFullData(characteristic: CBCharacteristic, data: Data) { + // Logger.log( data.joined(" ")) + delegate?.receiveManagerDidReceiveFullData( + characteristic: characteristic, data) totalData = Data() - - if characteristic.uuid.uuidString == readCharacteristicUUID { + + if characteristic.uuid.uuidString == readCharacteristicUUID { let info = IBWatchInfo(data) IBBluetooth.shared.currentConnected.battery = info.battery IBBluetooth.shared.currentConnected.macAddress = info.macAddress @@ -80,15 +71,17 @@ class IBReceiveManager{ IBBluetooth.shared.currentConnected.customerID = info.customerID sendDeviceInfo() } - + if IBNotify.handle(data) { -// Logger.log("通知消息") + Logger.log("通知消息") return } } - - func sendDeviceInfo(){ - let mac = UserDefaults.standard.object(forKey: "IOTBletooth.mac") as? [Int] ?? [] + + func sendDeviceInfo() { + let mac = + UserDefaults.standard.object(forKey: "IOTBletooth.mac") as? [Int] + ?? [] let model = IBPhoneInfo() model.mac = mac IBSender() @@ -96,23 +89,21 @@ class IBReceiveManager{ .parameters([.sendPhone(model)]) .response { result in Logger.log(result) - if result.code != .success{ + if result.code != .success { //通知连接失败 IBManager.completeHandler?(false) IBManager.completeHandler = nil return } - guard let value = result.value as? Int else {return} + guard let value = result.value as? Int else { return } if value == 2 { //通知连接成功 IBManager.completeHandler?(true) IBManager.completeHandler = nil - } - else if value == 1{ + } else if value == 1 { //等待手表同意连接 Logger.log("等待手表同意连接") - } - else if value == 3{ + } else if value == 3 { //手表已与其他手机绑定 IBManager.completeHandler?(false) IBManager.completeHandler = nil @@ -120,4 +111,3 @@ class IBReceiveManager{ } } } - diff --git a/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBSender.swift b/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBSender.swift index d498e98..dd7ec95 100644 --- a/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBSender.swift +++ b/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBSender.swift @@ -14,12 +14,31 @@ public typealias IBCompletionHandler = (_ result: IBResponse) -> Void public class IBSender { public init() { Self.all.append(self) + startTimer() } var ability: IBAbility! var parameters: [IBParameter] = [] var completion: IBCompletionHandler! + var timer: Timer? + func startTimer() { + deinitTimer() + + self.timer = Timer.scheduledTimer(withTimeInterval: 10.0, repeats: false, block: { [unowned self] _ in + deinitTimer() + self.completion?(.response.code(.timeout)) + self.remove() + }) + } + + func deinitTimer() { + guard let _ = self.timer else { return } + self.timer?.invalidate() + self.timer = nil + Logger.log("销毁定时器") + } + var dataPacket: [[UInt8]] { var totalData: [UInt8] = [] if isValue(ability.checker) { @@ -101,7 +120,7 @@ public class IBSender { } deinit { -// Logger.log("deinit IBSender") + Logger.log("deinit IBSender") } } @@ -135,6 +154,16 @@ extension IBSender { /// 从缓存实例集合中移除该实例 func remove() { + deinitTimer() Self.all.removeAll { $0 === self } } + + static func answer(_ data: Data) -> IBSender? { + for item in Self.all { + if item.isAnswer(data) { + return item + } + } + return nil + } } diff --git a/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBluetooth.swift b/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBluetooth.swift index 0fcd66f..de72d12 100644 --- a/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBluetooth.swift +++ b/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBluetooth.swift @@ -78,8 +78,8 @@ class IBBluetooth: NSObject { /// 当前连接设备 var currentConnected: IBPeripheral! - /// 最后消息发送实例 - private weak var lastSender: IBSender? +// /// 最后消息发送实例 +// private weak var lastSender: IBSender? /// 文件发送实例 internal weak var fileSender: IBFileSender? @@ -137,20 +137,6 @@ class IBBluetooth: NSObject { // Logger.log("手机未连上蓝牙设备!") // return // } - - if let _ = lastSender { - sender.completion(.response.code(.failure).message("有命令正在执行中...")) - sender.remove() - Logger.log("有命令正在执行中...") - if Self.timer == nil{ - startTimer() - } - return - } - - startTimer() - lastSender = sender - for dataPacket in sender.dataPacket { // Thread.sleep(forTimeInterval:0.02) @@ -226,13 +212,8 @@ extension IBBluetooth: CBCentralManagerDelegate { // IBNotify.post(.connectedDeviceDidChange) Logger.log("已连接", currentConnected.name) IBNotify.post(.connectStateDidChange, object: 1) - - IBAiManager.shared.login(deviceId: "28110687C456") { token, error in - - } -// IBAiManager.shared.login(deviceId: currentConnected.macAddress) { token, error in -// -// } + + IBAiManager.shared.login() } func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { @@ -246,12 +227,6 @@ extension IBBluetooth: CBCentralManagerDelegate { Logger.log("断开连接") deinitTimer() - if let sender = lastSender{ - lastSender = nil - sender.completion?(.response.code(.failure)) - sender.remove() - } - self.fileSender?.lastData?.fileWriteHander?(.response.code(.failure).message("蓝牙设备断开连接")) IBManager.completeHandler?(false) @@ -328,12 +303,12 @@ extension IBBluetooth: CBPeripheralDelegate { else{ Logger.log(characteristic.uuid.uuidString, "write success") } - if let sender = lastSender,sender.ability.type == .ai{ - lastSender = nil - sender.completion?(.response.code(.success)) - sender.remove() - return - } +// if let sender = lastSender,sender.ability.type == .ai{ +// lastSender = nil +// sender.completion?(.response.code(.success)) +// sender.remove() +// return +// } if let hander = self.fileSender?.lastData?.fileWriteHander{ hander(error == nil ? .response.code(.success):.response.code(.failure)) } @@ -342,9 +317,7 @@ extension IBBluetooth: CBPeripheralDelegate { extension IBBluetooth:IBReceiveManagerDelegate { func receiveManagerDidReceiveFullData(characteristic: CBCharacteristic,_ data: Data) { - if let sender = lastSender,sender.isAnswer(data) == true { - deinitTimer() - lastSender = nil + if let sender = IBSender.answer(data) { sender.completion?(sender.parse(data)) sender.remove() return @@ -360,23 +333,17 @@ extension IBBluetooth:IBReceiveManagerDelegate { extension IBBluetooth { static var timer: Timer? - func startTimer() { + private func startTimer() { deinitTimer() Self.timer = Timer.scheduledTimer(withTimeInterval: 10.0, repeats: false, block: { [unowned self] _ in deinitTimer() - if let sender = lastSender{ - lastSender = nil - sender.completion?(.response.code(.timeout)) - sender.remove() - } - self.fileSender?.lastData?.fileWriteHander?(.response.code(.timeout)) }) // Logger.log("创建定时器") } - func deinitTimer() { + private func deinitTimer() { guard let _ = Self.timer else { return } Self.timer?.invalidate() Self.timer = nil