Estimote / iOS-Fleet-Management-SDK

Estimote Fleet Management SDK for iOS
https://developer.estimote.com
MIT License
1.18k stars 398 forks source link

Nearable Sticker stopped working on iOS 13 with EstimoteSDK #288

Closed michzio closed 4 years ago

michzio commented 4 years ago

Basic information

Estimote iOS SDK version: pod 'Estimote SDK' newest iOS device(s) affected: all iOS devices iOS version(s) affected: iOS 13 Estimote device hardware version: Nearable Sticker Estimote device firmware version:

Additional information

Please read the checklist and place x sign where apropriate for your use case.

Description

After upgrade to iOS 13 working code that detects Nearble stickers stopped working. Now delegate method is never called.

Here are my code snippets:

 private func startRangingNearables() {

        self.tables.forEach { table in
            guard let nearableIdentifier = table.beaconId else { return }

            self.nearableManager.startRanging(forIdentifier: nearableIdentifier)

        }
    }

func nearableManager(_ manager: ESTNearableManager, didRangeNearable nearable: ESTNearable) {

        if nearable.rssi <= 0 {
            print("Did range nearable: \(nearable.identifier), power: \(nearable.txPowerInDbm), rssi: \(nearable.rssi), interval: \(nearable.advInterval)")

            beaconContainer.addBeacon(nearable.toBeacon())
        }

I haven’t changed recently nothing in my code, maybe there was update of EstimodeSDK pod and update from iOS 12.4 to iOS 13.

Thay are still detected in Estimote iOS app so they are live and identifiers are correct

Ranging nearables failed with error: Error Domain=com.estimote.nearables Code=301 “Blueooth is not powerd on.” UserInfo={NSLocalizedDescription=Blueooth is not powerd on.}

Additional information

The same code worked when run on iOS 12 device, but doesn't work on iOS 13. iBeacons work correctly, only Nearable Stickers stopped working.

chwastek commented 4 years ago

Thanks for spotting bug, we'll try release fix asap.

chwastek commented 4 years ago

btw would be nice to use pod 'EstimoteFleetManagementSDK' after all we switched a while back to a different naming and as well newest version would be 4.31.0 (instead of 4.28.0 ;) )

chwastek commented 4 years ago

4.31.1 will have fix for missing nearables

michzio commented 4 years ago

OK, thanks :)

HoangNguyenBigLabs commented 4 years ago

I have the same issue on EstimoteSDK (iOS 13.1.2). My iPhone is not able to range or discover any beacons. I tried both 'EstimoteFleetManagementSDK' and 'EstimoteBluetoothScanning.framework' but it is still not working. On iOS 12, ranging and discovering beacon work correctly.

chwastek commented 4 years ago

We're working on fixing that as we speak :) though can you specify which version of EstimoteBluetoothScanning do you have? This library should work (starting with https://github.com/Estimote/iOS-Bluetooth-Scanning/releases/tag/v1.0.6).. if it's not then please submit the issue there as well.

HoangNguyenBigLabs commented 4 years ago

Thanks, The library (https://github.com/Estimote/iOS-Bluetooth-Scanning/releases/tag/v1.0.6) work on iOS 13.

chwastek commented 4 years ago

Glad we helped :) if you need only ranging for packets I'd recommend using EBS (Estimote Bluetooth Scanning), if monitoring then Proximity SDK would be the best. Unless you have some legacy code requiring you to go with this SDK (which is mostly now deprecated and unattended - unless there is some critical bug).

HoangNguyenBigLabs commented 4 years ago

Unfortunately, I am using "EstimoteSDK" for ranging all beacons around the iPhone (about 100 beacons).

- (void)utilityManager:(ESTUtilityManager *)manager
    didDiscoverBeacons:(NSArray<ESTBluetoothBeacon *> *)beacons;

But "EstimoteBluetoothScanning" only allow to range and receive 1 beacon a time. - (void)universalScanner:(id<EBSUniversalScannerProtocol>)universalScanner didScanEstimoteDevice:(EBSScanInfo *)scanInfo; I hope the next release of EstimoteSDK will fix the issue on iOS 13 like EstimoteBluetoothScanning.

chwastek commented 4 years ago

I get it. Will let you know when we're done fixing. Out of curiosity:

  1. do you really need to range 100 different beacons or just recognize "yours" from the crowd?
  2. do you need ranging or monitoring would be enough?
HoangNguyenBigLabs commented 4 years ago
  1. Yes, I need to range all beacons around.
  2. Currently, I am using ESTUtilityManager for ranging, ESTDeviceManager for discovering and ESTBeaconConnection for establishing connection and write data.
chwastek commented 4 years ago

@HoangNguyenBigLabs @michzio please check out the newest version https://github.com/Estimote/iOS-Fleet-Management-SDK/releases/tag/4.31.1

michzio commented 4 years ago

Ok I will check it today or tomorrow and give you info how it works now :)

HoangNguyenBigLabs commented 4 years ago

@chwastek Thanks a lot for the 4.31.1 release. With this release my devices (iOS 13 and iOS 12) can range beacons perfectly by ESTUtilityManager. (I know this class is deprecated but I don’t know a replaced class).

But I am still unable to connect to my beacons which are the first generation Estimote Proximity Beacon (hardware revision “D”). If I use ESTBeaconConnection (deprecated), my app will crash with reason 'Invalid domain=nil in -[NSError initWithDomain:code:userInfo:]’

