我正在学习Swift,我有一个使用蓝牙来管理BLE外设的控制器。
我无法理解一些细节,完整的代码是here
我在代码之间写我的问题
import UIKit
import CoreBluetooth
class HomeViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate
{
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var stateLabel: UILabel!
@IBOutlet weak var tempLabel: UILabel!
var centralManager : CBCentralManager!
var sensorTagPeripheral : CBPeripheral!
在这里,我明白了:我声明了两个具有CBCentralManager和CBPeripheral类型的变量,现在这两个变量等于nil。
// IR Temp UUIDs
let IRTemperatureServiceUUID = CBUUID(string: "F000AA00-0451-4000-B000-000000000000")
let IRTemperatureDataUUID = CBUUID(string: "F000AA01-0451-4000-B000-000000000000")
let IRTemperatureConfigUUID = CBUUID(string: "F000AA02-0451-4000-B000-000000000000")
override func viewDidLoad() {
super.viewDidLoad()
centralManager = CBCentralManager(delegate: self, queue: nil)
// Do any additional setup after loading the view.
}
在这里,我将CBCentralManager类的实例分配给变量centralManager,但是我不明白为什么要传递委托。
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func centralManagerDidUpdateState(central: CBCentralManager!) {
if central.state == CBCentralManagerState.PoweredOn {
// Scan for peripherals if BLE is turned on
central.scanForPeripheralsWithServices(nil, options: nil)
self.stateLabel.text = "Searching for BLE Devices"
}
else {
// Can have different conditions for all states if needed - print generic message for now
println("Bluetooth switched off or not initialized")
}
}
func centralManager(central: CBCentralManager!, didDiscoverPeripheral peripheral: CBPeripheral!, advertisementData: [NSObject : AnyObject]!, RSSI: NSNumber!) {
let deviceName = "SensorTag"
let nameOfDeviceFound = (advertisementData as NSDictionary).objectForKey(CBAdvertisementDataLocalNameKey) as? NSString
if (nameOfDeviceFound == deviceName) {
// Update Status Label
self.stateLabel.text = "Sensor Tag Found"
// Stop scanning
self.centralManager.stopScan()
// Set as the peripheral to use and establish connection
self.sensorTagPeripheral = peripheral
self.sensorTagPeripheral.delegate = self
self.centralManager.connectPeripheral(peripheral, options: nil)
}
else {
self.stateLabel.text = "Sensor Tag NOT Found"
}
}
func centralManager(central: CBCentralManager!, didConnectPeripheral peripheral: CBPeripheral!) {
self.stateLabel.text = "Discovering peripheral services"
peripheral.discoverServices(nil)
}
func centralManager(central: CBCentralManager!, didDisconnectPeripheral peripheral: CBPeripheral!, error: NSError!) {
self.stateLabel.text = "Disconnected"
central.scanForPeripheralsWithServices(nil, options: nil)
}
// Check if the service discovered is a valid IR Temperature Service
func peripheral(peripheral: CBPeripheral!, didDiscoverServices error: NSError!) {
self.stateLabel.text = "Looking at peripheral services"
for service in peripheral.services {
let thisService = service as! CBService
if service.UUID == IRTemperatureServiceUUID {
// Discover characteristics of IR Temperature Service
peripheral.discoverCharacteristics(nil, forService: thisService)
}
// Uncomment to print list of UUIDs
//println(thisService.UUID)
}
}
// Enable notification and sensor for each characteristic of valid service
func peripheral(peripheral: CBPeripheral!, didDiscoverCharacteristicsForService service: CBService!, error: NSError!) {
// update status label
self.stateLabel.text = "Enabling sensors"
// 0x01 data byte to enable sensor
var enableValue = 1
let enablyBytes = NSData(bytes: &enableValue, length: sizeof(UInt8))
// check the uuid of each characteristic to find config and data characteristics
for charateristic in service.characteristics {
let thisCharacteristic = charateristic as! CBCharacteristic
// check for data characteristic
if thisCharacteristic.UUID == IRTemperatureDataUUID {
// Enable Sensor Notification
self.sensorTagPeripheral.setNotifyValue(true, forCharacteristic: thisCharacteristic)
}
// check for config characteristic
if thisCharacteristic.UUID == IRTemperatureConfigUUID {
// Enable Sensor
self.sensorTagPeripheral.writeValue(enablyBytes, forCharacteristic: thisCharacteristic, type: CBCharacteristicWriteType.WithResponse)
}
}
}
func peripheral(peripheral: CBPeripheral!, didUpdateValueForCharacteristic characteristic: CBCharacteristic!, error: NSError!) {
self.stateLabel.text = "Connected"
if characteristic.UUID == IRTemperatureDataUUID {
// Convert NSData to array of signed 16 bit values
let dataBytes = characteristic.value
let dataLength = dataBytes.length
var dataArray = [Int16](count: dataLength, repeatedValue: 0)
dataBytes.getBytes(&dataArray, length: dataLength * sizeof(Int16))
// Element 1 of the array will be ambient temperature raw value
let ambientTemperature = Double(dataArray[1])/128
// Display on the temp label
self.tempLabel.text = NSString(format: "%.2f", ambientTemperature) as String
}
}
}
这基本上是我的问题的核心:我知道协议需要这些功能,但是谁来调用这些功能呢?例如,谁在调用函数“centralManager”,为什么我有一些具有相同名称但具有不同属性的函数?
谢谢
最佳答案
在这里,我为变量CentralManager分配了一个实例
CBCentralManager类,但我不明白为什么要传递
代表。
您正在分配delegate
,以便centralManager
知道 call 谁。它使用指向您的HomeViewController
的指针来调用centralManager*
方法。
例如,当centralManager
更新状态后,它通过委托指针(即指向viewController
的指针)进行调用,从而告诉HomeViewController
:
delegate.centralManagerDidUpdateState(central: self)
通过
central
参数传递一个指向自身的指针。这基本上是我的问题的核心:我了解这些
协议需要功能,但是谁调用这些功能?
centralManager*
函数由centralManager
对象调用。它有一个指向HomeViewController
的指针。您传递了self
。 sensorTagPeripheral
再次通过您作为peripheral*
传递的对象指针self
调用delegate
函数。为什么我有一些同名但不同的功能
属性?
它们是不同的功能。它们不同是因为它们具有不同的参数。
在Swift中,函数由它们的名称,参数的数量和类型,其返回类型以及参数的外部名称定义。例如,这是add的两个版本,两个版本都已定义并且都可以被调用。请注意,在调用外部参数名称时会使用它们。这就是Swift区分两个功能的方式:
func add(first x: Int, second y: Int) -> Int {
return x + y
}
func add(one a: Int, two b: Int) -> Int {
return a + b
}
let x = add(first: 3, second: 4)
let y = add(one: 3, two: 4)
这是您未曾提出的问题:
centralManager对象如何知道您已经实现了
它要调用的功能?
请注意,当您定义
HomeViewController
类时,您声明它实现了CBCentralManagerDelegate
协议。该协议定义了必须实现的centralManager*
函数的接口。如果不这样做,Swift编译器会给您一个错误,指出您不符合CBCentralManagerDelegate
。此外,只有实现此协议,才能将self
作为委托传递。class HomeViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate