Give Feedback for the page

iOSiOSCocoaSwiftiOS Swift API Reference for Realtime Apps

Swift complete API reference for building Realtime Applications on PubNub, including basic usage and sample code.
PNConfiguration instance is storage for user-provided information which describe further PubNub client behaviour. Configuration instance contain additional set of properties which allow to perform precise PubNub client configuration.
To create configuration instance you can use the following function in the Swift SDK:
  1. ParameterTypeRequiredDescription
    publishKey StringYesYour PubNub Publish Key.
    subscribeKey StringYesYour PubNub Subscribe Key.
    heartbeatNotificationOptionsPNHeartbeatNotificationOptionsNo

    These are bitmask options, they can be combined. When client instances are notified about heartbeat operations, this happens through the PNObjectEventListener callback for statuses.

    PNHeartbeatNotifySuccess: explicitly tells client to notify on successful heartbeat operations.

    PNHeartbeatNotifyFailure: explicitly tells client to notify on failed heartbeat operations (default is only this option)

    PNHeartbeatNotifyAll: This is a combination of PNHeartbeatNotifySuccess and PNHeartbeatNotifyFailure

    PNHeartbeatNotifyNone: This means the client will not provide any callback notifications for heartbeat operations

    stripMobilePayloadBoolNoStores whether client should strip out received messages (real-time and history) from data which has been appended by client (like mobile payload for push notifications).
    cipherKeyStringNoKey which is used to encrypt messages pushed to PubNub service and decrypt messages received from live feeds on which client subscribed at this moment.
    subscribeMaximumIdleTimeTimeIntervalNo

    Maximum number of seconds which client should wait for events from live feed.

    Default 310.

    nonSubscribeRequestTimeoutTimeIntervalNo

    Number of seconds which is used by client during non-subscription operations to check whether response potentially failed with timeout or not.

    Default 10.

    presenceHeartbeatValueIntNoNumber of seconds which is used by server to track whether client still subscribed on remote data objects live feed or not.
    presenceHeartbeatIntervalIntNoNumber of seconds which is used by client to issue heartbeat requests to PubNub service.
    keepTimeTokenOnListChangeBoolNo

    Whether client should keep previous time token when subscribe on new set of remote data objects live feeds.

    Default true.

    catchUpOnSubscriptionRestoreBoolNo

    Whether client should try to catch up for events which occurred on previously subscribed remote data objects feed while client was off-line.

    Default true.

    applicationExtensionSharedGroupIdentifierStringNo

    Reference on group identifier which is used to share request cache between application extension and it's containing application.

    This property should be set to valid registered group only if PubNub client is used inside of application's extension (iOS 8.0+, macOS 10.10+).

    requestMessageCountThresholdUIntNoNumber of maximum expected messages from PubNub service in single response.
    maximumMessagesCacheSizeUIntNo

    Messages de-duplication cache size.

    Default 100.

    completeRequestsBeforeSuspensionBoolNo

    Whether client should try complete all API call which is done before application will be completely suspended.

    Default true.

let config = PNConfiguration(publishKey: "demo", subscribeKey: "demo")
self.client = PubNub.clientWithConfiguration(config)
self.client.addListener(self)
Configured and ready to use client configuration instance.
  1. let config = PNConfiguration(publishKey: "<pub key>", subscribeKey: "<sub key>")
    /**
     This is where you need to adjust the PNConfiguration object for the types of heartbeat notifications you want.
     This is a bitmask of options located at https://github.com/pubnub/objective-c/blob/1f1c7a41a3bd8c32b644a6ad98fe179d45397c2b/PubNub/Misc/PNStructures.h#L24
     */
    config.heartbeatNotificationOptions = [.notifyAll]
    
    self.client = PubNub.clientWithConfiguration(config)
    self.client.addListener(self)
  2. func client(_ client: PubNub, didReceive status: PNStatus) {
    		
    	if status.operation == .heartbeatOperation {
    		
    		/**
    		 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_basic_usage
    		 */
    		
    		if !status.isError { /* Heartbeat operation was successful. */ }
    		else { /* There was an error with the heartbeat operation, handle here. */ }
    	}
    }
PubNub client instance doesn’t allow dynamic configuration update, but it has helper functions which allow to receive new instance with updated configuration. Updated configuration will be applied on PubNub client copy. Original instance after copy block will return shouldn’t be used anymore.
To update client configuration you can use following functions in the Swift SDK:
  1. ParameterTypeRequiredDescription
    configuration
    PNConfiguration
    Yes
    Class Instance which stores the configuration settings which is used by the PubNub client.
    closure
    (PubNub) -> Void
    Yes
    Completion closure which is called at the end of update process, has one parameter - PubNub instance with updated configuration.
  2. ParameterTypeRequiredDescription
    configuration
    PNConfiguration
    Yes
    Class Instance which stores the configuration settings which is used by the PubNub client.
    callbackQueue
    dispatch_queue_t
    No
    The GCD dispatch queue where callbacks and completion handlers will be called (asynchronously).
    closure
    (PubNub) -> Void
    Yes
    Completion closure which is called at the end of update process, has one parameter - PubNub instance with updated configuration.
// User authorized and we need to update used UUID
let configuration = self.client.currentConfiguration()
configuration.uuid = "AuthorizedUserID"
self.client.copyWithConfiguration(configuration, completion: { (updatedClient) in

	// Store reference on new client with updated configuration.
	self.client = updatedClient
})
Void
Install the 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 tasks to complete:
  1. Create new Xcode project.

    Xcode project

  2. Create a Podfile in your newly created Xcode project root folder
    touch Podfile
  3. The PubNub client can be added as module (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).
    1. 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
          # Should only use this with projects 
          # that must have a minimum deployment 
          # target of iOS 8 
          platform :ios, '8.0' # (or '9.0' or '10.0')
          pod "PubNub", "~> 4"
      end
    2. 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.
  4. 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!

By creating the Podfile and running pod install in the same directory as your Podfile, you should now have a Swift project with the PubNub SDK installed. To access the PubNub Objective-C SDK with the deployment target set to iOS 7.0 and below, you will need to create a bridging header.
The bridging header is a way to make the Swift code aware of the available Objective-C interface to the PubNub client. To create your bridging header:
  1. Create a new File (File → New → File) of type Source → Header File

    Create a new File

  2. Specify a location and name (along the lines of [MyProjectName]-Bridging-Header.h) and create the file

    Specify a location and name

  3. Make your project aware of this newly created bridging header by opening your project, selecting Build Settings, and using the search box to find Objective-C Bridging Header

    Objective-C Bridging Header

  4. Specify the path to the bridging header. The location is relative to the project / workspace files location.

    Specify the path to the bridging header

  5. Select your bridging file from project tree (replace if new, add if existing) with:
    #import <PubNub/PubNub.h>
    The convention for bridging headers in Swift is to use a single bridging header file per project -- if you have other Pods included in your project that are written in Objective-C, they would be imported here as well.
If the project’s deployment target is set to iOS 8.0 and above, you will need to import the module named AppDelegate.swift:
import UIKit
import PubNub // <- Here is our PubNub module import.
	
class AppDelegate: UIResponder, UIApplicationDelegate, PNObjectEventListener {

	// Stores reference on PubNub client to make sure what it won't be released.
	var client: PubNub!

	func application(_ application: UIApplication, 
					 didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
		...
	}
}
	
This function is used for initializing the PubNub Client API context. This function must be called before attempting to utilize any API functionality in order to establish account level credentials such as publishKey and subscribeKey.
To Initialize Pubnub you can use the following method(s) in the Swift SDK:
  1. ParameterTypeRequiredDescription
    configuration
    PNConfiguration
    Yes
    Class Instance which stores the configuration settings which is used by the PubNub client.
  2. ParameterTypeRequiredDescription
    configuration
    PNConfiguration
    Yes
    Class Instance which stores the configuration settings which is used by the PubNub client.
    callbackQueue
    dispatch_queue_t
    No
    The GCD dispatch queue where callbacks and completion handlers will be called (asynchronously).
let configuration = PNConfiguration(publishKey: "demo", subscribeKey: "demo")
configuration.TLSEnabled = true
self.client = PubNub.clientWithConfiguration(configuration)
It returns the Pubnub instance for invoking PubNub APIs like publish(), subscribeToChannels(), historyForChannel, hereNowForChannel, etc.
  1. let configuration = PNConfiguration(publishKey: "demo", subscribeKey: "demo")
    self.client = PubNub.clientWithConfiguration(configuration)
  2. In the case where a client will only read messages and never publish to a channel, you can simply omit the publishKey when initializing the client:
    let configuration = PNConfiguration(publishKey: "", subscribeKey: "demo")
    self.client = PubNub.clientWithConfiguration(configuration)
  3. Under certain circumstances it useful to use a custom UUID to help in identifying your users.
    let configuration = PNConfiguration(publishKey: "demo", subscribeKey: "demo")
    configuration.uuid = "Stephen"
    self.client = PubNub.clientWithConfiguration(configuration)
  4. This examples demonstrates how to enable PubNub Transport Layer Encryption with SSL. Just initialize the client with ssl set to true. The hard work is done, now the PubNub API takes care of the rest. Just subscribe and publish as usual and you are good to go.
    let configuration = PNConfiguration(publishKey: "demo", subscribeKey: "demo")
    configuration.TLSEnabled = true
    self.client = PubNub.clientWithConfiguration(configuration)
This function is used to set a user ID on the fly.
To set UUID you can use the following method(s) in Swift SDK:
  1. open var uuid: String
