Please be aware that you are viewing our bleeding edge unstable documentation. Unless you wanted to view the bleeding edge (and possibly unstable) documentation, we recommend you use our stable docs.

Go to Ably's stable canonical documentation »

I know what I'm doing, let me see the bleeding edge docs »

You are viewing our bleeding edge unstable documentation. We recommend you use our stable documentation »
Fork me on GitHub

Presence

Presence enables clients to be aware of other clients that are currently “present” on a channel. Each member present on a channel has a unique self-assigned client identifier and system-assigned connection identifier, along with an optional payload that can be used to describe the member’s status or attributes. Presence allows you to quickly build apps such as chat rooms and multiplayer games by automatically keeping track of who is present in real time across any device.

Presence

Using the Ably REST API it is possible to obtain the set of members currently present on a channel, or obtain the presence history for the channel, if persistence is enabled for that channel.

Since the Ably REST API is stateless, and REST clients do not have realtime connections to the Ably service, it is not possible to enter or leave a channel via the REST API. Find out more about using presence with the Realtime API.

A single clientIdclient_idClientId may be present multiple times on the same channel via different client connections. As far as Ably is concerned, these are different members of the presence set for the channel, however they will be differentiated by their unique connectionIdConnectionIdconnection_id. For example, if a client with ID “Sarah” is connected to a chat channel on both a desktop and a mobile device simultaneously, “Sarah” will be present twice in the presence member set with the same client ID, yet will have two unique connection IDs. A member of the presence set is therefore unique by the combination of the clientIdclient_idClientId and connectionIdConnectionIdconnection_id strings.

If you would prefer to just dive into code and see some examples of how to use presence via the REST API, then we recommend you take a look at our REST tutorials.

Presence states and events

Whenever a member enters or leaves a channel, or updates their member data, a presence event is emitted to all presence subscribers on that channel. Subscribing to presence events makes it incredibly easy to build an app that shows, in real time, any changes to clients connected to Ably and present on a channel.

The following presence events are emitted:

:enterPresenceAction.ENTERAction.ENTERenter
A new member has entered the channel
:leavePresenceAction.LEAVEAction.LEAVEleave
A member who was present has now left the channel. This may be a result of an explicit request to leave or implicitly when detaching from the channel. Alternatively, if a member’s connection is abruptly disconnected and they do not resume their connection within a minute, Ably treats this as a leave event as the client is no longer present
:updatePresenceAction.UPDATEAction.UPDATEupdate
An already present member has updated their member data. Being notified of member data updates can be very useful, for example, it can be used to update the status of a user when they are typing a message
:presentPresenceAction.PRESENTAction.PRESENTpresent
When subscribing to presence events on a channel that already has members present, this event is emitted for every member already present on the channel before the subscribe listener was registered

View a realtime presence states and events example

Member data

In addition to the clientIdclient_idClientId for members on a channel, it is also possible to include data when entering a channel. Clients can update their data at any point which will be broadcasted to all presence subscribers as a :updatePresenceAction.UPDATEPresenceAction.UpdateAction.UPDATEupdate event.

See the Realtime Presence Member data documentation for more info.

Presence member list

The Presence object exposes a getGet method allowing a client to retrieve an array of all members currently present on the channel. In the REST client library this method directly queries Ably’s REST presence API. No presence state is cached in the library itself, unlike in the Realtime client library.

channel.presence.get(function(err, membersPage) {
  console.log(membersPage.items.length + ' presence members in first page');
  if(membersPage.hasNext()) {
    membersPage.next(function(err, nextPage) { ... });
  }
});
channel.presence.get(function(err, membersPage) {
  console.log(membersPage.items.length + ' presence members in first page');
  if(membersPage.hasNext()) {
    membersPage.next(function(err, nextPage) { ... });
  }
});
members_page = channel.presence.get
puts "#{members_page.items.length} presence members in first page"
if members_page.has_next?
  next_page = members_page.next
end
members_page = channel.presence.get()
print str(len(members_page.items)) + ' members present'
if members_page.has_next():
  next_page = members_page.next()
