CBPeripheral Service似乎是看不见的

时间:2016-09-24 18:40:34

标签: iphone swift xcode bluetooth-lowenergy core-bluetooth

我正在使用CoreBluetooth框架实现CentralManager,以便提取外围设备提供的值。

我首先查找具有特定UUID服务的外围设备(" 52486FA8-FF0B-4A91-A344-D642D0E91AD0")。 CentralManager找到外设,但是当我尝试打印该外围设备的服务时,我得到一个空数组。

这是我的代码

//
//  ViewController.swift
//  centralLearn
//
//  Created by Francesco Vanduynslager on 24/09/2016.
//  Copyright © 2016 Francesco Vanduynslager. All rights reserved.
//

import UIKit
import CoreBluetooth

class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate {
    var centralManager: CBCentralManager!
    var discoveredPeripherals: [CBPeripheral]!

    let serviceUUID = CBUUID(string:"52486FA8-FF0B-4A91-A344-D642D0E91AD0")

    override func viewDidLoad() {
        super.viewDidLoad()
        centralManager = CBCentralManager(delegate: self, queue: nil)
        discoveredPeripherals = []
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if central.state == .poweredOn {
            print("Central Started")
            centralManager.scanForPeripherals(withServices: [serviceUUID],
                                              options: nil)
        } else if central.state == .poweredOff {
            centralManager.stopScan()
        }
    }

    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        print("Discovered Peripheral: \(peripheral.name)")
        self.discoveredPeripherals.append(peripheral)
        centralManager.connect(peripheral, options: nil)
        centralManager.stopScan()
    }

    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        print("Connected to peripheral!!  \(peripheral)")
        print("count: \(peripheral.services?.count)")
        peripheral.delegate = self

        if (peripheral.services == nil) {
            peripheral.discoverServices([serviceUUID])
        }
    }

    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        if error != nil {
            print("Discover service Error: \(error)")
        } else {
            print("Discovered Service")
            for service in peripheral.services!{
                print("SERV: \(service)")
                peripheral.discoverCharacteristics([CBUUID(string: "5A5E5393-4505-471C-BA90-7AD044FFFD9C")], for: service)
            }
            print(peripheral.services)
            print("DONE")
        }
    }

    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        let characteristic = service.characteristics?[0]
        print("Discovered Characteristic")
        peripheral.readValue(for: characteristic!)
    }


    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
        if error != nil {
            print("Read value service Error: \(error)")
        } else {
            print("Value of Characteristic: \(characteristic.value)")
        }
    }
}

结果印刷品如下:

Central Started
Discovered Peripheral: Optional("-ShEsKo-")
Connected to peripheral!!  <CBPeripheral: 0x1740f7d00, identifier = A9B3F888-99E1-C62B-DF93-87F1F99AE847, name = -ShEsKo-, state = connected>
count: nil
Discovered Service
Optional([])
DONE

修改

这是我的外围代码:

//
//  ViewController.swift
//  peripheralLearn
//
//  Created by Francesco Vanduynslager on 24/09/2016.
//  Copyright © 2016 Francesco Vanduynslager. All rights reserved.
//

import UIKit
import CoreBluetooth
import CoreLocation

class ViewController: UIViewController, CBPeripheralManagerDelegate {
    var localBeacon: CLBeaconRegion!
    var beaconPeripheralData: NSDictionary!
    var peripheralManager: CBPeripheralManager!

    var services: [CBMutableService]!

    override func viewDidLoad() {
        super.viewDidLoad()
        initLocalBeacon()
        // Do any additional setup after loading the view, typically from a nib.
    }

    func initLocalBeacon() {
        if localBeacon != nil {
            stopLocalBeacon()
        }

        let localBeaconUUID = "B65D79F6-74A2-482F-A669-FA5AB35CD3B8"
        let localBeaconMajor: CLBeaconMajorValue = 123
        let localBeaconMinor: CLBeaconMinorValue = 456

        let uuid = UUID(uuidString: localBeaconUUID)!
        localBeacon = CLBeaconRegion(proximityUUID: uuid, major: localBeaconMajor, minor: localBeaconMinor, identifier: "Your private identifer here")

        beaconPeripheralData = localBeacon.peripheralData(withMeasuredPower: nil)
        peripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: nil)



        /// FIRST SERVICE
        let serviceUUID = CBUUID(string: "52486FA8-FF0B-4A91-A344-D642D0E91AD0")
        let characteristicUUID = CBUUID(string: "5A5E5393-4505-471C-BA90-7AD044FFFD9C")

        let characteristic = CBMutableCharacteristic(type: characteristicUUID,
                                                     properties: .read,
                                                     value: "hello".data(using: .utf8),
                                                     permissions: .readable)

        let service = CBMutableService(type: serviceUUID, primary: true)

        service.characteristics = [characteristic]

        services=[service]
        peripheralManager.add(service)
    }

    func stopLocalBeacon() {
        peripheralManager.stopAdvertising()
        peripheralManager = nil
        beaconPeripheralData = nil
        localBeacon = nil
    }

    func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
        if peripheral.state == .poweredOn {
            print("peripheral Started")
//            peripheralManager.startAdvertising(beaconPeripheralData as! [String: AnyObject]!)
            peripheralManager.startAdvertising([CBAdvertisementDataServiceUUIDsKey: [services[0].uuid, services[1].uuid]])
        } else if peripheral.state == .poweredOff {
            peripheralManager.stopAdvertising()
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) {
        if (error != nil){
            print("ERROR starting advertising")
        }else{
            print("Did Start advertising")
        }
    }

    func peripheralManager(_ peripheral: CBPeripheralManager, willRestoreState dict: [String : Any]) {
        print("Restoring state")
    }

    func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) {
        if (error != nil) {
            print("ERROR adding service: \(error)")
        }else{
            print("Service added: \(service)")
        }
    }
}

1 个答案:

答案 0 :(得分:2)

您的问题出在外围代码中。在CBMutablePeripheral处于开机状态之前,您无法将服务添加到CBPeripheralManager

我建议您将服务移动到自己的功能,并在处于开机状态时调用此功能。

func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
    if peripheral.state == .poweredOn {
        print("peripheral Started")
        //            peripheralManager.startAdvertising(beaconPeripheralData as! [String: AnyObject]!)
        self.setupService()
    } else if peripheral.state == .poweredOff {
        peripheralManager.stopAdvertising()
    }
}

func setupService() {
    let serviceUUID = CBUUID(string: "52486FA8-FF0B-4A91-A344-D642D0E91AD0")
    let characteristicUUID = CBUUID(string: "5A5E5393-4505-471C-BA90-7AD044FFFD9C")

    let characteristic = CBMutableCharacteristic(type: characteristicUUID,
                                                 properties: .read,
                                                 value: "hello".data(using: .utf8),
                                                 permissions: .readable)

    let service = CBMutableService(type: serviceUUID, primary: true)

    service.characteristics = [characteristic]

    services=[service]
    peripheralManager.add(service)
    peripheralManager.startAdvertising([CBAdvertisementDataServiceUUIDsKey: [services[0].uuid]])

}