Just a second...

Start publishing with OS X/macOS

Create an OS X®/macOS® client that publishes data through topics on Diffusion™ Cloud .

To complete this example, you need Apple's Xcode installed on your development system and a Diffusion Cloud service. For more information about getting a Diffusion Cloud service, see Getting started with Diffusion Cloud.

You also require a named user that has a role with the modify_topic and update_topic permissions. For example, the "TOPIC_CONTROL" role. For more information about roles and permissions, see Role-based authorization.

This example steps through the lines of code required to create and publish to a topic and was created using Xcode version 7.1 and the Diffusion Cloud dynamically linked framework targeted at OS X/macOS.

Skip to the full example.

  1. Get the Diffusion Cloud Apple® SDK for OS X/macOS.
    The diffusion-macosx-version.zip file is available from http://download.diffusiondata.com/cloud/latest/sdks.html.
    This example uses the OS X/macOS framework provided in diffusion-macosx-version.zip. Frameworks are also available for iOS® -targeted development in diffusion-iphoneos-version.zip and tvOS™ -targeted development in diffusion-tvos-version.zip.
  2. Extract the contents of the diffusion-macosx-version.zip file to your preferred location for third-party SDKs for use within Xcode.
    For example, ~/Documents/code/SDKs/diffusion-macosx-version.
  3. Create a new project in Xcode.
    1. From the File menu, select New > Project...
      The Choose a template for your new project wizard opens.
    2. Select OS X > Application on the left.
    3. Select Command Line Tool on the right and click Next.
      Xcode prompts you to Choose options for your new project.
    4. Configure your project appropriately for your requirements.

      Select Objective-C as the Language.

      For example, use the following values:

      • Product Name: CounterPublisher
      • Language: Objective-C
    5. Click the Next button.
      Xcode prompts you to select a destination directory for your new project.
    6. Select a target directory.
      For example: ~/Documents/code/
    7. Click the Create button.
      Xcode creates a new project that contains the required files.
  4. Link to the Diffusion framework.
    For more information, see the Xcode documentation http://help.apple.com/xcode/mac/8.1/#/dev51a648b07.
  5. Create a CounterPublisher.h file.
    1. Bring up the context menu for the root node of the project in the Project Navigator in the left sidebar.
      Select New File
    2. In the dialog that opens, select Header File
    3. Name the header file CounterPublisher.h and click Create.
  6. Import the Foundation module into the CounterPublisher.h file.
    @import Foundation;
  7. Define the CounterPublisher interface in the CounterPublisher.h file.
    @interface CounterPublisher : NSObject
    
    -(void)startWithURL:(NSURL *)url;
    
    @end
  8. Create a CounterPublisher.m file.
    1. Bring up the context menu for the root node of the project in the Project Navigator in the left sidebar.
      Select New File
    2. In the dialog that opens, select Objective-C File
    3. Name the file CounterPublisher.m and click Create.
  9. In the CounterPublisher.m file, import the required modules and set up properties and variables.
    1. Import Diffusion and CounterPublisher.h
      #import "CounterPublisher.h"
      @import Diffusion;
    2. Define a long-lived session property.
      Add the session instance to the class extension to maintain a strong reference to the session instance:
      @interface CounterPublisher ()
      @property(nonatomic) PTDiffusionSession* session;
      @end

      The strong reference ensures that once the session instance has been opened, it remains open.

    3. Declare an integer _counter to hold the value to publish to the topic.
      @implementation CounterPublisher {
          NSUInteger _counter;
      }
    4. Define the topic path of the topic to create and publish to.
      static NSString *const _TopicPath = @"foo/counter";
  10. In the CounterPublisher.m file, create a method that starts the session with Diffusion Cloud .
    1. Call the method startWithURL and give it a signature that matches that defined in CounterPublisher.h
      -(void)startWithURL:(NSURL *)url {
      
          
      }
    2. Inside the method, define the security principal and credentials that the client uses to connect.
      PTDiffusionCredentials *credentials = 
          [[PTDiffusionCredentials alloc] initWithPassword:@"password"];
      PTDiffusionSessionConfiguration *sessionConfiguration = 
          [[PTDiffusionSessionConfiguration alloc] initWithPrincipal:@"principal"
                                                         credentials:credentials];

      Replace principal and password with the username and password to connect to Diffusion Cloud with. This user must have sufficient permissions to create and update the topic, for example, by being assigned the "TOPIC_CONTROL" role.

    3. Open a session on Diffusion Cloud .
        [PTDiffusionSession openWithURL:url
                            configuration:sessionConfiguration
                        completionHandler:^(PTDiffusionSession *session, NSError *error)
          {
              if (!session) {
                  NSLog(@"Failed to open session: %@", error);
                  return;
              }
      
               // At this point we now have a connected session.
              NSLog(@"Connected.");
      
              // Maintain strong reference to session instance.
              self.session = session;
              
              // Next step
              
          }];
  11. Create a topic.
    After connecting a session and creating a strong reference to it, use session.topicControl to create a topic:
    // Send request to add topic for publishing to.
            [session.topicControl addWithTopicPath:_TopicPath
                                              type:PTDiffusionTopicType_SingleValue
                                             value:nil
                                 completionHandler:^(NSError *error)
            {
                if (error) {
                    NSLog(@"Failed to add topic: %@", error);
                    return;
                }
    
                // Next step
    
            }];
  12. Update the topic.
    1. After successfully creating the topic, call the updateCounter method:
      [self updateCounter];
    2. At the top-level of the CounterPublisher.m file, define the updateCounter method:
      -(void)updateCounter {
          // Get the updater to be used for non-exclusive topic updates.
          PTDiffusionTopicUpdater *updater = self.session.topicUpdateControl.updater;
      
          // Format string content for the update.
          NSString *string = [NSString stringWithFormat:@"%lu", (unsigned long)_counter++];
          NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
          PTDiffusionContent *content = [[PTDiffusionContent alloc] initWithData:data];
      
          // Send request to update topic.
          NSLog(@"Updating: %@", string);
          [updater updateWithTopicPath:_TopicPath
                                 value:content
                     completionHandler:^(NSError *error)
          {
              if (error) {
                  NSLog(@"Failed to update topic: %@", error);
              }
          }];
      
          // Schedule another update in one second's time.
          __weak CounterPublisher *const weakSelf = self;
          dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(1.0 * NSEC_PER_SEC)),
                         dispatch_get_main_queue(), ^
          {
              [weakSelf updateCounter];
          });
      }
      This method recursively calls itself via a weak reference to self.
  13. In the main.m, add the code needed to run your publishing client from the command line:
    1. Import the Foundation module and the CounterPublisher.h file.
      @import Foundation;
      #import "CounterPublisher.h"
    2. In a main method, create a CounterPublisher and call its startWithURL method:
      int main(int argc, const char * argv[]) {
          @autoreleasepool {
              CounterPublisher *const publisher = [CounterPublisher new];
              NSURL *const url = [NSURL URLWithString:@"wss://hostname"];
              [publisher startWithURL:url];
      
              // Run in an infinite Loop.
              [[NSRunLoop currentRunLoop] run];
          }
          return 0;
      }
      Replace hostname with the host name of your Diffusion Cloud service.
  14. Build and Run.