$membersPage = $channel->presence->get();
echo(count($membersPage->items) . ' presence members in first page');
if ($membersPage->hasNext()) {
  $nextPage = $membersPage.next();
}
PaginatedResult<PresenceMessage> membersPage = channel.presence.get(null);
System.out.println(membersPage.items().length + " members in first page");
if(membersPage.hasNext()) {
  PaginatedResult<PresenceMessage> nextPage = membersPage.next();
  System.out.println(nextPage.items().length + " members on 2nd page");
}
PaginatedResult<PresenceMessage> membersPage = await channel.Presence.GetAsync();
Console.WriteLine(membersPage.Items.Count + " members in first page");
if(membersPage.HasNext)
{
  PaginatedResult<PresenceMessage> nextPage = await membersPage.NextAsync();
  Console.WriteLine(nextPage.Items.Count + " members on 2nd page");
}
[channel.presence get:^(ARTPaginatedResult<ARTPresenceMessage *> *membersPage, ARTErrorInfo *error) {
  NSLog(@"%lu members in first page", [membersPage.items count]);
  if (membersPage.hasNext) {
    [membersPage next:^(ARTPaginatedResult<ARTPresenceMessage *> *nextPage, ARTErrorInfo *error) {
      NSLog(@"%lu members on 2nd page", [nextPage.items count]);
    }];
  }
}];
channel.presence.get { membersPage, error in
  let membersPage = membersPage!
  print("\(membersPage.items.count) in first page")
  if membersPage.hasNext {
    membersPage.next { nextPage, error in
      print("\(nextPage!.items.count) members on 2nd page")
    }
  }
}

Presence History

The Presence object exposes a historyHistory method allowing a client to retrieve historical presence events on the channel.

History provides access to instantaneous “live” history as well as the longer term persisted history for presence channels. If persisted history is enabled for the channel, then presence events will typically be stored for 24 – 72 hours. If persisted history is not enabled, Ably retains the last two minutes of presence event history in memory.

The following example retrieves the first two pages of historical presence events published.

