How to scan non LE devices using Swift? - ios

I have RFID reader, which is not LE device.
https://www.tsl.com/products/1153-bluetooth-wearable-uhf-rfid-reader
I'm trying to write an iOS application, scan this device and connect it using swift CoreBluetooth library but my App finds everything besides this device. How is it possible to scan this reader?
import UIKit
import CoreBluetooth
class ViewController: UIViewController, CBCentralManagerDelegate {
var manager: CBCentralManager!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
manager = CBCentralManager(delegate: self, queue: nil)
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
print(peripheral)
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .unknown:
break;
case .poweredOff:
break;
case .poweredOn:
manager.scanForPeripherals(withServices: nil)
break;
case .resetting:
break;
case .unauthorized:
break;
case .unsupported:
break;
default:
break;
}
}
}

That device states that is MFi certified and uses the SPP profile, not the BLE GATT profile. This means that you will need to use the External Accessory Framework, not Core Bluetooth, to communicate with it.
You will need to the manufacturer provided iOS SDK for the device. If they do and you want to release your app on the App Store then they will also need to approve your app and supply some paperwork to Apple.
The device says that it also supports the HID profile, so perhaps you could just treat it as a keyboard; This doesn't require any code but isn't the best user experience.

You need to use CoreNFC to read RFID tags. No need to use CoreBluetooth at all.
https://developer.apple.com/documentation/corenfc

Related

Was there any change in Simplicity Studio from v4 to v5 requiring a different method of connection from iOS CoreBluetooth to an embedded BLE device? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 days ago.
This post was edited and submitted for review 5 days ago.
Improve this question
We upgraded our embedded firmware's Silicon Labs IDE Simp Studio from v4 to v5 (which has substantial BLE enhancements).
PROBLEM...
Now our iphone Swift app, using corebluetooth, has connection trouble to our embedded.
DEBUGGING WE HAVE TRIED......
After installation of prior firmware, iOS app connects and operates without problem.
Tried alternate embedded device: same problem.
OUR iOS BLE ............
internal func centralManagerDidUpdateState(_ central: CBCentralManager)
{
switch central.state {
case .poweredOn:
start_peripheral_scan()
case .poweredOff:
start_comm_recovery( false )
return
case .resetting:
return
case .unauthorized:
if #available(iOS 13.0, *) {
switch central.authorization {
case .denied:
case .restricted:
default:
}
} else {
}
return
case .unknown:
return
case .unsupported:
return
#unknown default:
return
}
// NEXT: didDiscover
}
func start_peripheral_scan()
{
if centralManager == nil { handle_fault("start_peripheral_scan: centralManager == nil") }
centralManager.scanForPeripherals(withServices: nil, /////////////////// S T A R T S C A N N I N G //////////////////////
options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral,
advertisementData: [String: Any], rssi RSSI: NSNumber)
{
. . . // verifies peripheral.name is desired device.
if is_my_device
{
centralManager.connect(peripheral, options: nil)
// Attempts connection. But this occurs only once after uploading firmware to our embedded device.
// If our app
}
}

IOS vs OSX BLE: Instantiating CBCentralManager - coding for iOS

I'm learning iOS vs OSX BLE.
I notice that I can't instantiate CBCentralManager in iOS because of:
[CoreBluetooth] XPC connection invalid
Unsupported
Versus via OSX because the iOS platform doesn't have the 'App Sandbox' Characteristic where I can set for BLE use.
Here's my iOS Code:
import SwiftUI
struct ContentView: View {
#ObservedObject var bleManager = BLEManager()
var body: some View {
ZStack {
Color("Background")
Text("Hello")
}
}
}
class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate {
var centralManager: CBCentralManager!
override init() {
super.init()
centralManager = CBCentralManager(delegate: self, queue: nil)
}
public func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .poweredOn:
print("power is on")
case .resetting:
print("Resetting")
case .unsupported:
print("Unsupported")
case .unauthorized:
print("UnAuthorized")
case .unknown:
print("UnKnown")
case .poweredOff:
print("Powered OFF")
#unknown default:
print("**** Default ****")
}
}
}
Here's the required .plist entry:
I understand that iPhones can be either a BLE center or peripheral.
Simple Question: How do I code for a bona fide CBCentralMaster for iOS?
I'm merely taking baby steps here: coding for peripheral detection.
... then continue from there.
Are you running on the simulator (where it is unsupported) instead of on device?
See the main Core Bluetooth docs:
Your app will crash if its Info.plist doesn’t include usage description keys for the types of data it needs to access. To access Core Bluetooth APIs on apps linked on or after iOS 13, include the NSBluetoothAlwaysUsageDescription key. In iOS 12 and earlier, include NSBluetoothPeripheralUsageDescription to access Bluetooth peripheral data.

Swift launch thread in background

