如何解决watchOS可以单独连接到BLE设备吗?
我为Arduino制作了一个蓝牙温度计。 我想通过将温度连接到我的Apple Watch 5来显示温度。 我可以使用Apple Watch自行制作应用程序吗? 它正在搜索我的设备。 但无法连接。
TransferService.swift
import Foundation
import CoreBluetooth
struct TransferService {
static let serviceUUID = CBUUID(string: "6e400001-b5a3-f393-e0a9-e50e24dcca9e")
static let characteristicUUID = CBUUID(string: "6e400003-b5a3-f393-e0a9-e50e24dcca9e")
}
interfaceController.swift
import WatchKit
import Foundation
import CoreBluetooth
class InterfaceController: WKInterfaceController {
@IBOutlet weak var bleLabel: WKInterfaceLabel!
var centralManager: CBCentralManager!
var discoveredPeripheral: CBPeripheral?
var transferCharacteristic: CBCharacteristic?
var writeIterationsComplete = 0
var connectionIterationsComplete = 0
let defaultIterations = 5 // change this value based on test usecase
var data = Data()
override func awake(withContext context: Any?) {
print("awake()")
// Configure interface objects here.
centralManager = CBCentralManager(delegate: self,queue: nil,options: [CBCentralManagerOptionShowPowerAlertKey: true])
}
private func retrievePeripheral() {
let connectedPeripherals: [CBPeripheral] = (centralManager.retrieveConnectedPeripherals(withServices: [TransferService.serviceUUID]))
print("Found connected Peripherals with transfer service: %@",connectedPeripherals)
if let connectedPeripheral = connectedPeripherals.last {
print("Connecting to peripheral %@",connectedPeripheral)
self.discoveredPeripheral = connectedPeripheral
centralManager.connect(connectedPeripheral,options: nil)
} else {
// We were not connected to our counterpart,so start scanning
centralManager.scanForPeripherals(withServices: [TransferService.serviceUUID],options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
}
}
private func cleanup() {
// Don't do anything if we're not connected
guard let discoveredPeripheral = discoveredPeripheral,case .connected = discoveredPeripheral.state else { return }
for service in (discoveredPeripheral.services ?? [] as [CBService]) {
for characteristic in (service.characteristics ?? [] as [CBCharacteristic]) {
if characteristic.uuid == TransferService.characteristicUUID && characteristic.isNotifying {
// It is notifying,so unsubscribe
self.discoveredPeripheral?.setNotifyValue(false,for: characteristic)
}
}
}
// If we've gotten this far,we're connected,but we're not subscribed,so we just disconnect
centralManager.cancelPeripheralConnection(discoveredPeripheral)
}
private func writeData() {
guard let discoveredPeripheral = discoveredPeripheral,let transferCharacteristic = transferCharacteristic
else { return }
// check to see if number of iterations completed and peripheral can accept more data
while writeIterationsComplete < defaultIterations && discoveredPeripheral.canSendWriteWithoutResponse {
let mtu = discoveredPeripheral.maximumWriteValueLength (for: .withoutResponse)
var rawPacket = [UInt8]()
let bytesToCopy: size_t = min(mtu,data.count)
data.copyBytes(to: &rawPacket,count: bytesToCopy)
let packetData = Data(bytes: &rawPacket,count: bytesToCopy)
let stringFromData = String(data: packetData,encoding: .utf8)
print("Writing %d bytes: %s",bytesToCopy,String(describing: stringFromData))
discoveredPeripheral.writeValue(packetData,for: transferCharacteristic,type: .withoutResponse)
writeIterationsComplete += 1
}
if writeIterationsComplete == defaultIterations {
// Cancel our subscription to the characteristic
discoveredPeripheral.setNotifyValue(false,for: transferCharacteristic)
}
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
}
}
extension InterfaceController: CBCentralManagerDelegate {
// implementations of the CBCentralManagerDelegate methods
internal func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .poweredOn:
// ... so start working with the peripheral
print("CBManager is powered on")
retrievePeripheral()
case .poweredOff:
print("CBManager is not powered on")
// In a real app,you'd deal with all the states accordingly
return
case .resetting:
print("CBManager is resetting")
// In a real app,you'd deal with all the states accordingly
return
case .unauthorized:
// In a real app,you'd deal with all the states accordingly
if #available(iOS 13.0,*) {
switch central.authorization {
case .denied:
print("You are not authorized to use Bluetooth")
case .restricted:
print("Bluetooth is restricted")
default:
print("Unexpected authorization")
}
} else {
// Fallback on earlier versions
}
return
case .unknown:
print("CBManager state is unknown")
// In a real app,you'd deal with all the states accordingly
return
case .unsupported:
print("Bluetooth is not supported on this device")
// In a real app,you'd deal with all the states accordingly
return
@unknown default:
print("A previously unknown central manager state occurred")
// In a real app,you'd deal with yet unknown cases that might occur in the future
return
}
}
func centralManager(_ central: CBCentralManager,didDiscover peripheral: CBPeripheral,advertisementData: [String: Any],rssi RSSI: NSNumber) {
// Reject if the signal strength is too low to attempt data transfer.
// Change the minimum RSSI value depending on your app’s use case.
guard RSSI.intValue >= -70
else {
print("Discovered perhiperal not range : \(peripheral.name),at %d",RSSI.intValue)
return
}
print("Discovered %s at %d",String(describing: peripheral.name),RSSI.intValue)
// Device is in range - have we already seen it?
if discoveredPeripheral != peripheral {
// Save a local copy of the peripheral,so CoreBluetooth doesn't get rid of it.
discoveredPeripheral = peripheral
// And finally,connect to the peripheral.
print("Connecting to perhiperal %@",peripheral)
centralManager.connect(peripheral,options: nil)
}
}
func centralManager(_ central: CBCentralManager,didFailToConnect peripheral: CBPeripheral,error: Error?) {
print("Failed to connect to %@. %s",peripheral,String(describing: error))
cleanup()
}
func centralManager(_ central: CBCentralManager,didConnect peripheral: CBPeripheral) {
print("Peripheral Connected")
// Stop scanning
centralManager.stopScan()
print("Scanning stopped")
// set iteration info
connectionIterationsComplete += 1
writeIterationsComplete = 0
// Clear the data that we may already have
data.removeAll(keepingCapacity: false)
// Make sure we get the discovery callbacks
peripheral.delegate = self
// Search only for services that match our UUID
peripheral.discoverServices([TransferService.serviceUUID])
}
func centralManager(_ central: CBCentralManager,didDisconnectPeripheral peripheral: CBPeripheral,error: Error?) {
print("Perhiperal Disconnected")
discoveredPeripheral = nil
// We're disconnected,so start scanning again
if connectionIterationsComplete < defaultIterations {
retrievePeripheral()
} else {
print("Connection iterations completed")
}
}
}
extension InterfaceController: CBPeripheralDelegate {
// implementations of the CBPeripheralDelegate methods
func peripheral(_ peripheral: CBPeripheral,didModifyServices invalidatedServices: [CBService]) {
for service in invalidatedServices where service.uuid == TransferService.serviceUUID {
print("Transfer service is invalidated - rediscover services")
peripheral.discoverServices([TransferService.serviceUUID])
}
}
func peripheral(_ peripheral: CBPeripheral,didDiscoverServices error: Error?) {
if let error = error {
print("Error discovering services: %s",error.localizedDescription)
cleanup()
return
}
// Discover the characteristic we want...
// Loop through the newly filled peripheral.services array,just in case there's more than one.
guard let peripheralServices = peripheral.services else { return }
for service in peripheralServices {
peripheral.discoverCharacteristics([TransferService.characteristicUUID],for: service)
}
}
func peripheral(_ peripheral: CBPeripheral,didDiscoverCharacteristicsFor service: CBService,error: Error?) {
// Deal with errors (if any).
if let error = error {
print("Error discovering characteristics: %s",error.localizedDescription)
cleanup()
return
}
// Again,we loop through the array,just in case and check if it's the right one
guard let serviceCharacteristics = service.characteristics else { return }
for characteristic in serviceCharacteristics where characteristic.uuid == TransferService.characteristicUUID {
// If it is,subscribe to it
transferCharacteristic = characteristic
peripheral.setNotifyValue(true,for: characteristic)
}
// Once this is complete,we just need to wait for the data to come in.
}
func peripheral(_ peripheral: CBPeripheral,didUpdateValueFor characteristic: CBCharacteristic,error: Error?) {
// Deal with errors (if any)
if let error = error {
print("Error discovering characteristics: %s",error.localizedDescription)
cleanup()
return
}
guard let characteristicData = characteristic.value,let stringFromData = String(data: characteristicData,encoding: .utf8) else { return }
print("Received %d bytes: %s",characteristicData.count,stringFromData)
if characteristicData.count > 0 {
DispatchQueue.main.async() {
self.bleLabel.setText(stringFromData)
}
writeData()
}
}
func peripheral(_ peripheral: CBPeripheral,didUpdateNotificationStateFor characteristic: CBCharacteristic,error: Error?) {
if let error = error {
print("Error changing notification state: %s",error.localizedDescription)
return
}
guard characteristic.uuid == TransferService.characteristicUUID else { return }
if characteristic.isNotifying {
// Notification has started
print("Notification began on %@",characteristic)
} else {
// Notification has stopped,so disconnect from the peripheral
print("Notification stopped on %@. Disconnecting",characteristic)
cleanup()
}
}
func peripheralIsReady(toSendWriteWithoutResponse peripheral: CBPeripheral) {
print("Peripheral is ready,send data")
writeData()
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。