var presence = channel.presence;
presence.history(function(err, eventsPage) {
  if(err) {
    console.log('Unable to get presence history; err = ' + err.message);
  } else {
    console.log(eventsPage.items.length + ' presence events received in first page');
    if(eventsPage.hasNext()) {
      eventsPage.next(function(err, nextPage) { ... });
    }
});
var presence = channel.presence;
presence.history(function(err, eventsPage) {
  if(err) {
    console.log('Unable to get presence history; err = ' + err.message);
  } else {
    console.log(eventsPage.items.length + ' presence events received in first page');
    if(eventsPage.hasNext()) {
      eventsPage.next(function(err, nextPage) { ... });
    }
});
events_page = channel.presence.history
puts "#{events_page.items.length} presence events received in first page"
if events_page.has_next?
  next_page = events_page.next
  puts "#{next_page.items.length} presence events received on second page"
end
$eventsPage = $channel->presence->history();
echo(count($eventsPage->items) . ' presence events received in first page');
if ($eventsPage.hasNext()) {
  $nextPage = $eventsPage->next();
  echo(count($nextPage->items) . ' presence events received in second page');
}
events_page = channel.presence.history()
print str(len(events_page.items)) + " presence events received"
if events_page.has_next():
  next_page = events_page.next()
PaginatedResult<PresenceMessage> eventsPage = channel.presence.history(null);
System.out.println(eventsPage.items().length + " presence events received in first page");
if(eventsPage.hasNext()) {
  PaginatedResult<PresenceMessage> nextPage = eventsPage.next();
  System.out.println(nextPage.items().length + " presence events received in 2nd page");
}
PaginatedResult<PresenceMessage> eventsPage = await channel.Presence.HistoryAsync();
Console.WriteLine(eventsPage.Items.Count + " presence events received in first page");
if (eventsPage.HasNext)
{
  PaginatedResult<PresenceMessage> nextPage = await eventsPage.NextAsync();
  Console.WriteLine(nextPage.Items.Count + " presence events received in 2nd page");
}
[channel.presence history:^(ARTPaginatedResult<ARTPresenceMessage *> *eventsPage, ARTErrorInfo *error) {
  NSLog(@"%lu presence events received in first page", [eventsPage.items count]);
  if (eventsPage.hasNext) {
    [eventsPage next:^(ARTPaginatedResult<ARTPresenceMessage *> *nextPage, ARTErrorInfo *error) {
      NSLog(@"%lu presence events received in 2nd page", [nextPage.items count]);
    }];
  }
}];
channel.presence.history { eventsPage, error in
  let eventsPage = eventsPage!
  print("\(eventsPage.items.count) presence events received in first page")
  if eventsPage.hasNext {
    eventsPage.next { nextPage, error in
      print("\(nextPage!.items.count) presence events received in 2nd page")
    }
  }
}

See the presence history documentation for further details of the supported query parameters.

API Reference

Methods

getGet

Get the current presence member set for this channel. In the REST client library this method directly queries Ably’s REST presence API

get(Object options, callback(ErrorInfo err, PaginatedResult<PresenceMessage> resultPage))PaginatedResult<PresenceMessage> get(Hash options)PaginatedResult<PresenceMessage> get(kwargs_options)PaginatedResult<PresenceMessage> get(Array options)PaginatedResult<PresenceMessage> get(Param[] options)Task<PaginatedResult<PresenceMessage>> GetAsync(int? limit = null, string clientId = null, string connectionId = null);get(query: ARTPresenceQuery, callback: (ARTPresenceMessage, ARTErrorInfo?) → Void)

Gets an array of members present on the channel as PresenceMessage objects.

Parameters

optionsqueryParam[] options
an optional object containing query parametersoptional keyword arguments containing the query parametersan optional set of symbol key and value pairs containing the query parametersan optional Associate Array containing the query parameters as specified below.
callback
is a function of the form: function(err, "PaginatedResult":#paginated-result<"PresenceMessage":#presence-message> resultPage)
callback
called with a PaginatedResult<PresenceMessage>, or with an error

options parametersARTPresenceQuery propertiesArguments

clientIdclient_id:client_id
when provided, will filter array of members returned that match the provided clientIdclient_idClientId string
connectionIdconnection_id:connection_id
when provided, will filter array of members returned that match the provided connectionIdConnectionIdconnection_id":/realtime/connection/#id string

Callback result

On success, resultPage contains a PaginatedResult encapsulating an array of PresenceMessage objects corresponding to the current page of members currently present on the channel. PaginatedResult supports pagination using next() and first() methods.

On failure to retrieve the current presence member set, err contains an ErrorInfo object with the failure reason.

Returns

This method is asynchronous and needs to be awaited.

On success, the returned PaginatedResult encapsulates an array of PresenceMessage objects corresponding to the current page of members currently present on the channel. PaginatedResult supports pagination using nextNextAsync and firstFirstAsync methods.

Failure to retrieve the current presence member set will raise an AblyException

History

history(Object options, callback(ErrorInfo err, PaginatedResult<PresenceMessage> resultPage))PaginatedResult<PresenceMessage> history(Hash options)PaginatedResult<PresenceMessage> history(kwargs_options)PaginatedResult<PresenceMessage> history(Array options)PaginatedResult<PresenceMessage> history(Param[] options)Task<PaginatedResult<PresenceMessage>> HistoryAsync(HistoryRequestParams query);history(query: ARTDataQuery?, callback: (ARTPaginatedResult<ARTPresenceMessage>?, ARTErrorInfo?) → Void) throws

Gets a paginated set of historical presence message events for this channel. If the channel is configured to persist messages to disk, then the presence message event history will typically be available for 24 – 72 hours. If not, presence message events are only retained in memory by the Ably service for two minutes.

Parameters

optionsParam[] optionsqueryHistoryRequestParams query
an optional object containing query parametersoptional keyword arguments containing the query parametersan optional set of key value pairs containing query parametersan optional Associate Array containing the query parameters, as specified in the presence history API documentation.
callback
is a function of the form: function(err, resultPage)
callback
called with a ARTPaginatedResult<ARTPresenceMessage> object or an error

Callback result

On success, resultPage contains a PaginatedResult encapsulating an array of PresenceMessage objects corresponding to the current page of results. PaginatedResult supports pagination using next() and first() methods.

On failure to retrieve message history, err contains an ErrorInfo object with the failure reason.

Returns

This method is asynchronous and needs to be awaited.

On success, the returned PaginatedResult encapsulates an array of PresenceMessage objects corresponding to the current page of results. PaginatedResult supports pagination using nextNextAsync and firstFirstAsync methods.

Failure to retrieve the message history will raise an AblyException

PresenceMessageARTPresenceMessageAbly::Models::PresenceMessageio.ably.lib.types.PresenceMessageIO.Ably.PresenceMessage

A PresenceMessage represents an individual presence update that is sent to or received from Ably.

PropertiesMembersAttributes

action
the event signified by a PresenceMessage. See PresenceMessage.action
Type: enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }
Action
the event signified by a PresenceMessage. See PresenceMessage.action
Type: enum { Absent, Present, Enter, Leave, Update }
action
the event signified by a PresenceMessage. See Presence action
Type: int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }
action
the event signified by a PresenceMessage. See PresenceAction
Type: int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }
action
the event signified by a PresenceMessage. See PresenceMessage::ACTION
Type: enum { :absent, :present, :enter, :leave, :update }
action
the event signified by a PresenceMessage. See PresenceMessage::ACTION
Type: const PresenceMessage::ABSENT,PRESENT,ENTER,LEAVE,UPDATE
action
the event signified by a PresenceMessage. See PresenceMessage.action
Type: ARTPresenceAction
data
The presence update payload, if provided
Type: String, ByteArray, JSONObject, JSONArray
Data
The presence update payload, if provided
Type: String, byte[], plain C# object that can be converted to Json
data
The presence update payload, if provided
Type: String, StringBuffer, JSON Object
data
The presence update payload, if provided
Type: String, Binary (ASCII-8BIT String), Hash, Array
data
The presence update payload, if provided
Type: String, Bytearray, Dict, List
data
The message payload, if provided
Type: String, NSData, Dictionary, Array
data
The message payload, if provided
Type: NSString *, NSData *, NSDictionary *, NSArray *
data
The message payload, if provided
Type: String, Binary String, Associative Array, Array
idId
Unique ID assigned by Ably to this presence update
Type: String
clientIdclient_idClientId
The client ID of the publisher of this presence update
Type: String
connectionIdconnection_idConnectionId
The connection ID of the publisher of this presence update
Type: String
timestampTimestamp
Timestamp when the presence update was received by Ably, as milliseconds since the epoch.
Type: IntegerLong IntegerDateTimeOffsetTimeNSDate
encodingEncoding
This will typically be empty as all presence updates received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the data payload
Type: String

PresenceMessage constructors

PresenceMessage.fromEncoded

PresenceMessage.fromEncoded(Object encodedPresMsg, ChannelOptions channelOptions?) → PresenceMessage

A static factory method to create a PresenceMessage from a deserialized PresenceMessage-like object encoded using Ably’s wire protocol.

Parameters

encodedPresMsg
a PresenceMessage-like deserialized object.
Type: Object
channelOptions
an optional ChannelOptions. If you have an encrypted channel, use this to allow the library can decrypt the data.
Type: Object

Returns

A PresenceMessage object

PresenceMessage.fromEncodedArray

PresenceMessage.fromEncodedArray(Object[] encodedPresMsgs, ChannelOptions channelOptions?) → PresenceMessage[]

A static factory method to create an array of PresenceMessages from an array of deserialized PresenceMessage-like object encoded using Ably’s wire protocol.

Parameters

encodedPresMsgs
an array of PresenceMessage-like deserialized objects.
Type: Array
channelOptions
an optional ChannelOptions. If you have an encrypted channel, use this to allow the library can decrypt the data.
Type: Object

Returns

An Array of PresenceMessage objects

Presence actionPresenceActionARTPresenceActionio.ably.lib.types.PresenceMessage.ActionAbly::Models::PresenceMessage::ACTIONIO.Ably.PresenceAction

Presence action is a String with a value matching any of the Realtime Presence states & events.

var PresenceActions = [
  'absent', // (reserved for internal use)
  'present',
  'enter',
  'leave',
  'update'
]

io.ably.lib.types.PresenceMessage.Action is an enum representing all the Realtime Presence states & events.

public enum Action {
  ABSENT,  // 0 (reserved for internal use)
  PRESENT, // 1
  ENTER,   // 2
  LEAVE,   // 3
  UPDATE   // 4
}

IO.Ably.PresenceAction is an enum representing all the Realtime Presence states & events.

public enum Action {
  Absent,  // 0 (reserved for internal use)
  Present, // 1
  Enter,   // 2
  Leave,   // 3
  Update   // 4
}

PresenceAction is an enum-like class representing all the Realtime Presence states & events.

class PresenceAction(object):
  ABSENT = 0    # (reserved for internal use)
  PRESENT = 1
  ENTER = 2
  LEAVE = 3
  UPDATE = 4

