CocoaPods is a dependency manager and this is by far the easiest and quickest way to get started with PubNub iOS SDK! (If you don't have pods installed yet you can check CocoaPods installation section for installation guide).

Be sure you are running CocoaPods 1.0.0 or above! You can install the latest cocopods gem:

gem install cocoapods

If you’ve already installed you can upgrade to the latest CocoaPods gem using:

To build the framework as a standalone bundle and integrate into project, perform the following:

Clone the PubNub master repository

git clone git@github.com:pubnub/objective-c.git

Navigate to root of the cloned repository

Run the CocoaPods pod install command to pull out all required dependencies

pod install

Open the PubNub.xcworkspace from the PubNub repository in Xcode.

Select the Framework or Universal Framework target for target platform and hit Cmd+B to build the selected type of framework.

Navigate to the Framework directory and find the Products directory.

Drag&Drop PubNub.framework bundle from the Products directory to your application.

Select the Copy items if needed checkbox and click Finish.

Open your project's General tab and scroll to Embedded Binaries.

Click on + and select PubNub.framework file.

If the PubNub target has been used, then the framework will be generated only for the selected platform (device or simulator.) If you try to use the framework to compile for another platform, it will crash during run-time! Using the PubNub-Universal build target (which can be used on both device and simulator) will help mitigate any sort of crash scenarios during development.

Now that these steps are complete, let's learn more about how to use the framework in your app.

Add next line into a Cartfile which will allow to build framework bundles

github "pubnub/objective-c" ~> 4.1

Update and rebuild the project's dependencies (update command ensure what latest PubNub client code will be used to build framework). build can be used if frameworks has been built before and it will be much faster because git clone will be skipped.

carthage update

Command above will build framework for all configured platforms, but if only one required it can be called like this

Install CocoaPods gem by following the procedure defined under How to Get It.

To add the PubNub SDK to your project with CocoaPods, there are four basic tasks to complete which are covered below:

Create new Xcode project.

Create Podfile in new Xcode project root folder

touch Podfile

The PubNub client can be added as dynamic framework (only with a deployment target of iOS 8.0 and above) or as a static library (for deployment targets of iOS 7.0 and above).

For a deployment target of iOS 8.0 and above use:

source 'https://github.com/CocoaPods/Specs.git'
# optionally complete and uncomment if compilation issues arise
# project '<path to project relative to this Podfile>/<name of project without extension>'
# workspace 'MyPubNubProject'
use_frameworks!
target 'application-target-name' do
# Can only support iOS 8 or higher with frameworks,
# but can only target higher frameworks as well
platform :ios, '8.0' # (or '9.0' or '10.0')
pod "PubNub", "~> 4"
end

For a deployment target of iOS 7.0 and above use:

source 'https://github.com/CocoaPods/Specs.git'
# optionally complete and uncomment if compilation issues arise
# project '<path to project relative to this Podfile>/<name of project without extension>'
# workspace 'MyPubNubProject'
target 'application-target-name' do
# Should only use this with projects
# that must have a minimum deployment
# target of iOS 7
platform :ios, '7.0' # (if you don't need to use iOS 7, then see other Podfile)
pod "PubNub", "~> 4"
end

If you have any other pods you'd like to include, or if you have other targets you'd to add (like a test target) add those entries to this Podfile as well. See the CocoaPods documentation for more information on Podfile configuration.

Install your pods by running pod install via the command line from the directory that contains your Podfile.

After installing your Pods, you should only be working within the workspace generated by CocoaPods or specified by you in Podfile. Always open the newly generated workspace file, not the original project file!

To be able to use PubNub SDK within your application code you need to import it. Import PubNub SDK headers in implementation files for classes where you need to use it using this import statement:

Instantiate a new Pubnub instance. Only the subscribeKey is mandatory. Also include publishKey if you intend to publish from this instance, and the secretKey if you wish to perform PAM administrative operations from this Objective-C instance.

It is not a best practice to include the secret key in client-side code for security reasons.

When you init with secretKey, you get root permissions for the Access Manager. With this feature you don't have to grant access to your servers to access channel data. The servers get all access on all channels.

Subscribe request returned messages which can't be decrypted with configured cipherKey. Unencrypted message will be returned in status.associatedObject where associatedObject is PNMessageData which contain channel and message properties.

PNNetworkIssuesCategory

Subscribe request failed because there was no network connection at the moment when request has been sent.

Previously started subscribe loop did fail and at this moment client disconnected from real-time data channels.

PNRequestMessageCountExceededCategory

If requestMessageCountThreshold is set, this status event will arrive each time when client receive more messages when it has been specified for PNConfiguration property.

PNMalformedFilterExpressionCategory

Subscription request can't be processed by PubNub service because filter expression malformed and can't be evaluated.

PNHeartbeatOperation

In case if presence heartbeat value is set, client will sent this status category at specified periods. If status.isError set to YES it mean what heartbeat request did fail (potentially because of network issues).

This is list of categories which can be received in API completion blocks (non-subscribe):

API did fail because there was no network connection at the moment when request has been sent.

PNMalformedResponseCategory

Request received in response non-JSON data. It can be because of publish WiFi hotspot which require authorization or proxy server message.

PNBadRequestCategory

Request can't be completed because not all required values has been passed or passed values has unexpected data type.

PNDecryptionErrorCategory

History API may return this status category in case if some messages can't be decrypted. Unencrypted message will be returned in status.associatedObject where associatedObject is PNMessageData which contain channel and message properties.

PNTLSConnectionFailedCategory

TLS handshake issues and in most cases because of poor connection quality and packets loss and delays.

/**
Subscription process results arrive to listener which should adopt to PNObjectEventListener protocol
and registered using:
*/
[self.client addListener:self];
[self.client subscribeToChannels: @[@"my_channel1", @"my_channel2"] withPresence:NO];
// Handle new message from one of channels on which client has been subscribed.
- (void)client:(PubNub *)client didReceiveMessage:(PNMessageResult *)message {
// Handle new message stored in message.data.message
if (![message.data.channel isEqualToString:message.data.subscription]) {
// Message has been received on channel group stored in message.data.subscription.
}
else {
// Message has been received on channel stored in message.data.channel.
}
NSLog(@"Received message: %@ on channel %@ at %@", message.data.message,
message.data.channel, message.data.timetoken);
}
// Handle subscription status change.
- (void)client:(PubNub *)client didReceiveStatus:(PNStatus *)status {
if (status.operation == PNSubscribeOperation) {
// Check whether received information about successful subscription or restore.
if (status.category == PNConnectedCategory || status.category == PNReconnectedCategory) {
// Status object for those categories can be casted to `PNSubscribeStatus` for use below.
PNSubscribeStatus *subscribeStatus = (PNSubscribeStatus *)status;
if (subscribeStatus.category == PNConnectedCategory) {
// This is expected for a subscribe, this means there is no error or issue whatsoever.
}
else {
/**
This usually occurs if subscribe temporarily fails but reconnects. This means there was
an error but there is no longer any issue.
*/
}
}
else if (status.category == PNUnexpectedDisconnectCategory) {
/**
This is usually an issue with the internet connection, this is an error, handle
appropriately retry will be called automatically.
*/
}
// Looks like some kind of issues happened while client tried to subscribe or disconnected from
// network.
else {
PNErrorStatus *errorStatus = (PNErrorStatus *)status;
if (errorStatus.category == PNAccessDeniedCategory) {
/**
This means that PAM does allow this client to subscribe to this channel and channel group
configuration. This is another explicit error.
*/
}
else {
/**
More errors can be directly specified by creating explicit cases for other error categories
of `PNStatusCategory` such as: `PNDecryptionErrorCategory`,
`PNMalformedFilterExpressionCategory`, `PNMalformedResponseCategory`, `PNTimeoutCategory`
or `PNNetworkIssuesCategory`
*/
}
}
}
else if (status.operation == PNUnsubscribeOperation) {
if (status.category == PNDisconnectedCategory) {
/**
This is the expected category for an unsubscribe. This means there was no error in unsubscribing
from everything.
*/
}
}
else if (status.operation == PNHeartbeatOperation) {
/**
Heartbeat operations can in fact have errors, so it is important to check first for an error.
For more information on how to configure heartbeat notifications through the status
PNObjectEventListener callback, consult http://www.pubnub.com/docs/ios-objective-c/api-reference-configuration#configuration_basic_usage
*/
if (!status.isError) { /* Heartbeat operation was successful. */ }
else { /* There was an error with the heartbeat operation, handle here. */ }
}
}

The response of the call is handled by adding a Listener. Please see the Listeners section for more details. Listeners should be added before calling the method.

CocoaPods is a dependency manager and this is by far the easiest and quickest way to get started with PubNub Cocoa SDK! (If you don't have pods installed yet you can check CocoaPods installation section for installation guide).

Be sure you are running CocoaPods 1.0.0 or above! You can install the latest cocoapods gem:

gem install cocoapods

If you’ve already installed you can upgrade to the latest CocoaPods gem using:

To build the framework as a standalone bundle and integrate into project, perform the following:

Clone the PubNub master repository

git clone git@github.com:pubnub/objective-c.git

Navigate to root of the cloned repository

Run the CocoaPods pod install command to pull out all required dependencies

pod install

Open the PubNub.xcworkspace from the PubNub repository in Xcode.

Select the Framework or Universal Framework target for target platform and hit Cmd+B to build the selected type of framework.

Navigate to the Framework directory and find the Products directory.

Drag&Drop PubNub.framework bundle from the Products directory to your application.

Select the Copy items if needed checkbox and click Finish.

Open your project's General tab and scroll to Embedded Binaries.

Click on + and select PubNub.framework file.

If the PubNub target has been used, then the framework will be generated only for the selected platform (device or simulator.) If you try to use the framework to compile for another platform, it will crash during run-time! Using the PubNub-Universal build target (which can be used on both device and simulator) will help mitigate any sort of crash scenarios during development.

Now that these steps are complete, let's learn more about how to use the framework in your app.

Add next line into a Cartfile which will allow to build framework bundles

github "pubnub/objective-c" ~> 4.1

Update and rebuild the project's dependencies (update command ensure what latest PubNub client code will be used to build framework). build can be used if frameworks has been built before and it will be much faster because git clone will be skipped.

carthage update

Command above will build framework for all configured platforms, but if only one required it can be called like this

If you have any other pods you'd like to include, or if you have other targets you'd to add (like a test target) add those entries to this Podfile as well. See the CocoaPods documentation for more information on Podfile configuration.

Install your pods by running pod install via the command line from the directory that contains your Podfile.

After installing your Pods, you should only be working within the workspace generated by CocoaPods or specified by you in Podfile. Always open the newly generated workspace file, not the original project file!

To be able to use PubNub SDK within your application code you need to import it. Import PubNub SDK headers in implementation files for classes where you need to use it using this import statement:

Instantiate a new Pubnub instance. Only the subscribeKey is mandatory. Also include publishKey if you intend to publish from this instance, and the secretKey if you wish to perform PAM administrative operations from this Objective-C instance.

It is not a best practice to include the secret key in client-side code for security reasons.

When you init with secretKey, you get root permissions for the Access Manager. With this feature you don't have to grant access to your servers to access channel data. The servers get all access on all channels.

Subscribe request returned messages which can't be decrypted with configured cipherKey. Unencrypted message will be returned in status.associatedObject where associatedObject is PNMessageData which contain channel and message properties.

PNNetworkIssuesCategory

Subscribe request failed because there was no network connection at the moment when request has been sent.

Previously started subscribe loop did fail and at this moment client disconnected from real-time data channels.

PNRequestMessageCountExceededCategory

If requestMessageCountThreshold is set, this status event will arrive each time when client receive more messages when it has been specified for PNConfiguration property.

PNMalformedFilterExpressionCategory

Subscription request can't be processed by PubNub service because filter expression malformed and can't be evaluated.

PNHeartbeatOperation

In case if presence heartbeat value is set, client will sent this status category at specified periods. If status.isError set to YES it mean what heartbeat request did fail (potentially because of network issues).

This is list of categories which can be received in API completion blocks (non-subscribe):

API did fail because there was no network connection at the moment when request has been sent.

PNMalformedResponseCategory

Request received in response non-JSON data. It can be because of publish WiFi hotspot which require authorization or proxy server message.

PNBadRequestCategory

Request can't be completed because not all required values has been passed or passed values has unexpected data type.

PNDecryptionErrorCategory

History API may return this status category in case if some messages can't be decrypted. Unencrypted message will be returned in status.associatedObject where associatedObject is PNMessageData which contain channel and message properties.

PNTLSConnectionFailedCategory

TLS handshake issues and in most cases because of poor connection quality and packets loss and delays.

/**
Subscription process results arrive to listener which should adopt to PNObjectEventListener protocol
and registered using:
*/
[self.client addListener:self];
[self.client subscribeToChannels: @[@"my_channel1", @"my_channel2"] withPresence:NO];
// Handle new message from one of channels on which client has been subscribed.
- (void)client:(PubNub *)client didReceiveMessage:(PNMessageResult *)message {
// Handle new message stored in message.data.message
if (![message.data.channel isEqualToString:message.data.subscription]) {
// Message has been received on channel group stored in message.data.subscription.
}
else {
// Message has been received on channel stored in message.data.channel.
}
NSLog(@"Received message: %@ on channel %@ at %@", message.data.message,
message.data.channel, message.data.timetoken);
}
// Handle subscription status change.
- (void)client:(PubNub *)client didReceiveStatus:(PNStatus *)status {
if (status.operation == PNSubscribeOperation) {
// Check whether received information about successful subscription or restore.
if (status.category == PNConnectedCategory || status.category == PNReconnectedCategory) {
// Status object for those categories can be casted to `PNSubscribeStatus` for use below.
PNSubscribeStatus *subscribeStatus = (PNSubscribeStatus *)status;
if (subscribeStatus.category == PNConnectedCategory) {
// This is expected for a subscribe, this means there is no error or issue whatsoever.
}
else {
/**
This usually occurs if subscribe temporarily fails but reconnects. This means there was
an error but there is no longer any issue.
*/
}
}
else if (status.category == PNUnexpectedDisconnectCategory) {
/**
This is usually an issue with the internet connection, this is an error, handle
appropriately retry will be called automatically.
*/
}
// Looks like some kind of issues happened while client tried to subscribe or disconnected from
// network.
else {
PNErrorStatus *errorStatus = (PNErrorStatus *)status;
if (errorStatus.category == PNAccessDeniedCategory) {
/**
This means that PAM does allow this client to subscribe to this channel and channel group
configuration. This is another explicit error.
*/
}
else {
/**
More errors can be directly specified by creating explicit cases for other error categories
of `PNStatusCategory` such as: `PNDecryptionErrorCategory`,
`PNMalformedFilterExpressionCategory`, `PNMalformedResponseCategory`, `PNTimeoutCategory`
or `PNNetworkIssuesCategory`
*/
}
}
}
else if (status.operation == PNUnsubscribeOperation) {
if (status.category == PNDisconnectedCategory) {
/**
This is the expected category for an unsubscribe. This means there was no error in unsubscribing
from everything.
*/
}
}
else if (status.operation == PNHeartbeatOperation) {
/**
Heartbeat operations can in fact have errors, so it is important to check first for an error.
For more information on how to configure heartbeat notifications through the status
PNObjectEventListener callback, consult http://www.pubnub.com/docs/ios-objective-c/api-reference-configuration#configuration_basic_usage
*/
if (!status.isError) { /* Heartbeat operation was successful. */ }
else { /* There was an error with the heartbeat operation, handle here. */ }
}
}

The response of the call is handled by adding a Listener. Please see the Listeners section for more details. Listeners should be added before calling the method.