Then I try ESTDeviceLocationBeacon but it is unable to connect to my beacons. It seem the 1st-generation beacons are not supported on SDK 4 APIs.

chwastek commented 4 years ago

Will look into it.

chwastek commented 4 years ago

@HoangNguyenBigLabs can you share how do you exactly scan for old beacons etc?

HoangNguyenBigLabs commented 4 years ago

@chwastek Here is the class to discover beacon exactly by MAC address.

class ImmediateBeaconDetector: NSObject, ESTDeviceManagerDelegate, CBCentralManagerDelegate {

    @objc let deviceManager = ESTDeviceManager()

    @objc var bluetoothManager: CBCentralManager!

    unowned var delegate: ImmediateBeaconDetectorDelegate

    var macAddr : String?

    init(delegate: ImmediateBeaconDetectorDelegate) {
        self.delegate = delegate
        super.init()
        deviceManager.delegate = self
        bluetoothManager = CBCentralManager(delegate: self, queue: nil)
    }

    @objc func start() {
        deviceManager.startDeviceDiscovery(with: ESTDeviceFilterBeaconV1())
    }

    @objc func stop() {
        deviceManager.stopDeviceDiscovery()
    }

    // MARK: ESTDeviceManagerDelegate

    func deviceManager(_ manager: ESTDeviceManager, didDiscover devices: [ESTDevice]) {
        if macAddr != nil {
            findCorrectDevice(devices: devices)
        }
    }

    func findCorrectDevice(devices: [ESTDevice]) {
        if devices.count > 0 {
            let correctDevice = devices.first { $0.identifier.lowercased() == macAddr!.replace(":", withString: "").lowercased() }
            if let correctDevice = correctDevice {
                if let beacon = correctDevice as? ESTBluetoothBeacon {
                    delegate.immediateBeaconDetector(self, didDiscoverBeacon: beacon)
                } else {
                }
            }
        }
    }

    func deviceManagerDidFailDiscovery(_ manager: ESTDeviceManager) {
        if bluetoothManager.state != .poweredOn {
            delegate.immediateBeaconDetector(self, didFailDiscovery: .bluetoothDisabled)
        } else {
            delegate.immediateBeaconDetector(self, didFailDiscovery: .unknown)
        }
    }

    // MARK: CBCentralManagerDelegate
}

After receiving ESTBluetoothBeacon, I use ESTBeaconConnection to connect to the beacon.

func immediateBeaconDetector(_ immediateBeaconDetector: ImmediateBeaconDetector, didDiscoverBeacon beacon: ESTBluetoothBeacon) {
        immediateBeaconDetector.stop()
        let locationBeacon = ESTDeviceLocationBeacon(deviceIdentifier: beacon.identifier, peripheralIdentifier: beacon.peripheralIdentifier, rssi: beacon.rssi, discoveryDate: beacon.discoveryDate)
        immediateBeacon = locationBeacon
        // This first generation of Proximity Beacons has a different API for connection: ESTBeaconConnection.
        estBeaconConnection = ESTBeaconConnection(identifier: beacon.identifier, delegate: self, startImmediately: true)
    }
func beaconConnectionDidSucceed(_ connection: ESTBeaconConnection) {
        print("SettingsInteractor - beaconConnectionDidSucceed")
        writeSettingsToProximityBeacon()
    }

Here is the code to write data into the connected beacon.

func writeSettingsToProximityBeacon() {
        let expectedPower = ESTBeaconPower(rawValue: rangePowerLevel!.level.rawValue)!
        print("Connection writePower expectedPower: \(expectedPower)")
        estBeaconConnection?.writePower(expectedPower) { (power, error) in
            if let powerError = error {
                NSLog("SettingsInteractor - Error while writing beacon setting with power error: \(powerError)")
                self.output?.errorWhileWritingSettings()
                return
            }
            print("Connection writePower powerResult: \(power.rawValue)")
            let lat = NSNumber(value: (self.locationForSaving?.coordinate.latitude)!)
            let long = NSNumber(value: (self.locationForSaving?.coordinate.longitude)!)
            print("Connection write lat: [\(lat)], long: [\(long)]")
            self.estBeaconConnection?.writeLatitude(lat, longitude: long) { (error) in
                print("Connection finish write lat: [\(lat)], long: [\(long)]")
                if let err = error {
                    NSLog("SettingsInteractor - Error while writing beacon setting with lat, long error: \(err)")
                    self.output?.errorWhileWritingSettings()
                } else {
                    self.finishWriteSettings()
                }
            }
        }
    }
michzio commented 4 years ago

In my case Nearble seems to be detected correctly. I use ESTNearableManager and ESTBeaconManager. I have some problems but I think it can be in my code not in Estimote framework. Give more details soon if we better test them

chwastek commented 4 years ago

@michzio @HoangNguyenBigLabs we released just now a new version https://github.com/Estimote/iOS-Fleet-Management-SDK/releases/tag/4.31.2 (this one should mainly fix issue with legacy beacons). LMK if it works for you

HoangNguyenBigLabs commented 4 years ago

@chwastek Thanks, I will try this new version and let you know ASAP.

HoangNguyenBigLabs commented 4 years ago

@chwastek Wonderful, it work perfectly on iOS 13 and iOS 12 as well. Thanks a lot for you support. No need to change any lines of code.

chwastek commented 4 years ago

🙇 pleasure is mine! Glad we helped!