# SDK Migration Guide - iOS 1.0

> \[!CAUTION]
>
> Programmable Chat has been deprecated and is no longer supported. Instead, we'll be focusing on the next generation of chat: Twilio Conversations. Find out more about the [EOL process here](https://www.twilio.com/en-us/changelog/programmable-chat-end-of-life-notice).
>
> If you're starting a new project, please visit the [Conversations Docs](/docs/conversations) to begin. If you've already built on Programmable Chat, please visit our [Migration Guide](/docs/conversations/migrating-chat-conversations) to learn about how to switch.

## Overview

Twilio Programmable Chat 1.0 brings additional controls on data synchronization to enhance performance as well as many other improvements. This guide will help you migrate your existing Chat applications to the new strategies supported by release 1.0.

Client and Channel delegates have been expanded to indicate what parts of the object have been updated, allowing you to tailor UI updates to the information that has changed.

Users are no longer implicitly subscribed to improve performance on large instances. You can subscribe up to a maximum number of users at once after which your least recently used User will be unsubscribed. Using either subscribed Users or User Descriptors appropriately is key to the performance of your application:

* Subscribed Users will immediately reflect changes made on other clients, such as Friendly Name and Attributes and will also have the most up-to-date reachability and online status information. Subscribed Users are best for live display of messages or recently contacted Users by the client.
* User Descriptors are a snapshot in time of that user's status in the system. These snapshot objects are ideal for temporary lists of users within your user interface or for visualizing large numbers of users on a Channel where constant data synchronization is not key.

The notifications registration process has been streamlined, reflecting success of subscribing to push notifications in a callback rather than the separate delegate methods previously exposed.

Client initialization has been simplified to reflect most users typical usage of the system. All user channels (channels for which the current user is joined to or an owner of) will be subscribed to from client startup but only the members roster will be synchronized initially. This keeps client startup fast while still reflecting the latest activity immediately to the client. This removes the requirement to manually call `synchronizeWithCompletion:` on channel objects to begin utilizing them.

## TwilioChatClient Changes

### Initialization Changes

Creation of the Chat client is now asynchronous and the client object is returned to you as part of a new completion block. This change reflects the possibility that client creation may fail due to issues with the provided access token. Client creation with `chatClientWithToken:properties:delegate:` is now replaced with `chatClientWithToken:properties:delegate:completion:` and returns nil instead of a client object. The client object, once the completion is called, is ready for use.

The `TwilioChatClientProperties` object provided during client creation has two fewer properties:

`synchronizationStrategy` has been deprecated. All user channels are implicitly synchronized in Chat 1.0 so that events for Channels the user is joined to will be delivered from client initialization.

To ensure the impact on clients for this change are manageable, Chat will no longer implicitly load a pre-determined list of messages (now deprecated `initialMessageCount` property also on this object) nor will it synchronize the UserInfo objects for Channel's Members. These objects incur frequent updates and can incur additional burden for clients unnecessarily. If you are relying on `initialMessageCount` in your implementation, we recommend you consider fetching messages on demand as the user displays the UI for the channel. If having a some messages initially is key to your use case, you may iterate through the `subscribedChannels:` once the client is fully synchronized to seed the local cache with a history of messages.

`updateToken:` has transitioned to `updateToken:completion:` which will provide an indication of success for the token update operation.

### Push Notification Changes

`(de)registerWithToken:` has been renamed to `(de)registerWithNotificationToken:completion:` to differentiate notification tokens from access tokens and the completion block will indicate an initial reflection of the success of the request and `chatClientToastSubscribed:` and `chatClient:toastRegistrationFailedWithError:` have been retired.
`handleNotification:` has been expanded to `handleNotification:completion:` to indicate if the notification was able to be processed by the chat client.

The `chatClient:toastReceivedOnChannel:message:` delegate method has been changed to `chatClient:notificationNewMessageReceivedForChannelSid:messageIndex:` to better reflect both the nature of the notification and the fact the channel or message in question may not be synchronized to the client at the time the delegate is called.

### Overall Delegate Changes

Each changed delegate callback on both the Client and Channel delegates (Channel, Message, Member and User) includes an `updated` parameter which will give you information as to what on the object changed and has removed the `Changed` portion of its name.

The `chatClient:connectionStateChanged:` method has been renamed to `chatClient:connectionStateUpdated:` .

The `chatClient:synchronizationStatusChanged:` method has been renamed to `chatClient:synchronizationStatusUpdated:` .

The `chatClient:channel:synchronizationStatusChanged:` delegate method has been deprecated. You can now determine if the synchronization status has changed for a channel through the expanded `chatClient:channel:updated:` delegate callback, checking for a `TCHChannelUpdate` value of `TCHChannelUpdateSynchronizationStatus` .

### Other Changes

The `userInfo` property has been renamed to `user` to reflect the splitting of `TCHUserInfo` to distinct `TCHUser` and `TCHUserDescriptor` objects. Unlike User objects associated with Members, the User whose client this is will always be in a `subscribed` state (more on this further in the document.) You can access your client's `TCHUsers` using the `users` accessor on the `TwilioChatClient` object.