// User authorized and we need to update used UUID
let configuration = self.client.currentConfiguration()
configuration.uuid = NSUUID().uuidString
self.client.copyWithConfiguration(configuration, completion: { (updatedClient) in

	// Store reference on new client with updated configuration.
	self.client = updatedClient
})
  1. /**
     Subscription process results arrive to listener which should adopt to PNObjectEventListener protocol
     and registered using:
     */
    self.client.addListener(self)
    self.client.subscribeToChannels([NSUUID().uuidString], withPresence: false)
    
    
    // Handle new message from one of channels on which client has been subscribed.
    func client(_ client: PubNub, didReceiveMessage message: PNMessageResult) {
    		
    	// Handle new message stored in message.data.message
    	if message.data.channel != 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.
    	}
    	
    	print("Received message: \(message.data.message) on channel \(message.data.channel) " +
    		  "at \(message.data.timetoken)")
    }
    
    // Handle subscription status change.
    func client(_ client: PubNub, didReceive status: PNStatus) {
    	
    	if status.operation == .subscribeOperation {
    		
    		// Check whether received information about successful subscription or restore.
    		if status.category == .PNConnectedCategory || status.category == .PNReconnectedCategory {
    			
    			let subscribeStatus: PNSubscribeStatus = status as! PNSubscribeStatus
    			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 {
    			
    			let errorStatus: PNErrorStatus = status as! PNErrorStatus
    			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`
    				 */
    			}
    		}
    	}
    }
  2. let configuration = self.client.currentConfiguration()
    configuration.uuid = "my_custom_uuid"
    self.client.copyWithConfiguration(configuration, completion: { (updatedClient) in
     
    	// Store reference on new client with updated configuration.
    	self.client = updatedClient
    })
  3. let configuration = self.client.currentConfiguration()
    configuration.authKey = NSUUID().uuidString
    self.client.copyWithConfiguration(configuration, completion: { (updatedClient) in
    
    	// Store reference on new client with updated configuration.
    	self.client = updatedClient
    })
Setter and getter for users auth key.
let configuration = self.client.currentConfiguration()
configuration.authKey = "my_new_authkey"
self.client.copyWithConfiguration(configuration, completion: { (updatedClient) in

	// Store reference on new client with updated configuration.
	self.client = updatedClient
})
// Request current client configuration and pull out authorisation key from it.
let authKey = self.client.currentConfiguration().authKey
Get Auth key returns the current authentication key.
To set/get filters you can use the following methods.
let configuration = PNConfiguration(publishKey: "demo", subscribeKey: "demo")
self.client = PubNub.clientWithConfiguration(configuration)
self.client.filterExpression = "(senderID=='PubNub')";
print("Filtering expression: \(self.client.filterExpression)")
Get Filter Expression returns the Current filtering expression.

Set Filter Expression:

 
If filter expression is malformed, PNObjectEventListener won't receive any messages and presence events from service (only error status).
The publish() function is used to send a message to all subscribers of a channel. To publish a message you must first specify a valid publishKey at initialization. A successfully published message is replicated across the PubNub Real-Time Network and sent simultaneously to all subscribed clients on a channel.
Messages in transit can be secured from potential eavesdroppers with SSL/TLS by setting ssl to true during initialization.
 
Publish Anytime
It is not required to be subscribed to a channel in order to publish to that channel.
Message Data:
The message argument can contain any JSON serializable data, including: Objects, Arrays, Ints and Strings. Message data should not contain special Swift classes or functions as these will not serialize. String content can include any single-byte or multi-byte UTF-8 character.
Message Size:
The maximum number of characters per message is 32K by default. The maximum message size is based on the final escaped character count, including the channel name. An ideal message size is under 1800 bytes which allows a message to be compressed and sent using single IP datagram (1.5KB) providing optimal network performance.
If the message you publish exceeds the configured size, you will receive the following message:
Message Too Large Error
["PUBLISHED",[0,"Message Too Large","13524237335750949"]]
Message Publish Rate:
Messages can be published as fast as bandwidth conditions will allow. There is a soft limit based on max throughput since messages will be discarded if the subscriber cannot keep pace with the publisher.
For example, if 200 messages are published simultaneously before a subscriber has had a chance to receive any messages, the subscriber may not receive the first 100 messages because the message queue has a limit of only 100 messages stored in memory.
Publishing to Multiple Channels.
It is not possible to publish a message to multiple channels simultaneously. The message must be published to one channel at a time.
Publishing Messages Reliably.
There are some best practices to ensure messages are delivered when publishing to a channel:
  • Publish to any given channel in a serial manner (i.e. not concurrently).
  • Check that the return code is success (e.g. [1,"Sent","136074940..."])
  • Publish the next message only after receiving a success return code.
  • If a failure code is returned ([0,"blah","<timetoken>"]), retry the publish.
  • Avoid exceeding the in-memory queue's capacity of 100 messages. An overflow situation (aka missed messages) can occur if slow subscribers fail to keep up with the publish pace in a given period of time.
  • Throttle publish bursts in accordance with your app's latency needs e.g. Publish no faster than 5 msgs per second to any one channel.
 
Do Not JSON serialize!
It is important to note that you should not JSON serialize when sending signals/messages via PUBNUB. Why? Because the serialization is done for you automatically. Instead just pass the full object as the message payload. PubNub takes care of everything for you.
 

Single string messages are automatically sent to APNS if mobile push is enabled and devices are registered for push on that channel. So if you use encryption (cipher key in the init) and publish the message, then it will be sent to APNS if there is a device(s) registered to that channel.

This is a legacy feature and will be deprecated soon.

To Publish a message you can use the following method(s) in the Swift SDK:
  1. ParameterTypeRequiredDescription
    message
    AnyYes
    The message may be any valid foundation object ( String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    closure
    PNPublishCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  2. ParameterTypeRequiredDescription
    message
    AnyYes
    The message may be any valid foundation object ( String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    compressed
    Bool
    Yes
    If true the message will be compressed and sent with request body instead of the URI. Compression useful in case of large data, in another cases it will increase the packet size.
    closure
    PNPublishCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  3. ParameterTypeRequiredDescription
    message
    AnyYes
    The message may be any valid foundation object ( String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    shouldStore
    Bool
    Yes
    If false the messages will not be stored in history, default true.
    closure
    PNPublishCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  4. ParameterTypeRequiredDescription
    message
    AnyYes
    The message may be any valid foundation object ( String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    shouldStore
    Bool
    Yes
    If false the messages will not be stored in history, default true.
    compressed
    Bool
    Yes
    If true the message will be compressed and sent with request body instead of the URI. Compression useful in case of large data, in another cases it will increase the packet size.
    closure
    PNPublishCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  5. ParameterTypeRequiredDescription
    message
    AnyNo
    The message may be any valid foundation object ( String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    payloads
    [String : Any]
    No
    Dictionary with payloads for different vendors (Apple with aps key and Google with gcm). Either payloads or message should be provided.
    closure
    PNPublishCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  6. ParameterTypeRequiredDescription
    message
    AnyNo
    The message may be any valid foundation object ( String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    payloads
    [String : Any]
    No
    Dictionary with payloads for different vendors (Apple with aps key and Google with gcm). Either payloads or message should be provided.
    compressed
    Bool
    Yes
    If true the message will be compressed and sent with request body instead of the URI. Compression useful in case of large data, in another cases it will increase the packet size.
    closure
    PNPublishCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  7. ParameterTypeRequiredDescription
    message
    AnyNo
    The message may be any valid foundation object ( String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    payloads
    [String : Any]
    No
    Dictionary with payloads for different vendors (Apple with aps key and Google with gcm). Either payloads or message should be provided.
    shouldStore
    Bool
    Yes
    If false the messages will not be stored in history, default true.
    closure
    PNPublishCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  8. ParameterTypeRequiredDescription
    message
    AnyNo
    The message may be any valid foundation object ( String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    payloads
    [String : Any]
    No
    Dictionary with payloads for different vendors (Apple with aps key and Google with gcm). Either payloads or message should be provided.
    shouldStore
    Bool
    Yes
    If false the messages will not be stored in history, default true.
    compressed
    Bool
    Yes
    If true the message will be compressed and sent with request body instead of the URI. Compression useful in case of large data, in another cases it will increase the packet size.
    closure
    PNPublishCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  9. ParameterTypeRequiredDescription
    message
    AnyYes
    The message may be any valid foundation object (String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    metadata
    [String : Any]No
    NSDictionary with values which should be used by PubNub service to filter messages.
    closure
    PNPublishCompletionBlockNo
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  10. ParameterTypeRequiredDescription
    message
    AnyYes
    The message may be any valid foundation object (String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    compressed
    BoolYes
    If true the message will be compressed and sent with request body instead of the URI. Compression useful in case of large data, in another cases it will increase the packet size.
    metadata
    [String : Any]No
    NSDictionary with values which should be used by PubNub service to filter messages.
    closure
    PNPublishCompletionBlockNo
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  11. ParameterTypeRequiredDescription
    message
    AnyYes
    The message may be any valid foundation object (String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    shouldStore
    BoolYes
    If false the messages will not be stored in history, default true.
    metadata
    [String : Any]No
    NSDictionary with values which should be used by PubNub service to filter messages.
    closure
    PNPublishCompletionBlockNo
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  12. ParameterTypeRequiredDescription
    message
    AnyYes
    The message may be any valid foundation object (String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    shouldStore
    BoolYes
    If false the messages will not be stored in history, default true.
    compressed
    BoolYes
    If true the message will be compressed and sent with request body instead of the URI. Compression useful in case of large data, in another cases it will increase the packet size.
    metadata
    [String : Any]No
    NSDictionary with values which should be used by PubNub service to filter messages.
    closure
    PNPublishCompletionBlockNo
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  13. ParameterTypeRequiredDescription
    message
    AnyNo
    The message may be any valid foundation object (String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    payloads
    [String : Any]No
    Dictionary with payloads for different vendors (Apple with aps key and Google with gcm). Either payloads or message should be provided.
    metadata
    [String : Any]No
    NSDictionary with values which should be used by PubNub service to filter messages.
    closure
    PNPublishCompletionBlockNo
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  14. ParameterTypeRequiredDescription
    message
    AnyNo
    The message may be any valid foundation object (String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    payloads
    [String : Any]No
    Dictionary with payloads for different vendors (Apple with aps key and Google with gcm). Either payloads or message should be provided.
    compressed
    BoolYes
    If true the message will be compressed and sent with request body instead of the URI. Compression useful in case of large data, in another cases it will increase the packet size.
    metadata
    [String : Any]No
    NSDictionary with values which should be used by PubNub service to filter messages.
    closure
    PNPublishCompletionBlockNo
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  15. ParameterTypeRequiredDescription
    message
    AnyNo
    The message may be any valid foundation object (String, NSNumber, Array, Dictionary).
    channel
    StringYes
    Specifies channel name to publish messages to.
    payloads
    [String : Any]No
    Dictionary with payloads for different vendors (Apple with aps key and Google with gcm). Either payloads or message should be provided.
    shouldStore
    BoolYes
    If false the messages will not be stored in history, default true.
    metadata
    [String : Any]No
    NSDictionary with values which should be used by PubNub service to filter messages.
    closure
    PNPublishCompletionBlockNo
    The completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
  16. ParameterTypeRequiredDescription
    messageAnyNoThe message may be any valid foundation object (String, NSNumber, Array, Dictionary).
    channelStringYesSpecifies channel name to publish messages to.
    payloads[String : Any]NoDictionary with payloads for different vendors (Apple with aps key and Google with gcm). Either payloads or message should be provided.
    shouldStoreBoolYesIf false the messages will not be stored in history, default true.
    compressedBoolYesIf true the message will be compressed and sent with request body instead of the URI. Compression useful in case of large data, in another cases it will increase the packet size.
    metadata[String : Any]NoNSDictionary with values which should be used by PubNub service to filter messages.
    closurePNPublishCompletionBlockNoThe completion closure which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).

Publish a message to a channel:

self.client.publish("Hello from the PubNub Swift SDK", toChannel: "my_channel",
					compressed: false, withCompletion: { (status) in
						
	if !status.isError {
		
		// Message successfully published to specified channel.
	}
	else{
		
		/**
		 Handle message publish error. Check 'category' property to find 
		 out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.
		 
		 Request can be resent using: status.retry()
		 */
	}
})
 
Before running the above publish example, either using the Debug Console, or in a separate script running in a separate terminal window, subscribe to the same channel that is being published to.
The function returns the following formatted response:
[1, "Sent", "13769558699541401"]
  1. self.client.publish(["Dictionary": ["with", "array", "as", "value"]], toChannel: "pubnub",
    					withMetadata: ["senderID" : "bob"], completion: { (status) in
    								
    	if !status.isError {
    		
    		// Message successfully published to specified channel.
    	}
    	else{
    		
    		/**
    		 Handle message publish error. Check 'category' property to find 
    		 out possible reason because of which request did fail.
    		 Review 'errorData' property (which has PNErrorData data type) of status
    		 object to get additional information about issue.
    		 
    		 Request can be resent using: status.retry()
    		 */
    	}
    })
  2. self.client.publish("Hello from the PubNub Swift", toChannel: "chat_channel",
    					withMetadata: ["senderID" : "bob"], completion: { (status) in
    								
    	if !status.isError {
    		
    		// Message successfully published to specified channel.
    	}
    	else{
    		
    		/**
    		 Handle message publish error. Check 'category' property to find 
    		 out possible reason because of which request did fail.
    		 Review 'errorData' property (which has PNErrorData data type) of status
    		 object to get additional information about issue.
    		 
    		 Request can be resent using: status.retry()
    		 */
    	}
    })
This function publishes a message on a channel.
 This method uses the builder pattern, you can remove the args which are optional.
To run Publish Builder you can use the following method(s) in the Swift SDK
  1. ParameterTypeRequiredDescription
    messageAnyNoThe message may be any valid foundation object (String, NSNumber, Array, Dictionary).
    channelStringYesSpecifies channel name to publish messages to.
    shouldStoreBoolNo

    If false the messages will not be stored in history.

    Default true.

    replicateBoolNoSpecify whether published message should be replicated across the PubNub Real-Time Network and sent simultaneously to all subscribed clients on a channel.
    compressBoolNoIf true the message will be compressed and sent with request body instead of the URI. Compression useful in case of large data, in another cases it will increase the packet size.
    ttlUIntegerNoSpecify for how many hours published message should be stored.
    payloads[String : Any]NoDictionary with payloads for different vendors (Apple with aps key and Google with gcm). Either payloads or message should be provided.
    metadata[String : Any]NoDictionary with values which should be used by PubNub service to filter messages.
    blockPNPublishCompletionBlockNoThe completion block which will be called when the processing is complete, has one argument: - request status reports the publish was successful or not (errorData contains error information in case of failure).
Publish message which will be stored in channel's storage for next 16 hours.
self.client.publish().channel("my_channel").message("Hello from the PubNub Swift SDK").compress(false).ttl(16).performWithCompletion({ (status) in

    if !status.isError {

        // Message successfully published to specified channel.
    }
    else{

        /**
         Handle message publish error. Check 'category' property to find 
         out possible reason because of which request did fail.
         Review 'errorData' property (which has PNErrorData data type) of status
         object to get additional information about issue.

         Request can be resent using: status.retry()
         */
    }
});
This function causes the client to create an open TCP socket to the PubNub Real-Time Network and begin listening for messages on a specified channel. To subscribe to a channel the client must send the appropriate subscribeKey at initialization.
By default a newly subscribed client will only receive messages published to the channel after the subscribeToChannels() call completes.
 
You can be notified of connectivity via the connect callback. By waiting for the connect callback to return before attempting to publish, you can avoid a potential race condition on clients that subscribe and immediately publish messages before the subscribe has completed.
Using Swift SDK, if a client becomes disconnected from a channel, it can automatically attempt to reconnect to that channel and retrieve any available messages that were missed during that period by setting restore to true. By default a client will attempt to reconnect after exceeding a 320 second connection timeout.
To Subscribe to a channel you can use the following method(s) in the Swift SDK:
  1. ParameterTypeRequiredDescription
    channels
    [String]
    Yes
    List of channel names on which client should try to subscribe.
    shouldObservePresence
    Bool
    Yes
    If true presence observation will be enabled for channels.
  2. ParameterTypeRequiredDescription
    channels
    [String]
    Yes
    List of channel names on which client should try to subscribe.
    shouldObservePresence
    Bool
    Yes
    If true presence observation will be enabled for channels.
    state
    [String : Any]
    No
    Dictionary object containing the state for the channel.
  3. ParameterTypeRequiredDescription
    channels
    [String]
    Yes
    List of channel names on which client should try to subscribe.
    shouldObservePresence
    Bool
    Yes
    If true presence observation will be enabled for channels.
    timeToken
    NSNumber
    No
    Specifies time from which to start returning any available cached messages. Message retrieval with timetoken is not guaranteed and should only be considered a best-effort service.
  4. ParameterTypeRequiredDescription
    channels
    [String]
    Yes
    List of channel names on which client should try to subscribe.
    shouldObservePresence
    Bool
    Yes
    If true presence observation will be enabled for channels.
    timeToken
    NSNumber
    No
    Specifies time from which to start returning any available cached messages. Message retrieval with timetoken is not guaranteed and should only be considered a best-effort service.
    state
    [String : Any]
    No
    Dictionary object containing the state for the channel.
Subscribe to a channel:
/**
 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: false)


// Handle new message from one of channels on which client has been subscribed.
func client(_ client: PubNub, didReceiveMessage message: PNMessageResult) {
		
	// Handle new message stored in message.data.message
	if message.data.channel != 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.
	}
	
	print("Received message: \(message.data.message) on channel \(message.data.channel) " +
		  "at \(message.data.timetoken)")
}

// Handle subscription status change.
func client(_ client: PubNub, didReceive status: PNStatus) {
		
	if status.operation == .subscribeOperation {
		
		// Check whether received information about successful subscription or restore.
		if status.category == .PNConnectedCategory || status.category == .PNReconnectedCategory {
			
			let subscribeStatus: PNSubscribeStatus = status as! PNSubscribeStatus
			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 {
			
			let errorStatus: PNErrorStatus = status as! PNErrorStatus
			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 == .unsubscribeOperation {
		
		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 == .heartbeatOperation {
		
		/**
		 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_basic_usage
		 */
		
		if !status.isError { /* Heartbeat operation was successful. */ }
		else { /* There was an error with the heartbeat operation, handle here. */ }
	}
}
The output below demonstrates the response format to a successful call:
[[], "Time Token"]
  1. For any given channel there is an associated Presence channel. You can subscribe directly to the channel by appending -pnpres to the channel name. For example the channel named my_channel would have the presence channel named my_channel-pnpres.
    /**
     Subscription process results arrive to listener which should adopt to
     PNObjectEventListener protocol and registered using:
     */
    self.client.addListener(self)
    self.client.subscribeToPresenceChannels(["my_channel"])
    
    
    // New presence event handling.
    func client(_ client: PubNub, didReceivePresenceEvent event: PNPresenceEventResult) {
    	
    	// Handle presence event event.data.presenceEvent (one of: join, leave, timeout, state-change).
    	if event.data.channel != event.data.subscription {
    		
    		// Presence event has been received on channel group stored in event.data.subscription.
    	}
    	else {
    		
    		// Presence event has been received on channel stored in event.data.channel.
    	}
    	
    	if event.data.presenceEvent != "state-change" {
    		
    		print("\(event.data.presence.uuid) \"\(event.data.presenceEvent)'ed\"\n" +
    			  "at: \(event.data.presence.timetoken) on \(event.data.channel) " +
    			  "(Occupancy: \(event.data.presence.occupancy))");
    	}
    	else {
    		
    		print("\(event.data.presence.uuid) changed state at: " +
    			  "\(event.data.presence.timetoken) on \(event.data.channel) to:\n" +
    			  "\(event.data.presence.state)");
    	}
    }
    {
    	"action": "join",
    	"timestamp": 1345546797,
    	"uuid": "175c2c67-b2a9-470d-8f4b-1db94f90e39e",
    	"occupancy": 2
    }
    
    {
        "action" : "leave",
        "timestamp" : 1345549797,
        "uuid" : "175c2c67-b2a9-470d-8f4b-1db94f90e39e",
        "occupancy" : 1
    }
    {
    	"action": "timeout",
    	"timestamp": 1345549797,
    	"uuid": "76c2c571-9a2b-d074-b4f8-e93e09f49bd",
    	"occupancy": 0
    }
    
    {
    	"action": "state-change",
    	"uuid": "76c2c571-9a2b-d074-b4f8-e93e09f49bd",
    	"timestamp": 1345549797,
    	"data": {
    		"isTyping": true
    	}
    }
    
    {
    	"action":"interval",
    	"timestamp":1474396578,
    	"occupancy":2
    }
    

    When a channel is in interval mode with presence_deltas pnconfig flag enabled, the interval message may also include the following fields which contain an array of changed UUIDs since the last interval message.

    • joined
    • left
    • timedout

    For example, this interval message indicates there were 2 new UUIDs that joined and 1 timed out UUID since the last interval:

    {
        "action" : "interval",
        "occupancy" : <# users in channel>,
        "timestamp" : <unix timestamp>,
        "joined" : ["uuid2", "uuid3"],
        "timedout" : ["uuid1"]
    }
    

    If the full interval message is greater than 30KB (since the max publish payload is ∼32KB), none of the extra fields will be present. Instead there will be a here_now_refresh boolean field set to true. This indicates to the user that they should do a hereNow request to get the complete list of users present in the channel.

    {
        "action" : "interval",
        "occupancy" : <# users in channel>,
        "timestamp" : <unix timestamp>,
        "here_now_refresh" : true
    }
    
  2. You can set state for a uuid during a subscribe by using the state parameter. Simply specify the desired key/value pairs as a JSON object.
    /**
     Subscription process results arrive to listener which should adopt to
     PNObjectEventListener protocol and registered using:
     */
    self.client.addListener(self)
    self.client.subscribeToChannels(["chat"], withPresence: false,
    								 clientState: ["chat": ["age" : 67, "full": "Robert Plant", 
    											   "country": "UK", "appstate": "foreground", 
    											   "latlong": "51.5072° N, 0.1275° W"]])
    
    
    // Handle new message from one of channels on which client has been subscribed.
    func client(_ client: PubNub, didReceiveMessage message: PNMessageResult) {
    		
    	// Handle new message stored in message.data.message
    	if message.data.channel != 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.
    	}
    	
    	print("Received message: \(message.data.message) on channel \(message.data.channel) " +
    		  "at \(message.data.timetoken)")
    }
    
    // Handle subscription status change.
    func client(_ client: PubNub, didReceive status: PNStatus) {
    	
    	if status.operation == .subscribeOperation {
    		
    		// Check whether received information about successful subscription or restore.
    		if status.category == .PNConnectedCategory || status.category == .PNReconnectedCategory {
    			
    			let subscribeStatus: PNSubscribeStatus = status as! PNSubscribeStatus
    			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 {
    			
    			let errorStatus: PNErrorStatus = status as! PNErrorStatus
    			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`
    				 */
    			}
    		}
    	}
    }
This functions subscribes to a channel group.
To Subscribe to a Channel Group you can use the following method(s) in the Swift SDK
  1. ParameterTypeRequiredDescription
    groups
    [String]
    Yes
    List of channel group names on which client should try to subscribe.
    shouldObservePresence
    Bool
    Yes
    If true presence observation will be enabled for channels groups.
  2. ParameterTypeRequiredDescription
    groups
    [String]
    Yes
    List of channel group names on which client should try to subscribe.
    shouldObservePresence
    Bool
    Yes
    If true presence observation will be enabled for channels groups.
    state
    [String : Any]
    No
    Reference on dictionary which stores key-value pairs based on channel group name and value which should be assigned to it.
Subscribe to a channel group
let channelGroup = "family"
/**
 Subscription process results arrive to listener which should adopt to PNObjectEventListener protocol
 and registered using:
 */
self.client.addListener(self)
self.client.subscribeToChannelGroups([channelGroup], withPresence: false)


// Handle new message from one of channels on which client has been subscribed.
func client(_ client: PubNub, didReceiveMessage message: PNMessageResult) {
		
	// Handle new message stored in message.data.message
	if message.data.channel != 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.
	}
	
	print("Received message: \(message.data.message) on channel \(message.data.channel) " +
		  "at \(message.data.timetoken)")
}

