gpt4 book ai didi

iOS Core蓝牙无法通过特性传输数据

转载 作者:行者123 更新时间:2023-11-30 10:58:41 28 4
gpt4 key购买 nike

我正在创建一个 iOS 应用程序,目前应该在两个 iOS 设备之间传输短信。我想/必须为此使用核心蓝牙。一台设备正在成为外围设备,而另一台设备则成为中央设备。

使用包含两个特性(1 个读取、1 个写入)的一项服务设置外设是没有问题的。我使用LightBlue App连接外设,也可以看到它的特点。

当我使用中央角色设备时,我找到外围设备,可以连接并查看其特性。我将外设和特征都存储在自己的变量中,并在稍后使用它们来调用存储的外设的 writeValue(_ data: Data, forcharacteristic: CBCharacteristic, type: CBCharacteristicWriteType) ,这不会引发任何错误。但外围设备似乎没有收到该消息,因为没有调用其 didWriteValueFordidUpdateValueFor 方法。中央也不能订阅这些特性。

此外,当我使用外围设备更新其自身特征的值时,我与 LightBlue 应用程序的检查不成功,因为该值始终保持为空,并且中央设备当然也不会收到通知。

看起来应用程序中的所有内容都不起作用。只有传入的数据(例如来自 LightBlue 应用程序)似乎有效。

有人遇到过类似的问题吗?我使用了许多不同的教程,并且完全按照其中所描述的进行操作(因为到处都是几乎相同的过程)。

提前致谢!

<小时/>

我使用 XCode 版本 10.1,使用 Swift 进行编码,并使用 iPhone XS Max (iOS 12.1) 和 iPad Air 2 (iOS 12.0) 进行测试。

<小时/>

这是我的外围设备类:

import CoreBluetooth
import UIKit

class BLEPeripheralManager: NSObject {

//MARK:- Properties

static let shared = BLEPeripheralManager()

//just some delegates for other classes
var peripheralDataReceiver: PeripheralDataReceiver?
var peripheralChatDataReceiver: PeripheralChatDataReceiver?

var peripheralManager: CBPeripheralManager

var subscribedCentrals: [CBCentral] = []

var readCharacteristic: CBMutableCharacteristic = {
let uuidStringChar1 = UUIDs.characteristicUUID1
let uuidChar1 = CBUUID(string: uuidStringChar1)
let char = CBMutableCharacteristic(type: uuidChar1, properties: .read, value: nil, permissions: .readable)
return char
}()
var writeCharacteristic: CBMutableCharacteristic = {
let uuidStringChar2 = UUIDs.characteristicUUID2
let uuidChar2 = CBUUID(string: uuidStringChar2)
let char = CBMutableCharacteristic(type: uuidChar2, properties: .write, value: nil, permissions: .writeable)
return char
}()


//MARK:- Private Methods

private override init() {
self.peripheralManager = CBPeripheralManager(delegate: nil, queue: nil)
super.init()
self.peripheralManager.delegate = self
}

private func setupManager() {
let uuidStringServ = UUIDs.serviceUUID
let uuidServ = CBUUID(string: uuidStringServ)

let transferService = CBMutableService(type: uuidServ, primary: true)
transferService.characteristics = [self.readCharacteristic, self.writeCharacteristic]

self.peripheralManager.add(transferService)
}

private func teardownServices() {
self.peripheralManager.removeAllServices()
}

private func clearSubscribers() {
self.subscribedCentrals.removeAll()
}

//MARK:- Public Methods

public func sendMessage(fromPeripheral peripheral: String, text: String) {
if text.isEmpty { return }
let chatMessage = ChatMsg(messageText: text, fromDevice: peripheral)
let encoder = JSONEncoder()
do {
let data = try encoder.encode(chatMessage)
print(self.readCharacteristic.uuid)
if self.peripheralManager.updateValue(data, for: self.readCharacteristic, onSubscribedCentrals: nil) == false {
print("Update from Peripheral failed (ReadCharacteristic)")
} else {
print("Message sent (ReadCharacteristic)")
}
if self.peripheralManager.updateValue(data, for: self.writeCharacteristic, onSubscribedCentrals: nil) == false {
print("Update from Peripheral failed (WriteCharacteristic)")
} else {
print("Message sent (WriteCharacteristic)")
}
} catch {
print("Error in encoding data")
}
}

func startAdvertising() {
let services = [CBUUID(string: UUIDs.serviceUUID)]
let advertisingDict = [CBAdvertisementDataServiceUUIDsKey: services]

self.peripheralManager.startAdvertising(advertisingDict)
}

public func stopAdvertising() {
self.peripheralManager.stopAdvertising()
}

public func checkIfAdvertising() -> Bool {
return self.peripheralManager.isAdvertising
}
}


extension BLEPeripheralManager: CBPeripheralManagerDelegate {

func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
switch peripheral.state {
case .poweredOff:
print("Peripheral powered off")
self.teardownServices()
self.clearSubscribers()
case .poweredOn:
print("Peripheral powered on")
self.setupManager()
case .resetting:
print("Peripheral resetting")
case .unauthorized:
print("Unauthorized Peripheral")
case .unknown:
print("Unknown Peripheral")
case .unsupported:
print("Unsupported Peripheral")
}
}

//doesn`t get called
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {
for request in requests {
if let value = request.value {
if let messageText = String(data: value, encoding: String.Encoding.utf8) {
//
}
}
}
}

