if (central.state == .poweredOn) kontrolune girmiyor , bluetooth listesi gelmiyor ne yapabilirim ?
import CoreBluetooth
import UIKit
class ViewController: UIViewController {
var centralManager: CBCentralManager?
var peripherals = Array()
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
centralManager = CBCentralManager(delegate: self, queue: DispatchQueue.main)
}
}
extension ViewController: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
print(central.state)
if (central.state == .poweredOn){
self.centralManager?.scanForPeripherals(withServices: nil, options: nil)
}
else {
print("nil")
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
peripherals.append(peripheral)
print(peripheral)
}
}
swift 4
import CoreBluetooth
var bleCentralManager: CBCentralManager!
var arrayPeripheralList = [CBPeripheral]()
viewDidLoad(){
self.bleCentralManager = CBCentralManager(delegate: self, queue: nil)
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state{
case .poweredOn:
central.scanForPeripherals(withServices: nil, options: nil)
default:
bleCentralManager.stopScan()
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
if !(self.arrayPeripheralList.contains(peripheral)){
self.arrayPeripheralList.append(peripheral)
}
}
You have to call scanForPeripheralsWithServices from outside the delegate method firstly
override func viewDidLoad() {
super.viewDidLoad()
manager = CBCentralManager(delegate: self, queue: GlobalBackgroundQueue, options: [CBCentralManagerOptionShowPowerAlertKey: true])
if self.manager!.state == CBCentralManagerState.PoweredOn {
self.manager?.scanForPeripheralsWithServices(nil, options: nil)
delay(2, closure: {
self.manager?.stopScan()
print("scanning stopped.")
})
}
}
func centralManagerDidUpdateState(central: CBCentralManager) {
if (central.state != CBCentralManagerState.PoweredOn) {
self.bluetoothStatus = false
}
}
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
peripherals.append(["p": peripheral, "a": advertisementData, "r": RSSI])
}
Related
When I pass CBUUID as array to scanForPeripherals withServices nothing happened. (Xcode 12.5, Swift 5)
Step 1. Getting all devices near me and getting identifiers:
//
// ViewController.swift
//
import UIKit
import CoreBluetooth
class ViewController: UIViewController, CBCentralManagerDelegate {
private var centralManager : CBCentralManager!
override func viewDidLoad() {
super.viewDidLoad()
centralManager = CBCentralManager(delegate: self, queue: nil, options: nil)
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
centralManager.scanForPeripherals(withServices:nil, options: nil)
}
}
public func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
guard let name = peripheral.name else { return }
print("\nName : \(name)")
print(peripheral.identifier)// Getting identifier here.(9SD480E0-4362-4412-6350-D143DC3D14BE)
}
}
Step 2. (WRONG) Calling with identifiers and nothing is being discovered:
//
// ViewController.swift
//
import UIKit
import CoreBluetooth
class ViewController: UIViewController, CBCentralManagerDelegate {
private var centralManager : CBCentralManager!
override func viewDidLoad() {
super.viewDidLoad()
centralManager = CBCentralManager(delegate: self, queue: nil, options: nil)
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
centralManager.scanForPeripherals(withServices: [CBUUID.init(string: "9SD480E0-4362-4412-6350-D143DC3D14BE")], options: nil)
}
}
public func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
// NOTHING IS BEING DISCOVERED
}
}
Step 3. The correct path to follow is Step 1 (for getting id's) and Step 3 (to retrieve peripherals). Thank you #Paulw11:
//
// ViewController.swift
//
import UIKit
import CoreBluetooth
class ViewController: UIViewController, CBCentralManagerDelegate {
private var centralManager : CBCentralManager!
override func viewDidLoad() {
super.viewDidLoad()
centralManager = CBCentralManager(delegate: self, queue: nil, options: nil)
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
guard let uuid = UUID(uuidString: "9SD480E0-4362-4412-6350-D143DC3D14BE") else { return }
let result = centralManager.retrievePeripherals(withIdentifiers: [uuid])
print(result) // CBPeripheral
}
}
}
I'm coding BLE test apps for iOS with Swift 3 and I'm struggling with a problem that I can't scan devices.
I want to call the method "print("devicename: \(peripheral)")" at the last block.
import UIKit
import CoreBluetooth
class ViewController: UIViewController, CBCentralManagerDelegate {
private var isScanning = false
var centralManager: CBCentralManager!
override func viewDidLoad() {
super.viewDidLoad()
self.centralManager = CBCentralManager(delegate: self,queue: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == CBManagerState.poweredOn {
centralManager.scanForPeripherals(withServices: nil,options: nil)
} else {
print("not ready")
}
}
private func centralManager(central: CBCentralManager!,didDiscoverPeripheral peripheral: CBPeripheral!,advertisementData: [String : AnyObject]!,RSSI: NSNumber!)
{
print("devicename: \(peripheral)")
}
}
func centralManagerDidUpdateState(_ central: CBCentralManager){
switch central.state {
case .poweredOn: central.scanForPeripherals(withServices: nil, options: nil)
default: print("Please turn on bluetooth")
break
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber){
print("----->",advertisementData)
print("==>", peripheral)
}
I want to use the CBCentralManager in order to find the bluetooth low energy peripherals around me. The centralManager is getting initiated, it starts correctly and it is scanning. But the didDiscover function is never called. I read all the other posts to this and similar problem and am 99% sure that my problem has not the same cause. Still, I cannot find what I did wrong.
import Foundation
import CoreBluetooth
#objc(SmallerBeaconServiceImpl)
class SmallerBeaconServiceImpl : NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {
private let centralManager : CBCentralManager
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == CBManagerState.poweredOn && isRunning {
startScanningForPeripherals()
}
print("updated state: \(central.state)")
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
print(peripheral.name ?? "no name")
}
func startScanningForPeripherals() {
if centralManager.state != CBManagerState.poweredOn {
return
}
centralManager.scanForPeripherals(withServices: nil, options: nil)
print("is scanning: \(centralManager.isScanning)")
}
private(set) var isRunning = false
func startListening() {
if isRunning {
return
}
isRunning = true
print("started.")
startScanningForPeripherals()
}
func stopListening() {
if !isRunning {
return
}
isRunning = false
centralManager.stopScan()
}
override init() {
centralManager = CBCentralManager()
super.init()
print("initiated")
}
}
optional func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) is a CBCentralManagerDelegate method.
Your class SmallerBeaconServiceImpl is compliant with CBCentralManagerDelegate, but you didn't set your centralManager delegate (CBCentralManagerDelegate) property. That's why centralManager(_central:didDiscover:advertisementData:rssi) is not called.
This can be fixed with:
centralManager = CBCentralManager(delegate: self, queue: nil)
I'm starting with the bluetooth as a project car Arduino controlled by an iPhone.
The problem is that I try to send a single data from my iphone but looking more closely at the scan function is not good caracteristic and I think the problem comes from here.
Have you an idea to find the same in their characteristic UUID?
import UIKit
import CoreBluetooth
#IBOutlet weak var peripheralLabel: UILabel!
//713D0000503E4C75BA943148F18D941E
let BEAN_NAME = "Carduino"
let CBUUIDUuidTx = CBUUID(string: "713D0000-503E-4C75-BA94-3148F18D941E")
let CBUUIDUuIdRx = CBUUID(string: "713D0000-503E-4C75-BA94-3148F18D941E")
let UuidTx = "713D0000-503E-4C75-BA94-3148F18D941E"
let UuIdRx = "713D0000-503E-4C75-BA94-3148F18D941E"
var peripheralBLE: CBPeripheral?
var manager:CBCentralManager!
var myPeripheral:CBPeripheral!
var sendDataCharacteristic:CBCharacteristic!
var txCharacteristic: CBCharacteristic!
var rxCharacteristic: CBCharacteristic!
override func viewDidLoad() {
super.viewDidLoad()
manager = CBCentralManager(delegate: self, queue: nil)
}
//Scan For devices
func centralManagerDidUpdateState(_ central: CBCentralManager) {
manager.scanForPeripherals(withServices: [CBUUIDUuidTx], options: nil)
}
//Connect to a Device
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
let device = (advertisementData as NSDictionary)
.object(forKey: CBAdvertisementDataLocalNameKey)
as? NSString
if device?.contains(BEAN_NAME) == true {
self.manager.stopScan()
self.myPeripheral = peripheral
self.myPeripheral.delegate = self
manager.connect(peripheral, options: nil)
peripheralLabel.text = "Connect to \(peripheral.name!)"
}
}
//Get Services
func centralManager(
_ central: CBCentralManager,
didConnect peripheral: CBPeripheral) {
peripheral.discoverServices(nil)
}
//Get Characteristics
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
for service in peripheral.services! {
let thisService = service as CBService
if service.uuid == CBUUIDUuidTx {
peripheral.discoverCharacteristics(
nil,
for: thisService
)
}
print("This Service : \(thisService)")
}
}
func peripheral( _ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
for characteristic in service.characteristics! {
let thisCharacteristic = characteristic as CBCharacteristic
if thisCharacteristic.uuid == CBUUIDUuidTx {
self.myPeripheral.setNotifyValue(
true,
for: thisCharacteristic
)
}
print("This Characteristic : \(thisCharacteristic)")
}
}
//Disconnect and Try Again
func centralManager(
_ central: CBCentralManager,
didDisconnectPeripheral peripheral: CBPeripheral,
error: Error?) {
central.scanForPeripherals(withServices: nil, options: nil)
}
#IBAction func ledAction(_ sender: AnyObject) {
writeValue(data: "0x01")
}
func writeValue(data: String) {
if(myPeripheral != nil)
{
print(myPeripheral)
//happens for sure
var bytesData = [UInt8](data.utf8)
let writeData = NSData (bytes: &bytesData, length: bytesData.count)
myPeripheral.writeValue(writeData as Data, for: txCharacteristic, type: CBCharacteristicWriteType.withResponse)
print(txCharacteristic)
}
}
I am trying to write a simple app that constantly broadcasts a 'beacon' even when the app is not active. I know that using CoreLocation will switch this off when the app is not in use so I was trying to build a solution using Core Bluetooth.
The trouble is that I can't get the app to start advertising.
import UIKit
import CoreBluetooth
class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralManagerDelegate {
var centralManager:CBCentralManager = CBCentralManager()
var peripheralManager:CBPeripheralManager = CBPeripheralManager()
let uuid:CBUUID = CBUUID(string: "DCEF54A2-31EB-467F-AF8E-350FB641C97B")
override func viewDidLoad() {
super.viewDidLoad()
self.peripheralManager = CBPeripheralManager(delegate: self, queue: nil)
self.centralManager.delegate = self
let advertisingData = [CBAdvertisementDataLocalNameKey:"my-peripheral", CBAdvertisementDataServiceUUIDsKey: uuid]
peripheralManager.startAdvertising(advertisingData)
centralManager.scanForPeripheralsWithServices([uuid], options: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func peripheralManagerDidStartAdvertising(peripheral: CBPeripheralManager, error: NSError?) {
print("started advertising")
print(peripheral)
}
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
print("peripheral discovered")
print("peripheral: \(peripheral)")
print("RSSI: \(RSSI)")
}
func centralManagerDidUpdateState(central: CBCentralManager) {
print("central state updated")
print(central.description)
if central.state == .PoweredOff {
print("bluetooth is off")
}
if central.state == .PoweredOn {
print("bluetooth is on")
let advertisingData = [CBAdvertisementDataLocalNameKey:"my-peripheral", CBAdvertisementDataServiceUUIDsKey: uuid]
let service = CBMutableService(type: uuid, primary: true)
self.peripheralManager.addService(service)
peripheralManager.startAdvertising(advertisingData)
centralManager.scanForPeripheralsWithServices(nil, options: nil)
}
if central.state == .Unsupported {
print("bluetooth is unsupported on this device")
}
}
func peripheralManagerDidUpdateState(peripheral: CBPeripheralManager) {
print("peripheral state updated")
print("\(peripheral.description)")
}
}
I have installed this on two devices, the issue seems to be in the transmission of the advert since peripheralManagerDidStartAdvertising() is never called.
The issue is related to immediate call .startAdvertising() right after .addService() call.
You must call .startAdvertising() ONLY after func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) delegate method is called.
If you use this init method the centralManagerDidUpdateState is going to work. You can set the CBCentralManagerScanOptionAllowDuplicatesKey option if you would like to see the beacons continually.
import UIKit
import CoreBluetooth
class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralManagerDelegate {
var centralManager:CBCentralManager!
var peripheralManager:CBPeripheralManager = CBPeripheralManager()
let uuid:CBUUID = CBUUID(string: "DCEF54A2-31EB-467F-AF8E-350FB641C97B")
override func viewDidLoad() {
super.viewDidLoad()
self.peripheralManager = CBPeripheralManager(delegate: self, queue: nil)
self.centralManager = CBCentralManager(delegate: self, queue: nil)
let advertisingData = [CBAdvertisementDataLocalNameKey:"my-peripheral", CBAdvertisementDataServiceUUIDsKey: uuid]
peripheralManager.startAdvertising(advertisingData)
centralManager.scanForPeripheralsWithServices([uuid], options: [ CBCentralManagerScanOptionAllowDuplicatesKey : true])
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func peripheralManagerDidStartAdvertising(peripheral: CBPeripheralManager, error: NSError?) {
print("started advertising")
print(peripheral)
}
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
print("peripheral discovered")
print("peripheral: \(peripheral)")
print("advertisement: \(advertisementData)")
if let data = advertisementData["kCBAdvDataServiceData"] {
print("found advert data: \(data)")
}
print("RSSI: \(RSSI)")
}
func startAdvert(){
let advertisingData = [CBAdvertisementDataLocalNameKey:"my-peripheral", CBAdvertisementDataServiceUUIDsKey: uuid]
peripheralManager.startAdvertising(advertisingData)
}
func centralManager(central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: NSError?) {
print("peripheral disconnected")
print("peripheral: \(peripheral)")
}
func centralManagerDidUpdateState(central: CBCentralManager) {
print("central state updated")
print(central.description)
if central.state == .PoweredOff {
print("bluetooth is off")
}
if central.state == .PoweredOn {
print("bluetooth is on")
centralManager.scanForPeripheralsWithServices(nil, options: [ CBCentralManagerScanOptionAllowDuplicatesKey : true])
startAdvert()
}
if central.state == .Unsupported {
print("bluetooth is unsupported on this device")
}
}
func peripheralManagerDidUpdateState(peripheral: CBPeripheralManager) {
print("peripheral state updated")
print("\(peripheral.description)")
}
}
The CBAdvertisementDataServiceUUIDsKey value passed to startAdvertising should be an array of CBUUID objects but you are passing a single CBUUID
let advertisingData = [CBAdvertisementDataLocalNameKey:"my-peripheral", CBAdvertisementDataServiceUUIDsKey: [uuid]]