Reputation: 421
I have the OSX BLE heartrate example from: https://developer.apple.com/library/mac/samplecode/HeartRateMonitor/Introduction/Intro.html. This example updates the heartrate via binding the NSTextField to the heartRate
property. heartRate
is updated in peripheral:didUpdateValueForCharacteristic
, which updates the bound NSTextView accordingly. Isn't peripheral:didUpdateValueForCharacteristic
on another thread, but this works fine since the control's update is handled 'behind the scenes' by Cocoa?
I added another NSTextView to which I created an outlet ivar. This ivar also gets updated in peripheral:didUpdateValueForCharacteristic
and [txtfldHR setIntegerValue:bpm];
is called. This also seems to work properly. But isn't updating the NSTextField via the IBOutlet dangerous (or shouldn't work at all) from another thread? How can I updated the NSTextField via the function call safely without using bindings?
I've made a similar app in Android and there I need to pass the heartrate value via a message from the BLE callback to the UI thread in order to update the UI controls.
Upvotes: 2
Views: 734
Reputation: 114866
If you look at the sample code you will see that the CBCentralManager
is initialised using the following code -
manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
If you refer to the documentation for the queue
parameter of initWithDelegate
, it says -
The dispatch queue to use to dispatch the central role events. If the value is nil, the central manager dispatches central role events using the main queue.
This means that your various Bluetooth delegate events will be executed using the main queue.
If you were using a different queue for your delegate operations then you would need to explicitly dispatch UI update events on the main queue via something like dispatch_async(dispatch_get_main_queue() ^{ //code });
Upvotes: 4