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.
If you're starting a new project, please visit the Conversations Docs to begin. If you've already built on Programmable Chat, please visit our Migration Guide to learn about how to switch.
pod 'TwilioChatClient', '~> 0.16.0'
pod 'TwilioAccessManager', '~> 0.1.1'
pod repo update
pod install
to perform the installation. This will remove the previous TwilioIPMessagingClient and TwilioCommon components and add the TwilioChatClient and optionally TwilioAccessManager.
TwilioIPMessagingClient.framework
and
TwilioCommon.framework
files from your project.
Embedded Binaries
section in General settings, selecting 'Copy items if needed' when prompted
Run Script
Build Phase to remove simulator architectures during AppStore builds
Build Phases
Run Script
phrase, move it to below the
Embed Frameworks
step if it is not there already
bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/TwilioChatClient.framework/remove_archs"
Embedded Binaries
section in General settings, selecting 'Copy items if needed' when prompted
Run Script
Build Phase to remove simulator architectures during AppStore builds
Build Phases
Run Script
phrase, move it to below the
Embed Frameworks
step if it is not there already
bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/TwilioAccessManager.framework/remove_archs"
Twilio IP Messaging is now Twilio Chat, several changes are needed to your code but should be largely addressed with a simple search and replace.
As is generally advisable, ensure you have a backup of your code and/or have checked in any uncommitted changes to your SCM before making these changes.
Review then perform a search and replace within your project on the following. IMPORTANT: You must match case on the search and replaces or they will likely apply incorrectly.
TwilioIPMessaging
to
TwilioChat
TWM
to
TCH
ipMessagingClient:
to
chatClient:
ipMessagingClientWithAccessManager
to
chatClientWithToken
and pass in a string Access Token instead of AccessManager (whether you are keeping AccessManager or not)
TwilioIPMessaging
to
TwilioChat
TWM
to
TCH
ipMessagingClient(
to
chatClient(
TwilioIPMessagingClient.init(accessManager:
to
TwilioChatClient.init(token:
and pass in a string Access Token instead of AccessManager (whether you are keeping AccessManager or not)
Deprecations and Changes:
TCHChannels no longer has an allObjects
method. User and unjoined public channels are now separately loaded and available through asynchronous accessors detailed below.
User and unjoined public channels are now separate in the system. You can access a user's channels with the new userChannelsWithCompletion:
method. You can also obtain a list of public channels with the publicChannelsWithCompletion:
. Both calls return a paginator and may page results. You can access the items for a given paginator with getItems
. To determine if another page is present, you can query the boolean method hasNextPage
. To load subsequent pages of results, use the requestNextPageWithCompletion:
method.
Today, all user channels will be returned on the first page for userChannelsWithCompletion:
but this will change in the future. Please make use of the hasNextPage
method to determine completion of the query. Public channels are paged in groups of 50.
publicChannelsWithCompletion:
returns a snapshot of current data for each public channel. To join a channel, you will use the sid on the channel list entry object to load the channel using the channelWithSidOrUniqueName:completion:
method then call joinWithCompletion:
.
TCHChannels' synchronous channelWithId:
and channelWithUniqueName:
have been merged into a single asynchronous channelWithSidOrUniqueName:completion
method which will fetch a channel by either its SID or unique name.
Added counts to user channel objects regardless of synchronization state:
getUnconsumedMessagesCountWithCompletion:
- fetches the current number of unconsumed messages for the current user
getMessagesCountWithCompletion:
- fetches the current number of messages on the channel
getMembersCountWithCompletion:
- fetches the current number of members of the channel
Added createdBy
property
TCHMembers no longer has an allObjects
method. Members can be loaded with the asynchronous membersWithCompletion:
method that returns a paginator. Today, all members will be returned on the first page but this will change in the future. Please make use of the hasNextPage
method to determine completion of the query.
TWMMessages (now TCHMessages)'s allObjects
method has been fully deprecated. Please use the asynchronous get*Messages family of methods as a replacement.
The synchronous messageWithIndex:
and messageForConsumptionIndex:
methods have been made asynchronous, accepting a callback as a parameter.
setAllMessagesConsumed
now uses the most recent message on the server, rather than the client, since the most recent messages may not yet be loaded locally. Use setLastConsumedMessageIndex:
or advanceLastConsumedMessageIndex:
to reflect a local message id instead.
channelAdded
will no longer be called when public channels are added in the system, only upon the channel becoming part of the user channel list
channelAdded
will no longer be called when public channels are added in the system, only upon the channel becoming part of the user channel list
toastReceivedOnChannel:message:
returns nil for message
The AccessManager is optional now, and delivered separately. Your migration path here will differ depending on whether you wish to utilize the now optional AccessManager or not.
#import <TwilioCommon/TwilioCommon.h>
TwilioAccessManagerDelegate
protocol
accessManagerTokenExpired:
and
accessManager:error:
TwilioAccessManager
throughout your project
import TwilioCommon
TwilioAccessManagerDelegate
protocol
accessManagerTokenExpired(_ accessManager: TwilioAccessManager!)
and
accessManager(_ accessManager: TwilioAccessManager!, error: Error!)
TwilioAccessManager
throughout your project
#import <TwilioCommon/TwilioCommon.h>
with
#import <TwilioAccessManager/TwilioAccessManager.h>
- (void)accessManagerTokenExpired:(TwilioAccessManager *)accessManager
was actually called 3 minutes before expiration, it is now called at expiration. To have a chance to renew the token early, please implement
- (void)accessManagerTokenWillExpire:(nonnull TwilioAccessManager *)accessManager
instead which is called 3 minutes before expiration. An example:
_10 - (void)accessManagerTokenWillExpire:(TwilioAccessManager *)accessManager {_10 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{_10 NSString *newToken = <...>;_10 [accessManager updateToken:newToken];_10 });_10 }
- (void)accessManagerTokenExpired:(TwilioAccessManager *)accessManager
is now called at token expiry.
- (void)accessManager:(TwilioAccessManager *)accessManager error:(NSError *)error
is renamed to
- (void)accessManagerTokenInvalid:(nonnull TwilioAccessManager *)accessManager
and no longer passes an error object.
TwilioAccessManager
's
updateToken:(NSString *)token
method. Since AccessManager is no longer passed into the clients, you must register an update handler to convey token updates to your client(s). For each client you should register like this:
_10 __weak TwilioChatClient *weakClient = self.client;_10 [self.accessManager registerClient:self.client_10 forUpdates:^(NSString * _Nonnull updatedToken) {_10 [weakClient updateToken:updatedToken];_10 }];
registerClient:
method itself.
import TwilioCommon
with
import TwilioAccessManager
accessManagerTokenExpired(_ accessManager: TwilioAccessManager!)
was actually called 3 minutes before expiration, it is now called at expiration. To have a chance to renew the token early, please implement
accessManagerTokenWillExpire(_ accessManager: TwilioAccessManager)
instead which is called 3 minutes before expiration. AccessManager is also now non-optional. An example:
_11 func accessManagerTokenWillExpire(_ accessManager: TwilioAccessManager) {_11 if let identity = self.identity {_11 DispatchQueue.global(qos: .background).async {_11 let token = <...>_11_11 if let token = token {_11 accessManager.updateToken(token)_11 }_11 }_11 }_11 }
accessManagerTokenExpired(_ accessManager: TwilioAccessManager)
is now called at token expiry.
accessManager(_ accessManager: TwilioAccessManager!, error: Error!)
is renamed to
accessManagerTokenInvalid(_ accessManager: TwilioAccessManager)
and no longer passes an error object.
TwilioAccessManager
's
updateToken(token)
method. Since AccessManager is no longer passed into the clients, you must register an update handler to convey token updates to your client(s). For each client you should register like this:
_10 if let client = self.client {_10 self.accessManager?.registerClient(client, // should not be an optional value_10 forUpdates: { [weak client = self.client] (token) in_10 client?.updateToken(token)_10 })_10 }