Как я могу отслеживать несколько iBeacon и изменять UILabel на основе каждого маяка? - PullRequest
0 голосов
/ 10 июля 2019

У меня проблема с мониторингом нескольких маяков одновременно. Мой код отлично работает только с одним, но я не могу понять, как контролировать более одного маяка И обновить UILabel.

Все маяки отслеживаются и распознаются, когда я их включаю, но мой телефон не отображает правильные метки в представлении. Он постоянно показывает «НЕИЗВЕСТНО» в distanceReading.text, если это не последний маяк в функции (Estimote).

У меня также есть некоторые другие проблемы обновления имени, для которого это маяк. Я не уверен, как вызвать идентификатор маяка, который был бы идеальным способом (что-то вроде beacon.identifier). Я попытался создать другую переменную и обновить имя при каждом сканировании маяка, но он просто сканирует последнюю и не меняется. Я надеялся, что он будет сканировать его, когда он будет обнаружен, что позволит мне изменить переменную при обнаружении нового маяка.

Я попытался поместить все маяки в одну функцию startScanning (), присвоив каждому уникальному UUID свою переменную и используя locationManager.startMonitoring () и locationManager.startRangingBeacon () для каждого отдельного маяка. Затем я попытался создать функцию startScanning (), используя параметры для каждого UUID, основного, младшего и идентификатора, а затем вызвал функцию для каждого маяка.

class ViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet var distanceReading: UILabel!
    @IBOutlet var nameLabel: UILabel!
    var locationManager: CLLocationManager?
    var beaconDict: [String: String]?
    var labelName: String?

    override func viewDidLoad() {
        super.viewDidLoad()

        locationManager = CLLocationManager()
        locationManager?.delegate = self
        locationManager?.requestAlwaysAuthorization()

        alertShown = false

        view.backgroundColor = .gray  // default is in "unknown mode"

    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        if status == .authorizedAlways {
            // Can we monitor beacons or not?
            if CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self) {
                //  Can we detect the distance of a beacon?
                if CLLocationManager.isRangingAvailable() {
                    startScanning(uuid: UUID(uuidString: "5A4BCFCE-174E-4BAC-A814-092E77F6B7E5")!, major: 123, minor: 456, identifier: "Apple Beacon", name: "Apple")
                    startScanning(uuid: UUID(uuidString: "2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6")!, major: 123, minor: 456, identifier: "Radius Beacon", name: "Radius")
                    startScanning(uuid: UUID(uuidString: "5AFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF")!, major: 123, minor: 456, identifier: "Red Bear Beacon", name: "Red Bear")
                    startScanning(uuid: UUID(uuidString: "B9407F30-F5F8-466E-AFF9-25556B57FE6D")!, major: 123, minor: 456, identifier: "Estimote", name: "Estimote")
                }
            }
        }
    }

    func startScanning(uuid: UUID, major: UInt16, minor: UInt16, identifier: String, name: String) {
        let uuidApple = uuid
        let beaconRegion1 = CLBeaconRegion(proximityUUID: uuidApple, major: major, minor: minor, identifier: identifier)
        locationManager?.startMonitoring(for: beaconRegion1)
        locationManager?.startRangingBeacons(in: beaconRegion1)
        labelName = name
    }

    func update(distance: CLProximity) {
        UIView.animate(withDuration: 1) {
            switch distance {
            case .far:
                self.view.backgroundColor = .blue
                self.distanceReading.text = "FAR"
            case .near:
                self.view.backgroundColor = .orange
                self.distanceReading.text = "NEAR"
            case .immediate:
                self.view.backgroundColor = .red
                self.distanceReading.text = "RIGHT HERE"
            default:
                self.view.backgroundColor = .gray
                self.distanceReading.text = "UNKNOWN"
            }
        }
    }

    func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
        if let beacon = beacons.first {
            nameLabel.text = labelName
            update(distance: beacon.proximity)
        } else {
            update(distance: .unknown)
        }
    }

Я ожидаю, что каждый раз, когда обнаруживается новый маяк, моя метка меняется соответственно. Это работает как предназначено для маяка, названного ПОСЛЕДНИМ, но не первые три. Цвет меняется, но этикетка отказывается меняться. Я также хотел бы выяснить способ вызова идентификатора маяка, который я установил в CLBeaconRegion.

Ответы [ 2 ]

2 голосов
/ 10 июля 2019

Попробуйте перебрать все маяки в диапазоне, как в for beacon in beacons, вместо того, чтобы просто работать с первым в массиве, как в beacons.first.

1 голос
/ 11 июля 2019

Ваша проблема с именем маяка заключается в том, что labelName представляет собой одну строку, и вы устанавливаете ее значение в startScanning. Каждый раз, когда вы звоните, startScanning вы перезаписываете предыдущее значение labelName. С момента последнего звонка startScanning вы предоставляете имя Estimote , которое всегда будет отображаться в nameLabel.

У вас есть свойство beaconDict, которое показывает, что вы, возможно, думали об этом, но не продолжили.

То, что я хотел бы сделать, это создать структуру Beacon для хранения всех свойств маяка, включая name, создать экземпляры этой структуры для передачи в startScanning и сохранить эти экземпляры в [String:Beacon] толковый словарь. Используйте строку UUID в качестве ключа. Затем, если вам перезвонят, вы можете использовать идентификатор маяка, чтобы найти соответствующий Beacon из словаря и получить его name.

Что касается того, почему расстояние всегда неизвестно, Давид прав; Вы получите 4 маяка в режиме обратного вызова didRangeBeacons. Поскольку у вас есть только один физический маяк, все маяки, кроме того, который у вас активен в настоящее время, будут неизвестны, но вы смотрите только на первый.

Вероятно, вам будет проще использовать табличное представление с одной строкой на маяк, чем одну метку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...