// Handle subscription status change.
func client(_ client: PubNub, didReceive status: PNStatus) {
	
	if status.operation == .subscribeOperation {
		
		// Check whether received information about successful subscription or restore.
		if status.category == .PNConnectedCategory || status.category == .PNReconnectedCategory {
			
			let subscribeStatus: PNSubscribeStatus = status as! PNSubscribeStatus
			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 {
			
			let errorStatus: PNErrorStatus = status as! PNErrorStatus
			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`
				 */
			}
		}
	}
}
[[], "Time Token"]
  1. /**
     Subscription process results arrive to listener which should adopt to
     PNObjectEventListener protocol and registered using:
     */
    self.client.addListener(self)
    self.client.subscribeToChannelGroups([channelGroup], withPresence: true)
    
    
    // Handle new message from one of channels on which client has been subscribed.
    func client(_ client: PubNub, didReceiveMessage message: PNMessageResult) {
    		
    	// Handle new message stored in message.data.message
    	if message.data.channel != 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.
    	}
    	
    	print("Received message: \(message.data.message) on channel \(message.data.channel) " +
    		  "at \(message.data.timetoken)")
    }
    
    // New presence event handling.
    func client(_ client: PubNub, didReceivePresenceEvent event: PNPresenceEventResult) {
    	
    	// Handle presence event event.data.presenceEvent (one of: join, leave, timeout, state-change).
    	if event.data.channel != event.data.subscription {
    		
    		// Presence event has been received on channel group stored in event.data.subscription.
    	}
    	else {
    		
    		// Presence event has been received on channel stored in event.data.channel.
    	}
    	
    	if event.data.presenceEvent != "state-change" {
    		
    		print("\(event.data.presence.uuid) \"\(event.data.presenceEvent)'ed\"\n" +
    			  "at: \(event.data.presence.timetoken) on \(event.data.channel) " +
    			  "(Occupancy: \(event.data.presence.occupancy))");
    	}
    	else {
    		
    		print("\(event.data.presence.uuid) changed state at: " +
    			  "\(event.data.presence.timetoken) on \(event.data.channel) to:\n" +
    			  "\(event.data.presence.state)");
    	}
    }
    
    // Handle subscription status change.
    func client(_ client: PubNub, didReceive status: PNStatus) {
    	
    	if status.operation == .subscribeOperation {
    		
    		// Check whether received information about successful subscription or restore.
    		if status.category == .PNConnectedCategory || status.category == .PNReconnectedCategory {
    			
    			let subscribeStatus: PNSubscribeStatus = status as! PNSubscribeStatus
    			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 {
    			
    			let errorStatus: PNErrorStatus = status as! PNErrorStatus
    			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`
    				 */
    			}
    		}
    	}
    }
When subscribed to a single channel, this function causes the client to issue a leave from the channel and close any open socket to the PubNub Network. For multiplexed channels, the specified channel(s) will be removed and the socket remains open until there are no more channels remaining in the list.
To Unsubscribe from a channel you can use the following method(s) in the Swift SDK:
  1. ParameterTypeRequiredDescription
    group
    [String]Yes
    List of channel group names from which client should try to unsubscribe.
    shouldObservePresence
    BoolYes
    If true the presence observation will also be unsubscribed on specified channels.
Unsubscribe from a channel:
/**
 Subscription process results arrive to listener which should adopt to
 PNObjectEventListener protocol and registered using:
 */
self.client.addListener(self)
self.client.unsubscribeFromChannels(["my_channel1", "my_channel2"], withPresence: false)


// Handle subscription status change.
func client(_ client: PubNub, didReceive status: PNStatus) {

	if status.operation == .unsubscribeOperation && status.category == .PNDisconnectedCategory {
            
		/**
		 This is the expected category for an unsubscribe. This means there was no error in 
		 unsubscribing from everything.
		 */
	}
}
The output below demonstrates the response to a successful call:
{
	"action" : "leave"
}
Unsubscribe from all channels and all channel groups
/**
 Subscription process results arrive to listener which should adopt to
 PNObjectEventListener protocol and registered using:
 */
self.client?.addListener(self)
self.client?.unsubscribeFromAll()


// Handle subscription status change.
func client(client: PubNub, didReceiveStatus status: PNStatus) {

	if status.operation == .unsubscribeOperation && status.category == .PNDisconnectedCategory {
            
		/**
		 This is the expected category for an unsubscribe. This means there was no error in 
		 unsubscribing from everything.
		 */
	}
}
None
This function lets you Unsubscribe from a Channel Group
To run Unsubscribe from a Channel Group you can use the following method(s) in the Swift SDK
  1. ParameterTypeRequiredDescription
    group
    [String]Yes
    List of channel group names from which client should try to unsubscribe.
    shouldObservePresence
    BoolYes
    Whether client should disable presence observation on specified channel groups or keep listening for presence event on them.
/**
 Unsubscription process results arrive to listener which should adopt to
 PNObjectEventListener protocol and registered using:
 */
self.client.addListener(self)
self.client.unsubscribeFromChannelGroups(["developers"], withPresence: true)


// Handle subscription status change.
func client(client: PubNub, didReceiveStatus status: PNStatus) {

	if status.operation == .unsubscribeOperation && status.category == .PNDisconnectedCategory {
            
		/**
		 This is the expected category for an unsubscribe. This means there was no error in 
		 unsubscribing from everything.
		 */
	}
}
The output below demonstrates the response to a successful call:
{
	"action": "leave"
}
This function is used to subscribe to the presence channel.
Using Swift SDK, if a client becomes disconnected from a channel, it can automatically attempt to reconnect to that channel and retrieve any available messages that were missed during that period by setting restore to true. By default a client will attempt to reconnect after exceeding a 320 second connection timeout.
To do Presence you can use the following method(s) in the Swift SDK
  1. ParameterTypeRequiredDescription
    channels
    [String]
    Yes
    Specifies the channel(s) to subscribe to presence channel. It is possible to specify multiple channels.
Subscribe to the presence channel:
For any given channel there is an associated Presence channel. You can subscribe directly to the channel by appending -pnpres to the channel name. For example the channel named my_channel would have the presence channel named my_channel-pnpres
/**
 Subscription process results arrive to listener which should adopt to
 PNObjectEventListener protocol and registered using:
 */
self.client.addListener(self)
self.client.subscribeToPresenceChannels(["my_channel"])


// New presence event handling.
func client(_ client: PubNub, didReceivePresenceEvent event: PNPresenceEventResult) {
	
	// Handle presence event event.data.presenceEvent (one of: join, leave, timeout, state-change).
	if event.data.channel != event.data.subscription {
		
		// Presence event has been received on channel group stored in event.data.subscription.
	}
	else {
		
		// Presence event has been received on channel stored in event.data.channel.
	}
	
	if event.data.presenceEvent != "state-change" {
		
		print("\(event.data.presence.uuid) \"\(event.data.presenceEvent)'ed\"\n" +
			  "at: \(event.data.presence.timetoken) on \(event.data.channel) " +
			  "(Occupancy: \(event.data.presence.occupancy))");
	}
	else {
		
		print("\(event.data.presence.uuid) changed state at: " +
			  "\(event.data.presence.timetoken) on \(event.data.channel) to:\n" +
			  "\(event.data.presence.state)");
	}
}
The output below demonstrates the response format to a successful call:
{
	"action": "join",
	"timestamp": 1345546797,
	"uuid": "175c2c67-b2a9-470d-8f4b-1db94f90e39e",
	"occupancy": 2
}
This function lets you stop monitoring the presence of the channel(s). The channel(s) will be removed and the socket remains open until there are no more channels remaining in the list.
To Unsubscribe from Presence of a channel you can use the following method(s) in the Swift SDK
  1. ParameterTypeRequiredDescription
    channels
    [String]
    Yes
    List of channel names for which client should try to unsubscribe from presence observing channels
