Open xianengqi opened 1 year ago
遇到的问题是,文件大小只有300kb,使用蓝牙传输到此IOT设备时,传输速度只有7kb/s ,MTU值我设置的是500字节,优化了好几天了传输速率始终上不来。 这是我的完整代码
import CoreBluetooth import SwiftUI struct ContentView: View { @State private var fileURL: URL? = nil @State private var status: String = "Not Connected" @StateObject private var bluetoothManager = BluetoothManager() var transferRateText: String { let transferRateKB = bluetoothManager.transferRate / 1024 if transferRateKB < 1024 { return String(format: "%.2f KB/s", transferRateKB) } else { let transferRateMB = transferRateKB / 1024 return String(format: "%.2f MB/s", transferRateMB) } } var body: some View { VStack { Button("Select File") { // TODO: Select file selectFile() } .padding() Text("Status: \(bluetoothManager.status)") .padding() Text("Transfer Rate: \(transferRateText)") .padding() Text("Total Time: \(bluetoothManager.totalTime, specifier: "%.2f") seconds") .padding() List(bluetoothManager.discoveredDevices, id: \.identifier) { device in HStack { Text(device.name ?? "Unknown") Spacer() Button("Connect") { bluetoothManager.connectToDevice(device) } } } } } private func selectFile() { bluetoothManager.presentFilePicker() } } #Preview { ContentView() } class BluetoothManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeripheralDelegate { private var centralManager: CBCentralManager! private var peripheral: CBPeripheral? public var fileTransferCharacteristic: CBCharacteristic? @Published var status: String = "Not Connected" @Published var discoveredDevices: [CBPeripheral] = [] private var startTime: Date? private var endTime: Date? var fileData: Data! @Published var transferRate: Double = 0.0 @Published var totalTime: Double = 0.0 private var connectionParameters: [String: Any]? override init() { super.init() centralManager = CBCentralManager(delegate: self, queue: nil) } func centralManagerDidUpdateState(_ central: CBCentralManager) { if central.state == .poweredOn { centralManager.scanForPeripherals(withServices: nil, options: nil) } } // TODO: Implement other delegate methods func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) { if !discoveredDevices.contains(where: { $0.identifier == peripheral.identifier }) { discoveredDevices.append(peripheral) } } func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { print("Connected to peripheral: \(peripheral.name ?? "Unknown")") status = "Connected to \(peripheral.name ?? "Unknown")" peripheral.delegate = self peripheral.discoverServices(nil) } func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { if let error = error { print("Error discovering services: \(error)") return } for service in peripheral.services ?? [] { print("Discovered service: \(service.uuid)") peripheral.discoverCharacteristics(nil, for: service) } } func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { if let error = error { print("Error discovering characteristics: \(error)") return } for characteristic in service.characteristics ?? [] { print("Discovered characteristic: \(characteristic.uuid)") if characteristic.uuid == CBUUID(string: "0000ff01-0000-1000-8000-00805f9b34fb") { // Replace with your characteristic UUID fileTransferCharacteristic = characteristic // Check MTU size let mtu = peripheral.maximumWriteValueLength(for: .withResponse) print("MTU size: \(mtu) bytes") } } } public func sendFileData(_ data: Data, to characteristic: CBCharacteristic?) { guard let characteristic = characteristic else { return } // let mtu = 500 let mtu = peripheral!.maximumWriteValueLength(for: .withResponse) var offset = 0 DispatchQueue.global(qos: .background).async { // Move to a background thread self.startTime = Date() // Record the start time let writeType: CBCharacteristicWriteType = characteristic.properties.contains(.writeWithoutResponse) ? .withoutResponse : .withResponse while offset < data.count { let chunkSize = min(mtu, data.count - offset) let chunk = data.subdata(in: offset ..< offset + chunkSize) self.peripheral?.writeValue(chunk, for: characteristic, type: writeType) offset += chunkSize } } } func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) { if let error = error { print("Error writing value: \(error)") status = "Error: \(error)" return } print("Successfully wrote value for characteristic: \(characteristic.uuid)") endTime = Date() // Record the end time if let startTime = startTime, let endTime = endTime { let elapsedTime = endTime.timeIntervalSince(startTime) let fileSize = Double(fileData.count) let transferRateValue = fileSize / elapsedTime // bytes per second print("File transferred successfully") print("Transfer Rate: \(transferRateValue) B/s") print("Total Time: \(elapsedTime) seconds") // Update the published variables transferRate = transferRateValue totalTime = elapsedTime } } func presentFilePicker() { let filePicker = UIDocumentPickerViewController(documentTypes: ["public.data"], in: .import) filePicker.delegate = self UIApplication.shared.windows.first?.rootViewController?.present(filePicker, animated: true, completion: nil) } func connectToDevice(_ device: CBPeripheral) { peripheral = device peripheral?.delegate = self centralManager.connect(peripheral!, options: nil) } } extension BluetoothManager: UIDocumentPickerDelegate { func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { guard let url = urls.first else { return } // Create a temporary directory for the file let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent(url.lastPathComponent) do { // Check if file exists at temporary directory if FileManager.default.fileExists(atPath: tempURL.path) { // Remove the file if it exists try FileManager.default.removeItem(at: tempURL) } // Copy the file to the temporary directory try FileManager.default.copyItem(at: url, to: tempURL) // Read the file data // let fileData = try Data(contentsOf: tempURL) fileData = try Data(contentsOf: tempURL) // Send the file data sendFileData(fileData, to: fileTransferCharacteristic) } catch { print("Error reading file data: \(error)") status = "Error: \(error.localizedDescription)" } } }
遇到的问题是,文件大小只有300kb,使用蓝牙传输到此IOT设备时,传输速度只有7kb/s ,MTU值我设置的是500字节,优化了好几天了传输速率始终上不来。 这是我的完整代码