Skip to content

Instantly share code, notes, and snippets.

@serjooo
Created December 20, 2017 13:32
Show Gist options
  • Save serjooo/c26904b460584ff4bbb1c0a8352717ab to your computer and use it in GitHub Desktop.
Save serjooo/c26904b460584ff4bbb1c0a8352717ab to your computer and use it in GitHub Desktop.
Twilio Chat helper for iOS
import Foundation
import TwilioAccessManager
import TwilioChatClient
class TwilioChatManager: NSObject {
//MARK: Singleton instance
public static let manager = TwilioChatManager()
//MARK: Twilio Chat SDK Components
fileprivate var accessManager: TwilioAccessManager?
fileprivate var chatClient: TwilioChatClient?
fileprivate var pushToken: Data?
fileprivate var lastNotification: [AnyHashable: Any]?
//MARK: Public Methods
public func login(withIdentity: String, accessToken: String, completion: @escaping (_ success: Bool) -> Void) {
let properties = TwilioChatClientProperties()
TwilioChatClient.chatClient(withToken: accessToken, properties: properties, delegate: self) {
[weak self] (result, client) in
if result.isSuccessful() {
self?.chatClient = client
if let this = self {
this.accessManager = TwilioAccessManager.init(token: accessToken, delegate: this)
}
self?.updateClient()
completion(true)
print("Created Chat Client successfully")
// guard let accessManager = self.accessManager, let client = self.chatClient else {return}
// accessManager.registerClient(client, forUpdates: {
// (updatedToken) in
// print("updated token ", updatedToken)
// client.updateToken(updatedToken, completion: { (result) in
// if result.isSuccessful() {
// print("Successfully updated client token")
// completion(true)
// } else {
// print("Unsuccessful to update client token")
// completion(false)
// }
// })
// })
} else {
print("Failed to create chat client")
completion(false)
}
}
}
public func setUserAttributes(attributes: [String: Any], completion: @escaping (_ success: Bool) -> Void) {
guard let chatClient = chatClient, let user = chatClient.user else {return}
user.setAttributes(attributes) { (result) in
if result.isSuccessful() {
completion(true)
print("Attributes changed successfully")
} else {
completion(false)
print("Attributes change unsuccessful")
}
}
}
public func updatePushToken(token: Data) {
pushToken = token
updateClient()
}
public func receivedNotification(notification: [AnyHashable:Any]) {
lastNotification = notification
updateClient()
}
public func getUserIdentity() -> String? {
return chatClient?.user?.identity
}
public func disconnectChatClient() {
if let chatClient = chatClient {
if let token = pushToken {
chatClient.deregister(withNotificationToken: token, completion: {
(result) in
})
}
chatClient.shutdown()
self.chatClient = nil
self.accessManager = nil
}
}
//MARK: Private helper Methods
fileprivate func updateClient() {
if let client = chatClient, client.synchronizationStatus == .channelsListCompleted || client.synchronizationStatus == .completed, let token = pushToken {
client.register(withNotificationToken: token, completion: {
(result) in
if result.isSuccessful() {
print("Registered push token")
} else {
print("Failed to register push token")
}
})
if let notification = lastNotification {
client.handleNotification(notification, completion: {
(result) in
if result.isSuccessful() {
print("Handled notification")
} else {
print("Failed to handle notification")
}
})
}
}
}
}
//MARK: TwilioChatClientDelegate
extension TwilioChatManager: TwilioChatClientDelegate {
/** Called when the client connection state changes.
@param client The chat client.
@param state The current connection state of the client.
*/
func chatClient(_ client: TwilioChatClient, connectionStateUpdated state: TCHClientConnectionState) {
}
/** Called when the client synchronization state changes during startup.
@param client The chat client.
@param status The current synchronization status of the client.
*/
func chatClient(_ client: TwilioChatClient, synchronizationStatusUpdated status: TCHClientSynchronizationStatus) {
print("synchronized")
}
/** Called when the current user has a channel added to their channel list.
@param client The chat client.
@param channel The channel.
*/
func chatClient(_ client: TwilioChatClient, channelAdded channel: TCHChannel) {
}
/** Called when one of the current users channels is changed.
@param client The chat client.
@param channel The channel.
@param updated An indication of what changed on the channel.
*/
func chatClient(_ client: TwilioChatClient, channel: TCHChannel, updated: TCHChannelUpdate) {
}
/** Called when a channel the current the client is aware of changes synchronization state.
@param client The chat client.
@param channel The channel.
@param status The current synchronization status of the channel.
*/
func chatClient(_ client: TwilioChatClient, channel: TCHChannel, synchronizationStatusUpdated status: TCHChannelSynchronizationStatus) {
}
/** Called when one of the current users channels is deleted.
@param client The chat client.
@param channel The channel.
*/
func chatClient(_ client: TwilioChatClient, channelDeleted channel: TCHChannel) {
}
/** Called when a channel the current user is subscribed to has a new member join.
@param client The chat client.
@param channel The channel.
@param member The member.
*/
func chatClient(_ client: TwilioChatClient, channel: TCHChannel, memberJoined member: TCHMember) {
}
/** Called when a channel the current user is subscribed to has a member modified.
@param client The chat client.
@param channel The channel.
@param member The member.
@param updated An indication of what changed on the member.
*/
func chatClient(_ client: TwilioChatClient, channel: TCHChannel, member: TCHMember, updated: TCHMemberUpdate) {
}
/** Called when a channel the current user is subscribed to has a member leave.
@param client The chat client.
@param channel The channel.
@param member The member.
*/
func chatClient(_ client: TwilioChatClient, channel: TCHChannel, memberLeft member: TCHMember) {
}
/** Called when a channel the current user is subscribed to receives a new message.
@param client The chat client.
@param channel The channel.
@param message The message.
*/
func chatClient(_ client: TwilioChatClient, channel: TCHChannel, messageAdded message: TCHMessage) {
}
/** Called when a message on a channel the current user is subscribed to is modified.
@param client The chat client.
@param channel The channel.
@param message The message.
@param updated An indication of what changed on the message.
*/
func chatClient(_ client: TwilioChatClient, channel: TCHChannel, message: TCHMessage, updated: TCHMessageUpdate) {
}
/** Called when a message on a channel the current user is subscribed to is deleted.
@param client The chat client.
@param channel The channel.
@param message The message.
*/
func chatClient(_ client: TwilioChatClient, channel: TCHChannel, messageDeleted message: TCHMessage) {
}
/** Called when an error occurs.
@param client The chat client.
@param error The error.
*/
func chatClient(_ client: TwilioChatClient, errorReceived error: TCHError) {
}
/** Called when a member of a channel starts typing.
@param client The chat client.
@param channel The channel.
@param member The member.
*/
func chatClient(_ client: TwilioChatClient, typingStartedOn channel: TCHChannel, member: TCHMember) {
}
/** Called when a member of a channel ends typing.
@param client The chat client.
@param channel The channel.
@param member The member.
*/
func chatClient(_ client: TwilioChatClient, typingEndedOn channel: TCHChannel, member: TCHMember) {
}
/** Called as a result of TwilioChatClient's handleNotification: method being invoked. `handleNotification:` parses the push payload and extracts the channel and message for the push notification then calls this delegate method.
@param client The chat client.
@param channelSid The channel sid for the push notification.
@param messageIndex The index of the new message.
*/
func chatClient(_ client: TwilioChatClient, notificationNewMessageReceivedForChannelSid channelSid: String, messageIndex: UInt) {
}
/** Called when a processed push notification has changed the application's badge count. You should call:
[[UIApplication currentApplication] setApplicationIconBadgeNumber:badgeCount]
To ensure your application's badge updates when the application is in the foreground if Twilio is managing your badge counts. You may disregard this delegate callback otherwise.
@param client The chat client.
@param badgeCount The updated badge count.
*/
func chatClient(_ client: TwilioChatClient, notificationUpdatedBadgeCount badgeCount: UInt) {
}
/** Called when the current user's or that of any subscribed channel member's user is updated.
@param client The chat client.
@param user The object for changed user.
@param updated An indication of what changed on the user.
*/
func chatClient(_ client: TwilioChatClient, user: TCHUser, updated: TCHUserUpdate) {
}
/** Called when the client subscribes to updates for a given user.
@param client The chat client.
@param user The object for subscribed user.
*/
func chatClient(_ client: TwilioChatClient, userSubscribed user: TCHUser) {
}
/** Called when the client unsubscribes from updates for a given user.
@param client The chat client.
@param user The object for unsubscribed user.
*/
func chatClient(_ client: TwilioChatClient, userUnsubscribed user: TCHUser) {
}
}
//MARK: TwilioAccessManagerDelegate
extension TwilioChatManager: TwilioAccessManagerDelegate {
/** Called when the access token is within 3 minutes of expiring.
@param accessManager The access manager instance that needs to be updated.
*/
func accessManagerTokenWillExpire(_ accessManager: TwilioAccessManager) {
}
/** Called when the access token has expired. May be called after expiry if the application
was in backgrounded at the time of expiration.
@param accessManager The access manager instance that needs to be updated.
*/
func accessManagerTokenExpired(_ accessManager: TwilioAccessManager) {
}
/** Called if an access token is provided that is in an invalid format.
@param accessManager The access manager instance that experienced the error.
*/
func accessManagerTokenInvalid(_ accessManager: TwilioAccessManager) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment