Storage and Playback API for Cocoa Swift SDK

This SDK has been replaced by a new PubNub Swift SDK written purely in Swift. Check out the Swift SDK page

Message Persistence gives you real-time access to the history of messages published to PubNub. Each message is timestamped to the nearest 10 nanoseconds and stored across multiple availability zones in several geographic locations. You can encrypt stored messages with AES-256 so they are not readable on PubNub’s network. For details, see Message Persistence.

You control how long messages are stored through your account’s retention policy. Options include: 1 day, 7 days, 30 days, 3 months, 6 months, 1 year, or Unlimited.

You can retrieve the following:

  • Messages
  • Message reactions
  • Files (using the File Sharing API)

History

Requires Message Persistence

Enable Message Persistence for your key in the Admin Portal. See how to enable add-on features.

This function fetches historical messages of a channel.

You can control how messages are returned and in what order:

  • 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 timetoken.
  • Retrieve a slice of the timeline by providing both a startDate and endDate timetoken.
  • Limit the number of messages using the limit parameter.
Start & End parameter usage clarity

If you specify only startDate (without endDate), you receive messages older than and up to that startDate timetoken. If you specify only endDate (without startDate), you receive messages that match that endDate timetoken and newer. If you specify both startDate and endDate, you receive messages between those timetokens (inclusive of endDate). You still receive up to 100 messages even if more match. Make iterative calls to history, adjusting startDate, to page through the full result set.

Method(s)

To run History you can use the following method(s) in the Swift SDK:

History with closure

open func historyForChannel(
_ channel: String,
withCompletion closure: PubNub.PNHistoryCompletionBlock
)
* required
ParameterDescription
channel *
Type: String
Channel name to retrieve the History information.
closure *
Type: PNHistoryCompletionBlock
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).

History with dates and closure

open func historyForChannel(
_ channel: String,
start startDate: NSNumber?,
end endDate: NSNumber?,
withCompletion closure: PubNub.PNHistoryCompletionBlock
)
* required
ParameterDescription
channel *
Type: String
Channel name to retrieve the History information.
startDate
Type: NSNumber
Timetoken delimiting the start of time slice (exclusive) to pull messages from.
endDate
Type: NSNumber
Timetoken delimiting the end of time slice (inclusive) to pull messages from.
closure *
Type: PNHistoryCompletionBlock
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).

History with dates, limit, and closure

open func historyForChannel(
_ channel: String,
start startDate: NSNumber?,
end endDate: NSNumber?,
limit: UInt,
withCompletion closure: PubNub.PNHistoryCompletionBlock
)
* required
ParameterDescription
channel *
Type: String
Channel name to retrieve the History information.
startDate
Type: NSNumber
Timetoken delimiting the start of time slice (exclusive) to pull messages from.
endDate
Type: NSNumber
Timetoken delimiting the end of time slice (inclusive) to pull messages from.
limit *
Type: UInt
Specifies the number of historical messages to return.
default/maximum is 100.
closure *
Type: PNHistoryCompletionBlock
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).

History with dates, timetoken, and closure

open func historyForChannel(
_ channel: String,
start startDate: NSNumber?,
end endDate: NSNumber?,
includeTimeToken shouldIncludeTimeToken: Bool,
withCompletion closure: PubNub.PNHistoryCompletionBlock
)
* required
ParameterDescription
channel *
Type: String
Channel name to retrieve the History information.
startDate
Type: NSNumber
Timetoken delimiting the start of time slice (exclusive) to pull messages from.
endDate
Type: NSNumber
Timetoken delimiting the end of time slice (inclusive) to pull messages from.
shouldIncludeTimeToken *
Type: Bool
If true the message post timestamps will be included in the history response.
closure *
Type: PNHistoryCompletionBlock
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).

History with dates, limit, timetoken, and closure

open func historyForChannel(
_ channel: String,
start startDate: NSNumber?,
end endDate: NSNumber?,
limit: UInt,
includeTimeToken shouldIncludeTimeToken: Bool,
withCompletion closure: PubNub.PNHistoryCompletionBlock
)
* required
ParameterDescription
channel *
Type: String
Channel name to retrieve the History information.
startDate
Type: NSNumber
Timetoken delimiting the start of time slice (exclusive) to pull messages from.
endDate
Type: NSNumber
Timetoken delimiting the end of time slice (inclusive) to pull messages from.
limit *
Type: UInt
Specifies the number of historical messages to return.
default/maximum is 100.
shouldIncludeTimeToken *
Type: Bool
If true the message post timestamps will be included in the history response.
closure *
Type: PNHistoryCompletionBlock
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).

History with dates, limit, and closure, in reverse order

open func historyForChannel(
_ channel: String,
start startDate: NSNumber?,
end endDate: NSNumber?,
limit: UInt,
reverse shouldReverseOrder: Bool,
withCompletion closure: PubNub.PNHistoryCompletionBlock
)
* required
ParameterDescription
channel *
Type: String
Channel name to retrieve the History information.
startDate
Type: NSNumber
Timetoken delimiting the start of time slice (exclusive) to pull messages from.
endDate
Type: NSNumber
Timetoken delimiting the end of time slice (inclusive) to pull messages from.
limit *
Type: UInt
Specifies the number of historical messages to return.
Default/maximum is 100.
shouldReverseOrder *
Type: Bool
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 *
Type: PNHistoryCompletionBlock
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).

History with dates, limit, timetoken, and closure, in reverse order

open func historyForChannel(
_ channel: String,
start startDate: NSNumber?,
end endDate: NSNumber?,
limit: UInt,
reverse shouldReverseOrder: Bool,
includeTimeToken shouldIncludeTimeToken: Bool,
withCompletion closure: PubNub.PNHistoryCompletionBlock
)
* required
ParameterDescription
channel *
Type: String
Channel name to retrieve the History information.
startDate
Type: NSNumber
Timetoken delimiting the start of time slice (exclusive) to pull messages from.
endDate
Type: NSNumber
Timetoken delimiting the end of time slice (inclusive) to pull messages from.
limit *
Type: UInt
Specifies the number of historical messages to return. default/maximum is 100.
shouldReverseOrder *
Type: Bool
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 *
Type: Bool
If true the message post timestamps will be included in the history response.
closure *
Type: PNHistoryCompletionBlock
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).
Using the reverse parameter

Messages are always returned sorted in ascending time direction from history regardless of reverse. The reverse direction matters when you have more than 100 (or limit, if it's set) messages in the time interval, in which case reverse determines the end of the time interval from which it should start retrieving the messages.

Sample code

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
show all 23 lines

Response

The response object which is returned by the client when the history API is used:

open class PNHistoryData : PNServiceData {

// Channel history messages.
open var messages: [Any] { get }
// History time frame start time.
open var start: NSNumber { get }
// History time frame end time.
open var end: NSNumber { get }
}

open class PNHistoryResult : PNResult {

// Stores reference on channel history request processing information.
open var data: PNHistoryData { get }
}

Other examples

Use historyForChannel to retrieve the three oldest messages by retrieving from the time line in reverse

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 {

/**
show all 24 lines
Response
[
["Pub1","Pub2","Pub3"],
13406746729185766,
13406746780720711
]

Use historyForChannel to retrieve messages newer than a given timetoken by paging from oldest message to newest message starting at a single point in time (exclusive)

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 {

show all 25 lines
Response
[
["Pub3","Pub4","Pub5"],
13406746780720711,
13406746845892666
]

Use historyForChannel to retrieve messages until a given timetoken by paging from newest message to oldest message until a specific end point in time (inclusive)

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 {

show all 25 lines
Response
[
["Pub3","Pub4","Pub5"],
13406746780720711,
13406746845892666
]

History paging example

Usage

You can call the method by passing 0 or a valid timetoken as the argument.

// Pull out all messages newer than message sent at 14395051270438477.
let date = NSNumber(value: (14395051270438477 as CUnsignedLongLong));
self.historyNewerThan(date, onChannel: "history_channel", withCompletion: { (messages) in

print("Messages from history: \(messages)")
})

func historyNewerThan(_ date: NSNumber, onChannel channel: String,
withCompletion closure: @escaping (Array<Any>) -> Void) {

var msgs: Array<Any> = []
self.historyNewerThan(date, onChannel: channel, withProgress: { (messages) in

msgs.append(contentsOf: messages)
if messages.count < 100 { closure(msgs) }
show all 46 lines

History (builder pattern)

This function fetches historical messages of a channel.

This method uses the builder pattern; you can omit any optional arguments.

Method(s)

To get channel history using the Builder pattern, use the following method(s) in the Swift SDK:

history().channels([String])
.limit(UInt)
.performWithCompletion(PubNub.PNHistoryCompletionBlock)
* required
ParameterDescription
channels *
Type: [String]
List of channels for which history should be returned.
limit
Type: UInt
Maximum number of messages which should be returned for each channel. Default and maximum value is 100 for a single channel, 25 for multiple channels.
completion *
Type: PNHistoryCompletionBlock
History 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 of error occurred during request processing.
Using the reverse parameter

Messages are always returned sorted in ascending time direction from history regardless of reverse. The reverse direction matters when you have more than 100 (or limit, if it's set) messages in the time interval, in which case reverse determines the end of the time interval from which it should start retrieving the messages.

Sample code

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.
show all 22 lines

Delete messages from history

Requires Message Persistence

This method requires that Message Persistence is enabled for your key in the Admin Portal.

Removes the messages from the history of a specific channel.

Delete-From-History

There is a setting to accept delete from history requests for a key, which you must enable by checking the Enable Delete-From-History checkbox in the key settings for your key in the Admin Portal.

Requires Initialization with secret key.

Method(s)

To Delete Messages from History you can use the following method(s) in the Swift SDK.

open func deleteMessagesFromChannel(
_ channel: String,
start startDate: NSNumber?,
end endDate: NSNumber?,
withCompletion closure: PubNub.PNMessageDeleteCompletionBlock? = nil
)

Sample code

let startDate = NSNumber(value: (15101397027611671 as CUnsignedLongLong))
let endDate = NSNumber(value: (15101397427611671 as CUnsignedLongLong))
self.client.deleteMessagesFromChannel("channel", start: startDate, end: endDate, withCompletion: { (status) in

if !status.isError {
// Messages within specified time frame has been removed.
} else {
/**
* Handle message history download error. Check 'category' property to find out possible
* issue because of which request did fail.
*
* Request can be resent using: status.retry()
*/
}
})

