# Release notes (/en/realtime-media/rtm/reference/release-notes/macos)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

The Agora Signaling SDK provides a streamlined and stable messaging mechanism for you to quickly implement real-time messaging for various use-cases. See [Product overview](/en/realtime-media/rtm) for more information.

This page contains release notes for each Signaling SDK platform.

      
  
      
  
      
    ### Known issues and limitations [#known-issues-and-limitations-2]

    <Tabs defaultValue="swift" groupId="language">
      <TabsList>
        <TabsTrigger value="swift">
          Swift
        </TabsTrigger>

        <TabsTrigger value="objc">
          Objective-C
        </TabsTrigger>
      </TabsList>

      <TabsContent value="swift">
        Starting from v2.2.0, the Signaling SDK and Video SDK (version 4.3.0 or later) both include the `aosl.xframework` library. If you use both SDKs, take the following steps to avoid conflicts:

        * If you manually integrate the SDK through CDN, manually delete the older version of the `aosl.xframework` library;
        * If you integrate the SDK using a dependency management tool, such as Maven or CocoaPods, ensure that the newer version of the `aosl.xframework` library is included in your project.

        For more information, see [How do I handle issues when integrating the Signaling SDK and Video SDK simultaneously?](/en/api-reference/faq/integration/rtm2_rtc_integration_issue)

        * Signaling SDK v2.2.8 `aosl.xframework` version: 1.3.0.
        * Signaling SDK v2.2.6 `aosl.xframework` version: 1.2.13.
        * Signaling SDK v2.2.4 `aosl.xframework` version: 1.2.13.
        * Signaling SDK v2.2.2 `aosl.xframework` version: 1.0.11.
      </TabsContent>

      <TabsContent value="objc">
        Starting from v2.2.0, the Signaling SDK and Video SDK (version 4.3.0 or later) both include the `aosl.xframework` library. If you use both SDKs, take the following steps to avoid conflicts:

        * If you manually integrate the SDK through CDN, manually delete the older version of the `aosl.xframework` library;
        * If you integrate the SDK using a dependency management tool, such as Maven or CocoaPods, ensure that the newer version of the `aosl.xframework` library is included in your project.

        For more information, see [How do I handle issues when integrating the Signaling SDK and Video SDK simultaneously?](/en/api-reference/faq/integration/rtm2_rtc_integration_issue)

        * Signaling SDK v2.2.8 `aosl.xframework` version: 1.3.0.
        * Signaling SDK v2.2.6 `aosl.xframework` version: 1.2.13.
        * Signaling SDK v2.2.4 `aosl.xframework` version: 1.2.13.
        * Signaling SDK v2.2.2 `aosl.xframework` version: 1.0.11.
        * Signaling SDK v2.2.1 `aosl.xframework` version: 1.0.11.
        * Signaling SDK v2.2.0 `aosl.xframework` version: 1.0.0.17.
      </TabsContent>
    </Tabs>

    ### v2.2.8 [#v228-2]

    Released on February 24, 2026.

    #### Improvements [#improvements-19]

    Included in this release:

    * The iOS CocoaPods pod name has changed from `AgoraRtm_iOS` to `AgoraRtm`. The new repository supports Mac, visionOS, and iOS architectures simultaneously.
    * Added a `['RtmKit']` subspec version to resolve integration issues when co-integrating with the Video SDK. For details, see [Handle issues when integrating the Signaling SDK and Video SDK simultaneously](/en/api-reference/faq/integration/rtm2_rtc_integration_issue).

      ```ruby
      pod 'AgoraRtm', 'x.y.z', :subspecs => ['RtmKit']
      ```

    #### Issues fixed [#issues-fixed-8]

    This release fixed the following issues:

    * In certain scenarios, abnormal service connection states occurred when an app resumed from the background to the foreground while a network switch was in progress.
    * In some cases, event notifications failed to be delivered properly after setting a temporary user presence state with Presence.

    ### v2.2.6 [#v226-2]

    Released on November 15, 2025.

    <Tabs defaultValue="swift" groupId="language">
      <TabsList>
        <TabsTrigger value="swift">
          Swift
        </TabsTrigger>

        <TabsTrigger value="objc">
          Objective-C
        </TabsTrigger>
      </TabsList>

      <TabsContent value="swift">
        #### New features [#new-features-10]

        **Support for IoT device domain allowlist**

        In IoT scenarios, devices may be restricted by Internet Service Providers (ISPs). To address this limitation, this version adds the `ispPolicyEnabled` field to [`AgoraRtmClientConfig`](/en/api-reference/api-ref/signaling). When you set this field to `true`, the SDK connects only to servers whose domain names or IP addresses have been registered with the ISP and are included in the allowlist.

        #### Improvements [#improvements-20]

        **New reconnection timeout configuration**

        This version adds the `reconnectTimeout` field to [`AgoraRtmClientConfig`](/en/api-reference/api-ref/signaling). Use this field to configure the timeout period in seconds for the SDK to return a timeout error during login or reconnection. When the login or reconnection exceeds the configured duration, the SDK reports the current connection state and reason through a callback.

        #### Issues fixed [#issues-fixed-9]

        * In some scenarios, the token expiration notification was triggered multiple times.
        * In some scenarios, a peer-to-peer message was delivered to the recipient but the sender received a timeout error.
        * In some scenarios, when the iOS system exited the app, the Signaling SDK crashed.
        * In private deployment scenarios, frequent network switching caused abnormal connection states.
      </TabsContent>

      <TabsContent value="objc">
        #### New features [#new-features-11]

        **Support for IoT device domain allowlist**

        In IoT scenarios, devices may be restricted by Internet Service Providers (ISPs). To address this limitation, this version adds the `ispPolicyEnabled` field to [`AgoraRtmClientConfig`](/en/api-reference/api-ref/signaling). When you set this field to `true`, the SDK connects only to servers whose domain names or IP addresses have been registered with the ISP and are included in the allowlist.

        #### Improvements [#improvements-21]

        **New reconnection timeout configuration**

        This version adds the `reconnectTimeout` field to [`AgoraRtmClientConfig`](/en/api-reference/api-ref/signaling). Use this field to configure the timeout period in seconds for the SDK to return a timeout error during login or reconnection. When the login or reconnection exceeds the configured duration, the SDK reports the current connection state and reason through a callback.

        #### Issues fixed [#issues-fixed-10]

        * In some scenarios, the token expiration notification was triggered multiple times.
        * In some scenarios, a peer-to-peer message was delivered to the recipient but the sender received a timeout error.
        * In some scenarios, when the iOS system exited the app, the Signaling SDK crashed.
        * In private deployment scenarios, frequent network switching caused abnormal connection states.
      </TabsContent>
    </Tabs>

    ### v2.2.4 [#v224-2]

    v2.2.4 was released on April 10, 2025.

    <Tabs defaultValue="swift" groupId="language">
      <TabsList>
        <TabsTrigger value="swift">
          Swift
        </TabsTrigger>

        <TabsTrigger value="objc">
          Objective-C
        </TabsTrigger>
      </TabsList>

      <TabsContent value="swift">
        #### Improvements [#improvements-22]

        * New link state change reason

          This release adds the reason `LOGIN_TOO_FREQUENT` (37) to `RtmLinkStateChangeReason`, indicating that the current login operation is too frequent.

        * New renew token timeout error code

          To better reflect the result of the renew token operation, this release adds the error code `RTM_RENEW_TOKEN_TIMEOUT` (10026).

        * Presence event notification optimization

          When channel data fails to sync properly, the SDK retriggers the `SNAPSHOT` event. Upon receiving this event, you can update the app's local cache.

        * Other improvements

          * Improved reconnection speed of the Signaling service when switching to background or sleep mode.
          * Optimized SDK performance in weak network conditions.
          * Improved selection of access nodes to enhance connection speed.
          * Further optimized the response time of the login service.

        #### Issues fixed [#issues-fixed-11]

        * The subscription service occasionally did not recover during reconnection.
        * Query results for users in some channels included information about abnormally offline users.
        * Uncaught exceptions in callback functions could cause the SDK to crash.
        * Subscribing to a topic could sometimes return an error indicating that the user was not in the channel.
      </TabsContent>

      <TabsContent value="objc">
        #### Improvements [#improvements-23]

        * New link state change reason

          This release adds the reason `LOGIN_TOO_FREQUENT` (37) to `RtmLinkStateChangeReason`, indicating that the current login operation is too frequent.

        * New renew token timeout error code

          To better reflect the result of the renew token operation, this release adds the error code `RTM_RENEW_TOKEN_TIMEOUT` (10026).

        * Presence event notification optimization

          When channel data fails to sync properly, the SDK retriggers the `SNAPSHOT` event. Upon receiving this event, you can update the app's local cache.

        * Other improvements

          * Improved reconnection speed of the Signaling service when switching to background or sleep mode.
          * Optimized SDK performance in weak network conditions.
          * Improved selection of access nodes to enhance connection speed.
          * Further optimized the response time of the login service.

        #### Issues fixed [#issues-fixed-12]

        * The subscription service occasionally did not recover during reconnection.
        * Query results for users in some channels included information about abnormally offline users.
        * Uncaught exceptions in callback functions could cause the SDK to crash.
        * Subscribing to a topic could sometimes return an error indicating that the user was not in the channel.
      </TabsContent>
    </Tabs>

    ### v2.2.2 [#v222-2]

    v2.2.2 was released on December 13, 2024.

    <Tabs defaultValue="swift" groupId="language">
      <TabsList>
        <TabsTrigger value="swift">
          Swift
        </TabsTrigger>

        <TabsTrigger value="objc">
          Objective-C
        </TabsTrigger>
      </TabsList>

      <TabsContent value="swift">
        This is the first release of the Signaling SDK for Swift, which brings innovation in functional coverage, performance improvement, and experience optimization.

        * Functional coverage: v2.x covers more business use-cases by introducing functional modules such as channels, messages, topics, presence, storage, and locks. This enables you to focus more on your own business innovation.
        * Performance improvement: v2.x implements a restructured technical architecture and enhances performance through optimized network connections. Our long-term real-time network access capabilities ensure high service quality characterized by low latency, high reliability, extensive concurrency, and robust extensibility.
        * Experience optimization: v2.x redesigns and simplifies the API interface. We have additionally enriched our documentation, including user guides and API references, with extensive sample code to provide you with comprehensive developer resources. These improvements significantly reduce the effort required to understand and integrate the SDK, ultimately enhancing development efficiency.

        #### New features [#new-features-12]

        The release provides the following core functional modules:

        **Initial setup**

        The initial setup of the Signaling client involves pre-defining or configuring key parameters that influence its subsequent behaviors. Additionally, it offers functions such as login and logout. The core competencies of the Signaling client are as follows:

        * `createAgoraRtmClient`: Create an instance of the Signaling client and perform the initial configuration as follows:
          * `appId`: Set the App ID to enable communication between apps with the same ID while isolating apps with different IDs.
          * `userId`: Set the user ID to distinguish users or devices.
          * `areaCode`: Set the area code for the geo-fencing feature.
          * `presenceTimeout`: Set the presence timeout.
          * `useStringUserId`: Set the data type of the user ID, which can be of type `string` or type `uint`.
          * `logConfig`: Configure the log file size, log file path, and output level.
          * `proxyConfig`: Configure whether to enable proxy.
          * `encryptionConfig`: Configure whether to enable encryption.
        * Event handling: Implement event notification for the events such as `onMessageEvent`, `onPresenceEvent `, `onTopicEvent`, `onStorageEvent`, `onLockEvent`, `connectionStateChanged`, `onTokenPrivilegeWillExpire`.
        * `login`: Log into the Signaling service.
        * `logout`: Log out of the Signaling service.
        * `release`: Destroy the Signaling client.

        **Channel**

        In the Signaling real-time network, channels serve as a mechanism for managing data transmission. When a user subscribes to or joins a channel, they can receive messages and events transmitted within the channel with a latency of up to 100 milliseconds. Signaling enables clients to subscribe to hundreds or even thousands of channels. Most Signaling APIs perform operations such as sending, receiving, and encrypting data on a channel basis.

        Signaling includes two types of channels, message channel and stream channel, each offering distinct core capabilities as follows:

        * Message channel:
          * `subscribe`: Subscribe to the specified message channel and receive messages and event notifications in the channel.
          * `unsubscribe`: Unsubscribe from the specified message channel and stop receiving messages and event notifications in the channel.
        * Stream channel:
          * `createStreamChannel`: Create a stream channel instance and then call relevant APIs.
          * `join`: Join the stream channel and receive messages and event notifications in the channel.
          * `leave`: Leave the stream channel and stop receiving messages and event notifications in the channel.
          * `release`: Destroy the stream channel.

        By calling different methods, the SDK triggers different event notifications.

        * The `subscribe`, `unsubscribe`, `join`, and `leave` methods trigger the `onPresenceEvent` event notification. Other users in the channel receive the corresponding `Join` and `Leave` event notifications.
        * When calling `subscribe` and `join` to subscribe or join a channel, you can choose whether to configure` withMessage`, `withPresence`, `withMetadata`, `withLock`, and other parameters to enable or disable the monitoring of the corresponding event. To enable the monitoring, you also need to register the corresponding event listener to receive corresponding event notifications.

        **Message**

        The basis of Signaling is the ability to send messages. You can send messages to channels anytime, anywhere, and the messages are delivered within 100 milliseconds. Signaling supports message payloads of both `string` and `byte` type.

        Call `publish` to send a message to the specified message channel. Calling `publish` triggers the `onMessageEvent` event notification. If you want to receive messages in the channel, set `withMessage` to `true` when calling `subscribe` and register the event handler for the `onMessageEvent` event.

        **Topic**

        In stream channels, topics serve as a data flow management mechanism. This feature allows you to subscribe to, distribute, and notify events related to data streams within stream channels. By leveraging topics effectively, you can significantly reduce business complexity and enhance development efficiency. The main functions of topics are as follows:

        * `joinTopic`: Register as the publisher of this topic to gain the ability to send messages.
        * `publishTopicMessage`: Send a message to the topic in the stream channel.
        * `leaveTopic`: Unregister as the message publisher of this topic.
        * `subscribeTopic`: Subscribe to one or more message publishers of the topic in this channel.
        * `unsubscribeTopic`: Unsubscribe from this topic or unsubscribe from one or more message publishers in this topic.

        Register (`joinTopic`) and unregister (`leaveTopic`) as a message publisher trigger the `onTopicEvent` event notification that is sent to other users in the channel.

        <CalloutContainer type="info">
          <CalloutTitle>
            Info
          </CalloutTitle>

          <CalloutDescription>
            Topics exist only in stream channels, not in message channels.
          </CalloutDescription>
        </CalloutContainer>

        **Presence**

        Presence provides the ability to monitor the online status and temporary status changes of users. With presence, you can obtain real-time information as follows:

        * Real-time event notification when a user joins or leaves a specified channel.
        * Real-time event notification when the custom temporary user state changes.
        * Query which channels a specified user has joined or subscribed to.
        * Query which users have joined a specified channel and their temporary user state data.

        The following features can be used in both message channels and stream channels:

        * `setUserMetadata`: Set the user metadata or a user metadata item for a specified user.
        * `getUserMetadata`: Get the user metadata or a user metadata item for a specified user.
        * `setState`: Set the temporary status of a user in a specified channel.
        * `getState`: Get the temporary status of a user in a specified channel.
        * `removeState`: Remove the temporary status of a user in a specific channel.

        In addition, presence also provides event notification capabilities through the `onPresenceEvent`. Events such as users joining, leaving, going offline, setting user state, and removing user state are sent as notifications to other users in the channel in real time (Announce Mode) or at regular intervals (Interval Mode). Presence greatly simplifies the implementation of the synchronization logic related to user online and offline status and state changes. This feature helps make your business more stable, real-time, and reliable.

        **Storage**

        The storage feature provides a dynamic database mechanism that allows developers to dynamically set, store, update, and delete channel metadata and user metadata. It also listens to the events generated by changes of channel metadata or user metadata.

        1. Channel metadata

           * `setChannelMetadata`: Set the channel metadata or channel metadata item for a specified channel.
           * `getChannelMetadata`: Get the channel metadata and channel metadata item for a specified channel.
           * `removeChannelMetadata`: Remove the channel metadata or channel metadata item for a specified channel.
           * `updateChannelMetadata`: Update the existing channel metadata or channel metadata item for a specified channel.

           Setting, deleting, and updating channel metadata trigger the `onStorageEvent` event notification. This feature can greatly optimize your business logic and provide an excellent user experience. Currently, the event notification `onStorageEvent` carries the complete information of the current channel metadata. It will be optimized in future versions to provide incremental update capabilities.

           Channel metadata also introduces the ability to control locks. When calling APIs to set, delete, or update channel metadata, if the `lock` parameter is set, lock verification is enabled. In this case, only the owners of the lock can call the corresponding methods successfully.

        2. User Metadata

           * `setUserMetadata`: Set the user metadata or a user metadata item for a specified user.
           * `getUserMetadata`: Get the user metadata or a user metadata item for a specified user.
           * `removeUserMetadata`: Remove the user metadata or a user metadata item for a specified user.
           * `updateUserMetadata`: Update the existing user metadata or a user metadata item for a specified user.
           * `subscribeUserMetadata`: Subscribe to event notifications for changes in user metadata or a user metadata item for a specified user.
           * `unsubscribeUserMetadata`: Unsubscribe from event notifications for changes in user metadata or a user metadata item for a specified user.

           Setting, deleting, and updating user metadata trigger the `onStorageEvent` event notification. Other users subscribed to this user metadata receive the event notifications. This feature can greatly optimize your business logic and provide an excellent user experience. Currently, the `onStorageEvent` event notification carries the complete information of the current user metadata. It will be optimized in future versions to provide incremental update capabilities.

        3. Compare And Set (CAS) control

           Both channel metadata and user metadata introduce the CAS version control logic, which provides two independent version control fields that you can use according to your business use-case:

           * Enable version number verification for the entire set of channel metadata by setting the `majorRevision` property through the `setMajorRevision` method in the `Metadata` data type.
           * Enable version number verification for a single metadata item by setting the `revision` property in the `MetadataItem` class.

           When setting, deleting, or updating channel metadata or user metadata, you can control whether to enable revision verification by using the `majorRevision` or `revision` property. The logic is as follows:

           * If `majorRevision` or `revision` is set to `-1`, the CAS validation is not enabled for this call. If the metadata or metadata item already exists, it is overwritten by the latest value. If the metadata or metadata item does not exist, a new metadata or metadata item is created.
           * If `majorRevision` or `revision` is set as a positive `Uint64` integer, the CAS validation is enabled for this call. If the metadata or metadata item already exists, the value is updated after successful version number validation. If the metadata or metadata item does not exist, the SDK returns an error code.

        4. Lock

           A critical resource can only be used by one process at a time. If different processes share a critical resource, they need to adopt a mutually exclusive approach to prevent interference. Signaling offers a comprehensive set of lock solutions and process control in distributed systems, enabling you to effectively manage competition among users accessing shared resources. Lock provides the following capabilities:

           * `setLock`: Set a lock for a specified channel.
           * `acquireLock`: Acquire a specified lock in a specified channel.
           * `releaseLock`: Release a specified lock in a specified channel.
           * `revokeLock`: Revoke the ownership of a specific user for a lock in a specified channel to release the lock.
           * `getLocks`: Get the details of all locks in a specified channel.
           * `removeLock`: Remove a specified lock in a specified channel.

           The lock setting, acquisition, release, revocation, and deletion operations trigger the corresponding `onLockEvent` event notification. You can make full use of this feature to optimize the implementation logic of your business.
      </TabsContent>

      <TabsContent value="objc">
        #### Compatibility changes [#compatibility-changes-7]

        1. SNAPSHOT state trigger timing change

           This release changes the trigger timing of the `SNAPSHOT` event in the Presence event. Now, as long as the user is in the channel, they may receive the `SNAPSHOT` event again; after receiving it, users can update their full information to avoid state synchronization issues caused by exceptions.

        2. Lock timeout calculation rule change

           This release changes the calculation rule of the lock (Lock) timeout. Starting from this version, the lock timeout is calculated from the time when the server determines that the user is offline.

        #### New features [#new-features-13]

        1. SDK connection state change reason

           This release adds the [`RtmLinkStateChangeReason`](/en/api-reference/api-ref/signaling) enumeration class to the `LinkStateEvent` of the SDK connection state, to report the reason for the connection state change.

        #### Improvements [#improvements-24]

        This release improves the performance of the basic messaging service during exceptions, preventing service unavailability caused by the failure of some services.

        #### Fixed issues [#fixed-issues-13]

        This release fixed the following issues:

        * In some use-cases, incorrect token types cause exceptions.
        * In some use-cases, users may receive repeated offline notifications from the same user who has gone offline.
        * After logging in from different devices with the same UID, the connection state may be abnormal.
        * When setting the Presence state frequently, data may be abnormal.
        * When the specified service is not activated, joining a channel does not return an error.
        * In some use-cases, abnormal property values may cause crashes.
      </TabsContent>
    </Tabs>

    ### v2.2.1 [#v221-2]

    v2.2.1 was released on August 9, 2024.

    #### Compatibility changes [#compatibility-changes-8]

    This release optimizes the implementation of the following features, which involves renaming, deleting, or modifying the behavior of some APIs. To ensure the proper functioning of your project, modify your implementation after upgrading the SDK.

    * Removes the `createMetadata` method. Refer to the sample code below to modify your implementation:

      ```objc
      // Before v2.2.1
      AgoraRtmMetadata* metadata = [[rtm getStorage] createMetadata];
      ```

      ```objc
      // v2.2.1 or later
      AgoraRtmMetadata* metadata = [[AgoraRtmMetadata alloc] init];
      ```

    * Removes the `AgoraRtmStateItem` class and changes the type of the following parameters from `NSArray&lt;AgoraRtmStateItem *&gt;` to `NSDictionary`:
      * The `items` parameter of the [`setState`](/en/api-reference/api-ref/signaling) method.
      * The `states` parameter of the [`PresenceEvent`](/en/api-reference/api-ref/signaling) class.
      * The `states` parameter of the [`UserState`](/en/api-reference/api-ref/signaling) class.

    * Adds `CERTIFICATION_VERIFY_FAILURE(22)` in [`RtmConnectionChangeReason`](/en/api-reference/api-ref/signaling). The values of `STREAM_CHANNEL_NOT_AVAILABLE` and `INCONSISTENT_APPID` change to 23 and 24, respectively.

    #### New features [#new-features-14]

    1. VisionOS support

       This release adds support for VisionOS. For the minimum supported version and target architecture, see [Supported platforms](./supported-platforms.md). This release also changes the package name from `AgoraRtm_iOS` to `AgoraRtm`. After upgrading the SDK, if you use Cocoapods to integrate the SDK, modify the `Podfile` file as follows:

       ```ruby
       platform :ios, '11.0'
       target 'Your App' do
       pod 'AgoraRtm', '2.2.0'
       end
       ```

    2. Private deployment capability

       This release adds the `privateConfig` parameter in [`RtmConfig`](/en/api-reference/api-ref/signaling) to set private deployment. See [Private deployment configuration](../build/connect-and-authenticate/client-configuration.mdx).

    3. Heartbeat interval configuration

       This release adds the `heartbeatInterval` parameter in [`RtmConfig`](/en/api-reference/api-ref/signaling) to set the interval at which the SDK sends heartbeat packets to the server. See [Heartbeat interval and presence timeout parameters](../build/connect-and-authenticate/connection/connection-management.mdx).

    4. Dual environment configuration

       This release adds the `protocolType` parameter in [`RtmConfig`](/en/api-reference/api-ref/signaling) to set the network transport protocol. See [Connection protocol](../build/connect-and-authenticate/client-configuration.mdx).

    5. User channel

       This release adds the `USER` type in [`RtmChannelType`](/en/api-reference/api-ref/signaling) for sending messages to specific users. This feature can replace the peer-to-peer messaging feature in v1.

    6. Quiet mode configuration

       This release adds `beQuiet` in [`SubscribeOptions`](/en/api-reference/api-ref/signaling), and `beQuiet` in [`JoinChannelOptions`](/en/api-reference/api-ref/signaling) to enable quiet mode when subscribing or joining a channel. Once you enable the quiet mode, other users in the channel cannot receive your presence event notifications.

    #### Improvements [#improvements-25]

    1. Connection state management

       This release deprecates the `onConnectionStateChanged` callback and adds the [`onLinkStateEvent`](/en/api-reference/api-ref/signaling) callback instead. See [Connection management](../build/connect-and-authenticate/connection/connection-management.mdx) for details.

    2. `AgoraRtmPresenceEventTypeRemoteStateChanged` event notification logic

       This release changes the triggering logic of the `AgoraRtmPresenceEventTypeRemoteStateChanged` event. When a user sets or modifies multiple key-value pairs at once, other users in the channel receive only one event notification.

    3. Support for event notification timestamps

       This release adds a new `timestamp` parameter in the following data structures to report the timestamp of the triggered event notification:

       * [`MessageEvent`](/en/api-reference/api-ref/signaling)
       * [`PresenceEvent`](/en/api-reference/api-ref/signaling)
       * [`TopicEvent`](/en/api-reference/api-ref/signaling)
       * [`StorageEvent`](/en/api-reference/api-ref/signaling)
       * [`LockEvent`](/en/api-reference/api-ref/signaling)

    4. Optimized API behavior

       This release improves the behavior of the following APIs:

       * [`login`](/en/api-reference/api-ref/signaling)
         * Before v2.2.1: The SDK does not support multiple consecutive calls to this method, or passing an empty string in the `token` parameter.
         * v2.2.1 or later: The SDK supports multiple consecutive calls to this method without the need for additional calls to `logout` in between. Additionally, when the `token` parameter is an empty string, the SDK uses the App ID you provided during initialization as a replacement for the token.
       * [`subscribe`](/en/api-reference/api-ref/signaling)
         * Before than v2.2.1: The SDK does not support multiple consecutive calls to this method.
         * v2.2.1 or later: The SDK supports multiple consecutive calls to this method.
       * [`join`](/en/api-reference/api-ref/signaling)
         * Before v2.2.1: The SDK does not support multiple consecutive calls to this method, or passing an empty string in the `token` parameter.
         * v2.2.1 or later: The SDK supports multiple consecutive calls to this method. Additionally, when the `token` parameter is an empty string, the SDK uses the app ID you provided during initialization as a replacement for the token.

    5. Range of `presenceTimeout`

       This release changes the range of the `presenceTimeout` parameter in the [`RtmConfig`](/en/api-reference/api-ref/signaling) from \[10, 300] to \[5, 300].

    6. Others

       This release also enhances the underlying algorithm capability to improve data synchronization speed.

    #### Fixed issues [#fixed-issues-14]

    This release fixed the issue that remote users occasionally did not receive the `REMOTE_LEAVE` event notification when the local user directly called the `logout` method without calling the `leave` method.

    ### v2.1.12 [#v2112-2]

    v2.1.12 was released on July 2, 2024.

    #### Improvements [#improvements-26]

    This release includes the following improvements:

    * For data synchronization errors caused by network issues, this release introduces a user logout mechanism, which ensures that the SDK automatically logs out of the Signaling system.
    * Unsubscribing from a message channel during network disconnection will no longer return an error.

    #### Fixed issues [#fixed-issues-15]

    This release fixed the following issues:

    * During a disconnection with the Signaling system under poor network conditions, the user experienced errors when unsubscribing from a message channel.
    * Under poor network conditions, the user occasionally failed to receive callbacks after a successful login.
    * After reconnecting from a disconnection, the user occasionally could not receive the `onStorageEvent` event notification.
    * After reconnecting from a disconnection, the SDK occasionally failed to restore subscription relationships in the stream channel.
    * Occasional failure to receive topic messages from web clients.

    ### v2.1.11 [#v2111-2]

    v2.1.11 was released on May 13, 2024.

    #### Improvements [#improvements-27]

    **New privacy information file**

    To meet Apple's security and compliance requirements for app distribution, this release adds a `PrivacyInfo.xcprivacy` file. It contains API call instructions for accessing or using user data within the SDK, as well as descriptions of the data types collected by the SDK.

    <CalloutContainer type="info">
      <CalloutTitle>
        Information
      </CalloutTitle>

      <CalloutDescription>
        If you need to distribute an app with SDK versions earlier than v2.1.10 on the Apple App Store, you need to manually add the `PrivacyInfo.xcprivacy` file to your Xcode project. See [How can I add a privacy manifest to my iOS app?](/en/api-reference/faq/other/ios_privacy_manifest)
      </CalloutDescription>
    </CalloutContainer>

    **Other improvements**

    This release optimizes the response mechanism when subscribing to channels with the `withPresence` setting or joining channels with the `withPresence` setting. If the user does not receive the `SNAPSHOT` type of `onPresenceEvent` event notification within 5 seconds, the SDK will report the `CHANNEL_PRESENCE_NOT_READY` error code in the `completionBlock` parameter.

    #### Fixed issues [#fixed-issues-16]

    This release fixed the following issues:

    * In specific use-cases, after logging out of the Signaling system and logging back in, occasional failures occurred when subscribing to channels with the `withPresence` setting or joining channels with the `withPresence` setting.
    * In cases where the connection was lost due to network issues and then restored, if the local user actively called the `leave` method to leave the channel, a remote user occasionally did not receive the `REMOTE_TIMEOUT` type of the `onPresenceEvent` event notification.
    * Occasional failures occurred when frequently calling the `subscribe` and `unsubscribe` methods.

    ### v2.1.10 [#v2110-2]

    v2.1.10 was released on March 11, 2024.

    #### Fixed issues [#fixed-issues-17]

    This release fixed the following issues:

    * When sending messages frequently, message sending occasionally timed out.
    * After calling `renewToken` to renew the token, some services were not functioning correctly, resulting in unexpected disconnection.

    ### v2.1.9 [#v219-2]

    v2.1.9 was released on February 22, 2024.

    #### Compatibility changes [#compatibility-changes-9]

    This release improves message publishing options as follows:

    * Removes the `sendTs` parameter, and adds the `channelType` parameter in `AgoraRtmPublishOptions`. See details in [`AgoraRtmPublishOptions`](/en/api-reference/api-ref/signaling).
    * Modifies the type of the `options` parameter in the `publishTopicMessage` method from `AgoraRtmPublishOptions` to `AgoraRtmTopicMessageOptions`. See details in [`AgoraRtmTopicMessageOptions`](/en/api-reference/api-ref/signaling).

    #### Improvements [#improvements-28]

    This release adds the following improvements:

    * Adds error codes: `AgoraRtmErrorInvalidChannelType`, `AgoraRtmErrorInvalidEncryptionParameter`, and `AgoraRtmErrorOperationRateExceedLimitation`. For error code descriptions and solutions, see [Error Codes](/en/realtime-media/rtm/reference/error-codes).
    * Optimizes the handling logic for expired user status data during reconnection.

    #### Fixed issues [#fixed-issues-18]

    This release fixes the following issues:

    * The initialization process did not return a failure when the `encryptionKdfSalt` parameter length was not 32 bytes.
    * Occasional crashes occurred when calling the `getOnlineUsers` method to retrieve paginated results.
    * The memory leak issue during initialization.

    ### v2.1.7 [#v217-2]

    v2.1.7 was released on January 22, 2024.

    #### Compatibility changes [#compatibility-changes-10]

    If you use the features mentioned in this section, ensure that you modify the implementation of the relevant features after upgrading the SDK.

    1. Initialization parameters

       To remind users to set the required parameters during initialization, this release adds the following methods:

       * The `init` method in `AgoraRtmMetadata`, which prevents users from initializing without providing the required parameters.
       * The `init` and `initWithServer` methods in `AgoraRtmProxyConfig`, which require users to provide the `server`, `port`, and `proxyType` parameters during initialization.
       * The `init` and `initWithAppId` methods in `AgoraRtmClientConfig`, which require users to provide the `appId` and `userId` parameters during initialization.

    2. Channel options

       This release adds the following changes to the `AgoraRtmJoinChannelOption` and `AgoraRtmSubscribeOptions` classes:

       * Removes the `withMetadata`, `withPresence`, and `withLock` parameters from the `AgoraRtmJoinChannelOption` class, and adds a `features` parameter as a replacement. You can set one or more event notifications in the `features` parameter based on your needs.
       * Removes the `withMessage`, `withMetadata`, `withPresence`, and `withLock` parameters from the `AgoraRtmSubscribeOptions` class, and adds a `features` parameter as a replacement. You can set one or more event notifications in the `features` parameter based on your needs.

       This release also improves the performace of setting the presence event notification in `AgoraRtmJoinChannelOption`.

    3. Naming changes

       This release renames the following callbacks:

       | Before v2.1.6                | v2.1.6                     |
       | ---------------------------- | -------------------------- |
       | `onMessageEvent`             | `didReceiveMessageEvent`   |
       | `onPresenceEvent`            | `didReceivePresenceEvent`  |
       | `onLockEvent`                | `didReceiveLockEvent`      |
       | `onStorageEvent`             | `didReceiveStorageEvent`   |
       | `onTopicEvent`               | `didReceiveTopicEvent`     |
       | `onTokenPrivilegeWillExpire` | `tokenPrivilegeWillExpire` |
       | `connectionStateChanged`     | `connectionChangedToState` |

       This release also renames the `items` parameter of the `removeState` method to `keys`, and changes the type of the `areaCode` parameter from `unsigned int` to `AgoraRtmAreaCode`.

    #### New features [#new-features-15]

    1. Stream Channel

       Experience seamless, delay-free data flow from one point to another. Stream channel solution refers to a real-time data pipeline that enables the uninterrupted flow of data from one point to another without delay or latency.

    2. Pub/Sub

       Embrace asynchronous messaging, enabling instant communication between publishers and subscribers without the need for immediate responses. The pub/sub model is a messaging pattern used in real-time messaging solutions where publishers send messages to channels, and subscribers receive messages from the channels they are subscribed to.

    3. Topic

       Effectively manage data streams with topics, enabling seamless communications between users. Topic serves as a data flow management mechanism in the stream channel. It enables users to subscribe to, distribute, and notify events of data streams. Topics allow users to register as message publishers, send messages, and receive messages from subscribed publishers in a channel.

    4. Storage

       Storage is important in signaling solutions to ensure reliable message delivery and prevent message loss or drop.

    5. Removing Event Listeners

       This release adds the removeEventListener method. You can use it to remove a specified event listener.

    6. Interval Mode

       This release supports the interval mode of presence function. When the number of online users in a channel exceeds the specified Announce Max value, the channel enters the interval mode. The SDK triggers the presence event notification at regular intervals and provides aggregated incremental information about user join, leave, timeout, and state changes in the interval property. For more details, see [Interval Mode](/en/api-reference/api-ref/signaling).

    7. Multiple ways to add event listeners

       This release adds the `addDelegate` and `removeDelegate` methods. In addition to adding or removing an event listener object during initialization, you can also call the new methods to add or remove one or more event listener objects at any time during the app's lifecycle.

    8. Locks

       Implement locks to maintain the sequence of messages, ensuring your data is processed in a specific order, preventing any data conflicts. When a client accesses a resource, it can acquire a lock on that resource to prevent other clients from accessing it.

    #### Improvements [#improvements-29]

    1. Message sending

       This release adds two new methods, `publish` and `publishTopicMessage`, which have the same name as existing methods. Additionally, this release changes the type of the `message` parameter in the original methods. See details as follows:

       ```objc
       // Before v2.1.6
       // The type of the message parameter is NSObject
       // The NSObject type supports passing both string and binary messages
       - (void) publish: (NSString* _Nonnull)channelName
                   message: (NSObject* _Nonnull)message
                   withOption: (AgoraRtmPublishOptions* _Nullable)publishOption
                   completion: (AgoraRtmOperationBlock _Nullable)completionBlock;

       - (void) publishTopicMessage: (NSObject * _Nonnull) message
                   inTopic: (NSString * _Nonnull) topic
                   withOption:(AgoraRtmPublishOptions * _Nullable) options
                   completion: (AgoraRtmOperationBlock _Nullable)completionBlock;
       ```

       ```objc
       // v2.1.6
       // The type of the message parameter is NSString or NSData
       // The NSString type only supports passing string data
       // The NSData type only supports passing binary data

       // publish[1/2]
       - (void) publish:(NSString* _Nonnull)channelName
               message:(NSString* _Nonnull)message
               option:(AgoraRtmPublishOptions* _Nullable)publishOption
           completion:(AgoraRtmOperationBlock _Nullable)completionBlock

       // publish[2/2]
       - (void) publish:(NSString* _Nonnull)channelName
                   data:(NSData* _Nonnull)data
               option:(AgoraRtmPublishOptions* _Nullable)publishOption
           completion:(AgoraRtmOperationBlock _Nullable)completionBlock

       // publishTopicMessage[1/2]
       - (void) publishTopicMessage:(NSString * _Nonnull)topic
                           message:(NSString * _Nonnull)message
                           option:(AgoraRtmPublishOptions * _Nullable)options
                       completion:(AgoraRtmOperationBlock _Nullable)completionBlock

       // publishTopicMessage[2/2]
       - (void) publishTopicMessage:(NSString * _Nonnull)topic
                               data:(NSData * _Nonnull)data
                           option:(AgoraRtmPublishOptions * _Nullable)options
                       completion:(AgoraRtmOperationBlock _Nullable)completionBlock
       ```

    2. Message receiving

       This release removes the `getData` method, `getType` method, and `AgoraRtmMessageType` class in the `AgoraRtmMessage` class, and adds the `rawData` and `stringData` properties instead. You can use the `rawData` property to receive binary messages, and the `stringData` property to receive string messages.

    3. Response and error message optimization

       This release changes the information returned by the `completionBlock` callback function in various methods:

       * If the method call is successful, the `response` parameter returns the corresponding data, and the `errorInfo` parameter returns `nil`.
       * If the method call fails, the `response` parameter returns `nil`, and the `errorInfo` parameter returns the corresponding error message.

       Additionally, this release adds an `error` parameter to the `initWithConfig` and `createStreamChannel` methods. If the method call fails, you can see the output error description in the `error` parameter.

    #### Fixed issues [#fixed-issues-19]

    This release fixed the following issues:

    * Occasional inability to log out of Signaling when the network status changed.
    * Occasional inability to log in to Signaling after logging out when the network status changed.
    * When the network was disconnected, users occasionally did not receive the `Snapshot` event notification due to that the app did not clear data.
    * When a user joined a channel and switched the app to the background and then back to the foreground, the SDK occasionally triggered the `REMOTE_JOIN` event notification multiple times.

    
  
      
  
      
  
      
  
      
  
      
  
      
  