I'm trying to send a process in a background thread using the following code:
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
print("running in the background queue")
btDiscovery
})
but the class is only processing while begin in foreground...any idea ?
EDIT1:
btDiscovery is a class which performs a BLE device scan every X seconds:
let btDiscoverySharedInstance = Beacon();
class Beacon: NSObject, CBCentralManagerDelegate {
private var centralManager: CBCentralManager?
private var peripheralBLE: CBPeripheral?
....
func centralManagerDidUpdateState(central: CBCentralManager) {
switch (central.state) {
case CBCentralManagerState.PoweredOff:
print("BLE powered off")
self.clearDevices()
case CBCentralManagerState.Unauthorized:
// Indicate to user that the iOS device does not support BLE.
print("BLE not supported")
break
case CBCentralManagerState.Unknown:
// Wait for another event
print("BLE unknown event")
break
case CBCentralManagerState.PoweredOn:
print("BLE powered on")
self.startScanning()
break
case CBCentralManagerState.Resetting:
print("BLE reset")
self.clearDevices()
case CBCentralManagerState.Unsupported:
print("BLE unsupported event")
break
}
}
func startScanning() {
print("Start scanning...")
if let central = centralManager {
central.scanForPeripheralsWithServices(nil, options: nil)
}
}
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
print("Discovered peripheral \(RSSI) dBM name: \(peripheral.name)")
print("UUID: \(peripheral.identifier.UUIDString)")
...
sleep(delayPolling)
self.startScanning()
}
when the app is launched and remains in foreground, the scan is performed correctly every "delayPolling" seconds.
but as soon as I put my app is background, the scan is paused. it restarts only when it comes back again in foreground.
I would need to leave this scan running in background every time (even if we set a lower priority to this thread).
EDIT2:
by reading the documentation https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html
I can see that
When an app that implements the central role includes the UIBackgroundModes key with the bluetooth-central value in its Info.plist file, the Core Bluetooth framework allows your app to run in the background to perform certain Bluetooth-related tasks. While your app is in the background you can still discover and connect to peripherals, and explore and interact with peripheral data. In addition, the system wakes up your app when any of the CBCentralManagerDelegate or CBPeripheralDelegate delegate methods are invoked
I selected the corresponding options in my Info.plist file:
but my app is not running my thread in background.
I realize this is an old question, but scanning in the background requires that you supply a Service UUID.
central.scanForPeripheralsWithServices(nil, options: nil)
needs to be
central.scanForPeripheralsWithServices(serviceUUID, options: nil)

Swift: Why can't my iOS scanned other bluetooth devices

Now I'm currently doing an application project that needs my iPhone to scan other nearby bluetooth devices and list them out. I'm wondering is my code has any problem?
Code:
import UIKit
import CoreBluetooth
class ViewController: UIViewController, CBCentralManagerDelegate {
var manager: CBCentralManager!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
manager = CBCentralManager (delegate: self, queue: nil)
}
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
print("Peripheral: \(peripheral)")
}
func centralManagerDidUpdateState(central: CBCentralManager) {
print("Checking")
switch(central.state)
{
case.Unsupported:
print("BLE is not supported")
case.Unauthorized:
print("BLE is unauthorized")
case.Unknown:
print("BLE is Unknown")
case.Resetting:
print("BLE is Resetting")
case.PoweredOff:
print("BLE service is powered off")
case.PoweredOn:
print("BLE service is powered on")
print("Start Scanning")
manager.scanForPeripheralsWithServices(nil, options: nil)
default:
print("default state")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I'm using iPhone 5 (iOS 9) and I'm sure that my Bluetooth is turned on.
When I run the application in my iPhone, the console only log the following output:
Checking
BLE service is powered on
Start Scanning
But there is no Bluetooth device's name shown in the output. Even I turn on my iPad (iPad Mini 4 iOS 8) and the list still wouldn't update.
Sometimes it does scan my MacBook Pro Bluetooth and the output will have this:
Peripheral: <CBPeripheral: 0x14d70e00, identifier = 54738076-6C97-FD04-18CF-5E1AF6705865, name = vivien’s MacBook Pro, state = disconnected>
So, why is this happening? Can someone please explain to me?
case 1:
You must use GKSession to scan and connect with another iOS device,not CoreBluetooth.
case 2:
Your bluetooth device is a Bluetooth 3.0 accessory.Your iPhone can discover and show it in Setting->Bluetooth.
But this message isn't delivered to your app,so your app won't discover it.
Try again with a Bluetooth 4.0 accessory.

scanForPeripheralWithServices does not return anything

I am new to swift language. I have been working on establishing a bluetooth connection between my iOS app and a barcode scanner. The barcode scanner has bluetooth enabled. I tried to establish a global bluetooth connection with my iphone and it works. Based on some references from the Internet, I have written the following sample code.
import UIKit
import CoreBluetooth
class ViewController: UIViewController, CBCentralManagerDelegate, CBPeripheralDelegate {
var manager : CBCentralManager!
override func viewDidLoad() {
super.viewDidLoad()
manager = CBCentralManager(delegate : self, queue : nil)
}
func centralManagerDidUpdateState(central: CBCentralManager) {
var consoleMsg = "hello"
switch(central.state) {
case .PoweredOff:
consoleMsg = "Bluetooth is powered off"
case .PoweredOn:
consoleMsg = "Bluetooth is powered on"
manager.scanForPeripheralsWithServices(nil, options: nil)
case .Resetting:
consoleMsg = "Bluetooth is Resetting"
case .Unauthorized:
consoleMsg = "Bluetooth is Unauthorized"
case .Unknown:
consoleMsg = "Bluetooth is Unknown"
case .Unsupported:
consoleMsg = "Bluetooth is Unsupported"
}
print("\(consoleMsg)")
}
func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {
print("Discovered a peripheral \(peripheral)")
}
When I try to run the above code, log displays "Bluetooth is Powered on" and thats it. It is not discovering my barcode scanner. I also made sure that the barcode scanner is in discoverable mode. Why my code is not discovering the near-by bluetooth enabled barcode scanner? Have I done any mistake in the above code?
Thanks
You should absolutely check authorization first !

Resources