Build

3 Ways to Handle Receiving Messages in Cocoa

4 min read Michael Carroll on Jun 26, 2014

As you explore the PubNub Cocoa SDK, you’ll learn quickly that there seem to be several different ways to handle incoming messages. You might be asking yourself what the differences are between all these methods. There are three ways in which you can handle messages received via subscribed channels:

  1. via the PubNub singleton client delegate methods
  2. via the PNObservationCenter by adding observers, and
  3. via the core foundation NotificationCenter by adding callbacks to event notifications.

Cocoa

**NOTE: Since we wrote this tutorial, we’ve released a new, completely-redesigned version of our iOS SDK (4.0). We rebuilt the entire codebase and took advantage of new features from Apple, simplifying and streamlining the SDK.

The code from this tutorial still works great, but we recommend checking out our new SDK. We’ve included a migration guide to help you move from 3.x to 4.0, and a getting started guide to help you create a simple Hello World application in minutes.**

1. PubNub Singleton

The main PubNub singleton has a number of delegate method stubs defined on it. By overriding those, you can have your own code react to those events. If you are using PubNub in simple ways, overriding the delegate methods is often a quick and easy way to handle them.

Common Use Cases

  • Single subscribed channel for messages
  • Simple PubNub publish subscribe logic
  • Single event handler needed for most situations

These delegate methods are “global” in the sense they are triggered every time a particular event happens, and any filtering logic needs to be written into that method, for example:

Message Received [didReceiveMessage]

// Message Receive Event for All Subscribed Channels
- (void)pubnubClient:(PubNub *)client didReceiveMessage:(PNMessage *)msg
{
    NSLog(@"Message Received:
Channel:%@
Message:%@", msg.channel.name, [msg message]); }

Every message received on every channel will execute this method! In order to have flow control for various channel messages, you would need to do something like the following:

Message Received [didReceiveMessage]

- (void)pubnubClient:(PubNub *)client didReceiveMessage:(PNMessage *)message {
    if ([message.channel.name isEqualToString:@"my-test-channel"]) {
        // Do things with messages on the test channel
        NSLog(@"Message Received:
Channel:%@
Message:%@", msg.channel.name, [msg message]); } else if ([message.channel.name isEqualToString:@"my-control-channel"]) // Do things with messages on the control channel NSLog(@"Message Received:
Channel:%@
Message:%@", msg.channel.name, [msg message]); } }

The delegate methods are defined in the class that implements the PNDelegate interface, often your main AppDelegate.m. So this puts your handler logic all in that same file which means you may break your model encapsulation.

When you have different logic and functionality for different subscribed channels, it can also grow your delegate method code significantly, and in those cases it’s often easier to use the PNObservationCenter instead.

2. PNObservationCenter Singleton

The PubNub Observation Center (PNObservationCenter) singleton registers a full lifecycle of events in the core Notification Center and allows you to pass in blocks as handlers. This was added for flexibility and convenience. Passing in blocks allows you to create multiple handlers very easily and dynamically.

  • Different handler code for different subscribed channels
  • Create Dynamic event handlers on the fly using Blocks
  • Encapsulate handler logic properly in your model

Message Received Observers [addMessageReceiveObserver]

 [[PNObservationCenter defaultCenter] addMessageReceiveObserver:@"my-test-channel" withBlock:^(PNMessage * msg) {
        if ([message.channel.name isEqualToString:@"my-test-channel"]) {
            NSLog(@"Message Received:
Channel:%@
Message:%@", msg.channel.name, [msg message]); } }]; [[PNObservationCenter defaultCenter] addMessageReceiveObserver:@"my-control-channel" withBlock:^(PNMessage * msg) { if ([message.channel.name isEqualToString:@"my-control-channel"]) { NSLog(@"Message Received:
Channel:%@
Message:%@", msg.channel.name, [msg message]); } }];

In this scenario, every observer will still receive that notification event, however it’s easier keep logic concise in your handlers. In addition, you can put this observation logic into your models and have better encapsulation.

The other beatiful thing is that you can add and remove observers dynamically. Therefore your channel names, and message handling code is not hardcoded into your application. This allows for more advanced usage scenarios.

3. Core Notification Center

Cocoa

The Cocoa Core Framework provides a Notification Center Singleton of it’s own [NSNotificationCenter defaultCenter]. The PNObservation center singleton registers a number of events in the NotificationCenter that can be subscribed to for callbacks and used just like any other notification event that you commonly use in Cocoa. The complete list of constants can be found in the PNNotifications.h file in the SDK Library.

While this is functionally just as good as using PNObservationCenter, it’s definitely simpler to use the PNObservationCenter wrapper and the convenience of passing in handler blocks.

Conclusion

The examples above for message received events illustrate the usage, but those aren’t the only events! There are Publish/Subscribe, Presence, Mobile Push Notifications, and many other events that you can handle via the PNObservationCenter.

0