CBPeripheral Service 似乎是不可见的
Posted
技术标签:
【中文标题】CBPeripheral Service 似乎是不可见的【英文标题】:CBPeripheral Service seems to be invisible 【发布时间】:2016-09-24 18:40:34 【问题描述】:我正在使用 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)")
【问题讨论】:
什么是外设?它是否同时提供和宣传指定的服务?您是否尝试过 Light Blue 应用,看看它是否可以看到该服务。 用print("SERV: \(service.UUID.UUIDString)")
打印服务UUID怎么样?
@Enix 没有意义,因为 peripheral.services 是一个空数组,这意味着程序不会进入该循环。
@Paulw11 LightBlue 找到服务但我无法访问服务的特征
@Paulw11 我的外围设备是另一个 swift 程序。我在这篇文章的编辑中添加了代码
【参考方案1】:
您的问题出在外围代码中。在CBPeripheralManager
处于开机状态之前,您无法将服务添加到CBMutablePeripheral
。
我建议你将你的服务移动到它自己的函数中,并在你处于开机状态时调用这个函数。
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]])
【讨论】:
保罗你老板!! 我刚刚添加了委托函数 peripheral:DidRecieveReadRequest,即使我的设备读取了消息,它也不会被调用。知道为什么吗? 您在创建特征时已为特征指定了一个值,因此它具有固定值。如果将其初始值设置为nil
,则将调用委托方法。以上是关于CBPeripheral Service 似乎是不可见的的主要内容,如果未能解决你的问题,请参考以下文章
在“CBPeripheral *”类型的对象上找不到属性“uuid”