My past few articles on Bluetooth and Android , came with some sample source codes to provide an easier start for those interested in this wireless technology.
Now I'm surprised to see that another successful mobile OS - Apple's iOS - has the same never-ending issues when it comes to a simple development task - writing a bluetooth application. Starting with iOS development was easy and straight-forward, but Bluetooth and iOS seems to be a no can do. Is it really?
The purpose is to control the Bluetooth Radio: on, off , set it in discoverable mode, discover nearby devices, and establish a RFCOMM connection. Ideally we would also want access to L2CAP and SDP, but for a start let's take it slow.

Evaluating the available options

Here's a list with possible approaches one should consider when wanting to write a BLuetooth application for iPhone. The list is sorted having the better/official choice in mind. Workarounds get to the bottom of the list:
1. Enroll in the made for iPhone/iPod/iPad (MFI) program. Details on costs are not available, but this is not for the small development companies, barely selling a few licenses. Some sources indicate costs depending on project, and starting numbers somewhere at 10K USD.
Not really an option IMO, as the costs involved and trouble getting certified are ridiculously high, for something so basic and simple such as building a Bluetooth application.
2. CoreBluetooth framework, currently usable only with Low Energy Bluetooth 4 devices. Since these are not largely spread this is not really an option. You won't be able to connect to standard headsets, keyboards, or other non-Bluetooth 4 devices. Also at the moment of speaking, the iPhone 4S is the only device capable of LE Bluetooth functionality. Again, not an option.
3. GameKit framework, this allows some basic Bluetooth functionality, such as finding nearby devices and establishing a serial communication link, but it only intended for use between iOS devices. So Android plus iPhone via GameKit is a no go. Remember to thank Apple for making it this way. Or not.
4. Private APIs. There is a BluetoothManager framework, in the private APIs, inside the SDK. This can be used to achieve the proposed task, but you won't get your App approved on Appstore, as private API's is not allowed by Apple. Since this is so convenient, and working so nice, almost like the real thing Apple didn't want to include, I will be using it for this article.
5. Jailbreaking and using Ringwald's BTStack. Jailbreaking = rooting = freedom, probably the best way to go . But this places you so far away from Apple's guidelines, and the Appstore itself. So better decide what your project is all about, and who your users will be.

iOS BluetoothManager Framework

Installing the Header files
Get the 4 .h files from here or here.
Browse to your Xcode installation at:
Create a new folder, "Headers", and copy the 4 .h files there:

Adding the new Framework in Xcode
Go to Xcode, click the project in the Navigator, and select "Build Phases". Under "Link binary with Libraries", press the Plus symbol. Select BluetoothManager.framework and click Add.

Using BluetoothManager.framework
In your

  1. viewDidLoad

do the following:
1. get an handler to and instance of the BluetoothManager service:

  2. // setup bluetooth interface
  3. btManager = [BluetoothManager sharedInstance];

2. register for notifications, for Bluetooth radio change (on/off) and for discovering a new device:

  2. // setup bluetooth notifications
  3. [[NSNotificationCenter defaultCenter]
  4. addObserver:self
  5. selector:@selector(deviceDiscovered:)
  6. name:@"BluetoothDeviceDiscoveredNotification"
  7. object:nil];
  9. [[NSNotificationCenter defaultCenter]
  10. addObserver:self
  11. selector:@selector(bluetoothAvailabilityChanged:)
  12. name:@"BluetoothAvailabilityChangedNotification"
  13. object:nil];

3. Not needed for the purpose of this app, but it really helped me during development, you can set a notification Observer, and get all system notifications, including the Bluetooth notifications or other unknown notifications. You can later register them as shown at step 2).

  3. // global notification explorer
  4. CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(),
  5. NULL,
  6. MyCallBack,
  7. NULL,
  8. NULL,
  9. CFNotificationSuspensionBehaviorDeliverImmediately);

And the callback function is a simple debug logger, outside viewDidLoad:

  2. // global notification callback
  3. void MyCallBack (CFNotificationCenterRef center,
  4. void *observer,
  5. CFStringRef name,
  6. const void *object,
  7. CFDictionaryRef userInfo) {
  8. NSLog(@"CFN Name:%@ Data:%@", name, userInfo);
  9. }

As I said, this is an extremely useful piece of code.

4. Set the callback for the notifications registered at step 2):

  2. /* Bluetooth notifications */
  3. - (void)bluetoothAvailabilityChanged:(NSNotification *)notification {
  5. NSLog(@"NOTIFICATION:bluetoothAvailabilityChanged called. BT State: %d", [btManager enabled]);
  6. }

