Apple introduced Core Bluetooth Framework with IOS 5 SDK. With the Core Bluetooth framework, developers can write an application that communicates with hardware gadgets and ios devices using Bluetooth Low Energy Standard.
In this article, we will see about Bluetooth low energy and an overview of the Core Bluetooth Framework.
Bluetooth Low Energy(BLE), sometimes referred to as Bluetooth Smart, is the technology for transferring data. It consumes low energy and allows the device battery to last longer. Ideally, BLE is used to transmit small packets of data, such as fitness-related data, to a fitness tracker.
Two major players are involved in all Bluetooth low-energy communication: Central and Peripheral.
It defines the logic behind Core Bluetooth communication. It can scan, connect and disconnect peripherals and consumes information available at each peripheral. The central devices are usually mobile devices or tablets.
The device with information to share, e.g., Heart rate or temperature etc. The information can be pushed or advertised over the air. The peripheral devices are things like Heart rate monitors, BLE enables proximity tags, etc.
The following image defines the relationship between central and peripherals.
In the above scenario, IOS devices (Central) communicate with the Heart rate Monitoring system (Peripheral) to get heart rate information and show it on a device.
In Bluetooth low energy, Advertising is the primary way peripherals make their presence known via BLE.
Peripherals broadcast some of the data they have in advertising packets. An advertising packet is a relatively small bundle of data that may contain useful information that peripheral offers, such as the peripheral’s name and other primary functionality. For example, a Heart rate monitor may advertise that it provides a Heartbeat per minute.
On the other hand, Central can scan and listen to any peripheral advertising device and connect to a particular device for more information that it’s interested in.
BLE peripheral is connected to Only one central at One time. As a peripheral connects to a central device, it will stop advertising itself, and other devices will no longer be able to see or connect to it until the existing connection is broken.
The Bluetooth low-energy devices transfer the data through Services and Characteristics.
Services are the collection of data or characteristics. The device can contain multiple services. Each service distinguishes itself from other services by using a Unique Numeric Id called UUID, which can be either 16-bit or 128-bit.
Characteristics are like properties of the peripheral device, which provides more details about the services. the service can have more than one characteristic. Similar to the service characteristics also distinguishes itself using predefined 16-bit or 128-bit UUID.
In the core Bluetooth framework, peripherals are represented by the CBPeripheral object and services related to the peripheral device are represented by the CBService object.
CBCharacteristics objects are used to represent characteristics of peripheral services. Central is represented by the CBCentralManager object that manages discovered and connected peripherals.
The following figure shows the basic hierarchical structure of peripherals services and characteristics.
Now we have enough knowledge about core Bluetooth before we proceed, I will give you the basic workflow of core Bluetooth:–
1. First, Create an Object of CBCentralManager.
2. If the Central device state is PoweredOn, Scan for the peripheral device.
3. When you find a peripheral you want to connect to, stop scanning and then connect to the peripheral you found.
4. After the connection successfully discovers the peripheral services, you can discover a specific service or ask to return all services that the peripheral offers.
5. After you find the service you are interested in, discover its characteristics. The peripheral service may have one or more characteristics.
6. When you find the characteristic you are interested in, you can read from or Write the values to those characteristics.
Let’s create one project with a single view controller and add the Core Bluetooth Framework.
Import the corebluetooth framework in viewcontroller and confirm the delegate CBCentralManagerDelegate and CBPeripheralDelegate.
First, you must allocate and initialize a central manager instance before you can perform any Bluetooth low-energy transactions.
Create object of CBCentralManager and confirm delegates in viewDidLoad
var centralManager:CBCentralManager! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. centralManager = CBCentralManager() centralManager = CBCentralManager(delegate: self, queue: dispatch_get_main_queue(), options:nil) }
When you create a central manager, the central manager calls the centralManagerDidUpdateState: method of its delegate object. you must implement this delegate method to ensure that Bluetooth low energy is supported and available on the central device.
There are the following states of CBCentralManager:–
Implement the method to get the device state. As mentioned earlier central discovers and connects to peripherals that are advertising. You can discover any peripheral advertising device by calling scanForPeripheralsWithServices:options: method of CBCentralManager class. Like this :
print(“Scanning Started“) centralManager.scanForPeripheralsWithServices(nil,options:[CBCentralManagerScanOptionAllowDuplicatesKey : false])
NOTE:
Here we pass nil for the first parameter; the central manager returns all discovered peripherals regardless of their supported services. instead of nil, you can pass an array of CBUUID objects, each representing the UUID of a service that is peripheral advertising.
After scanning is completed, the central manager calls the central manager: didDiscoverPeripheral:advertisementData:RSSI: method each time a peripheral is discovered. Each peripheral that is discovered is returned as CBPeripheral object.
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
print(“Discovered \(peripheral.name) at \(RSSI)”)
}
Stop scanning for other devices to save power when you find a peripheral.
centralManager.stopScan()
print(“Scanning Stopped“)
After you have discovered a peripheral device that is advertising services you are interested in, you can request a connection to the peripheral by calling the connectPeripheral:options: method. simply call this method and specify the discovered peripheral you want to connect to. Like this: –
central.connectPeripheral(peripheral, options: nil)
Assuming that your connection request is successful, the central manager calls the centralManager:didConnectPeripheral: method like:–
func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) { print(“Connected“) }
and before you begin interacting with the peripheral, you should set the peripherals delegate to ensure that it receives the appropriate callback
peripheral.delegate = self
after you have established a connection to the peripheral, you can begin to explore its data. First, discover its available services. You can discover all services of peripheral by calling discoverSerices: method of CBPeripheral class like: –
peripheral.discoverServices(nil)
NOTE:
In the above method, you can pass an array of CBUUID of the services you are interested in to save battery life and unnecessary use of time.
When the specified services are discovered, the peripheral calls the peripheral:didDiscoverServices: method. It creates an array of CBService objects for each service discovered on the peripheral. Implement this delegate method to access the array of discovering services like:–
func peripheral(peripheral: CBPeripheral, didDiscoverServices error: NSError?) { for service in peripheral.services! { print(“Discovered service: \(service)”) …. } ….. }
after you find the service that you are interested in. The next step is to explore the service’s characteristics to discover all characteristics of the service simply call discoverCharacteristics:forservice: method of CBPeripheral class.
print(“Discovering characteristic for service: \(interestedservice)”)
peripheral.discoverCharacteristics(nil,forService: service)
NOTE:
Here we discover all characteristics of peripheral’s service. Because a peripheral’s service may contain many more characteristics than you are interested in, instead of discovering all of them, specify the UUIDs of the characteristic that you are interested in to save battery life and unnecessary use of time.
The peripheral calls peripheral:didDiscovercharacterisitcsForSerivce:error: method of its delegate object when a characteristic of the specified service is discovered. Core Bluetooth creates an array of CBCharacteristic objects, one for each characteristic that is discovered like this: –
func peripheral(peripheral: CBPeripheral, didDiscoverCharacteristicsForService service: CBService, error: NSError?) { if (error != nil) { print(“error: \(error?.localizedDescription)”) return } for characteristic in service.characteristics! { print(“Discovered characteristic: \(characteristic)”) …… } ….. }
A characteristic contains a single value representing more information about a peripheral’s service. you can retrieve the value of a characteristic by reading it directly or subscribing to it.
After you have found a characteristic of the service that you are interested in, you can read the characteristic value by calling readValueForCharacteristic: method by specifying the appropriate characteristic.
print(“Reading value for characteristic: \(interestedcharacteristic)”)
peripheral.readValueForCharacteristic(interestedcharacteristic)
when you read a value of characteristic, the peripheral calls peripheral:didUpdateValueForCharacteristic:error: method to retrieve the value. If the value is successfully retrieved, you can access it through the characteristic value property like this: –
func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) { if (error != nil) { print(“Error:\(error?.localizedDescription)”) return } var data: NSData = characteristic.value // parse the retrieved data …….. }
NOTE
All the characteristic values are not readable. You can determine whether a characteristic value is readable by accessing the CBCharacteristicPropertyRead constant. If you try to read a value that is not readable, the peripheral:didUpdateValueForCharacteristic:error method return a suitable error.
When you subscribe to a characteristic value, you receive a notification from the peripheral when the value changes.
You can subscribe to the value of a characteristic that you are interested in by calling the setNotifyValue:forcharacteristic: method of CBPeripheral class, set the value of the first parameter as true, like this: –
peripheral.setNotifyValue(true, forCharacteristic: interestedcharacteristic)
func peripheral(peripheral: CBPeripheral, didUpdateNotificationStateForCharacteristic characteristic: CBCharacteristic, error: NSError?) { if ((error) != nil) { print(“Error changing notification state \(error?.localizedDescription)”) } else { print(“Notification began on: \(characteristic)”) } }
After successfully subscribing to a characteristic value, the peripheral notifies your app when the value has changed. each time the value changes, the peripheral calls the peripheral:didUpdateValueForcharacteristic:error: method, to retrieve the updated value, implement this method.
If the characteristic value is writable, you can write its value with some data by calling the writeValue:forcharacteristic:type: method of CBPeripheral class like this:
print(“Writing value for characteristic: \(interestedcharacteristic)”) peripheral.writeValue(data, forCharacteristic: interestedcharacteristic, type: .WithResponse)
When attempting to write the value of a characteristic, specify the type of writing you want to perform. In the above example, the write type is specified as CBCharacteristicWriteWithResponse, which indicates the peripheral let your app know whether the write is successful.
If you specified CBCharacteristicWriteType as CBCharacteristicWriteWithResponse the peripheral responds to your write request by calling peripheral:didWriteValueForCharacteristic:error: method.
func peripheral(peripheral: CBPeripheral, didWriteValueForCharacteristic characteristic: CBCharacteristic, error: NSError?) { if ((error) != nil) { print(“Error Writing characteristic value \(error?.localizedDescription)”) } }
You can also refer to a BLE-IOS-Data-Exchange project for more details.
After reading this tutorial, you should understand the core Bluetooth framework specifications and how you can use this to connect with low-energy peripheral devices to retrieve certain attributes related to the device.
How to Effectively Hire and Manage a Remote Team of Developers.
Download NowThe Mindbowser team's professionalism consistently impressed me. Their commitment to quality shone through in every aspect of the project. They truly went the extra mile, ensuring they understood our needs perfectly and were always willing to invest the time to...
CTO, New Day Therapeutics
I collaborated with Mindbowser for several years on a complex SaaS platform project. They took over a partially completed project and successfully transformed it into a fully functional and robust platform. Throughout the entire process, the quality of their work...
President, E.B. Carlson
Mindbowser and team are professional, talented and very responsive. They got us through a challenging situation with our IOT product successfully. They will be our go to dev team going forward.
Founder, Cascada
Amazing team to work with. Very responsive and very skilled in both front and backend engineering. Looking forward to our next project together.
Co-Founder, Emerge
The team is great to work with. Very professional, on task, and efficient.
Founder, PeriopMD
I can not express enough how pleased we are with the whole team. From the first call and meeting, they took our vision and ran with it. Communication was easy and everyone was flexible to our schedule. I’m excited to...
Founder, Seeke
Mindbowser has truly been foundational in my journey from concept to design and onto that final launch phase.
CEO, KickSnap
We had very close go live timeline and Mindbowser team got us live a month before.
CEO, BuyNow WorldWide
If you want a team of great developers, I recommend them for the next project.
Founder, Teach Reach
Mindbowser built both iOS and Android apps for Mindworks, that have stood the test of time. 5 years later they still function quite beautifully. Their team always met their objectives and I'm very happy with the end result. Thank you!
Founder, Mindworks
Mindbowser has delivered a much better quality product than our previous tech vendors. Our product is stable and passed Well Architected Framework Review from AWS.
CEO, PurpleAnt
I am happy to share that we got USD 10k in cloud credits courtesy of our friends at Mindbowser. Thank you Pravin and Ayush, this means a lot to us.
CTO, Shortlist
Mindbowser is one of the reasons that our app is successful. These guys have been a great team.
Founder & CEO, MangoMirror
Kudos for all your hard work and diligence on the Telehealth platform project. You made it possible.
CEO, ThriveHealth
Mindbowser helped us build an awesome iOS app to bring balance to people’s lives.
CEO, SMILINGMIND
They were a very responsive team! Extremely easy to communicate and work with!
Founder & CEO, TotTech
We’ve had very little-to-no hiccups at all—it’s been a really pleasurable experience.
Co-Founder, TEAM8s
Mindbowser was very helpful with explaining the development process and started quickly on the project.
Executive Director of Product Development, Innovation Lab
The greatest benefit we got from Mindbowser is the expertise. Their team has developed apps in all different industries with all types of social proofs.
Co-Founder, Vesica
Mindbowser is professional, efficient and thorough.
Consultant, XPRIZE
Very committed, they create beautiful apps and are very benevolent. They have brilliant Ideas.
Founder, S.T.A.R.S of Wellness
Mindbowser was great; they listened to us a lot and helped us hone in on the actual idea of the app. They had put together fantastic wireframes for us.
Co-Founder, Flat Earth
Ayush was responsive and paired me with the best team member possible, to complete my complex vision and project. Could not be happier.
Founder, Child Life On Call
The team from Mindbowser stayed on task, asked the right questions, and completed the required tasks in a timely fashion! Strong work team!
CEO, SDOH2Health LLC
Mindbowser was easy to work with and hit the ground running, immediately feeling like part of our team.
CEO, Stealth Startup
Mindbowser was an excellent partner in developing my fitness app. They were patient, attentive, & understood my business needs. The end product exceeded my expectations. Thrilled to share it globally.
Owner, Phalanx
Mindbowser's expertise in tech, process & mobile development made them our choice for our app. The team was dedicated to the process & delivered high-quality features on time. They also gave valuable industry advice. Highly recommend them for app development...
Co-Founder, Fox&Fork