I have a BLE device (obd2 dongle) that I want to connect to. I can pair with it through "settings" but I can't discover it via didDiscoverPeripheral delegate method , any help ?
- (void)viewDidLoad {
[super viewDidLoad];
_centralManager =[[CBCentralManager alloc]initWithDelegate:self queue:nil];
[self scan];
}
-(void)scan {
NSDictionary *options1 =#{ CBCentralManagerScanOptionAllowDuplicatesKey : #YES };
[_centralManager scanForPeripheralsWithServices:nil options:options1];
}
-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
if (central.state == CBCentralManagerStatePoweredOn) {
[self scan];
}
}
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI {
[peripheral readRSSI];
[central connectPeripheral:peripheral options:nil];
}
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
CBPeripheral *peripheral1 =peripheral;
NSLog(#"peripheral1 name = %#",peripheral1.name); peripheral.delegate=self;
[peripheral discoverServices:nil];
}
Related
I have a connected & paired up Bluetooth LE bracelet (Service ID: FF20), which have 2 characteristics:
0xFF21 : Write without Response
0xFF22 : Notify
Now I try to write data via CoreBluetooth Framework to 0xFF21 with the following code:
I defined 2 constants at header file:
#define TRANSFER_SERVICE_UUID #"FF20"
#define TRANSFER_SERVICE_CHARACTERISTIC_UUID #"FF21"
.m
- (void)viewDidLoad {
[super viewDidLoad];
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
if (central.state != CBCentralManagerStatePoweredOn) {
return;
}
if (central.state == CBCentralManagerStatePoweredOn) {
NSArray* connectedDevices = [_centralManager retrieveConnectedPeripheralsWithServices:#[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]]];
for (CBPeripheral *peripheral in connectedDevices) {
NSLog(#"Device Found. CBPeripheral = %#", peripheral);
peripheral.delegate = self;
if(peripheral.services.count == 0) {
NSLog(#"No service found");
}
for (CBService *service in peripheral.services) {
if(service.characteristics != nil) {
for (CBCharacteristic *characteristic in service.characteristics) {
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:TRANSFER_CHARACTERISTIC_UUID]]) {
// check notifying ?
NSData *data = [#"Testing" dataUsingEncoding:NSUTF8StringEncoding];
[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
} else {
NSLog(#"Specific Characteristic Not found");
}
}
} else {
NSLog(#"Characteristic is NULL");
}
}
}
}
}
The log appears:
Device Found. CBPeripheral = <CBPeripheral: 0x1740f5080, identifier = 4EFF694C-017A-536F-9301-2EB2CC316CBE, name = Bracelet-0366, state = disconnected>
No service found
What did I miss?
You need to issue a connect to the discovered peripheral and get a call to your didConnectPeripheral delegate method before you can issue read/write requests.
When you reach the poweredOn state you should issue a scanForDevicesWithServices call, wait for the call back to your delegate, then connect, discover the service and characteristics, then you can issue a write.
-(void) centralManagerDidUpdateState:(CBCentralManager *)central {
switch (central.state) {
case CBCentralManagerStatePoweredOn:
[central scanForPeripheralsWithServices:#[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]] options:nil];
break;
}
}
-(void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
NSLog(#"Discovered peripheral %# (%#)",peripheral.name,peripheral.identifier.UUIDString);
if (self.connectedPeripheral == nil) {
[central connectPeripheral:peripheral options:nil];
}
}
-(void) centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
self.connectedPeripheral=peripheral;
NSLog(#"Connected to %#(%#)",peripheral.name,peripheral.identifier.UUIDString);
peripheral.delegate=self;
[peripheral discoverServices:#[[CBUUID UUIDWithString:TRANSFER_SERVICE_UUID]];
}
-(void) peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
for (CBService *service in peripheral.services) {
NSLog(#"Discovered service %#",service.description);
[peripheral discoverCharacteristics:nil forService:service];
}
}
-(void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
for (CBCharacteristic *characteristic in service.characteristics ) {
NSLog(#"Discovered characteristic %#(%#)",characteristic.description,characteristic.UUID.UUIDString);
if ([characteristic.UUID.UUIDString isEqualToString:TRANSFER_SERVICE_CHARACTERISTIC_UUID) {
NSData *data = [#"Testing" dataUsingEncoding:NSUTF8StringEncoding];
[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
}
}
}
Note, that from your previous question the characteristic only supports write without response, so you can't use CBCharacteristicWriteWithResponse
I have two devices (ipad 3 and iphone 4s), and was trying to find a way to recognize one of the two devices (For future exchange information between them), for that, I'm with active Bluetooth devices in 2, and using the following code:
- (void)viewDidLoad {
[super viewDidLoad];
CBUUID *otherDevice = [CBUUID UUIDWithString:#"180A"];
NSDictionary *scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
self.mgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
[self.mgr scanForPeripheralsWithServices:[NSArray arrayWithObject:otherDevice] options:scanOptions];
}
#pragma mark - delegates
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
NSLog(#"I found new devices -> %#",[NSString stringWithFormat:#"%#",[advertisementData description]]);
}
-(void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals{
NSLog(#"This is it!");
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
NSString *messtoshow;
switch (central.state) {
case CBCentralManagerStatePoweredOn:
{
messtoshow=[NSString stringWithFormat:#"Bluetooth is currently powered on and available to use."];
[self.mgr scanForPeripheralsWithServices:nil options:nil];
break;
}
}
NSLog(#"%#",messtoshow);
}
The problem with this code is that I am getting the message on the console that bluetooth is active, but the method 'didDiscoverPeripheral:' not being called, why this is happening? (since the Bluetooth on both devices are active)?
I'm pulling my hair out of this problems. I'm trying to connect to BLE devices, can't see what I've done wrong in my code below.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_cm = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
+ (NSString*)UUIDString:(CFUUIDRef)uuid {
CFStringRef string = CFUUIDCreateString(NULL, uuid);
return (__bridge_transfer NSString*)string;
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
if (central.state == CBCentralManagerStatePoweredOn) {
[self scanForPeripherals];
}
}
- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI {
// NSLog(#"Received peripheral : \n%#", peripheral);
// NSLog(#"Adv data : %#", advertisementData);
[peripheral setDelegate:self];
[central connectPeripheral:peripheral options:nil];
[peripheral readRSSI];
}
- (int)scanForPeripherals {
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], CBCentralManagerScanOptionAllowDuplicatesKey,
nil];
[_cm scanForPeripheralsWithServices:nil options:options];
return 0;
}
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(#"didConnectPeripheral");
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(#"didDisconnectPeripheral");
}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(#"failed to connect");
}
- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(NSError *)error {
NSLog(#"didReadRSSI");
}
These devices are not my own. I don't know its proximity UUID, but as far as I know, It won't be needed in connecting via CoreBluetooth right?
All of the devices are discovered in didDiscoverPeripheral:, in the selector I tried to connect them. But there's nothing comes after that.
Am I to expect a dialog with Pairing Password Request when I called to didDiscoverPeripheral:?
If so I don't see any dialog, why is that?
From apple documents, It clearly stated that after trying to connect to a device you should get a called to either didConnectPeripheral or didFailToConnectPeripher but I got none.
Any thoughts? I've been trying for almost a week now.
Appreciate every helps, thanks.
If you don't somehow retain the peripheral object that is delivered to didDiscoverPeripheral then it is released once this delegate method exits and you won't get a connection.
I suggest adding a property to track discovered peripherals
#property (strong,nonatomic) NSMutableArray *peripherals;
initialise this in viewDidLoad or init
self.peripherals=[NSMutableArray new];
And then add the peripheral to it in didDiscoverPeripheral
-(void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(#"Discovered peripheral %#",peripheral.identifier.UUIDString);
[self.peripherals addObject:peripheral];
[central connectPeripheral:peripheral options:nil];
}
var peripherals = [CBPeripheral]()
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
peripherals.append(peripheral)
bleManager.connectPeripheral(peripheral, options: nil)
}
This is the Swift version.
I try to make program to detect uncertain Bluetooth device at iOS.
The device scanning work well but it could not detect any device. However in the basic option in Ipad, the bluetooth devices were detected well. Bellow show the my code. Please advise to fix some problem.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//CB setup
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
// You should test all scenarios
if (central.state != CBCentralManagerStatePoweredOn) {
return;
}
if (central.state == CBCentralManagerStatePoweredOn) {
_scan_state = 1;
}
[self deviceScan];
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
NSLog(#"dicovered: %#", peripheral.name);
if(![self.BTNames containsObject:peripheral]){
[self.BTNames addObject:peripheral];
}
_num_cell = self.BTNames.count;
[self.BTList reloadData];
}
- (void) deviceScan{
if(_scan_state){
/* [_centralManager scanForPeripheralsWithServices:nil options:#{ CBCentralManagerScanOptionAllowDuplicatesKey : #NO }];*/
[_centralManager scanForPeripheralsWithServices:nil options:nil];
NSLog(#"Scan Starting");
}
}
I initialize the CBCenteralManager in viewdidload on main queue. First time update state method is called and start scanning for bluetooth devices but didDiscoverPeripheral: delegate method never get called.
Code is :
- (void)viewDidLoad
{
[super viewDidLoad];
self.CM = [[CBCentralManager alloc]initWithDelegate:self queue:nil];
}
-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
if (central.state == CBCentralManagerStatePoweredOn) {
[self.CM scanForPeripheralsWithServices:nil options:nil];
}
}
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral(CBPeripheral*)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
}
-(void)centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals{
}
-(void)centralManager:(CBCentralManager *)central didRetrieveConnectedPeripherals:(NSArray *)peripherals{
}
-(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
}
-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
}
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
}