Other examples

Delete specific message from history

To delete a specific message, pass the publish timetoken (received from a successful publish) in the End parameter and timetoken +/- 1 in the Start parameter. For example, if 15526611838554310 is the publish timetoken, pass 15526611838554309 in Start and 15526611838554310 in End parameters respectively as shown in the following code snippet.

let startDate = NSNumber(value: (15526611838554309 as CUnsignedLongLong))
let endDate = NSNumber(value: (15526611838554310 as CUnsignedLongLong))
self.client.deleteMessagesFromChannel("channel", start: startDate, end: endDate, withCompletion: { (status) in

if !status.isError {
// Messages within specified time frame has been removed.
} else {
/**
* Handle message history download error. Check 'category' property to find out possible
* issue because of which request did fail.
*
* Request can be resent using: status.retry()
*/
}
})

Delete messages from history (builder pattern)

Requires Message Persistence

This method requires that Message Persistence is enabled for your key in the Admin Portal.

Removes the messages from the history of a specific channel.

Delete-From-History

There is a setting to accept delete from history requests for a key, which you must enable by checking the Enable Delete-From-History checkbox in the key settings for your key in the Admin Portal.

Requires Initialization with secret key.

Method(s)

To Delete Messages from History you can use the following method(s) in the Swift SDK.

deleteMessage().channel(String)
.start(NSNumber?)
.end(NSNumber?)
.performWithCompletion(PubNub.PNMessageDeleteCompletionBlock? = nil)

Sample code

let startDate = NSNumber(value: (15101397027611671 as CUnsignedLongLong))
let endDate = NSNumber(value: (15101397427611671 as CUnsignedLongLong))
self.client.deleteMessage().channel("channel").start(startDate).end(endDate).performWithCompletion({ (status) in

if !status.isError {
// Messages within specified time frame has been removed.
} else {
/**
* Handle message history download error. Check 'category' property to find out possible
* issue because of which request did fail.
*
* Request can be resent using: status.retry()
*/
}
})

Message counts

Requires Message Persistence

This method requires that Message Persistence is enabled for your key in the Admin Portal.

Returns the number of messages published on one or more channels since a given time. The count returned is the number of messages in history with a timetoken value greater than or equal to than the passed value in the timetokensparameter.

Unlimited message retention

For keys with unlimited message retention enabled, this method considers only messages published in the last 30 days.

Method(s)

You can use the following method(s) in the Swift SDK:

messageCounts().channels([String])
.timetokens([Int])
.performWithCompletion(PNMessageCountCompletionBlock)
* required
ParameterDescription
channels *
Type: [String]
Default:
n/a
The channels to fetch the message count
timetokens *
Type: [Int]
Default:
n/a
List with single or multiple timetokens, where each timetoken position in correspond to target channel location in channel names list.
completion *
Type: PNMessageCountCompletionBlock
Default:
n/a
Messages count fetch completion closure which pass two arguments: result - in case of successful request processing data field will contain results of message count fetch operation; status - in case of error occurred during request processing.

Sample code

let timetoken = NSNumber(value: (15501015683744028 as CUnsignedLongLong))
self.client.messageCounts().channels(["unread-channel-1", "unread-channel-2"])
.timetokens([timetoken])
.performWithCompletion({ (result, status) in

if !status.isError {
// Client state retrieved number of messages for channels.
} 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()
show all 18 lines

Returns

Channels count

Channels without messages have a count of 0. Channels with 10,000 messages or more have a count of 10000.

open class PNMessageCountData : PNServiceData {

// Dictionary where each key is name of channel and value is number of messages in it.
var channels: [String:Int] { get }
}

open class PNMessageCountResult : PNResult {

// Message count request processing information.
var data: PNMessageCountData { get }
}

Other examples

Retrieve count of messages using different timetokens for each channel

let timetoken = NSNumber(value: (15501015683744028 as CUnsignedLongLong))
let timetoken2 = NSNumber(value: (15501015683744130 as CUnsignedLongLong))
self.client.messageCounts().channels(["unread-channel-1", "unread-channel-2"])
.timetokens([timetoken, timetoken2])
.performWithCompletion({ (result, status) in

if !status.isError {
// Client state retrieved number of messages for channels.
} 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.

show all 19 lines
Last updated on