July 5, 2024 • by Wahyu Untoro

Harnessing Bluetooth Low Energy (BLE) in Native iOS Apps for Agricultural Innovation

Harnessing Bluetooth Low Energy (BLE) in Native iOS Apps for Agricultural Innovation

In our rapidly advancing technological era, various sectors, including agriculture, are finding innovative ways to leverage these developments to boost efficiency and productivity. In agriculture, heavy machinery like tractors are essential for tasks such as soil cultivation and crop harvesting. Recognizing the importance of these machines, one of our clients has innovatively integrated advanced sensor technology into their tractors. This enables real-time data transmission to a server, accessible through a mobile app.

The app is divided into two versions: one for tractor manufacturers, allowing them to monitor tractor conditions and locations in real time, and swiftly address any issues. The second app is for drivers, providing them with comprehensive and real-time data to support their operations.

To facilitate real-time data transmission, Bluetooth technology was chosen due to its wireless connectivity capabilities. Operating on the 2.4 GHz frequency in the ISM (Industrial, Scientific, and Medical) spectrum, Bluetooth is divided into two models: Bluetooth Low Energy (BLE) and Bluetooth Classic, with version 5 being the latest at the time of writing.

Given the need for energy efficiency in tractor sensor devices, BLE is the ideal choice. Designed for two-way communication with minimal energy consumption, BLE is perfect for applications that don’t require continuous or high-speed data transfer. Unlike Bluetooth Classic, which is suited for continuous data streaming like audio, BLE is designed to send small amounts of data intermittently.

Implementing BLE in iOS

To connect a device with BLE, start by scanning for nearby devices using `CBCentralManagerDelegate`. Once the desired device is found, the next step is to establish a connection. This ensures that data from the tractor sensors can be efficiently transmitted to the server and displayed through the mobile app, providing real-time operational and maintenance information.

func startScan(uuid: String) {
if let _peripheral = centralManager!.retrievePeripherals(withIdentifiers: [UUID(uuidString: uuid)!]).first {
peripheral = _peripheral
BLEPeripheral = _peripheral
BLEPeripheral.delegate = self

NotificationCenter.default.post(name: Notification.Name("PeripheralStateDidChange"), object: nil)

Timer.scheduledTimer(withTimeInterval: 15, repeats: false) { timer in
if !self.isConnected {
NotificationCenter.default.post(name: Notification.Name("ShowFailedToConnectDialog"), object: nil)

Code to scan for devices

func connectDevice(peripheral: CBPeripheral) {
BLEPeripheral = peripheral
BLEPeripheral.delegate = self


Timer.scheduledTimer(withTimeInterval: 15, repeats: false) { timer in

Code to connect to the selected device

After establishing a connection, the next step is to discover the services that act as containers for the characteristics. Services in BLE are like chapters in a book, organizing various functions of the device.

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {

Code to handle successful connection and service discovery

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
guard let services = peripheral.services else { return }

for service in services {
peripheral.discoverCharacteristics(nil, for: service)

NotificationCenter.default.post(name: Notification.Name("HandleDiscoverService"), object: nil)

Code to handle service discovery

func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
guard let characteristics = service.characteristics else { return }

let desiredCharacteristicUUID = CBUUID(string: Constants.pinUUID)
for characteristic in characteristics {
if characteristic.uuid == desiredCharacteristicUUID {
desiredCharacteristic = characteristic

let value: UInt16 = generatePIN(serialNumberHex: peripheral.name ?? "")
var littleEndianValue = value.littleEndian
let data = Data(bytes: &littleEndianValue, count: MemoryLayout<UInt16>.size)

peripheral.writeValue(data, for: characteristic, type: .withResponse)
} else {
if characteristic.properties.contains(.read) {
peripheral.readValue(for: characteristic)
peripheral.setNotifyValue(true, for: characteristic)

Code to handle characteristics

This overview showcases the implementation of Bluetooth Low Energy in a native iOS app, highlighting the process of scanning, connecting, and discovering services and characteristics. Utilizing native features ensures efficiency and reliability without needing third-party tools.

Elevate Your Mobile App Development with Timedoor Indonesia

At Timedoor Indonesia, we specialize in digital development with a focus on creating powerful, efficient mobile applications tailored to your needs. Our expertise in integrating advanced technologies like Bluetooth Low Energy (BLE) into native iOS apps can drive your agricultural innovations to new heights.

Ready to transform your digital presence? Contact us today to discover how we can help you build the perfect mobile solution for your business.

Get in touch with Timedoor Indonesia now and let’s create something amazing together!

Happy Coding! 🌾🌾🌾