BLE Advertising

Hi, I am trying to write simple code that my iPhone acts as BLE peripheral (advertise packet). but i cannot see the advertisement on other devices that do scanning. What could be the cause?

Code snippet

============= import SwiftUI import CoreBluetooth

// 1. Conform to CBPeripheralManagerDelegate class BLEAdvertiser: NSObject, ObservableObject, CBPeripheralManagerDelegate { var peripheralManager: CBPeripheralManager?

// 2. Start advertising
func startAdvertising() {
    peripheralManager = CBPeripheralManager(delegate: self, queue: nil)
}

// 3. CBPeripheralManagerDelegate method called when state changes
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
        switch peripheral.state {
        case .poweredOn:
            // Define a service UUID
            let serviceUUID = CBUUID(string: "1234") // Custom UUID for your service
            
            // Create a CBMutableService
            let service = CBMutableService(type: serviceUUID, primary: true)
            
            // Add service to the peripheral manager
            peripheralManager?.add(service)
            
            // Start advertising the service
            let advertisementData: [String: Any] = [
                CBAdvertisementDataServiceUUIDsKey: [serviceUUID],
                CBAdvertisementDataLocalNameKey: "My iPhone"
            ]
            peripheralManager?.startAdvertising(advertisementData)
            
            print("Started advertising!")
        case .poweredOff:
            print("Bluetooth is powered off.")
        case .resetting:
            print("Bluetooth is resetting.")
        case .unauthorized:
            print("Bluetooth access is unauthorized.")
        case .unsupported:
            print("Bluetooth is unsupported on this device.")
        case .unknown:
            print("Bluetooth state is unknown.")
        @unknown default:
            print("A new state that we don’t know about.")
        }
}

// 4. Optional: Handle peripheral manager adding service
func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) {
    if let error = error {
        print("Failed to add service: \(error.localizedDescription)")
        return
    }
    print("Service added successfully!")
}

}

struct ContentView: View { @StateObject private var bleAdvertiser = BLEAdvertiser()

var body: some View {
    VStack {
        Text("BLE Advertising")
            .font(.largeTitle)
            .padding()
        
        Button(action: {
            bleAdvertiser.startAdvertising()
        }) {
            Text("Start Advertising")
                .padding()
                .background(Color.blue)
                .foregroundColor(.white)
                .cornerRadius(10)
        }
    }
}

}

Without going into your code, some questions:

  • is your app in the foreground when advertising?
  • is the central device another Apple device?

Apps that advertise as BLE peripherals in the background can only be detected by other apps running on other Apple devices which are running in the foreground. And even in that case, background advertising is done on a best effort basis and is not guaranteed that the device will advertise the app at all times.

If you are advertising in the foreground, and cannot detect it on a central app running in the foreground (or a 3rd party central device), then we can check what might be wrong with the code.

It also matters what service UUID you are trying to advertise, as there will be some reserved UUID which you cannot use.


Argun Tekant /  DTS Engineer / Core Technologies

Hi, I my code was already working indeed, i just needed to install nRF app to see the advertisement

BLE Advertising
 
 
Q