Конвертировать из Nsnumber в данные для отправки rssi в модуль bluetooth IOS swift 4 - PullRequest
0 голосов
/ 01 февраля 2020

Я нашел уровень принятого сигнала iPhone для используемого модуля bluetooth 4.0, но он имеет формат NSNumber, а метод writeValue () принимает только значения типа Data.

Как мне go преобразовать NSNumber в Data? Или есть другой, лучший способ отправить эти данные из моего iPhone в модуль Bluetooth?

Используемый мной модуль Bluetooth - это HM-10, и он подключен к Arduino.

import UIKit
import CoreBluetooth

class ViewController: UIViewController, CBPeripheralDelegate, CBCentralManagerDelegate {
    private var centralManager: CBCentralManager!
    private var peripheral: CBPeripheral!
    var readRSSITimer: Timer!
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        print("Central state update")
        if central.state != .poweredOn {
            print("Central is not powered on")
        } else {
            print("Central scanning for", ParticlePeripheral.particleLEDServiceUUID);
            centralManager.scanForPeripherals(withServices: [ParticlePeripheral.particleLEDServiceUUID],
                                              options: [CBCentralManagerScanOptionAllowDuplicatesKey : true])
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        centralManager = CBCentralManager(delegate: self, queue: nil)
    }
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        // We've found it so stop scan
        self.centralManager.stopScan()
        // Copy the peripheral instance
        self.peripheral = peripheral
        self.peripheral.delegate = self
        // Connect!
        self.centralManager.connect(self.peripheral, options: nil)
    }
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        if peripheral == self.peripheral {
            print("Connected to your Particle Board")
            peripheral.discoverServices([ParticlePeripheral.particleLEDServiceUUID])
            print(self.peripheral.readRSSI())
            self.startReadRSSI()
            peripheral.delegate = self
        }
    }
    func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
        self.stopReadRSSI()
        if self.peripheral != nil {
            self.peripheral.delegate = nil
            self.peripheral = nil
        }
    }
    func stopScan() {
        self.centralManager.stopScan()
    }
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        if let services = peripheral.services {
            for service in services {
                if service.uuid == ParticlePeripheral.particleLEDServiceUUID {
                    print("LED service found")
                    //Now kick off discovery of characteristics
                    peripheral.discoverCharacteristics([ParticlePeripheral.redLEDCharacteristicUUID,
                                                        ], for: service) //edited this
                    return
                }
            }
        }
    }
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        if let characteristics = service.characteristics {
            for characteristic in characteristics {
                if characteristic.uuid == ParticlePeripheral.redLEDCharacteristicUUID {
                    print("Red LED characteristic found")
                } else if characteristic.uuid == ParticlePeripheral.greenLEDCharacteristicUUID {
                    print("Green LED characteristic found")
                } else if characteristic.uuid == ParticlePeripheral.blueLEDCharacteristicUUID {
                    print("Blue LED characteristic found");
                }
            }
        }
    }
    func peripheral(_ peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: Error?) {
        print("RSSI = \(RSSI)")
    }
    @objc func readRSSI() {
        if (self.peripheral != nil) {
            self.peripheral.delegate = self
            print("RSSI Request - \(peripheral.name!)")
            print(self.peripheral.readRSSI())
        } else {
            print("peripheral = nil")
        }    
    }
    func startReadRSSI() {
        if self.readRSSITimer == nil {
            self.readRSSITimer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(ViewController.readRSSI), userInfo: nil, repeats: true)
        }
    } 
    func stopReadRSSI() {
        if (self.readRSSITimer != nil) {
            self.readRSSITimer.invalidate()
            self.readRSSITimer = nil
        }
    }
}

1 Ответ

0 голосов
/ 01 февраля 2020

Вы можете использовать инициализатор байтов данных и передать полученный номер для преобразования его в данные:

init(bytes: UnsafeRawPointer, count: Int)

extension NSNumber {
    var data: Data {
        var source = self
        return Data(bytes: &source, count: MemoryLayout<NSNumber>.size)
    }
}

Чтобы преобразовать его из данных обратно в NSNumber, вы можете использовать метод данных.

func withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType

extension Data {
    func object<T>() -> T { withUnsafeBytes { $0.load(as: T.self) } }
    var nsNumber: NSNumber { object() }
}

Тестирование игровой площадки:

let integerNumber = NSNumber.init(value: 2)
let integerNumberData = integerNumber.data

let loadedintegerNumber: NSNumber = integerNumberData.nsNumber

loadedintegerNumber  // 2

let floatNumber = NSNumber.init(value: 2.7)
let floatNumberData = floatNumber.data

let loadedFloatNumber: NSNumber = floatNumberData.nsNumber

loadedFloatNumber  // 2.7

let boolNumber = NSNumber.init(value: true)
let boolNumberData = boolNumber.data

let loadedBoolNumber: NSNumber = boolNumberData.nsNumber

loadedBoolNumber  // 1
...