Configuration API for PubNub Swift Native SDK
Note
The PubNub Swift 3.0 SDK contains many significant changes from the 2.x SDK, including breaking changes. Please refer to the PubNub Swift 3.0 Migration Guide for more details.
A configuration object that defines behavior and policies for a PubNub
instance
Initializer(s)
Description
Creates a configuration using the specified PubNub Publish and Subscribe Keys:
Method(s)
To Initialize
PubNub you can use the following method(s) in the Swift SDK:
PubNubConfiguration(publishKey: String?, subscribeKey: String?)
Parameter | Type | Required | Defaults | Description |
---|---|---|---|---|
publishKey | String? | Optional | nil | Specifies the PubNub Publish Key to be used when publishing messages to a channel. |
subscribeKey | String? | Yes | nil | Specifies the PubNub Subscribe Key to be used when subscribing to a channel. |
cipherKey | Crypto? | Optional | nil | If set, all communication will be encrypted with this key. |
authKey | String | Optional | nil | If Access Manager (PAM) is enabled, client will use authKey on all requests. |
uuid | String | Yes | UUID to use. You should set a unique UUID to identify the user or the device that connects to PubNub. If you don't set the UUID , you won't be able to connect to PubNub. | |
useSecureConnections | Bool | Optional | true | If true , requests will be made over HTTPS; otherwise they will use HTTP. You will still need to disable ATS for the system to allow insecure network traffic. See Apple's documentation for further details. |
origin | String | Optional | "ps.pndsn.com" | Domain name used for requests. |
useInstanceId | Bool | Optional | false | Whether a PubNub object instanceId should be included on outgoing requests. |
automaticRetry | AutomaticRetry? | Optional | nil | Reconnection policy which will be used if/when a request fails. |
urlSessionConfiguration | URLSessionConfiguration | Yes | URLSessionConfiguration.pubnub | URLSessionConfiguration used for URLSession network events. |
durationUntilTimeout | Int | Optional | 300 | How long (in seconds) the server will consider the client alive for presence. Minimum value is 20 . |
heartbeatInterval | UInt | Optional | 0 | How often (in seconds) the client will announce itself to server. Minimum value is 0. |
suppressLeaveEvents | Bool | Optional | false | Whether to send out the leave requests. |
requestMessageCountThreshold | UInt | Optional | 100 | The number of messages into the payload before emitting RequestMessageCountExceeded . |
filterExpression | String? | Optional | nil | PSV2 feature to subscribe with a custom filter expression. |
Basic Usage
Initialize the PubNub client API with a custom UUID:
Note
Always set the UUID
to uniquely identify the user or device that connects to PubNub. This UUID
should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the UUID
, you won't be able to connect to PubNub.
let config = PubNubConfiguration(
publishKey: "demo",
subscribeKey: "demo",
uuid: "myUniqueUUID"
)
let pubnub = PubNub(configuration: config)
Other Examples
Initialization for a Read-Only client:
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:Note
Always set the
UUID
to uniquely identify the user or device that connects to PubNub. ThisUUID
should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set theUUID
, you won't be able to connect to PubNub.let config = PubNubConfiguration( subscribeKey: "demo" ) let pubnub = PubNub(configuration: config)
Event Listeners
Description
You can be notified of connectivity status, message, and presence notifications via the listeners.
Listeners should be added before calling the method.
Adding Listeners
// Create a new listener instance
let listener = SubscriptionListener()
// Add listener event callbacks
listener.didReceiveSubscription = { event in
switch event {
case let .messageReceived(message):
print("Message Received: \(message) Publisher: \(message.publisher ?? "defaultUUID")")
case let .connectionStatusChanged(status):
print("Status Received: \(status)")
case let .presenceChanged(presence):
print("Presence Received: \(presence)")
case let .subscribeError(error):
print("Subscription Error \(error)")
default:
break
}
}
// Start receiving subscription events
pubnub.add(listener)
Note
You can check the UUID of the publisher of a particular message by checking the message.publisher
property in the subscription listener.
Removing Listeners
The SubscriptionListener
can be removed by either calling listener.cancel()
, or by letting it fall out of scope and be removed as an autoreleased object.
Listener Subscription Events
This is the list of SubscriptionEvent
case types that can be emitted from didReceiveSubscription
, or grouped together using didReceiveBatchSubscription
. Each event case also has a standalone listener that can save code space, but will be functionally equivalent to using didReceiveSubscription
.
SubscriptionEvent Case | Event Type | Standalone Listener | Event Description |
---|---|---|---|
messageReceived | PubNubMessage | didReceiveMessage | Messages sent to subscribed channels/groups |
signalReceived | PubNubMessage | didReceiveSignal | Signals sent to subscribed channels/groups |
connectionStatusChanged | ConnectionStatus | didReceiveStatus | Changes in the connection to the PubNub system |
subscriptionChanged | SubscriptionChangeEvent | didReceiveSubscriptionChange | Notifies when channels/groups are subscribed or unsubscribed |
presenceChanged | PubNubPresenceChange | didReceivePresence | Presence changes on subscribed channels/groups tracking presence |
uuidMetadataSet | PubNubUUIDMetadataChangeset | didReceiveObjectMetadataEvent | UUID metadata was set |
uuidMetadataRemoved | String | didReceiveObjectMetadataEvent | UUID metadata was removed |
channelMetadataSet | PubNubChannelMetadataChangeset | didReceiveObjectMetadataEvent | Channel metadata was set |
channelMetadataRemoved | String | didReceiveObjectMetadataEvent | Channel metadata was removed |
membershipMetadataSet | PubNubMembershipMetadata | didReceiveObjectMetadataEvent | Membership metadata was set |
membershipMetadataRemoved | PubNubMembershipMetadata | didReceiveObjectMetadataEvent | Membership metadata was removed |
messageActionAdded | PubNubMessageAction | didReceiveMessageAction | A PubNubMessageAction was added to a published message |
messageActionRemoved | PubNubMessageAction | didReceiveMessageAction | A PubNubMessageAction was removed from a published message |
subscribeError | PubNubError | subscribeError | Any error that might have occurred during the subscription stream |
Basic Usage
This is an example using didReceiveBatchSubscription
, to allow you to receive multiple events per event call
listener.didReceiveBatchSubscription = { events in
for event in events {
switch event {
case .messageReceived(let message):
print("The \(message.channel) channel received a message at \(message.published)")
if let subscription = message.subscription {
print("The channel-group or wildcard that matched this channel was \(subscription)")
}
print("The message is \(message.payload) and was sent by \(message.publisher ?? "")")
case .signalReceived(let signal):
print("The \(signal.channel) channel received a message at \(signal.published)")
if let subscription = signal.subscription {
print("The channel-group or wildcard that matched this channel was \(subscription)")
}
print("The signal is \(signal.payload) and was sent by \(signal.publisher ?? "")")
case .connectionStatusChanged(let connectionChange):
switch connectionChange {
case .connecting:
print("Status connecting...")
case .connected:
print("Status connected!")
case .reconnecting:
print("Status reconnecting...")
case .disconnected:
print("Status disconnected")
case .disconnectedUnexpectedly:
print("Status disconnected unexpectedly!")
}
case .subscriptionChanged(let subscribeChange):
switch subscribeChange {
case let .subscribed(channels, groups):
print("\(channels) and \(groups) were added to subscription")
case let .responseHeader(channels, groups, previous, next):
print("\(channels) and \(groups) received a response at \(previous?.timetoken ?? 0)")
print("\(next?.timetoken ?? 0) will be used as the new timetoken")
case let .unsubscribed(channels, groups):
print("\(channels) and \(groups) were removed from subscription")
}
case .presenceChanged(let presenceChange):
print("The channel \(presenceChange.channel) has an updated occupancy of \(presenceChange.occupancy)")
for action in presenceChange.actions {
switch action {
case let .join(uuids):
print("The following list of occupants joined at \(presenceChange.timetoken): \(uuids)")
case let .leave(uuids):
print("The following list of occupants left at \(presenceChange.timetoken): \(uuids)")
case let .timeout(uuids):
print("The following list of occupants timed-out at \(presenceChange.timetoken): \(uuids)")
case let .stateChange(uuid, state):
print("\(uuid) changed their presence state to \(state) at \(presenceChange.timetoken)")
}
}
case .uuidMetadataSet(let uuidMetadataChange):
print("Changes were made to \(uuidMetadataChange.metadataId) at \(uuidMetadataChange.updated)")
print("To apply the change, fetch a matching object and call `uuidMetadataChange.apply(to: otherUUIDMetadata)`")
case .uuidMetadataRemoved(let metadataId):
print("Metadata for the uuid \(metadataId) has been removed")
case .channelMetadataSet(let channelMetadata):
print("Changes were made to \(channelMetadata.metadataId) at \(channelMetadata.updated)")
print("To apply the change, fetch a matching object and call `channelMetadata.apply(to: otherUUIDMetadata)`")
case .channelMetadataRemoved(let metadataId):
print("Metadata for the channel \(metadataId) has been removed")
case .membershipMetadataSet(let membership):
print("A membership was set between \(membership.uuidMetadataId) and \(membership.channelMetadataId)")
case .membershipMetadataRemoved(let membership):
print("A membership was removed between \(membership.uuidMetadataId) and \(membership.channelMetadataId)")
case .messageActionAdded(let messageAction):
print("The \(messageAction.channel) channel received a message at \(messageAction.messageTimetoken)")
print("This action was created at \(messageAction.actionTimetoken)")
print("This action has a type of \(messageAction.actionType) and has a value of \(messageAction.actionValue)")
case .messageActionRemoved(let messageAction):
print("The \(messageAction.channel) channel received a message at \(messageAction.messageTimetoken)")
print("A message action with the timetoken of \(messageAction.actionTimetoken) has been removed")
case .subscribeError(let error):
print("The following error was generated during subscription \(error.localizedDescription)")
print("If a `disconnectedUnexpectedly` also occurred then subscription has stopped, and needs to be restarted")
}
}
}
Other Examples
For didReceiveSubscription
, simply rename the remove the for...in
loop while keeping the event switch
:
listener.didReceiveSubscription = { event in
switch event {
// Same content as the above example
}
}
Overriding PubNub Configuration
All PubNubConfiguration
properties are mutable, and can be changed after the object has been initialized. However, once the configuration is set on a PubNub
instance those configurations are locked and can't be changed. Any changes would require a creating new PubNub
instance.
UUID
var config = pubnub.configuration
config.uuid = "my_new_UUID"
let pubnub = PubNub(configuration: config)
Authentication
var config = pubnub.configuration
config.authKey = "my_new_authkey"
let pubnub = PubNub(configuration: config)
Filter
You can override the subscribe filter expression without creating a new PubNub instance in one of two ways.
Note
These are functionally equivalent, and will take effect on the next subscription request and persist until changed.
In combination with a subscribe change:
pubnub.subscribe(to: ["new_subscription"], filterOverride: "(senderID=='my_new_UUID')")
Without needing to make a subscription change:
pubnub.subscribeFilterExpression = "(senderID=='my_new_UUID')"