Unsubscribe from the presence channel:
// Unsubscribe from one of channels presence channels.
self.client.unsubscribeFromPresenceChannels(["my_channel"])
The output below demonstrates the response to a successful call:
{"action": "leave"}
You can obtain information about the current state of a channel including a list of unique user-ids currently subscribed to the channel and the total occupancy count of the channel by calling the hereNowForChannel function in your application.
To call Here Now you can use the following method(s) in the Swift SDK:
  1. ParameterTypeRequiredDescription
    channel
    String
    Yes
    Channel name to retrieve the Here Now information.
    closure
    PNHereNowCompletionBlock
    Yes
    The completion closure has two arguments: result - in case of successful request processing (data field will contain results of presence audition operation); status - in case if error occurred during request processing (errorData contains error information).
  2. ParameterTypeRequiredDescription
    channel
    String
    Yes
    Channel name to retrieve the Here Now information.
    level
    PNHereNowVerbosityLevel
    Yes
    PNHereNowVerbosityLevel enum filters the response based on the value selected.
    closure
    PNHereNowCompletionBlock
    Yes
    The completion closure has two arguments: result - in case of successful request processing (data field will contain results of presence audition operation); status - in case if error occurred during request processing (errorData contains error information).
// With .UUID client will pull out list of unique identifiers and occupancy information.
self.client.hereNowForChannel("my_channel", withVerbosity: .UUID,
							  completion: { (result, status) in
										
	if status == nil {
		
		/**
		 Handle downloaded presence information using:
			result.data.uuids - list of uuids.
			result.data.occupancy - total number of active subscribers.
		 */
	}
	else {
		
		/**
		 Handle presence audit error. Check 'category' property to find
		 out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.
		 
		 Request can be resent using: status.retry()
		 */
	}
})
The hereNowForChannel function returns a list of uuid s currently subscribed to the channel.
  • uuids:["String","String", ... ,"String"] - List of UUIDs currently subscribed to the channel.
  • occupancy: Number - Total current occupancy of the channel.
{
	occupancy : 4,
	uuids : ['123123234t234f34fq3dq', '143r34f34t34fq34q34q3', '23f34d3f4rq34r34rq23q', 'w34tcw45t45tcw435tww3']
}
  1. /**
     With .state client aside from occupancy and unique identifiers will will pull out
     state information associated with them.
     */
    self.client.hereNowForChannel("my_channel", withVerbosity: .state,
    							  completion: { (result, status) in
    										
    	if status == nil {
    		
    		/**
    		 Handle downloaded presence information using:
    		 result.data.uuids - list of uuids. Each uuid entry will have next 
    		 					 fields: "uuid" - identifier and "state" if it 
    		 					 has been provided.
    		 result.data.occupancy - total number of active subscribers.
    		 */
    	}
    	else {
    		
    		/**
    		 Handle presence audit error. Check 'category' property
    		 to find out possible reason because of which request did fail.
    		 Review 'errorData' property (which has PNErrorData data type) of status
    		 object to get additional information about issue.
    		 
    		 Request can be resent using: status.retry()
    		 */
    	}
    })
    {
    	"status" : 200,
    	"message" : "OK",
    	"service" : "Presence",
    	"uuids" : [
    		{
    			"uuid" : "myUUID0"
    		},
    		{
    			"state" : {
    				"abcd" : {
    					"age" : 15
    				}
    			},
    			"uuid" : "myUUID1"
    		},
    		{
    			"uuid" : "b9eb408c-bcec-4d34-b4c4-fabec057ad0d"
    		},
    		{
    			"state" : {
    				"abcd" : {
    					"age" : 15
    				}
    			},
    			"uuid" : "myUUID2"
    		},
    		{
    			"state" : {
    				"abcd" : {
    					"age" : 24
    				}
    			},
    			"uuid" : "myUUID9"
    		}
    	],
    	"occupancy" : 5
    }
    
  2. You can return only the occupancy information for a single channel by specifying the channel and setting uuids to false:
    // With .occupancy client will pull out only occupancy information.
    self.client.hereNowForChannel("my_channel", withVerbosity: .occupancy,
    							  completion: { (result, status) in
    								
    	if status == nil {
    		
    		/**
    		 Handle downloaded presence information using:
    		 	result.data.occupancy - total number of active subscribers.
    		 */
    	}
    	else {
    		
    		/**
    		 Handle presence audit error. Check 'category' property
    		 to find out possible reason because of which request did fail.
    		 Review 'errorData' property (which has PNErrorData data type) of status
    		 object to get additional information about issue.
    		 
    		 Request can be resent using: status.retry()
    		 */
    	}
    })
    {
    	"channels": {
    		"my_channel": {
    			"occupancy": 3
    		}
    	},
    	"total_channels": 1,
    	"total_occupancy": 3
    }
    
  3. You can return the list of uuids and occupancy for all channels by omitting the channel:
    // With .UUID client will pull out list of unique identifiers and occupancy information.
    self.client.hereNowWithVerbosity(.UUID, completion: { (result, status) in
    	
    	if status == nil {
    		
    		/**
    		 Handle downloaded presence information using:
    		 result.data.channels - dictionary with active channels and presence
    		 						information on each. Each channel will have
    		 						next fields: "uuids" - list of subscribers;
    		 						"occupancy" - number of active subscribers.
    		 result.data.totalChannels - total number of active channels.
    		 result.data.totalOccupancy - total number of active subscribers.
    		 */
    	}
    	else {
    		
    		/**
    		 Handle presence audit error. Check 'category' property
    		 to find out possible reason because of which request did fail.
    		 Review 'errorData' property (which has PNErrorData data type) of status
    		 object to get additional information about issue.
    		 
    		 Request can be resent using: status.retry()
    		 */
    	}
    })
    {
        "total_channels" : 2,
        "total_occupancy" : 3,
        "channels" : {
            "lobby" : {
                "occupancy" : 1,
                "uuids" : [
                    "dara01"
                ]
            },
            "game01" : {
                "occupancy" : 2,
                "uuids" : [
                    "jason01",
                    "jason02"
                ]
            }
        }
    }
    
  4. You can return only the occupancy information (Global Here Now) by omitting the channel name
    self.client.hereNowWithCompletion({ (result, status) in
    
    	if status == nil {
    
    		/**
    		 Handle downloaded presence information using:
    			result.data.channels - dictionary with active channels and presence
    								   information on each. Each channel will have
    								   next fields: "uuids" - list of subscribers;
    								   "occupancy" - number of active subscribers.
    								   Each uuids entry has next fields:
    								   "uuid" - identifier and "state" if it has been
    								   provided.
    			result.data.totalChannels - total number of active channels.
    			result.data.totalOccupancy - total number of active subscribers.
    		 */
    	}
    	else {
    
    		/**
    		 Handle presence audit error. Check 'category' property
    		 to find out possible reason because of which request did fail.
    		 Review 'errorData' property (which has PNErrorData data type) of status
    		 object to get additional information about issue.
    
    		 Request can be resent using: status.retry()
    		 */
    	}
    })
    {
    	"channels": {
    		"my_channel": {
    			"occupancy": 3
    		}
    	},
    	"total_channels": 1,
    	"total_occupancy": 3
    }
    
Request information about subscribers on specific channel group. This API method will retrieve the list of UUIDs along with their state for each remote data object and the number of subscribers.
To do Here Now for Channel Groups you can use the following method(s) in the Swift SDK
  1. ParameterTypeRequiredDescription
    group
    String
    Yes
    Channel Group name to retrieve the Here Now information.
    closure
    PNChannelGroupHereNowCompletionBlock
    Yes
    The completion closure has two arguments: result - in case of successful request processing (data field will contain results of presence audition operation); status - in case if error occurred during request processing (errorData contains error information).
  2. ParameterTypeRequiredDescription
    group
    String
    Yes
    Channel Group name to retrieve the Here Now information.
    level
    PNHereNowVerbosityLevel
    Yes
    PNHereNowVerbosityLevel enum filters the response based on the value selected.
    closure
    PNChannelGroupHereNowCompletionBlock
    Yes
    The completion closure has two arguments: result - in case of successful request processing (data field will contain results of presence audition operation); status - in case if error occurred during request processing (errorData contains error information).
self.client.hereNowForChannelGroup("my_group", withCompletion: { (result, status) in

	if status == nil {

		/**
		 Handle downloaded presence information using:
			result.data.channels - dictionary with active channels and presence information on 
								   each. Each channel will have next fields: "uuids" - list of
								   subscribers; occupancy - number of active subscribers.
								   Each uuids entry has next fields: "uuid" - identifier and 
								   "state" if it has been provided.
			result.data.totalChannels - total number of active channels.
			result.data.totalOccupancy - total number of active subscribers.
		 */
	}
	else {

		/**
		 Handle presence audit error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.

		 Request can be resent using: status.retry()
		 */
	}
})
The hereNowForChannelGroup function returns a list of uuid s currently subscribed to the channel.
  • uuids:["String","String", … ,"String"] - List of UUIDs currently subscribed to the channel.
  • occupancy: Number - Total current occupancy of the channel.
{
	occupancy : 4,
	uuids : ['123123234t234f34fq3dq', '143r34f34t34fq34q34q3', '23f34d3f4rq34r34rq23q', 'w34tcw45t45tcw435tww3']
}
Return Occupancy for all channels by calling the hereNowWithCompletion function in your application.
To call Global Here Now you can use the following method(s) in the Swift SDK:
  1. ParameterTypeRequiredDescription
    closure
    PNGlobalHereNowCompletionBlock
    Yes
    The completion closure has two arguments: result - in case of successful request processing (data field will contain results of presence audition operation); status - in case if error occurred during request processing (errorData contains error information).
  2. ParameterTypeRequiredDescription
    level
    PNHereNowVerbosityLevel
    Yes
    PNHereNowVerbosityLevel enum filters the response based on the value selected.
    closure
    PNGlobalHereNowCompletionBlock
    Yes
    The completion closure has two arguments: result - in case of successful request processing (data field will contain results of presence audition operation); status - in case if error occurred during request processing (errorData contains error information).
