Issue with Proximity-Zones - iOS

#1

Hello everyone,

first things first: I’m using Xcode with Swift and am working on an iOS-App with 3 Estimote Beacons.

For this project, I’m initializing an inner zone and an outer zone for each Beacon.
Whenever 2 zones of 2 different Beacons get in touch with each other, I want something to take “action”.

To make this work, I initialized an int-variable “counter”.
So, basically whenever I enter or leave a zone, the counter shall increase or decrease.
If the counter has a specific value, something shall “happen”.

My problem right now is that the App is having problems detecting 2 different zones of one Beacon.
Here’s how I’ve implemented it right now

Xcode Source-Text
override func viewDidLoad() {
        print ("The App was loaded!")
        super.viewDidLoad()
        let cloudCredentials = CloudCredentials(appID: "<Here's my app ID>", appToken: "<Here's my app-token>")
        
        
        self.proximityObserver = ProximityObserver(credentials: cloudCredentials, onError: { error in
            print("proximity observer error: \(error)")
        })
        
        
        var counter : Int
        counter = 0
        //Beacon middle of the room
        let innerZoneB1 = ProximityZone(tag: "beacon3",  range: ProximityRange(desiredMeanTriggerDistance: 1.25)!)
        
        innerZoneB1.onEnter = {_ in
            counter += 1
            print ("The inner zone 3 was entered, current value: ", counter)
        }
        
        innerZoneB1.onExit = {_ in
            counter -= 1
            print ("The inner zone 3 was left, current value: ", counter)
        }
        
         self.proximityObserver.startObserving([innerZoneB1])
            [......]}

Does anyone of you have an Idea, what I’m doing wrong?

Thanks in advance!

#2

The code you’ve attached shows only one zone, and the counter is not used anywhere. Can you share the complete code? You can post it to https://gist.github.com, and then share a link here.

And what exactly is not working, you’re not seeing the “The inner zone 3 was entered/left” messages?

#3

I uploaded the code here: https://gist.github.com/mvolkm/efaad518ab5b8f1306bcdab66120b646

At this point I have 2 problems:

  1. If I’m inside of the innere zone of beacon 1, the value should actually be at 2. Sometimes, it truly is detecting, that I’m inside of the inner AND outer zone. Sometimes it’s not even detecting any zone. However, most of the times, it’s only detecting the outer zone but not the inner zone

  2. The if-statement at the very bottom is just running once. Is there a way to let it update all the time? So it changes the background-color simultaneously with entering/leaving a zone? The reason why I’m using a counter is because I want to change the color of the background when the counter has a specific value. Therefore I need to be in 2 zones of 2 different beacons. e.g. if I’m in the outer zone of beacon 1 and the outer zone of beacon 2, the counter has the value x. If the variable “counter” has the value x, the background color shall change to purple; and so on.
    Long story short: It’s supposed to be an alternative to the Trilateration!

Note: So far, I’ve only tested it with the beacon1. Currently, I’m not able to test it with the other beacons.

Thanks in advance!

#4

In your code, you define all these zones, and then you do:

self.proximityObserver.startObserving([innerZoneB1])
// ...
self.proximityObserver.startObserving([outerZoneB1])

… which means you start observing zone inner-B1, and then start observing outer-B1, and the latter overwrites the former. Which would explain why:

most of the times, it’s only detecting the outer zone but not the inner zone

(;

Have you tried:

startObserving([innerZoneB1, outerZoneB1, innerZoneB2, outerZoneB2, innerZoneB3, outerZoneB3])

?

The if-statement at the very bottom is just running once

That’s because that if statement is inside viewDidLoad, which only happens once when the respective UIViewController loads. If you want this to run at every enter/exit event, you can extract this code into a separate function/method, and call that function/method in each enter/exit handler:

// extract the counter to be a property on the ViewController
var counter : Int = 0

override func viewDidLoad() {
    // ...
    innerZoneB1.onEnter = {_ in
        self.counter += 1
        print ("The inner zone 3 was entered, current value: ", counter)
        updateBackground() // <=============
    }
    // ...
}

func updateBackground() {
    UIView.animate(withDuration: 0.9) {
        switch self.counter {
        case 0:
            self.view.backgroundColor = UIColor.cyan
        case 1:
            self.view.backgroundColor = UIColor.black
        case 2:
            self.view.backgroundColor = UIColor.red
        default:
            self.view.backgroundColor = UIColor.green
        }
    }
}
#5

Thank you very much! This worked perfectly the way I wanted it to work!

1 Like