Create an Objective-C iOS® client within minutes that connects to
Diffusion™ Cloud. This example creates a client that prints the value
of a topic to the console when the topic is updated.
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 either a named user that has a role with the select_topic and read_topic permissions or that anonymous
client connections are assigned a role with the select_topic and read_topic permissions. For example, the "CLIENT" role. For more
information about roles and permissions, see Role-based authorization.
This example steps through the lines of code required to subscribe to a topic and
was created using Xcode version 7.1 and the Diffusion Cloud
dynamically linked framework targeted at iOS 8. Skip to the full example.
-
Get the Diffusion Cloud
Apple® SDK for iOS.
This example uses the iOS framework
provided in
diffusion-iphoneos-version.zip.
Frameworks are also available for OS X®/macOS®-targeted
development in
diffusion-macosx-version.zip and tvOS™-targeted
development in
diffusion-tvos-version.zip.
-
Extract the contents of the
diffusion-iphoneos-version.zip
file to your preferred location for third-party SDKs for use within Xcode.
For example,
~/Documents/code/SDKs/diffusion-iphoneos-version.
-
Create a new project in Xcode.
-
From the File menu, select
The Choose a template for your new project
wizard opens.
-
Select on the left.
-
Select Single View Application on the right and
click Next.
Xcode prompts you to Choose options for your new
project.
-
Configure your project appropriately for your requirements.
Select Objective-C as the
Language.
For example, use the following values:
- Product Name:
TestClient
- Language:
Objective-C
- Devices:
Universal
For this example, it is not necessary to select Use Core
Data, Include Unit Tests, or
Include UI Tests.
-
Click the Next button.
Xcode prompts you to select a destination directory for your new
project.
-
Select a target directory.
For example: ~/Documents/code/
-
Click the Create button.
Xcode creates a new project that contains the required files.
-
Import the Diffusion Cloud framework,
Diffusion.framework, into Xcode.
-
From the View menu, select
-
Select the root node of the project in the Project
Navigator in the left sidebar.
The project editor opens in the main panel.
-
In the project editor, click on the project name at the top left and
select .
The target editor opens in the main panel.
-
In the target editor, select the General
tab.
-
Expand the Embedded Binaries section and click
the + icon (Add Items).
The Choose items to add wizard opens.
-
Click the Add Other... button.
-
Navigate to the location of the expanded
Diffusion.framework SDK for iOS8 and click
Open.
Xcode prompts you to choose options for adding these files.
-
Select the options you require for adding the files and click
Finish
Unless you require different options, use the following values:
- Do not select Copy items if needed.
- Select Create groups.
-
Make the framework visible to your code.
Despite the framework now appearing under both Embedded
Binaries and Linked Frameworks and
Libraries, it is still necessary to tell Xcode where the header
files for the framework can be found.
-
Select the Build Settings tab in the target
editor.
You can also do this at project level if you prefer and depending on
your requirements.
-
Click on All to display All Build
Settings.
-
Expand the Search Paths section.
-
Expand the Framework Search Paths section and
click the + icon next to
Release.
Add the absolute path to the iOS8 directory that
contains Diffusion.framework.
Note: Ensure that you use the path to the directory, not to the
Diffusion.framework file. Linking to the
file causes a silent failure.
-
Import the Diffusion module into the
ViewController.h file.
-
In the ViewController.m file, create a connection to Diffusion Cloud.
-
Define a long-lived session property.
Add the session instance to the class extension to maintain a strong
reference to the session instance:
@interface ViewController ()
@property PTDiffusionSession* session;
@end
The strong reference ensures that once the session instance has been
opened, it remains open.
-
Open a session connection to Diffusion Cloud.
This example opens the session when the view controller loads.
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"Connecting...");
// Connect anonymously.
// Replace 'hostname' with that of your server.
[PTDiffusionSession openWithURL:[NSURL URLWithString:@"ws://hostname"]
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;
}];
}
Replace hostname with the host name of your
Diffusion Cloud service.
-
Subscribe to a topic.
-
In the ViewController.h file, conform to the topic
stream delegate protocol.
In this example, the single view controller class handles topic
stream update messages.
@interface ViewController : UIViewController <PTDiffusionTopicStreamDelegate>
-
In the ViewController.h file, create a
UILabel control.
Add a label to your user interface and bind it to an outlet in the
view controller:
@property(nonatomic) IBOutlet UILabel *counterLabel;
This label is used to display the value of the topic as it
updates.
-
In the ViewController.m file, implement the topic
stream update method.
This is a required method in the topic stream delegate protocol.
-(void)diffusionStream:(PTDiffusionStream *)stream
didUpdateTopicPath:(NSString *)topicPath
content:(PTDiffusionContent *)content
context:(PTDiffusionUpdateContext *)context {
// Interpret the received content's data as a string.
NSString *counterString = [[NSString alloc] initWithData:content.data
encoding:NSUTF8StringEncoding];
// Diffusion sends messages to delegates on the main dispatch queue so it's
// safe to update the user interface here.
self.counterLabel.text = counterString;
}
-
In the ViewController.h file, within the session's
completionHandler callback, register with the
Topics feature as the
fallback topic stream handler.
[session.topics addFallbackTopicStreamWithDelegate:self];
-
Next, request that Diffusion Cloud subscribe your
session to the foo/counter
topic.
[session.topics subscribeWithTopicSelectorExpression:@"foo/counter"
completionHandler:^(NSError *error)
{
if (error) {
NSLog(@"Subscribe request failed. Error: %@", error);
} else {
NSLog(@"Subscribe request succeeded.");
}
}];
-
Build and Run.
The client app updates the label every time the value of the foo/counter topic is updated. You can update
the value of the foo/counter topic by using the Diffusion Cloud
Dashboard's test client or by creating a publishing client to update the
topic. To create and publish to the foo/counter topic, you require a user with the modify_topic and update_topic permissions. For more information, see Start publishing with OS X/macOS.
Full example
The completed view controller implementation for the subscribing client contains the
following code.
ViewController.h:
@import UIKit;
@interface ViewController : UIViewController <PTDiffusionTopicStreamDelegate>
@property(nonatomic) IBOutlet UILabel *counterLabel;
@end
ViewController.m:
#import "ViewController.h"
@interface ViewController ()
@property PTDiffusionSession* session;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"Connecting...");
// Connect anonymously.
// Replace 'hostname' with that of your server.
[PTDiffusionSession openWithURL:[NSURL URLWithString:@"ws://hostname"]
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;
// Register self as the fallback handler for topic updates.
[session.topics addFallbackTopicStreamWithDelegate:self];
NSLog(@"Subscribing...");
[session.topics subscribeWithTopicSelectorExpression:@"foo/counter"
completionHandler:^(NSError *error)
{
if (error) {
NSLog(@"Subscribe request failed. Error: %@", error);
} else {
NSLog(@"Subscribe request succeeded.");
}
}];
}];
}
-(void)diffusionStream:(PTDiffusionStream *)stream
didUpdateTopicPath:(NSString *)topicPath
content:(PTDiffusionContent *)content
context:(PTDiffusionUpdateContext *)context {
// Interpret the received content's data as a string.
NSString *counterString = [[NSString alloc] initWithData:content.data
encoding:NSUTF8StringEncoding];
// Diffusion sends messages to delegates on the main dispatch queue so it's
// safe to update the user interface here.
self.counterLabel.text = counterString;
}
@end