self.client.hereNowWithCompletion({ (result, status) in

	if status == nil {

		/**
		 Handle downloaded presence information using:
			result.data.channels - dictionary with active channels and presence
								   information on each. Each channel will have
								   next fields: "uuids" - list of subscribers;
								   "occupancy" - number of active subscribers.
								   Each uuids entry has next fields:
								   "uuid" - identifier and "state" if it has been
								   provided.
			result.data.totalChannels - total number of active channels.
			result.data.totalOccupancy - total number of active subscribers.
		 */
	}
	else {

		/**
		 Handle presence audit error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.

		 Request can be resent using: status.retry()
		 */
	}
})
{
	"status": 200,
	"message": "OK",
	"payload": {
		"channels": {
			"81d8d989-b95f-443c-a726-04fac323b331": {
				"uuids": [
					"70fc1140-22b5-4abc-85b2-ff8c17b24d59"
				],
				"occupancy": 1
			},
			"81b7a746-d153-49e2-ab70-3037a75cec7e": {
				"uuids": [
					"91363e7f-584b-49cc-822c-52c2c01e5928"
				],
				"occupancy": 1
			},
			"c068d15e-772a-4bcd-aa27-f920b7a4eaa8": {
				"uuids": [
					"ccfac1dd-b3a5-4afd-9fd9-db11aeb65395"
				],
				"occupancy": 1
			}
		},
		"total_channels": 3,
		"total_occupancy": 3
	},
	"service": "Presence"
}
You can obtain information about the current list of a channels to which a uuid is subscribed to by calling the whereNowUUID function in your application.
 
If the app is killed/crashes and restarted (or the page containing the PubNub instance is refreshed on the browser) within the heartbeat window no timeout event is generated.
To call whereNowUUID you can use the following method(s) in the Swift SDK:
  1. ParameterTypeRequiredDescription
    uuid
    String
    Yes
    The UUID for which request should be performed.
    closure
    PNWhereNowCompletionBlock
    Yes
    The completion closure which will be called when the processing is complete, has two arguments: result - in case of successful processing (data will contain results of presence operation); status - in case of error while processing (errorDatacontains error information).
You simply need to define the uuid and the callback function to be used to send the data to as in the example below.
self.client.whereNowUUID(self.client.uuid(), withCompletion: { (result, status) in
			
	if status == nil {
		
		// Handle downloaded presence 'where now' information using: result.data.channels
	}
	else {
		
		/**
		 Handle presence audit error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.
		 
		 Request can be resent using: status.retry()
		 */
	}
})
The whereNowUUID function returns a list of channels a uuid is subscribed to.
  • channels:["String","String", ... ,"String"] - List of channels a uuid is subscribed to.
{
	"channels": [
		"lobby",
		"game01",
		"chat"
	]
}
The state API is used to set/get key/value pairs specific to a subscriber uuid.
State information is supplied as a JSON object of key/value pairs.
  1. ParameterTypeRequiredDescription
    state
    [String : Any]
    No
    Reference on dictionary which should be bound to uuid on specified channel. If value is nil, state will be removed for uuid on channel.
    uuid
    String
    Yes
    The unique user identifier for which state should be bound.
    channel
    String
    Yes
    Channel name against which the store state information is stored.
    closure
    PNChannelStateCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: request processing status - in case of error while processing (errorDatacontains error information).
  2. ParameterTypeRequiredDescription
    state
    [String : Any]
    No
    Reference on dictionary which should be bound to uuid on specified channel group. If value is nil, state will be removed for uuid on group.
    uuid
    String
    Yes
    The unique user identifier for which state should be bound.
    group
    String!
    Yes
    Channel Group name against which the store state information is stored.
    closure
    PNChannelStateCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: request processing status - in case of error while processing (errorDatacontains error information).
  1. ParameterTypeRequiredDescription
    uuid
    String
    Yes
    The unique user identifier for which state should be retrieved.
    channel
    String
    Yes
    Channel name to retrieve the state information.
    closure
    PNChannelStateCompletionBlock
    Yes
    The completion closure which will be called when the processing is complete, has two arguments: result - in case of successful processing (data will contain results of client state retrieve operation); status - in case of error while processing (errorDatacontains error information).
  2. ParameterTypeRequiredDescription
    uuid
    String
    Yes
    The unique user identifier for which state should be retrieved.
    group
    String
    Yes
    Channel Group name to retrieve the state information.
    closure
    PNChannelGroupStateCompletionBlock
    Yes
    The completion closure which will be called when the processing is complete, has two arguments: result - in case of successful processing (data will contain results of client state retrieve operation); status - in case of error while processing (errorDatacontains error information).
self.client.setState(["Key": "Value"], forUUID: self.client.uuid(), onChannel: "my_channel",
					 withCompletion: { (status) in
								
	if !status.isError {
		
		// Client state successfully modified on specified channel.
	}
	else {
		
		/**
		 Handle client state modification error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.
		 
		 Request can be resent using: status.retry()
		 */
	}
})
self.client.stateForUUID(self.client.uuid(), onChannel: "chat",
						 withCompletion: { (result, status) in
									
	if status == nil {
		
		// Handle downloaded state information using: result.data.state
	}
	else{
		
		/**
		 Handle client state audit error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.
		 
		 Request can be resent using: status.retry()
		 */
	}
})
The state API returns a JSON object containing key value pairs.
{
	first   : "Robert",
	last    : "Plant",
	age     : 59,
	region  : "UK"
}
This function adds a channel to a channel group.
Adding Channels is accomplished by using the following method(s) in the Swift SDK:
  1. ParameterTypeRequiredDescription
    channels
    [String]
    Yes
    List of channel names which should be added to the group.
    group
    String
    Yes
    Name of the group into which channels should be added.
    closure
    PNChannelGroupChangeCompletionBlock
    No
    Channel(s) addition completion closure, has one argument - request processing status to report whether data push was successful or not (errorData contains error information in case of failure).
let channelGroup = "family"
self.client.addChannels(["wife"], toGroup: channelGroup, withCompletion: { (status) in
			
	if !status.isError {
		
		// Handle successful channels list modification for group.
	}
	else {
		
		/**
		 Handle channels list modification for group error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.
		 
		 Request can be resent using: status.retry()
		 */
	}
})
{
    "service" : "channel-registry",
    "status"  : 200,
    "error"   : false,
    "message" : "OK"
}
This function lists all the channels of the channel group.
Listing Channels is accomplished by using the following method(s) in the Swift SDK:
  1. ParameterTypeRequiredDescription
    group
    String
    Yes
    Channel Group to list the channel(s) of.
    closure
    PNGroupChannelsAuditCompletionBlock
    Yes
    The completion closure which will be called when the processing is complete, has two arguments: result - in case of successful processing (data field will contain results of channel groups audit operation); status - in case of error while processing (errorDatacontains error information).
let channelGroup = "family"
self.client.channelsForGroup(channelGroup, withCompletion: { (result, status) in
			
	if status == nil {
		
		// Handle downloaded list of chanels using: result.data.channels
	}
	else {
		
		/**
		 Handle channels for group audition error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.
		 
		 Request can be resent using: status.retry()
		 */
	}
})
{
	"status" : 200,
	"payload" : {
		"channels" : ["hi"], 
		"group" : "abcd"
	},
	"service" : "channel-registry",
	"error" : False
}
This function removes the channels from the channel group.
Removing Channels is accomplished by using the following method(s) in the Swift SDK:
  1. ParameterTypeRequiredDescription
    channels
    [String]
    Yes
    List of channel names which should be removed from group. If empty list passed whole channel group will be removed.
    group
    String
    Yes
    Channel group from which channels should be removed.
    closure
    PNChannelGroupChangeCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: request processing status - in case of error while processing (errorDatacontains error information).
Removing channels :
let channelGroup = "family"
self.client.removeChannels(["son"], fromGroup: channelGroup, withCompletion: { (status) in
			
	if !status.isError {
		
		// Handle successful channels list modification for group.
	}
	else {
		
		/**
		 Handle channels list modification for group error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.
		 
		 Request can be resent using: status.retry();
		 */
	}
})
{
	"status" : 200,
	"message" : "OK",
	"service" : "channel-registry",
	"error" : False
}
This function removes the channel group.
Deleting Channel Group is accomplished by using the following method(s) in the Swift SDK:
  1. ParameterTypeRequiredDescription
    group
    String
    Yes
    Name of the group from which all channels should be removed.
    closure
    PNChannelGroupChangeCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: request processing status - in case of error while processing (errorDatacontains error information).
Deleting Channel Group :
let channelGroup = "family"
self.client.removeChannelsFromGroup(channelGroup, withCompletion: { (status) in
			
	if !status.isError {
		
		// Handle successful channel group removal.
	}
	else {
		
		/**
		 Handle channel group removal error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.
		 
		 Request can be resent using: status.retry();
		 */
	}
})
{
	"status" : 200,
	"message" : "OK",
	"service" : "channel-registry",
	"error" : False
}
This function fetches historical messages of a channel.
PubNub Storage/Playback Service provides real-time access to an unlimited history for all messages published to PubNub. Stored messages are replicated across multiple availability zones in several geographical data center locations. Stored messages can be encrypted with AES-256 message encryption ensuring that they are not readable while stored on PubNub's network.
It is possible to control how messages are returned and in what order, for example you can:
  • Search for messages starting on the newest end of the timeline (default behavior - reverse = false)
  • Search for messages from the oldest end of the timeline by setting reverse to true.
  • Page through results by providing a startDate OR endDate time token.
  • Retrieve a slice of the time line by providing both a startDate AND endDate time token.
  • Limit the number of messages to a specific quantity using the limit parameter.
 