And here is the second one, for discovering devices nearby:

  2. - (void)deviceDiscovered:(NSNotification *) notification {
  4. BluetoothDevice *bt = [notification object];
  6. NSLog(@"NOTIFICATION:deviceDiscovered: %@ %@",, bt.address);
  8. //create a new list item
  9. BTListDevItem *item = [[BTListDevItem alloc] description:bt.address type:0 btdev:bt];
  11. //add it to list
  12. NSMutableArray *tempArray = [[NSMutableArray alloc] initWithArray:btDevItems];
  13. [tempArray addObject:(item)];
  14. btDevItems = tempArray;
  15. [myTableView reloadData];
  16. }

As you can see, the incoming notification itself is a newly discovered device, sent in the form of a BluetoothDevice object. To get it correctly I've used :

  2. BluetoothDevice *bt = [notification object];

We store the name, the bluetooth address and the pointer to the BluetoothDevice object for later use. The name and address is used to populate the list view:

5. Turn bluetooth on / off . This is easy: we have two buttons, pressing them results in calling one of the following methods:

  2. /* Interface actions - bt on */
  3. - (IBAction)bluetoothON {
  4. NSLog(@"bluetoothON called.");
  5. [btManager setPowered:YES];
  6. [btManager setEnabled:YES];
  8. }
  10. /* Interface actions - bt off */
  11. - (IBAction)bluetoothOFF {
  12. NSLog(@"bluetoothOFF called.");
  13. //BluetoothManager *manager = [BluetoothManager sharedInstance];
  14. [btManager setEnabled:NO];
  15. [btManager setPowered:NO];
  16. }

6. Triggering bluetooth discovery. I do not enable searching for nearby bluetooth devices by default. Instead, I've added a Scan Button. The logic behind it is as following: check the bluetooth state , if on, start looking for nearby devices (resulting in device found notifications), if bluetooth is off, just throw an error message to inform the user:

  2. /* Interface actions - scan */
  3. - (IBAction)scanButtonAction {
  4. if ([btManager enabled]) {
  5. // clear listview
  6. [self clearAllList];
  7. // start scan
  8. [btManager setDeviceScanningEnabled:YES];
  9. } else {
  10. showMessage(@"Error", @"Turn Bluetooth on first!");
  11. }
  12. }

7. Establishing a connection
There are two approaches here:
7A. Use BluetoothManager's "connectDevice" method (see BluetoothManager.h) . This method taken a single parameter, a string representing the bluetooth address we need to connect to. For some reason this only worked partially, so I abandoned this method in favor of:
7B. Use BluetoothDevice's "connect" . Remember when we saved a pointer to a BluetoothDevice in the Discovery callback function? Now it's so easy using it!
When the user clicks an item in our list, we do the following:

  2. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  3. BTListDevItem *item = (BTListDevItem *)[btDevItems objectAtIndex:indexPath.row];
  5. NSString *message = [NSString stringWithFormat:@"Device %@ [%@]",, item.description];
  7. showMessage(@"Connect to:", message);
  9. [self deviceConnect <img src="" alt=":(" class="wp-smiley" style="height: 1em; max-height: 1em;" /> indexPath.row)];
  11. }

