德州仪器的SensorTag是一个方便的、低成本的平台,用于演示各种传感器的能力,其中包括温度、湿度、运动等传感器。这款传感器有着许多潜在的应用,包括环境监测、运动追踪等。在此文章中,我们将深入介绍如何使用Swift语言,结合蓝牙低功耗(BLE)技术,将iOS设备与SensorTag建立连接,并从中读取数据。
首先,你需要准备以下工具和设备:
打开Xcode并创建一个新的iOS应用项目。选择Single View App作为模板,并给它一个合适的名字,例如“SensorTagBLEConnector”。
在项目设置中,确保你选择了最新的Swift语言版本,并为目标iOS版本选择一个相对较新的版本。
为了与SensorTag进行通信,你需要使用到iOS的CoreBluetooth库。这是一个内置库,用于和蓝牙设备通信。
在你的项目中,选择你的项目名称 -> Build Phases -> Link Binary With Libraries,点击“+”,然后搜索并添加CoreBluetooth.framework
。
首先,我们需要创建一个管理BLE的类,这里我们称之为“BLEManager”。
在Xcode中,点击File -> New -> File,然后选择Swift File。命名它为“BLEManager”。
在BLEManager.swift
文件中,开始我们的代码:
import CoreBluetooth
class BLEManager: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {
var centralManager: CBCentralManager!
var sensorTag: CBPeripheral?
override init() {
super.init()
centralManager = CBCentralManager(delegate: self, queue: nil)
}
// CBCentralManagerDelegate的方法将在后续部分中详细描述
}
这只是一个基础的框架,但它为我们提供了一个开始。这里,我们导入了CoreBluetooth库,并创建了一个新的类BLEManager
。这个类继承了NSObject
,并实现了CBCentralManagerDelegate
和CBPeripheralDelegate
两个协议。
在此基础上,我们定义了两个属性:centralManager
(用于管理和搜索蓝牙设备)和sensorTag
(代表找到的SensorTag设备)。
override init
方法是我们的初始化函数,用于设置centralManager
的代理为当前的BLEManager
对象。
目前,我们已经建立了项目的基础框架,并完成了BLEManager的初步编写。
注意:为了简洁和清晰,本文中的代码可能不是最优的或最完整的实现。为了获得完整的项目和更多的优化技巧,请下载完整项目
为了找到并连接到SensorTag,我们首先需要实现CBCentralManagerDelegate
中的几个方法来发现和管理蓝牙设备。
继续编辑我们的BLEManager.swift
文件:
// 已有的代码...
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .poweredOn:
print("Bluetooth is On")
startScanning()
case .poweredOff:
print("Bluetooth is Off")
default:
break
}
}
func startScanning() {
centralManager.scanForPeripherals(withServices: nil, options: nil)
}
在上面的代码中,我们实现了centralManagerDidUpdateState
方法,该方法是CBCentralManagerDelegate
的一部分,当蓝牙的状态改变时,它会被调用。我们检查蓝牙是否已打开,如果是,则开始扫描附近的蓝牙设备。
// 在BLEManager类中添加以下方法:
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
if let deviceName = advertisementData[CBAdvertisementDataLocalNameKey] as? String, deviceName.contains("SensorTag") {
self.sensorTag = peripheral
self.centralManager.stopScan()
self.centralManager.connect(peripheral, options: nil)
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
print("Connected to SensorTag!")
peripheral.delegate = self
peripheral.discoverServices(nil)
}
在didDiscover
方法中,我们检查发现的设备是否是SensorTag。如果是,我们将停止扫描其他设备,并尝试连接到SensorTag。
在didConnect
方法中,我们简单地打印出已成功连接,并开始探索该设备提供的服务。
为了从SensorTag读取数据,我们需要进一步实现CBPeripheralDelegate
的方法。
// 在BLEManager类中添加以下方法:
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
if let services = peripheral.services {
for service in services {
print("Discovered service: \(service.uuid.uuidString)")
peripheral.discoverCharacteristics(nil, for: service)
}
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
if let characteristics = service.characteristics {
for characteristic in characteristics {
print("Discovered characteristic: \(characteristic.uuid.uuidString)")
if characteristic.properties.contains(.read) {
peripheral.readValue(for: characteristic)
}
}
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if let data = characteristic.value {
// 这里可以根据你的需要对数据进行解析
print("Received data from SensorTag: \(data)")
}
}
上述代码中,我们首先探索了SensorTag提供的所有服务,然后探索每个服务中的特性,并从那些可以读取的特性中读取数据。
在 Main.storyboard
中,我们要创建一个基础的界面来显示从 SensorTag 读取的数据。为了简单起见,我们仅添加一个文本框 (TextView) 来显示数据。
Main.storyboard
。ViewController.swift
中命名为 dataTextView
。现在,我们需要将 BLEManager
集成到 ViewController
中,以便从 SensorTag 获取数据并在 TextView 中显示。
编辑 ViewController.swift
文件:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var dataTextView: UITextView!
var bleManager: BLEManager?
override func viewDidLoad() {
super.viewDidLoad()
bleManager = BLEManager()
}
}
这里,我们初始化了 BLEManager
类的实例。为了从 BLEManager
获取数据并更新界面,我们需要为 ViewController
添加一些新方法。
首先,在 BLEManager
中,我们添加一个闭包 (closure) 来获取数据:
// 在 BLEManager.swift 中添加
var onDataReceived: ((String) -> Void)?
// 修改此方法
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if let data = characteristic.value {
// 这里可以根据你的需要对数据进行解析
let dataString = "Received data from SensorTag: \(data)"
onDataReceived?(dataString)
}
}
接着,在 ViewController
中,我们将这个闭包与更新界面的逻辑关联起来:
override func viewDidLoad() {
super.viewDidLoad()
bleManager = BLEManager()
bleManager?.onDataReceived = { [weak self] dataString in
DispatchQueue.main.async {
self?.dataTextView.text += "\n\(dataString)"
}
}
}
我们使用 DispatchQueue.main.async
确保 UI 更新在主线程上执行,这是进行任何 UI 操作的必要步骤。
现在,你可以运行你的应用在实际的 iOS 设备上(记住,iOS 的模拟器不支持蓝牙功能)。一旦你的应用运行并且蓝牙打开,它应该开始扫描 SensorTag。一旦连接,你应该能在 TextView 中看到从 SensorTag 收到的数据。
我们已经完成了整个应用的开发,该应用能够使用 Swift 和 BLE 技术将 iOS 设备连接到 Texas Instruments 的 SensorTag,并从中读取数据。我们还设计了一个简单的 UI,以实时方式展示收到的数据。
对于进一步的开发,你可以考虑添加更多的功能,如数据的图形化展示、将数据存储到数据库或云端,或与其他 IoT 设备集成。
希望这篇文章能帮助你理解如何使用 Swift 和 iOS 的 CoreBluetooth 库来与蓝牙设备交互。感谢你的阅读!
注意:实际开发中,建议更细致地处理可能出现的错误或异常情况,并遵循最佳的编码实践,以确保应用的稳定性和可靠性。
注意:为了简洁和清晰,本文中的代码可能不是最优的或最完整的实现。为了获得完整的项目和更多的优化技巧,请下载完整项目