Start & End parameter usage clarity:
If only the startDate parameter is specified (without endDate), you will receive messages that are older than and up to that startDate timetoken value.
If only the endDate parameter is specified (without startDate) you will receive messages that match that endDate timetoken value and newer.
Specifying values for both startDate and endDate parameters will return messages between those timetoken values (inclusive on the endDate value).
Keep in mind that you will still receive a maximum of 100 messages even if there are more messages that meet the timetoken values. Iterative calls to history adjusting the startDate timetoken is necessary to page through the full set of results if more than 100 messages meet the timetoken values.
To run History you can use the following method(s) in the Swift SDK
  1. ParameterTypeRequiredDescription
    channel
    String
    Yes
    Channel name to retrieve the History information.
    closure
    PNHistoryCompletionBlock
    Yes
    The completion closure has two arguments: result - in case of successful processing (data field will contain results of history request operation);status - in case if error occurred during request processing (errorData contains error information).
  2. ParameterTypeRequiredDescription
    channel
    String
    Yes
    Channel name to retrieve the History information.
    startDate
    NSNumber
    No
    Time token delimiting the start of time slice (exclusive) to pull messages from.
    endDate
    NSNumber
    No
    Time token delimiting the end of time slice (inclusive) to pull messages from.
    closure
    PNHistoryCompletionBlock
    Yes
    The completion closure has two arguments: result - in case of successful processing (data field will contain results of history request operation);status - in case if error occurred during request processing (errorData contains error information).
  3. ParameterTypeRequiredDescription
    channel
    String
    Yes
    Channel name to retrieve the History information.
    startDate
    NSNumber
    No
    Time token delimiting the start of time slice (exclusive) to pull messages from.
    endDate
    NSNumber
    No
    Time token delimiting the end of time slice (inclusive) to pull messages from.
    limit
    UInt
    Yes
    Specifies the number of historical messages to return. default/maximum is 100.
    closure
    PNHistoryCompletionBlock
    Yes
    The completion closure has two arguments: result - in case of successful processing (data field will contain results of history request operation);status - in case if error occurred during request processing (errorData contains error information).
  4. ParameterTypeRequiredDescription
    channel
    String
    Yes
    Channel name to retrieve the History information.
    startDate
    NSNumber
    No
    Time token delimiting the start of time slice (exclusive) to pull messages from.
    endDate
    NSNumber
    No
    Time token delimiting the end of time slice (inclusive) to pull messages from.
    shouldIncludeTimeToken
    Bool
    Yes
    If true the message post timestamps will be included in the history response.
    closure
    PNHistoryCompletionBlock
    Yes
    The completion closure has two arguments: result - in case of successful processing (data field will contain results of history request operation);status - in case if error occurred during request processing (errorData contains error information).
  5. ParameterTypeRequiredDescription
    channel
    String
    Yes
    Channel name to retrieve the History information.
    startDate
    NSNumber
    No
    Time token delimiting the start of time slice (exclusive) to pull messages from.
    endDate
    NSNumber
    No
    Time token delimiting the end of time slice (inclusive) to pull messages from.
    limit
    UInt
    Yes
    Specifies the number of historical messages to return. default/maximum is 100.
    shouldIncludeTimeToken
    Bool
    Yes
    If true the message post timestamps will be included in the history response.
    closure
    PNHistoryCompletionBlock
    Yes
    The completion closure has two arguments: result - in case of successful processing (data field will contain results of history request operation);status - in case if error occurred during request processing (errorData contains error information).
  6. ParameterTypeRequiredDescription
    channel
    String
    Yes
    Channel name to retrieve the History information.
    startDate
    NSNumber
    No
    Time token delimiting the start of time slice (exclusive) to pull messages from.
    endDate
    NSNumber
    No
    Time token delimiting the end of time slice (inclusive) to pull messages from.
    limit
    UInt
    Yes
    Specifies the number of historical messages to return. default/maximum is 100.
    shouldReverseOrder
    Bool
    Yes
    Setting to true will traverse the time line in reverse starting with the oldest message first. Default is false. If both start and end arguments are provided, reverse is ignored and messages are returned starting with the newest message.
    closure
    PNHistoryCompletionBlock
    Yes
    The completion closure has two arguments: result - in case of successful processing (data field will contain results of history request operation);status - in case if error occurred during request processing (errorData contains error information).
  7. ParameterTypeRequiredDescription
    channel
    String
    Yes
    Channel name to retrieve the History information.
    startDate
    NSNumber
    No
    Time token delimiting the start of time slice (exclusive) to pull messages from.
    endDate
    NSNumber
    No
    Time token delimiting the end of time slice (inclusive) to pull messages from.
    limit
    UInt
    Yes
    Specifies the number of historical messages to return. default/maximum is 100.
    shouldReverseOrder
    Bool
    Yes
    Setting to true will traverse the time line in reverse starting with the oldest message first. Default is false. If both start and end arguments are provided, reverse is ignored and messages are returned starting with the newest message.
    shouldIncludeTimeToken
    Bool
    Yes
    If true the message post timestamps will be included in the history response.
    closure
    PNHistoryCompletionBlock
    Yes
    The completion closure has two arguments: result - in case of successful processing (data field will contain results of history request operation);status - in case if error occurred during request processing (errorData contains error information).
Retrieve the last 100 messages on a channel:
self.client.historyForChannel("history_channel", withCompletion: { (result, status) in

	if status == nil {

		/**
		 Handle downloaded history using:
			result.data.start - oldest message time stamp in response
			result.data.end - newest message time stamp in response
			result.data.messages - list of messages
		 */
	}
	else {

		/**
		 Handle message history download error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.

		 Request can be resent using: status.retry()
		 */
	}
})
The Swift SDK returns false on fail. An array is returned on success. The historyForChannel function returns a list of up to 100 messages, the time token of the first (oldest) message and the time token of the last (newest) message in the resulting set of messages. The output below demonstrates the format for a historyForChannel response:
[
	["message1", "message2", "message3",... ],
	"Start Time Token",
	"End Time Token"
]
  1. self.client.historyForChannel("my_channel", start: nil, end: nil, limit: 3,
    						      reverse: true, withCompletion: { (result, status) in
    										
    	if status == nil {
    		
    		/**
    		 Handle downloaded history using:
    			result.data.start - oldest message time stamp in response
    			result.data.end - newest message time stamp in response
    			result.data.messages - list of messages
    		 */
    	}
    	else {
    		
    		/**
    		 Handle message history download error. Check 'category' property
    		 to find out possible reason because of which request did fail.
    		 Review 'errorData' property (which has PNErrorData data type) of status
    		 object to get additional information about issue.
    		 
    		 Request can be resent using: status.retry()
    		 */
    	}
    })
     [
    	["Pub1","Pub2","Pub3"],
    	13406746729185766,
    	13406746780720711
    ]
    
  2. let start = NSNumber(value: (13406746780720711 as CUnsignedLongLong))
    self.client.historyForChannel("my_channel", start: start, end: nil, limit: 100, 
    							  reverse: true, withCompletion: { (result, status) in
    								
    	if status == nil {
    		
    		/**
    		 Handle downloaded history using:
    			result.data.start - oldest message time stamp in response
    			result.data.end - newest message time stamp in response
    			result.data.messages - list of messages
    		 */
    	}
    	else {
    		
    		/**
    		 Handle message history download error. Check 'category' property
    		 to find out possible reason because of which request did fail.
    		 Review 'errorData' property (which has PNErrorData data type) of status
    		 object to get additional information about issue.
    		 
    		 Request can be resent using: status.retry()
    		 */
    	}
    })
     [
    	["Pub3","Pub4","Pub5"],
    	13406746780720711,
    	13406746845892666
    ]
    
  3. let end = NSNumber(value: (13406746780720711 as CUnsignedLongLong))
    self.client.historyForChannel("my_channel", start: nil, end: end, limit: 100, reverse: true, 
    							  withCompletion: { (result, status) in
    
    	if status == nil {
    
    		/**
    		 Handle downloaded history using:
    			result.data.start - oldest message time stamp in response
    			result.data.end - newest message time stamp in response
    			result.data.messages - list of messages
    		 */
    	}
    	else {
    
    		/**
    		 Handle message history download error. Check 'category' property
    		 to find out possible reason because of which request did fail.
    		 Review 'errorData' property (which has PNErrorData data type) of status
    		 object to get additional information about issue.
    
    		 Request can be resent using: status.retry()
    		 */
    	}
    })
    [
    	["Pub3","Pub4","Pub5"],
    	13406746780720711,
    	13406746845892666
    ]
    
  4.  
    Usage!
    You can call the method by passing 0 or a valid time token as the argument.
    // Pull out all messages newer then message sent at 14395051270438477.
    let date = NSNumber(value: (14395051270438477 as CUnsignedLongLong));
    self.historyNewerThen(date, onChannel: "history_channel", withCompletion:  { (messages) in
    	
    	print("Messages from history: \(messages)")
    })
    
    
    func historyNewerThen(_ date: NSNumber, onChannel channel: String, 
    					  withCompletion closure: @escaping (Array<Any>) -> Void) {
    		
    	var msgs: Array<Any> = []
    	self.historyNewerThen(date, onChannel: channel, withProgress: { (messages) in
    		
    		msgs.append(contentsOf: messages)
    		if messages.count < 100 { closure(msgs) }
    	})
    }
    	
    private func historyNewerThen(_ date: NSNumber, onChannel channel: String, 
    							  withProgress closure: @escaping (Array<Any>) -> Void) {
    	
    	self.client?.historyForChannel(channel, start: date, end: nil, limit: 100, 
    								   reverse: false, withCompletion: { (result, status) in
    									
    		if status == nil {
    			
    			closure((result?.data.messages)!)
    			if result?.data.messages.count == 100 {
    				
    				self.historyNewerThen((result?.data.end)!, onChannel: channel, 
    									  withProgress: closure)
    			}
    		}
    		else {
    			
    			/**
    			 Handle message history download error. Check 'category' property
    			 to find out possible reason because of which request did fail.
    			 Review 'errorData' property (which has PNErrorData data type) of status
    			 object to get additional information about issue.
    			 
    			 Request can be resent using: [status retry];
    			 */
    		}
    	})
    }
This function fetches historical messages of a channel.
 This method uses the builder pattern, you can remove the args which are optional.
To run History Builder you can use the following method(s) in the Swift SDK
  1. ParameterTypeRequiredDescription
    channels[String]YesList of channels for which history should be returned.
    limitUIntNoMaximum number of messages which should be returned for each channel.

    Maximum: 25.
    completionPNHistoryCompletionBlockYesHistory pull processing completion block which pass two arguments: result - in case of successful request processing data field will contain results of history request operation; status - in case if error occurred during request processing.
self.client.history().channels(["my_channel"]).limit(15).performWithCompletion({ (result, status) in

    if status == nil {

        /**
         Handle downloaded history using:
         result.data.channels - dictionary with channels' history. Each key is channel name and value is 
         list of fetched messages.
         */
    }
    else {

        /**
         Handle message history download error. Check 'category' property
         to find out possible reason because of which request did fail.
         Review 'errorData' property (which has PNErrorData data type) of status
         object to get additional information about issue.

         Request can be resent using: [status retry]
         */
    }
})
Enable push notifications on provided set of channels.
To run Adding Device to Channel you can use the following method(s) in the Swift SDK
  1. ParameterTypeRequiredDescription
    channels
    [String]
    Yes
    List of channel names for which push notifications should be enabled.
    pushToken
    Data
    Yes
    Device push token which should be used to enable push notifications on specified set of channels.
    closure
    PNPushNotificationsStateModificationCompletionBlock
    No
    Add push notifications process completion closure which has one argument - request processing status to report about whether data push was successful or not (errorData contains error information in case of failure).
