What devices does CBCentralManager.retrieveConnectedPeripherals() return? - ios

I want to check which Bluetooth Devices my iPhone is connected to. In order to do that, I use CBCentralManager.retrieveConnectedPeripherals() like this:
let connectedPerphs = centralManager.retrieveConnectedPeripherals(withServices: []);
My problem is that even if my iPhone is connected to a BluetoothDongle (it explicitly says "connected" in the settings), the list that is returned by retriveConnectedPeripherals() is always empty. Am I using the method in a wrong way or can it not be used to detect a bluetooth connection such as the connection to to my dongle? If the latter is the case, how can I detect that connection?

Let me clear, centralManager.retrieveConnectedPeripherals always return empty or nil value, If you are not passing any value into serviceUUIDs
retrieveConnectedPeripherals(withServices:)
Returns a list of the peripherals (containing any of the specified
services) currently connected to the system.
serviceUUIDs:
A list of service UUIDs (represented by CBUUID objects).
Update:
Unfortunately this the long way to do it. You can create Array of CBUUID statically then you can pass it to the method. Please refer below code.
let aryUUID = ["1800","18811"]
var aryCBUUIDS = [CBUUID]()
for uuid in aryUUID{
let uuid = CBUUID(string: "1800")
aryCBUUIDS.append(uuid)
}
let connectedPerphs = centralManager.retrieveConnectedPeripherals(withServices: aryCBUUIDS)
List of available services

First, this works only with BLE devices, thus if your dongle is using a common BT you will not get it from here, but probably using EAAccessoryManager var connectedAccessories: [EAAccessory] method, but as far as I know your app must comply to MFI.
That is why is asking which service your devices are exposing as a filter.

Related

how to detect what bluetooth device audio is coming out of

I have two BluetoothHFP bluetooth devices connected to my iPad(bluetoothA2DP and bluetoothLE) and I need to detect which one is currently getting the audio. Below is the code I am using to detect what bluetooth is available :
let currentRoute = audioSession.currentRoute
for description in currentRoute.outputs {
if convertFromAVAudioSessionPort(description.portType) == convertFromAVAudioSessionPort(AVAudioSession.Port.bluetoothA2DP) {
//Do Something
break
}else if convertFromAVAudioSessionPort(description.portType) == convertFromAVAudioSessionPort(AVAudioSession.Port.bluetoothHFP) {
//Do Something
break
}else if convertFromAVAudioSessionPort(description.portType) == convertFromAVAudioSessionPort(AVAudioSession.Port.bluetoothLE){
//Do Something
break
}
}
What can I use to find out what one of the BluetoothHFP devices is currently getting audio?
You can distinguish between ports of the same type using description.portName and description.uid. Note that the name is not promised to be unique (it comes from the device). The UID is system-assigned and is not promised to be stable. It's only promised to be consistent with the owningPortUID property, and will be unique at any given time.
It happens to be true currently (iOS 13) that the UID is based on the hardware MAC address, and is stable. It's in the format aa:bb:cc:dd:ee:ff-tacl (the MAC address followed by -tacl). This has been true for a long time. I've been using this fact since at least iOS 8, and it's very likely it's been true as long as AVAudioSession has been around. But it's not promised, and is exactly the kind of thing that Apple has been known to change without notice.

How to get Paired BLE device in iOS?

