iBeacon — может обнаруживать с помощью startRangingBeacons, но не для didEnterRegion

Мне нужно определить, когда устройство входит или выходит из региона, и выполняет какое-то действие на основе этого.

Используя «startRangingBeaconsInRegion», я могу обнаружить ближайший iBeacon и изменить цвет фона на основе этого и белый, если он не может обнаружить iBeacon.

Однако я не могу заставить его срабатывать на «didEnterRegion» или «didExitRegion».

Я знаю, что если устройство уже находится в регионе, то enterRegion не сработает. Я удостоверяюсь, что маяк не обнаружен (белый экран), а затем, что маяк обнаружен (цветной экран), но ничего не срабатывает.

Я пытался использовать estimote SDK, но у меня возникла та же проблема. Перезагрузка устройства тоже не помогла.

Мой код ниже, есть предложения?

import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

    let locationManager = CLLocationManager()
    let region = CLBeaconRegion(proximityUUID: NSUUID(UUIDString: "B9407F30-F5F8-466E-AFF9-25556B57FE6D"), identifier: "Estimotes")

    let colors = [
        3861: UIColor(red: 84/255, green: 77/255, blue: 160/255, alpha: 1),
        19152: UIColor(red: 142/255, green: 212/255, blue: 220/255, alpha: 1),
        40527: UIColor(red: 162/255, green: 213/255, blue: 181/255, alpha: 1)
    ]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        locationManager.delegate = self
        locationManager.pausesLocationUpdatesAutomatically = false
        region.notifyEntryStateOnDisplay  = true
        region.notifyOnEntry = true
        region.notifyOnExit = true

        // Request authorisation to track location
        if (CLLocationManager.authorizationStatus() != CLAuthorizationStatus.AuthorizedWhenInUse) {
            locationManager.requestWhenInUseAuthorization()
        }


        if (CLLocationManager .isMonitoringAvailableForClass(CLBeaconRegion))
        {
            println("OK")
        }
        else {
            println("Problem")

        }

        locationManager.startMonitoringForRegion(region)
        locationManager.startRangingBeaconsInRegion(region)
        locationManager.startUpdatingLocation()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    func locationManager(manager: CLLocationManager!, didRangeBeacons beacons: [AnyObject]!, inRegion region: CLBeaconRegion!) {

        let knownBeacons = beacons.filter { $0.proximity != CLProximity.Unknown }
        if (knownBeacons.count > 0) {
            let closestBeacon = knownBeacons[0] as CLBeacon
            self.view.backgroundColor = self.colors[closestBeacon.minor.integerValue]
            println(beacons)

        }
        else {
            self.view.backgroundColor = UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1)
        }
    }
    func locationManager(manager: CLLocationManager!, didEnterRegion region: CLRegion!) {
        println("Region entered")
    }

    func locationManager(manager: CLLocationManager!, didExitRegion region: CLRegion!) {
        println("Region exited")
    }
    func locationManager(manager: CLLocationManager!, monitoringDidFailForRegion region: CLRegion!, withError error: NSError!) {
        println("FAIL!")
    }

}

person CYMR0    schedule 21.02.2015    source источник


Ответы (1)


Вы пытаетесь изменить пользовательский интерфейс в обратном вызове диспетчера местоположения - это большое нет, поскольку эти обратные вызовы обычно не находятся в основном потоке. Оберните каждое изменение пользовательского интерфейса в блоке отправки в основной поток и посмотрите, изменит ли это что-нибудь.

О, у меня была такая же проблема несколько дней назад. Вам необходимо реализовать:

func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
    println("STATUS CHANGED: \(status.rawValue)")
    if status == .AuthorizedAlways && !monitoring {
        println("YAY! Authorized!")
        locationManager.startMonitoringForRegion(beaconRegion)
        monitoring = true
    }
}

Вы можете начать мониторинг только ПОСЛЕ того, как система сообщит вам, что у вас есть на это разрешение.

Кроме того, если вам нужны фоновые уведомления, вы ДОЛЖНЫ иметь эту строку в своем Info.plist: NSLocationAlwaysUsageDescription, и вам нужно App registers for location updates, определенное в Required background modes.

person David H    schedule 21.02.2015
comment
Спасибо! Я добавил NSLocationAlwaysUsageDescription в plist, и это сработало. У меня уже было NSLocationWhenInUseUsageDescription, но этого могло быть недостаточно... что странно, поскольку именно это я и просил. В любом случае, теперь это работает, и спасибо за вашу помощь! - person CYMR0; 22.02.2015