PresenceMessage Action is one of the class constants representing all the Realtime Presence states & events.

namespace Ably\Models;
class PresenceMessages {
  const ABSENT  = 0; /* (reserved for internal use) */
  const PRESENT = 1;
  const ENTER   = 2;
  const LEAVE   = 3;
  const UPDATE  = 4;
}

Example usage

if ($presenceMessage->action == Ably\Models\PresenceMesage::ENTER) {
  /* do something */
}

Ably::Models::PresenceMessage::ACTION is an enum-like value representing all the Realtime Presence states & events. ACTION can be represented interchangeably as either symbols or constants.

Symbol states

:absent  # => 0 (reserved for internal use)
:present # => 1
:enter   # => 2
:leave   # => 3
:update  # => 4

Constant states

PresenceMessage::ACTION.Absent  # => 0 (internal use)
PresenceMessage::ACTION.Present # => 1
PresenceMessage::ACTION.Enter   # => 2
PresenceMessage::ACTION.Leave   # => 3
PresenceMessage::ACTION.Update  # => 4

Example usage

# Example with symbols
presence.on(:attached) { ... }

# Example with constants
presence.on(Ably::Models::PresenceMessage::ACTION.Enter) { ... }

# Interchangeable
Ably::Models::PresenceMessage::ACTION.Enter == :enter # => true

ARTPresenceAction is an enum representing all the Realtime Presence states & events.

typedef NS_ENUM(NSUInteger, ARTPresenceAction) {
    ARTPresenceAbsent,
    ARTPresencePresent,
    ARTPresenceEnter,
    ARTPresenceLeave,
    ARTPresenceUpdate
};
enum ARTPresenceAction : UInt {
  case Absent
  case Present
  case Enter
  case Leave
  case Update
}

HistoryRequestParams

HistoryRequestParams is a type that encapsulates the parameters for a history queries. For example usage see Channel#historyChannel#History.

Members

Start
null The start of the queried interval
Type: DateTimeOffset
End
null The end of the queried interval
Type: DateTimeOffset
Limit
null By default it is null. Limits the number of items returned by history or stats
Type: Integer
Direction
Backwards Enum which is either Forwards or Backwards
Type: Direction enum
ExtraParameters
Optionally any extra query parameters that may be passed to the query. This is mainly used internally by the library to manage paging.
Type: Dictionary<string, string>

PaginatedResultARTPaginatedResultAbly::Models::PaginatedResultio.ably.lib.types.PaginatedResultIO.Ably.PaginatedResult

A PaginatedResult is a type that represents a page of results for all message and presence history, stats and REST presence requests. The response from a Ably REST API paginated query is accompanied by metadata that indicates the relative queries available to the PaginatedResult object.

PropertiesMembersAttributes

itemsItems
contains the current page of results (for example an Array of Message or PresenceMessage objects for a channel history request)
Type: Array <Message, Presence, Stats>Type: List <Message, Presence, Stats>

Methods

firstFirst

first(callback(ErrorInfo err, PaginatedResult resultPage))PaginatedResult firstPaginatedResult first()PaginatedResult first()Task<PaginatedResult> FirstAsync()PaginatedResult first()first(callback: (ARTPaginatedResult?, ARTErrorInfo?) → Void)

Returns a new PaginatedResult for the first page of results. When using the Realtime library, the first method returns a Deferrable and yields a PaginatedResult.The method is asynchronous and returns a Task which needs to be awaited to get the PaginatedResult.

hasNextHasNexthas_next?has_next

Boolean hasNext()Boolean has_next?Boolean hasNext()Boolean has_next()Boolean HasNext()Boolean hasNext()Boolean hasNext()

Returns true if there are more pages available by calling nextNext and returns false if this page is the last page available.

isLastIsLastlast?is_last

Boolean isLast()Boolean last?Boolean isLast()Boolean is_last()Boolean IsLast()Boolean isLast()Boolean isLast()

Returns true if this page is the last page and returns false if there are more pages available by calling nextNext available.

nextNext

next(callback(ErrorInfo err, PaginatedResult resultPage))PaginatedResult nextPaginatedResult next()PaginatedResult next()Task<PaginatedResult> NextAsync()PaginatedResult next()next(callback: (ARTPaginatedResult?, ARTErrorInfo?) → Void)