self.client.addPushNotificationsOnChannels(["wwdc", "google.io"],
											withDevicePushToken: self.devicePushToken,
											andCompletion: { (status) in

	if !status.isError {

		// Handle successful push notification enabling on passed channels.
	}
	else {

		/**
		 Handle modification error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.

		 Request can be resent using: status.retry()
		 */
	}
})
[1, "Modified Channels"]
Request for all channels on which push notification has been enabled using specified pushToken.
To run Listing Channels For Device you can use the following method(s) in the Swift SDK
  1. ParameterTypeRequiredDescription
    pushToken
    Data
    Yes
    Device push token.
    closure
    PNPushNotificationsStateAuditCompletionBlock
    Yes
    The completion closure which will be called when the processing is complete, has two arguments: result - in case of successful processing (data will contain results of push notifications audit operation); status - in case of error while processing (errorDatacontains error information).
self.client.pushNotificationEnabledChannelsForDeviceWithPushToken(self.devicePushToken,
																  andCompletion: { (result, status) in

	if status == nil {

		// Handle downloaded list of channels using: result.data.channels
	}
	else {

		/**
		 Handle audition error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.

		 Request can be resent using: status.retry()
		 */
	}
})
The output below demonstrates the response to a successful call:
will contain a list of channels registered for push notifications
Disable push notifications on provided set of channels. If nil will be passed as channels then client will remove push notifications from all channels which associated with pushToken.
To run Removing Device From Channel you can use the following method(s) in the Swift SDK
  1. ParameterTypeRequiredDescription
    channels
    [String]
    Yes
    List of channel names for which push notifications should be disabled. If passed list is empty all notifications will be disabled.
    pushToken
    Data
    Yes
    Device push token which should be used to disable push notifications on specified set of channels.
    closure
    PNChannelGroupChangeCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: request processing status - in case of error while processing (errorDatacontains error information).
self.client.removePushNotificationsFromChannels(["wwdc","google.io"],
												withDevicePushToken: self.devicePushToken,
												andCompletion: { (status) in

	if !status.isError {

		// Handle successful push notification disabling on passed channels.
	}
	else {

		/**
		 Handle modification error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.

		 Request can be resent using: status.retry();
		 */
	}
})
The output below demonstrates the response to a successful call:
[1, "Modified Channels"]
Disable push notifications from all channels which is registered with specified pushToken.
To run Remove all push notifications you can use the following method(s) in the Swift SDK
  1. ParameterTypeRequiredDescription
    pushToken
    Data
    Yes
    Device push token which should be used to disable all push notifications registered with it.
    closure
    PNPushNotificationsStateModificationCompletionBlock
    No
    The completion closure which will be called when the processing is complete, has one argument: request processing status - in case of error while processing (errorDatacontains error information).
self.client.removeAllPushNotificationsFromDeviceWithPushToken(self.devicePushToken,
															  andCompletion: { (status) in

	if !status.isError {

		/**
		 Handle successful push notification disabling for all channels associated with
		 specified device push token.
		 */
	}
	else {

		/**
		 Handle modification error. Check 'category' property
		 to find out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.

		 Request can be resent using: status.retry();
		 */
	}
})
The server responds with a status code of 200.
This function will return a 17 digit precision Unix epoch.
 
Timetoken
The timetoken is constructed using the following algorithm:
timetoken = (Unix epoch time in seconds) * 10000000
Example of creating a timetoken for a specific time & date
08/19/2013 @ 9:20pm in UTC = 1376961606
timetoken = 1376961606 * 10000000
timetoken = 13769616060000000
To fetch Time you can use the following method(s) in Swift SDK
  1. ParameterTypeRequiredDescription
    closure
    PNTimeCompletionBlockYes
    The completion closure which will be called when the processing is complete, has two arguments: result - in case of successful processing (data will contain server-provided time token); status - in case of error while processing (errorDatacontains error information).
self.client.timeWithCompletion({ (result, status) in

	if status == nil {

		// Handle downloaded server time token using: result.data.timetoken
	}
	else {

		/**
		 Handle time token download error. Check 'category' property to find 
		 out possible reason because of which request did fail.
		 Review 'errorData' property (which has PNErrorData data type) of status
		 object to get additional information about issue.
		
		 Request can be resent using: status.retry()
		 */
	}
})
The timeWithCompletion() function returns a string timetoken in the following format:
13769501243685161
After subscription to channel(s), channel group(s) or enabling presence events handling PubNub clent start to receive realtime events. To be aware of these events listeners should be added to notification list. Client can have any number of listeners and all of them will receive updates every time when new realtime event will arrive. Target listener should conform to PNObjectEventListener protocol, in other case client will ignore it.
To add listener you can use the following function in the Swift SDK:
  1. ParameterTypeRequiredDescription
    listener
    Any
    Yes
    Any object which conform to PNObjectEventListener protocol and would like to receive notifications on realtime events.
self.client.addListener(self)
Void
This function provides a mechanism to calculate resulting message before it will be sent to the PubNub network.
To run Get size of message you can use the following method(s) in the Swift SDK
  1. ParameterTypeRequiredDescription
    message
    Any
    Yes
    The messagefor which the size needs be calculated.
    channel
    String
    Yes
    The channel on which the message has to be sent (it is part of request URI).
    closure
    PNMessageSizeCalculationCompletionBlock
    Yes
    Completion closure which will be called when the message size calculation is complete.
  2. ParameterTypeRequiredDescription
    message
    Any
    Yes
    The message for which the size needs be calculated.
    channel
    String
    Yes
    The channel on which the message has to be sent (it is part of request URI).
    compressMessage
    Bool
    Yes
    Should be true if the message is compressed before sending to PubNub network.
    closure
    PNMessageSizeCalculationCompletionBlock
    Yes
    Completion closure which will be called when the message size calculation is complete.
  3. ParameterTypeRequiredDescription
    message
    Any
    Yes
    The message for which the size needs be calculated.
    channel
    String
    Yes
    The channel on which the message has to be sent (it is part of request URI).
    shouldStore
    Bool
    Yes
    Should be true if the message is marked to be stored in history.
    closure
    PNMessageSizeCalculationCompletionBlock
    Yes
    Completion closure which will be called when the message size calculation is complete.
  4. ParameterTypeRequiredDescription
    message
    Any
    Yes
    The message for which the size needs be calculated.
    channel
    String
    Yes
    The channel on which the message has to be sent (it is part of request URI).
    compressMessage
    Bool
    Yes
    Should be true if the message is compressed before sending to PubNub network.
    shouldStore
    Bool
    Yes
    Should be true if the message is marked to be stored in history.
    closure
    PNMessageSizeCalculationCompletionBlock
    Yes
    Completion closure which will be called when the message size calculation is complete.
  5. ParameterTypeRequiredDescription
    messageAnyYesThe message for which the size needs be calculated.
    channelStringYesThe channel on which the message has to be sent (it is part of request URI).
    metadata[String : Any]NoNSDictionary with values which should be used by PubNub service to filter messages.
    closurePNMessageSizeCalculationCompletionBlockYesCompletion closure which will be called when the message size calculation is complete.
  6. ParameterTypeRequiredDescription
    messageAnyYesThe message for which the size needs be calculated.
    channelStringYesThe channel on which the message has to be sent (it is part of request URI).
    compressMessageBoolYesShould be true if the message is compressed before sending to PubNub network.
    metadata[String : Any]NoNSDictionary with values which should be used by PubNub service to filter messages.
    closurePNMessageSizeCalculationCompletionBlockYesCompletion closure which will be called when the message size calculation is complete.
  7. ParameterTypeRequiredDescription
    messageAnyYesThe message for which the size needs be calculated.
    channelStringYesThe channel on which the message has to be sent (it is part of request URI).
    shouldStoreBoolYesShould be true if the message is marked to be stored in history.
    metadata[String : Any]NoNSDictionary with values which should be used by PubNub service to filter messages.
    closurePNMessageSizeCalculationCompletionBlockYesCompletion closure which will be called when the message size calculation is complete.
  8. ParameterTypeRequiredDescription
    messageAnyYesThe message for which the size needs be calculated.
    channelStringYesThe channel on which the message has to be sent (it is part of request URI).
    shouldStoreBoolYesShould be true if the message is marked to be stored in history.
    compressMessageBoolYesShould be true if the message is compressed before sending to PubNub network.
    metadata[String : Any]NoNSDictionary with values which should be used by PubNub service to filter messages.
    closurePNMessageSizeCalculationCompletionBlockYesCompletion closure which will be called when the message size calculation is complete.
self.client.sizeOfMessage(["Hello":"World"], toChannel: "announcement",
						  withCompletion: { (size) in
									
	// Process calculated target message size.
})
The message size
  1. self.client.sizeOfMessage(["Hello":"World"], toChannel: "announcement", 
    						  withMetadata:["senderID" : "bob"], completion: { (size) in
    									
    	// Process calculated target message size.
    })
Stop listening for realtime events.
To remove listener you can use the following function in the Swift SDK:
  1. ParameterTypeRequiredDescription
    listener
    Any
    Yes
    Any object which conform to PNObjectEventListener protocol and doesn’t want to receive notifications on realtime events anymore.
self.client.removeListener(self)
Void
This function allow to encrypt the data.
To encrypt the data you can use the following method(s) in Swift SDK.
  1. ParameterTypeRequiredDescription
    dataDataYesReference on Data object which should be encrypted.
    keyStringYesReference on key which should be used to encrypt data basing on it.
let message = "No one should see me as plain"
let messageData = message.data(using: String.Encoding.utf8, allowLossyConversion: false)
let secretMessage = PNAES.encrypt(messageData!, withKey: "my_cipherkey")
Encrypted Base64-encoded string received from Foundation object. nil will be returned in case of failure.
This function allow to decrypt the data.
To decrypt the data you can use the following method(s) in Swift SDK.
  1. ParameterTypeRequiredDescription
    objectStringYesReference on previously encrypted Base64-encoded string which should be decrypted.
    keyStringYesReference on key which should be used to decrypt data.
let encryptedMessage = messagePayload["secret"] as! String
let messageData = PNAES.decrypt(encryptedMessage, withKey: "my_cipherkey")
if let decryptedData = messageData {

    let decryptedMessage = NSString(data: decryptedData, encoding: String.Encoding.utf8.rawValue) as! String
}
Initial Data which has been encrypted earlier. nil will be returned in case of decryption error.
Check out PubNub's other Swift-based SDKs, such as Swift, Cocoa Swift.