## TCHUserInfo Changes

`TCHUserInfo` has been deprecated and replaced with two distinct objects, `TCHUser` and `TCHUserDescriptor`. Similar to `TCHChannelDescriptor` objects, a `TCHUserDescriptor` represents a snapshot of data in time that should be utilized directly after obtaining it but not retained since it will not be updated with new data over time.

`TCHUser` objects add a new concept to Programmable Chat, subscriptions. A Programmable Chat primitive is subscribed if it will receive updates from the server. `TCHChannel` objects at this time are always subscribed, and `TCHChannelDescriptor` objects are not. Similarly, `TCHUserDescriptor` objects are not subscribed but a `TCHUser` object may or may not be subscribed. When a `TCHUser` is initially subscribed to on the client, you will receive the `chatClient:userSubscribed:` delegate callback.

When you first obtain a `TCHUser` object, it will be subscribed but there is a maximum number of `TCHUser` objects which may be subscribed at a time in the Programmable Chat client. Once this limit is exceeded, the least recently subscribed `TCHUser` object in memory will be unsubscribed. Several things happen when this occurs:

* The new `chatClient:userUnsubscribed:` delegate method will be called to let you know the object is no longer receiving updates
* The Chat client will no longer maintain a strong reference to the `TCHUser` object, causing it to be released unless you were holding it strongly
* The `isSubscribed` accessor will start to return a false value if you still have a reference to the `TCHUser` object
* Attempting to read data from the unsubscribed `TCHUser` object will return nil for it values
* The `online` and `notifiable` Boolean values on an unsubscribed TCHUser will return NO. This reflects a lack of information of the user's current status similar to the nil values returned for other parameters.
* If you subscribe the `TCHUser` again using the methods described below, a new `TCHUser` object will be generated

The number of Users you can concurrently subscribe to in a given instance of the Chat client is large enough that many implementation of Chat will not be affected by User objects being unsubscribed. This is something you should provide for in your code though, and ensure you are using `TCHUser` objects when consistently updated representation of users is important and `TCHUserDescriptor`s when displaying a temporary UI such as a membership list.

The new `TCHUserDescriptor` object has all of the accessors of the deprecated `TCHUserInfo` object but none of the setters. It also has a synchronous method `subscribeWithCompletion:` that will return a subscribed `TCHUser` object.

The new `TCHUser` object has the full functionality of the old `TCHUserInfo` object along with a `isSubscribed` property which should be checked to see if a `TCHUser` object is still subscribed. Also, the accessors on this object may return nil if the `TCHUser` object has been unsubscribed. There is an `unsubscribe` method on this object which will remove the `TCHUser` object from the subscription pool explicitly if you no longer need updates for it at this time.

A new `TCHUsers` class exists, accessible from the client instance with the `users` method. This class is one way to access `TCHUser` and `TCHUserDescriptor` objects. Methods this class provides include:

* `userDescriptorsForChannel:completion:` is a convenience method to retrieve `TCHUserDescriptor` objects for an entire Channel's membership with a single asynchronous call. You always have the option to obtain `TCHUserDescriptor` objects individually for a channel's Member but for a large number of Members this method is faster. The return will be a list of ephemeral UserDescriptor objects
* `userDescriptorWithIdentity:completion:` provides a `TCHUserDescriptor` instance for the specified identity
* `subscribedUserWithIdentity:completion:` retrieves and subscribes the `TCHUser` object for the specified identity. If the user object is already subscribed, this will be an instance to that object otherwise a new subscription will be created
* `subscribedUsers` synchronously returns a list of currently subscribed `TCHUser` objects
  TCHChannels Changes

There is a new synchronous method, `subscribedChannels` which will give you the list of currently synchronized channels. This method replaces the deprecated `userChannelsWithCompletion:` method. The `publicChannelsWithCompletion:` method has been renamed to `publicChannelDescriptorsWithCompletion:` for clarity on its returned objects and a new method, `userChannelDescriptorsWithCompletion:` has been added.

## TCHChannel Changes

`synchronizeWithCompletion:` has been deprecated since TCHChannel objects are now always synchronized once loaded.

All delegate methods supported by the TCHChannelDelegate protocol have `updated` variables passed for methods indicating objects have changed, describing the nature of the change.

## TCHMembers Changes

The `membersWithCompletion:` accessor on the `TCHMembers` object for a channel will now page results, previously this always returned a single page regardless of Channel membership size. It is also important to note that the first call to this method will need to bring down the channel's membership list - it is subscribed implicitly when the channel is obtained but not populated with existing Members.

## TCHMember Changes

`userInfo` is replaced with a new `identity` property which will provide the string identity for the Member. There are also two convenience methods on this class, `userDescriptorWithCompletion:` and `subscribedUserWithCompletion:` to obtain a `TCHUserDescriptor` and subscribed `TCHUser` object respectively.

## TCHResult Changes

Two new properties exist, `resultCode` and `resultText` to give more context to operation responses. The `isSuccessful` Boolean check remains the best way to tell quickly if an operation succeeded.