//doesn`t get called
func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) {
var shouldAdd: Bool = true
for sub in self.subscribedCentrals {
if sub == central {
shouldAdd = false
}
}
if shouldAdd { self.subscribedCentrals.append(central) }
}

}

这是我的中心类(class):

import CoreBluetooth
import UIKit


class BLECentralManager: NSObject {

static let shared = BLECentralManager()

//just some delegates for other classes
var centralDataReceiver: CentralDataReceiver?
var centralChatDataReceiver: CentralChatDataReceiver?

var centralManager: CBCentralManager

var peripheralArray: [CBPeripheral] = []

var writeTransferPeripheral: (peripheral: CBPeripheral, characteristic: CBCharacteristic)?
var readTransferPeripheral: (peripheral: CBPeripheral, characteristic: CBCharacteristic)?

private override init() {
self.centralManager = CBCentralManager(delegate: nil, queue: nil, options: nil)
super.init()
self.centralManager.delegate = self
}

private func startScan() {
self.centralManager.scanForPeripherals(withServices: [CBUUID(string: UUIDs.serviceUUID)], options: nil)
//self.centralManager.scanForPeripherals(withServices: nil, options: nil)
}

public func connectTo(index: Int) {
self.centralManager.connect(self.peripheralArray[index], options: nil)
}

public func sendMessage(fromPeripheral peripheral: String, text: String) {
let chatMsg = ChatMsg(messageText: text, fromDevice: peripheral)
let encoder = JSONEncoder()

do {
let data = try encoder.encode(chatMsg)
self.writeTransferPeripheral?.peripheral.writeValue(data, for: (self.writeTransferPeripheral?.characteristic)!, type: .withoutResponse)
} catch {
print("Error in encoding data")
}
}

public func getActiveConnections() -> String {
var connString: String = ""
let conns = self.centralManager.retrieveConnectedPeripherals(withServices: [CBUUID(string: UUIDs.serviceUUID)])
for peri in conns {
if connString == "" {
connString = "\(peri)"
} else {
connString = "\(connString), \(peri)"
}
}
return connString
}

public func getMessages() {
self.readTransferPeripheral?.peripheral.readValue(for: (self.readTransferPeripheral?.characteristic)!)
}

public func lookForPeripherals() {
self.peripheralArray.removeAll()
self.startScan()
}

public func getPeripherals() -> [CBPeripheral] {
return self.peripheralArray
}

private func getNameOfPeripheral(peripheral: CBPeripheral) -> String {
if let name = peripheral.name {
return name
} else {
return "Device"
}
}
}


extension BLECentralManager: CBCentralManagerDelegate, CBPeripheralDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .poweredOff:
print("BLE has powered off")
centralManager.stopScan()
case .poweredOn:
print("BLE is now powered on")
self.startScan()
case .resetting:
print("BLE is resetting")
case .unauthorized:
print("Unauthorized BLE state")
case .unknown:
print("Unknown BLE state")
case .unsupported:
print("This platform does not support BLE")
}
}

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
self.peripheralArray.append(peripheral)
}

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
self.centralDataReceiver?.connectionEstablished(peripheral: peripheral)
print("Connection Established")
peripheral.delegate = self
peripheral.discoverServices(nil)
}

func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
self.centralDataReceiver?.connectionTornDown()
}

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
for service in peripheral.services! {
peripheral.discoverCharacteristics(nil, for: service)
}
}

func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
for characteristic in service.characteristics! {
print(characteristic.uuid)
let char = characteristic as CBCharacteristic
if char.uuid.uuidString == UUIDs.characteristicUUID2 {
self.writeTransferPeripheral?.peripheral = peripheral
self.writeTransferPeripheral?.characteristic = char
self.writeTransferPeripheral?.peripheral.setNotifyValue(true, for: (self.writeTransferPeripheral?.characteristic)!)
} else if char.uuid.uuidString == UUIDs.characteristicUUID1 {
self.readTransferPeripheral?.peripheral = peripheral
self.readTransferPeripheral?.characteristic = char
self.readTransferPeripheral?.peripheral.setNotifyValue(true, for: (self.readTransferPeripheral?.characteristic)!)
}
}
}

//doesn`t get called
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
if let data = characteristic.value {
if data.isEmpty { return }
if let text = String(data: characteristic.value!, encoding: String.Encoding.utf8) {
self.centralChatDataReceiver?.receiveMessage(fromPeripheral: self.getNameOfPeripheral(peripheral: peripheral), text: text)
}
}
}

//doesn`t get called
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if let data = characteristic.value {
if data.isEmpty { return }
if let text = String(data: characteristic.value!, encoding: String.Encoding.utf8) {
self.centralChatDataReceiver?.receiveMessage(fromPeripheral: self.getNameOfPeripheral(peripheral: peripheral), text: text)
}
}
}

//doesn`t get called
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
print("Notification state changed")
}

}

最佳答案

我发现中央出了什么问题:

发现后,我将外围设备及其特征存储在两个变量/元组中(writeTransferPeripheral 和 readTransferPeripheral)。我这样做是错误的:

self.writeTransferPeripheral?.peripheral = peripheral
self.writeTransferPeripheral?.characteristic = char

这样以后使用变量写入值时变量仍然是nil。似乎您应该像这样设置元组的值:

self.writeTransferPeripheral = (peripheral, char)

关于iOS Core蓝牙无法通过特性传输数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53654864/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com