Custom Data

Last Edit: May 05 2020

You can add extra data to users, channels, messages or attachments.

  1. You need to create a Codable type for your extra data. For example:


struct UserDetails: UserExtraDataCodable {
    let email: String
}

struct ChannelInfo: ChannelExtraDataCodable {
    let info: String
}

struct Action: Codable {
    let title: String
}

struct Product: Codable {
    let id: String
}
                    
  1. Register once your extra data types for the decoding. This should be done once, before setting up the client (before set(user:token:) call). For example:


User.extraDataType = UserDetails.self
Channel.extraDataType = ChannelInfo.self
Message.extraDataType = Action.self
Attachment.extraDataType = Product.self
                    
  1. Add extra data for the user:


let details = UserDetails(email: "john@example.com")
let user = User(id: "john-doe", extraData: details)
Client.shared.set(user: user, token: <#Token#>)
                    
  1. Add extra data for channel, message and attachment:


let channelInfo = ChannelInfo(info: "Here you can buy our products")
let messageAction = Action(title: "Buy")
let product = Product(id: "iPhoneXsMax")

// Add to a channel.
let channel = Client.shared.channel(type: .messaging, id: "apple", extraData: channelInfo)
    
// Add to an attachment.
let attachment = Attachment(type: .link,
                            title: "iPhone Xs Max",
                            url: URL(string: "https://www.apple.com/iphone/"),
                            imageURL: URL(string: "https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/iphone-xs-max-gold-select-2018"),
                            extraData: product)

// Add to a message.
let message = Message(text: "Do you want to buy it now?", attachments: [attachment], extraData: messageAction)
                    
  1. Get a parsed extra data in query response or from web socket events. For example:


// Query the channel.
channel.query { (result) in
    if let channelInfo = result.value?.channel.extraData as? ChannelInfo {
        print(channelInfo.info)
    }
}

// Send a new message.
channel.send(message: message) { (result) in
        // The user of the message will have an `extraData` with a data of `UserDetails`.
        print(result.value?.message.user.extraData?.data as? UserDetails)
        // The message will have an `extraData` with a data of `Action`.
        print(result.value?.message.extraData?.data as? Action)
        // The message attachment will have an `extraData` with a data of `Product`.
        print(result.value?.message.attachments.first?.extraData?.data as? Product)
}
                    

Multiple extra data types

If you need to use different extra data types you can wrap it in some container Codable type. For example:


enum MessageExtraData: Codable {
    case action(Action)
    case product(Product)
}

Message.extraDataType = MessageExtraData.self

// Create an extra data for a message:
let extraData = MessageExtraData.product(Product(id: "iPhoneXs"))

let message = Message(text: "We recommend this iPhone", extraData: extraData)

// Send a new message.
channel.send(message: message) { (result) in
        if let extraData = result.value?.message.extraData?.data as? MessageExtraData,
          case .product(let product) = extraData {
            // Show product info.
        }
}