我正在创建一个iOS应用程序,该应用程序现在应该在两个iOS设备之间传输文本消息。 我想要/必须使用Core Bluetooth。一种设备成为外围设备,另一种成为中心设备。
使用一种服务包含两种特征(读1读1写)的外设设置没有问题。我使用LightBlue App连接到外围设备,我也可以看到其特性。
当我使用中央角色设备时,我会找到外围设备,可以连接并查看其特性。我将外围设备和特征都存储在自己的变量中,以后使用它们调用存储的外围设备的 writeValue(_ data:Data,用于特征:CBCharacteristic,类型:CBCharacteristicWriteType),不会抛出任何错误。 但是外围设备似乎未收到该消息,因为未调用其 didWriteValueFor 或 didUpdateValueFor 方法。中央也不能订阅这些特征。
此外,当我使用外围设备更新其自身特性的值时,我对LightBlue App的检查也不成功,因为该值始终保持为空,并且中央设备当然也不会得到通知。
该应用程序发出的所有内容似乎都无法正常运行。似乎只有传入的数据(例如来自LightBlue App的数据)起作用。
有人遇到过类似的问题吗?我使用了许多不同的教程,并且完全按照那里的描述进行操作(因为到处都是相同的过程)。
谢谢!
我使用XCode版本10.1,在Swift中进行编码,并使用iPhone XS Max(iOS 12.1)和iPad Air 2(iOS 12.0)进行测试。
这是我的外围课程:
validation_steps
这是我的中心班级:
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) }
}
}
答案 0 :(得分:0)
我发现中央部分出了什么问题
发现后,我将外围设备及其特征存储在两个变量/元组中(writeTransferPeripheral和readTransferPeripheral)。我这样做是错误的:
self.writeTransferPeripheral?.peripheral = peripheral
self.writeTransferPeripheral?.characteristic = char
这样,以后使用变量写入值时,该变量仍为零。 似乎您应该像这样设置元组的值:
self.writeTransferPeripheral = (peripheral, char)