And the deviceConnect function, taking a parameter identifying the index of the device we want to connect to , in our array of devices , is even simpler:

  2. /* Bluetooth connectivity */
  3. - (void)deviceConnect:(NSInteger)index {
  4. BTListDevItem *item = (BTListDevItem *)[btDevItems objectAtIndex:index];
  5. NSLog(@"deviceConnect to %@",;
  7. [item.btdev connect];
  8. }

The connection results

I've tried to connect to a notebook computer equipped with Bluetooth (named Moon-PC) and to a HID Bluetooth Keyboard (named Celluon).

Connecting to the notebook
The notebook exposes the following Bluetooth profiles:
Bluetooth File Transfer Service
Bluetooth Information Synchronization Service
Bluetooth Object Push Service
Bluetooth AV Service
Bluetooth Headset Service

The BluetoothDevice.connect() resulted in the following:

  2. 2012-07-16 19:51:25.364 Bluetooth[706:707] deviceConnect to MOON-PC
  3. 2012-07-16 19:51:25.366 Bluetooth[706:707] BTM: connecting to device "MOON-PC" C4:46:19:C6:39:D1
  4. 2012-07-16 19:51:27.743 Bluetooth[706:707] BTM: attempting to connect to service 0x00000010 on device "MOON-PC" C4:46:19:C6:39:D1
  5. 2012-07-16 19:51:27.751 Bluetooth[706:707] BTM: attempting to connect to service 0x00000008 on device "MOON-PC" C4:46:19:C6:39:D1
  6. 2012-07-16 19:51:28.994 Bluetooth[706:707] BTM: connection to service 0x00000010 on device "MOON-PC" C4:46:19:C6:39:D1 failed with error 305
  7. 2012-07-16 19:51:30.286 Bluetooth[706:707] BTM: connection to service 0x00000008 on device "MOON-PC" C4:46:19:C6:39:D1 failed with error 305

The Celluon keyboard only exposes the HID profile, and here is the connection result:

  2. 2012-07-16 19:53:45.727 Bluetooth[706:707] deviceConnect to Celluon
  3. 2012-07-16 19:53:45.732 Bluetooth[706:707] BTM: connecting to device "Celluon " 00:18:E4:27:18:39
  4. 2012-07-16 19:53:47.204 Bluetooth[706:707] BTM: attempting to connect to service 0x00000020 on device "Celluon " 00:18:E4:27:18:39
  5. 2012-07-16 19:53:47.216 Bluetooth[706:707] BTM: connection to service 0x00000020 on device "Celluon " 00:18:E4:27:18:39 failed with error 305

It is clear that the BluetoothManager identified 2 of the 5 profiles exported by the notebook, and the HID profile exported by the Celluon keyboard. These profiles seem to be coded with the hex identifiers shown in the debug content: 0x00000010, 0x00000008, 0x00000020

Even if the connection fails, it is a good starting point in investigating how to establish a solid connection, and receive data. Since the services are recognized by the BluetoothManager , it is surely possible to use the existing functionality, and the already implemented protocols.

This research work has been performed on an iPod, running OS 5.1 .

You can use this code or any parts of it, ONLY if you provide a visible link within your work/project/article, to this webpage. If you agree, you can download the complete source code: Bluetooth iOS Code.

(Visited 15,192 times, 4 visits today)
Tagged on:                                                                     

64 thoughts on “Bluetooth and iOS – Use Bluetooth in your iPhone apps

  • January 17, 2014 at 10:54 pm

    sorry – there is the link at the bottom. Now I found my issue. It works now

  • January 28, 2014 at 8:08 am

    Hi Radu,
    Thanks for the guide. Its a really good one for showing how to connect, but did you ever get any RFCOMM (serial) data going between the devices.

    I am wondering if you ever tried that, as this would be a logical next step to what you were trying to achieve as mentioned above: “discover nearby devices, and establish a RFCOMM connection”
    Looking through the functions in the header file, I do not see any send data methods, or any other way of doing this.
    Would really appreciate if you could point me to a useful resource.


  • April 14, 2014 at 8:56 am

    Not work in ios 7, iphone 5s, :(

    I am newbie, no clues, :)

  • May 4, 2014 at 2:59 pm

    I’m trying to connect an iOS device with a little printer. I don’t want the user to have to go to the settings to pair them.
    Would it be possible to get them pair with this? It’s not for the App Store, so I’m safe that way.
    I will know the MAC address and the Bluetooth pin of each printer, so “forcing” the pairing hopefully should be possible.

    Any help and code snippets would be gratefully appreciated.

  • May 10, 2014 at 12:01 pm

    This sample runs in iOS 6.1 and iOS 7.0.4 but in iOS 7.0.4 cannot scan. Do you have any idea what is the problem in iOS7.0.4

  • August 29, 2014 at 1:07 am

    I am getting below build error when I choose my IPhone 5S (iOS7.1). Do you have any idea what is the problem? When I choose target IPhone Retina 4inch 64 bit, compiles/build/run fine on the simulator.

    ld: framework not found BluetoothManager
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

    Any help is much appreciated.

  • January 1, 2015 at 9:39 am


    1. What is the next steps to send / recv data? Does someone have an extended sample that does so?
    2. Do I have to write HID driver over the PC (Win8)?

    Has someone managed to transfer data over BT (Windows-iOS)?

  • February 3, 2015 at 5:11 pm

    does anyone know how could we transfer data between them using BluetoothManager.framework?

  • February 3, 2015 at 5:16 pm

    Does anyone know how to transfer data using BlutoothManager.framework? I found that there are three empty struct declaration in the header:BTAccessoryManagerImpl & BTSessionImpl &BTDeviceImpl,maybe the answer lies in here.any help,bloody thx.

  • February 3, 2015 at 5:24 pm

    Dear Radu
    do you know how to transfer data using BlutoothManager.framework? I found that there are three empty struct declaration in the header:BTAccessoryManagerImpl & BTSessionImpl &BTDeviceImpl,maybe the answer lies in here.any help,bloody thx.

  • March 2, 2015 at 7:43 am

    Dear me
    Can we modified the CLF (compact light florescent)circuit into induction heater circuit thank you

  • June 26, 2015 at 2:34 pm

    problem of #import “NSObject.h” in #import “BluetoothManager.h” class …. plz help me

  • June 26, 2015 at 4:10 pm

    NSObject.h is not found in DeviceManager.h…………….

  • July 22, 2015 at 10:09 am

    Hi Radu,

    Does the code can support HID bluetooth profile?
    i’m trying to link my iOS device with a bluetooth module which using bluetooth HID profile
    Can provide bluetooth HID protocol set?
    Thank you.

Leave a Reply

Your email address will not be published. Required fields are marked *