使用Swift语言实现iOS设备与德州仪器SensorTag的蓝牙BLE连接与数据交互教程

第一部分:前言与环境准备

1. 前言

德州仪器的SensorTag是一个方便的、低成本的平台,用于演示各种传感器的能力,其中包括温度、湿度、运动等传感器。这款传感器有着许多潜在的应用,包括环境监测、运动追踪等。在此文章中,我们将深入介绍如何使用Swift语言,结合蓝牙低功耗(BLE)技术,将iOS设备与SensorTag建立连接,并从中读取数据。

2. 环境准备

首先,你需要准备以下工具和设备:

  • 一个德州仪器SensorTag。
  • 一台运行iOS的设备,例如iPhone或iPad。
  • 最新版本的Xcode,确保其支持最新的Swift语言版本。
  • 一个Apple开发者账户,以便在设备上进行实际测试。
3. 项目设置

打开Xcode并创建一个新的iOS应用项目。选择Single View App作为模板,并给它一个合适的名字,例如“SensorTagBLEConnector”。

在项目设置中,确保你选择了最新的Swift语言版本,并为目标iOS版本选择一个相对较新的版本。

4. 添加必要的库

为了与SensorTag进行通信,你需要使用到iOS的CoreBluetooth库。这是一个内置库,用于和蓝牙设备通信。

在你的项目中,选择你的项目名称 -> Build Phases -> Link Binary With Libraries,点击“+”,然后搜索并添加CoreBluetooth.framework

5. 初步的代码编写

首先,我们需要创建一个管理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,并实现了CBCentralManagerDelegateCBPeripheralDelegate两个协议。

在此基础上,我们定义了两个属性:centralManager(用于管理和搜索蓝牙设备)和sensorTag(代表找到的SensorTag设备)。

override init方法是我们的初始化函数,用于设置centralManager的代理为当前的BLEManager对象。

目前,我们已经建立了项目的基础框架,并完成了BLEManager的初步编写。

注意:为了简洁和清晰,本文中的代码可能不是最优的或最完整的实现。为了获得完整的项目和更多的优化技巧,请下载完整项目

第二部分:BLEManager的继续开发与连接SensorTag

6. 搜索蓝牙设备

为了找到并连接到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的一部分,当蓝牙的状态改变时,它会被调用。我们检查蓝牙是否已打开,如果是,则开始扫描附近的蓝牙设备。

7. 发现SensorTag并建立连接
// 在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方法中,我们简单地打印出已成功连接,并开始探索该设备提供的服务。

8. 读取SensorTag的数据

为了从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提供的所有服务,然后探索每个服务中的特性,并从那些可以读取的特性中读取数据。

第三部分:集成 BLEManager 到应用界面并展示数据

9. 设置应用界面

Main.storyboard 中,我们要创建一个基础的界面来显示从 SensorTag 读取的数据。为了简单起见,我们仅添加一个文本框 (TextView) 来显示数据。

  1. 打开 Main.storyboard
  2. 从对象库中拖动一个 TextView 到 View Controller 中。
  3. 使用 Auto Layout 设置约束,使其占据大部分屏幕空间。
  4. 为该 TextView 创建一个 IBOutlet,在 ViewController.swift 中命名为 dataTextView
10. 集成 BLEManager

现在,我们需要将 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 操作的必要步骤。

11. 测试应用

现在,你可以运行你的应用在实际的 iOS 设备上(记住,iOS 的模拟器不支持蓝牙功能)。一旦你的应用运行并且蓝牙打开,它应该开始扫描 SensorTag。一旦连接,你应该能在 TextView 中看到从 SensorTag 收到的数据。

结束本部分 & 文章总结

我们已经完成了整个应用的开发,该应用能够使用 Swift 和 BLE 技术将 iOS 设备连接到 Texas Instruments 的 SensorTag,并从中读取数据。我们还设计了一个简单的 UI,以实时方式展示收到的数据。

对于进一步的开发,你可以考虑添加更多的功能,如数据的图形化展示、将数据存储到数据库或云端,或与其他 IoT 设备集成。

希望这篇文章能帮助你理解如何使用 Swift 和 iOS 的 CoreBluetooth 库来与蓝牙设备交互。感谢你的阅读!


注意:实际开发中,建议更细致地处理可能出现的错误或异常情况,并遵循最佳的编码实践,以确保应用的稳定性和可靠性。

注意:为了简洁和清晰,本文中的代码可能不是最优的或最完整的实现。为了获得完整的项目和更多的优化技巧,请下载完整项目

你可能感兴趣的:(ios,swift,交互)