Returns a new PaginatedResult loaded with the next page of results. If there are no further pages, then nulla blank PaginatedResult will be returnedNullNonenil is returned. The method is asynchronous and return a Task which needs to be awaited to get the PaginatedResultWhen using the Realtime library, the first method returns a Deferrable and yields a PaginatedResult.

Example

channel.history(function(err, paginatedResult) {
  console.log('Page 0 item 0:' + paginatedResult.items[0].data);
  paginatedResult.next(function(err, nextPage) {
    console.log('Page 1 item 1: ' + nextPage.items[1].data);
    console.log('Last page?: ' + nextPage.isLast());
  });
});
channel.history(function(err, paginatedResult) {
  console.log('Page 0 item 0:' + paginatedResult.items[0].data);
  paginatedResult.next(function(err, nextPage) {
    console.log('Page 1 item 1: ' + nextPage.items[1].data);
    console.log('Last page?: ' + nextPage.isLast());
  });
});
PaginatedResult firstPage = channel.history();
System.out.println("Page 0 item 0:" + firstPage.items[0].data);
if (firstPage.hasNext) {
  PaginatedResult nextPage = firstPage.next();
  System.out.println("Page 1 item 1:" + nextPage.items[1].data);
  System.out.println("More pages?:" + Strong.valueOf(nextPage.hasNext()));
};
PaginatedResult<Message> firstPage = await channel.HistoryAsync(null);
Message firstMessage = firstPage.Items[0];
Console.WriteLine("Page 0 item 0: " + firstMessage.data);
if (firstPage.HasNext)
{
    var nextPage = await firstPage.NextAsync();
    Console.WriteLine("Page 1 item 1:" + nextPage.Items[1].data);
    Console.WriteLine("More pages?: " + nextPage.HasNext());
}
# When using the REST sync library
first_page = channel.history
puts "Page 0 item 0: #{first_page.items[0].data}"
if first_page.has_next?
  next_page = first_page.next
  puts "Page 1 item 1: #{next_page.items[1].data}"
  puts "Last page?: #{next_page.is_last?}"
end

# When using the Realtime EventMachine library
channel.history do |first_page|
  puts "Page 0 item 0: #{first_page.items[0].data}"
  if first_page.has_next?
    first_page.next do |next_page|
      puts "Page 1 item 1: #{next_page.items[1].data}"
      puts "Last page?: #{next_page.is_last?}"
    end
  end
end
result_page = channel.history()
print 'Page 0 item 0: ' + str(result_page.items[0].data)
if result_page.has_next():
  next_page = result_page.next()
  print 'Page 1 item 1: ' + str(next_page.items[1].data)
  print 'Last page?: ' + str(next_page.is_last())
$firstPage = $channel.history();
echo("Page 0 item 0: " . $firstPage->items[0]->data);
if ($firstPage->hasNext()) {
  $nextPage = $firstPage->next();
  echo("Page 1 item 1: " . $nextPage->items[1]->data);
  echo("Last page?: " . $nextPage->isLast());
}
[channel history:^(ARTPaginatedResult<ARTMessage *> *paginatedResult, ARTErrorInfo *error) {
    NSLog(@"Page 0 item 0: %@", paginatedResult.items[0].data);
    [paginatedResult next:^(ARTPaginatedResult<ARTMessage *> *nextPage, ARTErrorInfo *error) {
        NSLog(@"Page 1 item 1: %@", nextPage.items[1].data);
        NSLog(@"Last page?: %d", nextPage.isLast());
    }];
}];
channel.history { paginatedResult, error in
    let paginatedResult = paginatedResult!
    print("Page 0 item 0: \((paginatedResult.items[0] as! ARTMessage).data)")
    paginatedResult.next { nextPage, error in
        let nextPage = nextPage!
        print("Page 0 item 0: \((nextPage.items[1] as! ARTMessage).data)")
        print("Last page? \(nextPage.isLast())")
    }
}

io.ably.lib.types.Param

Param is a type encapsulating a key/value pair. This type is used frequently in method parameters allowing key/value pairs to be used more flexible, see Channel#history for an example.

Please note that key and value attributes are always strings. If an Integer or other value type is expected, then you must coerce that type into a String.

Members

key
The key value
Type: String
value
The value associated with the key
Type: String

Back to top