0

I am very new to iOS development and I'm struggling to make an app which connects to BLE devices. As I have many view controllers I need to keep the peripheral always connected in all of them.

To achieve this, I implemented all the BLE connection methods in a Singleton. This works just great, I call the connect method from View Controller and the Singleton connects to the peripheral.

Now, the problem is I have a UILabel in my view controller which I would like to update with the connection state (scanning, connecting, connected, disconnected) from the Singleton.

So I tried to get instance from the View Controller and change the label directly like:

MainViewController *controller = [[MainViewController alloc] init];
controller.myLabel.text =  @"TEST";

I also instantiated the view controller class like:

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MyStoryboard" bundle: nil];
MainViewController *controller = (MainViewController*)[mainStoryboard instantiateViewControllerWithIdentifier:@"MainVC"];

Then I tried to create a method in the main View Controller:

- (void) updateLabel:(NSString *) labelText{
     NSLog(@"CALLED IN MAIN");
     self.myLabel.text = labelText;
 }

And call it from Singleton like:

MainViewController *controller = [[MainViewController alloc] init];
[controller updateLabel:@"TEST"]

Which was called properly (NSLog was shown) but the label was not updated.

I don't really know how to update my View Controller label from the Singleton. Don't know neither if the way I'm trying to do it is the right one or not.

Any advice or help would be much appreciated. Thanks.

----- UPDATE: -----

Thanks to Mundi and Nikita, I got a better way to implement what I need through NSNotification. For all those who need it here is how I do it:

In my View Controller in viewDidLoad I call:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateConnectionLabel:) name:@"connectionLabelNotification" object:nil];

Then in the same class I implement the notification observer method like:

- (void)updateConnectionLabel:(NSNotification *) notification {
     if ([[notification name] isEqualToString:@"connectionLabelNotification"]) {
        self.connectionLabel.text = notification.object; //The object is a NSString
     }
}

Then in my Singleton, when I need I call:

[[NSNotificationCenter defaultCenter] postNotificationName:@"connectionLabelNotification" object:[NSString stringWithFormat:@"CONNECTED"]];

When the View Controller receives the notification from the Singleton it updates the label with the text I add on the notification object (in this case @"CONNECTED").

kodartcha
  • 1,063
  • 12
  • 23

2 Answers2

3

You need to use NSNotification.

Here is sample code:

in viewDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(mySelector:)
                                             name:DeviceStateChanged
                                           object:nil];

in dealloc:

[[NSNotificationCenter defaultCenter] removeObserver:self
                                                name:DeviceStateChanged
                                              object:nil];

also add a method in ViewController:

- (void) mySelector:(NSNotification *) notification {
    // action performed
}

in Sigleton

- (void) foo {
    /// some actions

    // device connected
    [[NSNotificationCenter defaultCenter] postNotificationName:DeviceStateChanged object:self];

    ///
}

Recommendation: move notification name to your constants and use constant name. For naming convention look at Apple guidelines

Nikita Took
  • 3,980
  • 25
  • 33
  • Thanks a lot! Already found the answer thanks to Mundi, but your example may also work. I upvoted your answer! – kodartcha Jul 21 '14 at 09:21
1

The proper way to do this is via NSNotification. This communication device is meant for exactly this kind of situation. It broadcast a message without caring whether the potential receiver is available.

In your view controllers, you call NSNotificationCenter's addObserver / removeObserver when they appear / disappear. You post the notification via postNotification:.

Mundi
  • 79,884
  • 17
  • 117
  • 140