watchOS可以单独连接到BLE设备吗?

如何解决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 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-