我正在学习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.
}
这里我给变量centralManager分配了一个CBCentralManager类的实例,但我无法理解为什么我要传递委托。
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"为什么我有一些具有相同名称但具有不同属性的函数?
谢谢
答案 0 :(得分:2)
这里我给变量centralManager分配了一个实例 CBCentralManager类,但我无法理解为什么我要通过 委派。
您正在分配delegate
,以便centralManager
知道要拨打电话的人。它使用指向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
答案 1 :(得分:0)
centralManager = CBCentralManager(delegate: self, queue: nil)
Classname(...)
初始化该类的实例。在你的代码中,它是一个CBCentralManager
类。它将self(你的视图控制器)设置为实例的delegate
,这意味着当这个CBCentralManager的实例完成为你的视图控制器做某事时,它会通过一些通过您应在视图控制器中实现的委托方法向视图控制器提供信息。