The client publishes a value to the foo/counter topic every second. You can subscribe to the foo/counter topic by using the Diffusion Cloud Dashboard's test client or by creating a client to subscribe to the topic. For more information, see Start subscribing with iOS.

Full example

The completed implementation of the publishing client files contain the following code:

main.m:
@import Foundation;
#import "CounterPublisher.h"

/**
 Wrapper around the counter publisher example class demonstrating how it can
 be launched as a command line tool.
 */
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        CounterPublisher *const publisher = [CounterPublisher new];
        NSURL *const url = [NSURL URLWithString:@"wss://hostname"];
        [publisher startWithURL:url];

        // Run, Infinite Loop.
        [[NSRunLoop currentRunLoop] run];
    }
    return 0;
}
CounterPublisher.h:
@import Foundation;

@interface CounterPublisher : NSObject

-(void)startWithURL:(NSURL *)url;

@end
CounterPublisher.m:
@import Diffusion;

@interface CounterPublisher ()
@property(nonatomic) PTDiffusionSession* session;
@end

@implementation CounterPublisher {
    NSUInteger _counter;
}

@synthesize session = _session;

static NSString *const _TopicPath = @"foo/counter";

-(void)startWithURL:(NSURL *)url {
    NSLog(@"Connecting...");

    // Connect with control client credentials.
    PTDiffusionCredentials *credentials =
        [[PTDiffusionCredentials alloc] initWithPassword:@"password"];
    PTDiffusionSessionConfiguration *sessionConfiguration =
        [[PTDiffusionSessionConfiguration alloc] initWithPrincipal:@"principal"
                                                       credentials:credentials];

    [PTDiffusionSession openWithURL:url
                      configuration:sessionConfiguration
                  completionHandler:^(PTDiffusionSession *session, NSError *error)
    {
        if (!session) {
            NSLog(@"Failed to open session: %@", error);
            return;
        }

        // At this point we now have a connected session.
        NSLog(@"Connected.");

        // Maintain strong reference to session instance.
        self.session = session;

        // Send request to add topic for publishing to.
        [session.topicControl addWithTopicPath:_TopicPath
                                          type:PTDiffusionTopicType_SingleValue
                                         value:nil
                             completionHandler:^(NSError *error)
        {
            if (error) {
                NSLog(@"Failed to add topic: %@", error);
                return;
            }

            // At this point we now have a topic.
            [self updateCounter];
        }];
    }];
}

-(void)updateCounter {
    // Get the updater to be used for non-exclusive topic updates.
    PTDiffusionTopicUpdater *updater = self.session.topicUpdateControl.updater;

    // Format string content for the update.
    NSString *string = [NSString stringWithFormat:@"%lu", (unsigned long)_counter++];
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    PTDiffusionContent *content = [[PTDiffusionContent alloc] initWithData:data];

    // Send request to update topic.
    NSLog(@"Updating: %@", string);
    [updater updateWithTopicPath:_TopicPath
                           value:content
               completionHandler:^(NSError *error)
    {
        if (error) {
            NSLog(@"Failed to update topic: %@", error);
        }
    }];

    // Schedule another update in one second's time.
    __weak CounterPublisher *const weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(1.0 * NSEC_PER_SEC)),
                   dispatch_get_main_queue(), ^
    {
        [weakSelf updateCounter];
    });
}

@end