Class: Tgios::BeaconManager
Constant Summary
collapse
- ALGORITHMS =
[:continue, :timeout]
- BeaconFoundKey =
'Tgios::BeaconManager::BeaconFound'
- BeaconsFoundKey =
'Tgios::BeaconManager::BeaconsFound'
- EnterRegionKey =
'Tgios::BeaconManager::EnterRegion'
- ExitRegionKey =
'Tgios::BeaconManager::ExitRegion'
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from BindingBase
#hook, #prepareForRelease, #unhook
Constructor Details
range_method: :rssi or :accuracy range_limit: around -70 for :rssi / around 1.5 (meters) for :accuracy background: range beacons when device is in background algorithm: :continue or :timeout tolerance: for algorithm continue: number of times a beacon is ranged continuously required to trigger beacon changed event, for algorithm timeout: time in seconds for a beacon marked as changed
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
# File 'lib/tgios/beacon_manager.rb', line 43
def initialize(options)
@events = {}
@previous_beacons = []
@beacons_last_seen_at = {}
@background = options[:background]
self.algorithm = (options[:algorithm] || :continue)
@tolerance = (options[:tolerance] || 5)
@uuid = NSUUID.alloc.initWithUUIDString(options[:uuid])
@major = options[:major]
@minor = options[:minor]
@range_method = (options[:range_method] || :rssi)
@range_limit = (options[:range_limit] || -70)
@region = if @major && @minor
CLBeaconRegion.alloc.initWithProximityUUID(@uuid, major: @major, minor: @minor, identifier: identifier)
elsif @major
CLBeaconRegion.alloc.initWithProximityUUID(@uuid, major: @major, identifier: identifier)
else
CLBeaconRegion.alloc.initWithProximityUUID(@uuid, identifier: identifier)
end
@region.notifyOnEntry = true
@region.notifyOnExit = true
@region.notifyEntryStateOnDisplay = true
start_monitor
UIApplicationWillEnterForegroundNotification.add_observer(self, 'on_enter_foreground:')
UIApplicationDidEnterBackgroundNotification.add_observer(self, 'on_enter_background:')
end
|
Instance Attribute Details
#background ⇒ Object
Returns the value of attribute background.
19
20
21
|
# File 'lib/tgios/beacon_manager.rb', line 19
def background
@background
end
|
#current_beacon ⇒ Object
Returns the value of attribute current_beacon.
19
20
21
|
# File 'lib/tgios/beacon_manager.rb', line 19
def current_beacon
@current_beacon
end
|
#range_limit ⇒ Object
Returns the value of attribute range_limit.
19
20
21
|
# File 'lib/tgios/beacon_manager.rb', line 19
def range_limit
@range_limit
end
|
#range_method ⇒ Object
Returns the value of attribute range_method.
19
20
21
|
# File 'lib/tgios/beacon_manager.rb', line 19
def range_method
@range_method
end
|
#tolerance ⇒ Object
Returns the value of attribute tolerance.
19
20
21
|
# File 'lib/tgios/beacon_manager.rb', line 19
def tolerance
@tolerance
end
|
Class Method Details
.beacon_eqs(beacon1, beacon2) ⇒ Object
267
268
269
270
|
# File 'lib/tgios/beacon_manager.rb', line 267
def self.beacon_eqs(beacon1, beacon2)
return beacon1 == beacon2 if beacon1.nil? || beacon2.nil?
beacon1.minor == beacon2.minor && beacon1.major == beacon2.major && beacon1.proximityUUID == beacon2.proximityUUID
end
|
.beacon_key(beacon) ⇒ Object
272
273
274
|
# File 'lib/tgios/beacon_manager.rb', line 272
def self.beacon_key(beacon)
[beacon.try(:proximityUUIDbeacon), beacon.try(:major), beacon.try(:minor)].join('/')
end
|
.default ⇒ Object
31
32
33
|
# File 'lib/tgios/beacon_manager.rb', line 31
def self.default
@default
end
|
.default=(val) ⇒ Object
27
28
29
|
# File 'lib/tgios/beacon_manager.rb', line 27
def self.default=(val)
@default = val
end
|
.supported ⇒ Object
280
281
282
|
# File 'lib/tgios/beacon_manager.rb', line 280
def self.supported
CLLocationManager.isRangingAvailable
end
|
Instance Method Details
#algorithm=(val) ⇒ Object
85
86
87
88
89
90
91
92
93
94
|
# File 'lib/tgios/beacon_manager.rb', line 85
def algorithm=(val)
alg = val.to_s.to_sym
return unless alg.present?
if @algorithm != alg
@previous_beacons.clear
end
raise ArgumentError.new("Algorithm not found, valid algorithm are: [#{ALGORITHMS.join(', ')}]") unless ALGORITHMS.include?(alg)
@algorithm = alg
end
|
#beacon_eqs(beacon1, beacon2) ⇒ Object
263
264
265
|
# File 'lib/tgios/beacon_manager.rb', line 263
def beacon_eqs(beacon1, beacon2)
self.class.beacon_eqs(beacon1, beacon2)
end
|
#dealloc ⇒ Object
294
295
296
297
|
# File 'lib/tgios/beacon_manager.rb', line 294
def dealloc
onPrepareForRelease
super
end
|
#did_enter_region(region) ⇒ Object
200
201
202
203
204
205
206
207
208
|
# File 'lib/tgios/beacon_manager.rb', line 200
def did_enter_region(region)
if region.isKindOfClass(CLBeaconRegion)
location_manager.startRangingBeaconsInRegion(region)
if has_event(:enter_region)
@events[:enter_region].call(region)
end
EnterRegionKey.post_notification(self, {region: region})
end
end
|
#did_exit_region(region) ⇒ Object
210
211
212
213
214
215
216
217
218
|
# File 'lib/tgios/beacon_manager.rb', line 210
def did_exit_region(region)
if region.isKindOfClass(CLBeaconRegion)
location_manager.stopRangingBeaconsInRegion(region)
if has_event(:exit_region)
@events[:exit_region].call(region)
end
ExitRegionKey.post_notification(self, {region: region})
end
end
|
#has_event(event) ⇒ Object
220
221
222
|
# File 'lib/tgios/beacon_manager.rb', line 220
def has_event(event)
@events.has_key?(event)
end
|
#identifier ⇒ Object
76
77
78
|
# File 'lib/tgios/beacon_manager.rb', line 76
def identifier
[@uuid.UUIDString, @major, @minor].join('/')
end
|
#location_manager ⇒ Object
148
149
150
151
152
153
154
155
156
|
# File 'lib/tgios/beacon_manager.rb', line 148
def location_manager
@location_manager ||=
begin
manager = CLLocationManager.alloc.init
manager.delegate = self
request_authorization(manager)
manager
end
end
|
#locationManager(manager, rangingBeaconsDidFailForRegion: region, withError: error) ⇒ Object
96
97
98
99
100
101
102
103
104
|
# File 'lib/tgios/beacon_manager.rb', line 96
def locationManager(manager, didDetermineState: state, forRegion: region)
NSLog "didDetermineState #{state}"
if state == CLRegionStateInside
manager.startRangingBeaconsInRegion(region)
did_enter_region(region)
elsif state == CLRegionStateOutside
did_exit_region(region)
end
end
|
#new_fake_beacon(options) ⇒ Object
276
277
278
|
# File 'lib/tgios/beacon_manager.rb', line 276
def new_fake_beacon(options)
FakeBeacon.new({uuid: @uuid}.merge(options))
end
|
#on(event_key, &block) ⇒ Object
80
81
82
83
|
# File 'lib/tgios/beacon_manager.rb', line 80
def on(event_key,&block)
@events[event_key] = block.weak!
self
end
|
#on_enter_background(noti) ⇒ Object
195
196
197
198
|
# File 'lib/tgios/beacon_manager.rb', line 195
def on_enter_background(noti)
NSLog 'on_enter_background'
stop_monitor unless @background
end
|
#on_enter_foreground(noti) ⇒ Object
190
191
192
193
|
# File 'lib/tgios/beacon_manager.rb', line 190
def on_enter_foreground(noti)
NSLog 'on_enter_foreground'
self.performSelector('start_monitor', withObject: nil, afterDelay:1)
end
|
#onPrepareForRelease ⇒ Object
284
285
286
287
288
289
290
291
292
|
# File 'lib/tgios/beacon_manager.rb', line 284
def onPrepareForRelease
UIApplicationWillEnterForegroundNotification.remove_observer(self)
UIApplicationDidEnterBackgroundNotification.remove_observer(self)
stop_monitor
@location_manager = nil
@events = nil
@current_beacon = nil
@previous_beacons = nil
end
|
#push_beacon(beacon) ⇒ Object
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
# File 'lib/tgios/beacon_manager.rb', line 224
def push_beacon(beacon)
case @algorithm
when :continue
if beacon_eqs(beacon, @current_beacon)
@current_beacon = beacon
else
if @previous_beacons.find { |b| !beacon_eqs(beacon, b) }.blank?
@current_beacon = beacon
else
@current_beacon = nil if @previous_beacons.find{ |b| beacon_eqs(@current_beacon, b)}.blank?
end
end
@previous_beacons << beacon
@previous_beacons.delete_at(0) if @previous_beacons.length > @tolerance
when :timeout
time_now = Time.now
beacon_hash = {beacon: beacon, time: time_now}
@beacons_last_seen_at[self.class.beacon_key(beacon)] = beacon_hash
while @previous_beacons.present? && time_now - @previous_beacons.first[:time] > @tolerance do
@previous_beacons.delete_at(0)
end
@previous_beacons << beacon_hash
current_beacon_hash = @beacons_last_seen_at[self.class.beacon_key(@current_beacon)]
if current_beacon_hash
end
if !current_beacon_hash || time_now - current_beacon_hash[:time] < @tolerance
else
count_hash = @previous_beacons.each_with_object(Hash.new(0)) {|e, h| h[self.class.beacon_key(e[:beacon])] += @tolerance - (time_now - e[:time])}
max_beacon_key = count_hash.max_by(&:last).first
@current_beacon = @beacons_last_seen_at[max_beacon_key][:beacon]
end
end
end
|
#request_authorization(manager) ⇒ Object
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
# File 'lib/tgios/beacon_manager.rb', line 158
def request_authorization(manager)
if manager.respond_to?(:requestAlwaysAuthorization)
status = CLLocationManager.authorizationStatus
if status == KCLAuthorizationStatusAuthorizedWhenInUse || status == KCLAuthorizationStatusDenied
denied_title = 'Tgios::BeaconManager.request_alert.title.denied'._
denied_title = 'Location services are off' if denied_title == 'Tgios::BeaconManager.request_alert.title.denied'
disabled_title = 'Tgios::BeaconManager.request_alert.title.disabled'._
disabled_title = 'Background location is not enabled' if disabled_title == 'Tgios::BeaconManager.request_alert.title.disabled'
message = 'Tgios::BeaconManager.request_alert.message'._
message = "To use background location you must turn on 'Always' in the Location Services Settings" if message == 'Tgios::BeaconManager.request_alert.message'
title = (status == KCLAuthorizationStatusDenied) ? denied_title : disabled_title
UIAlertView.alert(title, message: message)
else
manager.requestAlwaysAuthorization
end
end
end
|
#start_monitor ⇒ Object
180
181
182
183
|
# File 'lib/tgios/beacon_manager.rb', line 180
def start_monitor
location_manager.startMonitoringForRegion(@region)
location_manager.requestStateForRegion(@region)
end
|
#stop_monitor ⇒ Object
185
186
187
188
|
# File 'lib/tgios/beacon_manager.rb', line 185
def stop_monitor
location_manager.stopRangingBeaconsInRegion(@region)
location_manager.stopMonitoringForRegion(@region)
end
|