I connect BLE with CoreBluetooth and paired.
Now when I back to my app screen, I want to make sure that BLE already paired with iOS device.
If I store value in defaults and remove app, this case will not work to fetch device.
If user remove paired bluetooth peripheral from Setting -> Bluetooth -> list of devices this case also not work to identify.
NSArray *ary = [self.bleMgr retrieveConnectedPeripheralsWithServices:#[[CBUUID UUIDWithString:#"180A"]]];
NSUUID *nsUUID = [[NSUUID alloc] initWithUUIDString:identifier];
NSArray *temp = [self.bleMgr retrievePeripheralsWithIdentifiers:#[nsUUID]];
Above both code lines not giving robust result.
How to get that paired BLE device in app?
The first time you discover a peripheral, the system generates an identifier (a UUID, represented by an NSUUID object) to identify the peripheral.
You can then store this identifier (using, for instance, the resources of the NSUserDefaults class), and later use it to try to reconnect to the peripheral using the retrievePeripheralsWithIdentifiers: method of the CBCentralManager class.
The following describes one way to use this method to reconnect to a peripheral you’ve previously connected to.
knownPeripherals = [myCentralManager retrievePeripheralsWithIdentifiers:savedIdentifiers];
The NSUUID class is not toll-free bridged with CoreFoundation’s
CFUUID. Use UUID strings to convert between CFUUIDRef and NSUUID, if
needed. Two NSUUID objects are not guaranteed to be comparable by
pointer value (as CFUUID is); use isEqual(_:) to compare two NSUUID
instances.
Refer this: https://developer.apple.com/documentation/foundation/nsuuid
Refer last two sections: https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/BestPracticesForInteractingWithARemotePeripheralDevice/BestPracticesForInteractingWithARemotePeripheralDevice.html#//apple_ref/doc/uid/TP40013257-CH6-SW1

How to pair with another BLE device using Ionic?

so in this question I asked how would I identify a bluetooth device after doing an scan. It seems that only those devices I have connected to show their name, all other devices are shown as unnamed.
So my question is, how do I pair all the unnamed devices using the Ionic Native BLE library? It doesn't matter if I need to do a manual process for each one (since this will be done only once). Thanks in advance.
Using your example, when you scan you get objects like this:
{
id: "2BD5D5A7-EF50-B4F4-D4FD-9A8413006D4B",
rssi: -24,
advertising: {
kCBAdvDataIsConnectable: true
},
name: ""
}
where name is an empty string which is your term unnamed.
You can check if the name is an empty string, take the id value instead to establish BLE connection.
ble.connect("2BD5D5A7-EF50-B4F4-D4FD-9A8413006D4B", connectSuccess, connectFailure);

GetDescriptor() null value / 128-bit UUID descriptor?

I'm writing my code using Xamarin. I'm developing my IOS app which allows me to read the BLE devices, Services, characteristic value and activation of the notification.
My BLE beacon have one custom Services that contain two custom characteristics and both have the notification implemented using CCCD.
My ble devices work correctly I test it with BLE scanner app and it working well without any problem.
I can read value and I can active the notification for both characteristic. See picture here.
The app that I wrote using xamarin work correctly (reading services, characteristic value....) the only problem that didn't work is the activation of the notification. Here's a portion of the code :
public UUID Charac_UUID0 = UUID.FromString("0000beef-1212-efde-1523-785fef13d123");
public UUID Charac_UUID = UUID.FromString("0000b1e0-1212-efde-1523-785fef13d123") ;
public UUID Descr_UUID = UUID.FromString("00002902-1212-efde-1523-785fef13d123");
protected BluetoothGattCharacteristic _charac;
....
....
this._charac = App.Current.State.SelectedService.GetCharacteristic(Charac_UUID0);
BluetoothLEManager.Current.ConnectedDevices[App.Current.State.SelectedDevice].SetCharacteristicNotification(_charac, true);
BluetoothGattDescriptor descriptor = _charac.GetDescriptor(Descr_UUID0);
descriptor.SetValue(BluetoothGattDescriptor.EnableNotificationValue.ToArray());
BluetoothLEManager.Current.ConnectedDevices[App.Current.State.SelectedDevice].WriteDescriptor(descriptor);
The code always give me an error at descriptor.SetValue and it indicate me that the descriptor is NULL meaning that _charac.GetDescriptor didn't return any value.
I suspect the Descriptor UUID value (Descr_UUID) is not correct. I don't know excatly how can I determine the Descr_UUID but I saw many example in the internet of people replacing the custom UUID of the caracteristic by 2902 which give me in my case a 128 descriptor UUID equal to 00002902-1212-efde-1523-785fef13d123.
But there is a problem here. The descriptor UUID for both characteristic will be the same because the base UUID is the same for both characteristic?
Any solution?
3 years later im sure you figured it out but, 2902 is the 16 bit value for a Client Characteristic Configuration Descriptor, and I believe it should also be inflated using the "BASE UUID" not just whatever your characteristic descriptor uses. See this: answer
This will convert your 16 (or 32) bit uuids to full 128 bit uuids using the BASE UUID:
public static UUID ConvertUuid(uint uuid)
{
const long msbMask = 0x0000000000001000;
const ulong lsb = 0x800000805f9b34fb;
var msb = msbMask | ((ulong)(uuid & uint.MaxValue) << 32);
return new UUID((long)msb, unchecked((long)lsb));
}

How can I get details about the device data provider (like Verizon/AT&T) of an iphone programmatically?

I am trying to create an ios application and I want to segment the users based on the data providers they are using, such as Verizon and AT&T. Is it possible to get this information programmatically from the ios application.
You should check the CTCarrier.
Just import CoreTelephony into your Swift file.
Then you can use the carrierName property to get the name of your carrier.
// Setup the Network Info and create a CTCarrier object
let networkInfo = CTTelephonyNetworkInfo()
let carrier = networkInfo.subscriberCellularProvider
// Get carrier name
let carrierName = carrier.carrierName
Now that you can have multiple SIM cards, subscriberCellularProvider is deprecated in favor of serviceSubscriberCellularProviders. You can get an array of the providers with this:
let carriers = CTTelephonyNetworkInfo().serviceSubscriberCellularProviders?.values
In my case, I was checking to see if the user has an American phone number so they can text support instead of email. You can do that with this:
carriers.contains { $0.isoCountryCode?.lowercased() == "us" }
On my phone, I only have one SIM card, but this array returns two values and one has all nil properties so be sure to handle that if you are inspecting them.
You will want to use the CTCarrier carrierName in the CoreTelephony framework: https://developer.apple.com/library/prerelease/ios/documentation/NetworkingInternet/Reference/CTCarrier/index.html#//apple_ref/occ/instp/CTCarrier/carrierName

Resources