【发布时间】:2019-09-03 10:22:15
【问题描述】:
解决方法:
我正在创建一个实用程序类,比如说BLEScanManager,它负责扫描附近的 BLE 设备。实用程序类的唯一工作是扫描 BLE 设备并列出它。
其他类可以创建此BLEScanManager 的对象并获取BLE 设备数组,例如[Bluetooth](这里Bluetooth 是自定义模态类)。
现在要扫描 BLE 设备,我在同一个类中创建了 BLEScanManager 的扩展,并覆盖了它的委托方法,如下所示:
import UIKit
import CoreBluetooth
protocol BLEScanDelegate {
func reloadDeviceList()
}
internal class BLEScanManager: NSObject {
private var centralManager: CBCentralManager?
var devices : [Bluetooth] = []
var delegate: BLEScanDelegate?
override init() {
super.init()
centralManager = CBCentralManager(delegate: self, queue: .main)
}
// MARK:- Custom methods
func isScanning() -> Bool {
return centralManager?.isScanning ?? false
}
func stopScanning() {
centralManager?.stopScan()
}
func startScanning() {
devices.removeAll()
let options: [String: Any] = [CBCentralManagerScanOptionAllowDuplicatesKey:
NSNumber(value: false)]
centralManager?.scanForPeripherals(withServices: nil, options: options)
}
}
extension BLEScanManager : CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .unknown: print("central.state is .unknown")
case .resetting: print("central.state is .resetting")
case .unsupported: print("central.state is .unsupported")
case .unauthorized: print("central.state is .unauthorized")
case .poweredOff: print("central.state is .poweredOff")
case .poweredOn: print("central.state is .poweredOn")
self.startScanning()
@unknown default: fatalError("unknow state")
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
print("Discovered \(peripheral)")
var bluetooth = Bluetooth()
bluetooth.name = peripheral.name
bluetooth.identifier = peripheral.identifier.uuidString
bluetooth.state = peripheral.state.rawValue
bluetooth.advertisementData = advertisementData
let power = advertisementData[CBAdvertisementDataTxPowerLevelKey] as? Double
let value: Double = pow(10, ((power ?? 0 - Double(truncating: RSSI))/20))
bluetooth.signalStrength = String(describing: value.round)
// Do not add duplicate device
let fitlerArray : [Bluetooth] = devices.filter { $0.identifier == bluetooth.identifier}
if fitlerArray.count == 0 {
devices.append(bluetooth)
}
self.delegate?.reloadDeviceList()
}
}
这里的问题是这些方法也暴露在其他类中。
例如:
我在其他类BLEListViewController 中创建了一个BLEScanManager 对象,以显示UITableView 中的BLE 设备列表。
class BLEListViewController: UITableViewController {
var scanManager: BLEScanManager!
}
我可以使用对象scanManager 访问BLEListViewController 类中的CBCentralManagerDelegate 委托方法。
如下所示,
self.scanManager.centralManager?(<#T##central: CBCentralManager##CBCentralManager#>, didConnect: <#T##CBPeripheral#>)
这应该将内部实用程序委托方法暴露给外界。
问题是如何停止暴露这些代表?
请注意,如果我使用 internal 关键字,它只会隐藏该特定方法。但它仍然允许访问所有其他 CBCentralManagerDelegate 方法。
【问题讨论】:
-
不确定它是否有效,但您是否尝试过
private extension BLEScanManager : CBCentralManagerDelegate? -
我之前使用过SwiftyBluetooth Library,它允许我使用委托方法将核心蓝牙更改为基于闭包的方法。也许这可以帮助你
-
@Tj3n:是的,我试过了,它给了我一个错误:'private' 修饰符不能与声明协议一致性的扩展一起使用
-
@chirag90:谢谢,让我也检查一下。
-
为了更清楚,我已经添加了实用程序类的所有代码
标签: ios swift delegates swift-extensions