Eventos de chat
Anteriormente, creaste una conversación en la CLI de Vonage y añadiste a los dos usuarios a dicha conversación. Las conversaciones son el medio a través del cual se comunicarán los usuarios. Puedes obtener más información sobre las conversaciones en la Documentación de la Conversation API. Eventos de chat, o VGConversationEvent Los objetos se envían a través de la conversación que has creado, por lo que, para recibir eventos de chat, primero tendrás que unirte a la conversación. Para implementar esto, actualiza el ChatViewModel clase.
Añade el getMemberIDIfNeeded función:
@MainActor
final class ChatViewModel: NSObject, ObservableObject {
...
func getMemberIDIfNeeded() async {
guard memberID == nil else { return }
await getMemberID()
}
}
Esto comprobará si el memberIDque se genera cuando te unes a una conversación. Si no es así, llama a getMemberID. Cree getMemberID:
@MainActor
final class ChatViewModel: NSObject, ObservableObject {
...
private func getMemberID() async {
let member = try? await client.getConversationMember(conversationID, memberId: "me")
memberID = member?.id
if memberID == nil {
memberID = try? await client.joinConversation(conversationID)
}
}
}
Esta función intenta obtener primero el ID de miembro de este usuario mediante getConversationMembersi falla, se unirá a la conversación con joinConversation que devuelve el ID de socio.
Ahora que está garantizado que ese usuario es miembro de la conversación, puedes obtener los eventos de la conversación utilizando el cliente. Crea una función llamada getConversationEvents:
@MainActor
final class ChatViewModel: NSObject, ObservableObject {
...
func getConversationEvents() async {
let params = VGGetConversationEventsParameters(order: .asc, pageSize: 100)
let eventsPage = try? await client.getConversationEvents(conversationID, parameters: params)
self.events = eventsPage?.events ?? []
}
}
getConversationEvents toma un identificador de conversación y VGGetConversationEventsParameters. Los parámetros le permiten personalizar la forma en que se le devuelven los eventos. Esta función devuelve una respuesta paginada. Para obtener más información sobre la paginación, puede leer el documento guía de paginación. Para mostrar los eventos, crea una función auxiliar que convierta los objetos de evento en una cadena de visualización:
@MainActor
final class ChatViewModel: NSObject, ObservableObject {
...
func generateDisplayText(_ event: VGPersistentConversationEvent) -> (body: String, isUser: Bool) {
var from = "System"
switch event.kind {
case .memberJoined:
let memberJoinedEvent = event as! VGMemberJoinedEvent
from = memberJoinedEvent.body.user.name
return ("\(from) joined", false)
case .memberLeft:
let memberLeftEvent = event as! VGMemberLeftEvent
from = memberLeftEvent.body.user.name
return ("\(from) left", false)
case .messageText:
let messageTextEvent = event as! VGMessageTextEvent
var isUser = false
if let userInfo = messageTextEvent.from as? VGEmbeddedInfo {
isUser = userInfo.memberId == memberID
from = isUser ? "" : "\(userInfo.user.name): "
}
return ("\(from) \(messageTextEvent.body.text)", isUser)
default:
return ("", false)
}
}
}
Los tres eventos que se utilizan en este tutorial son memberJoined, memberLefty messageText. En el caso de messageText La función utiliza el memberID para determinar si el mensaje fue enviado por el usuario actual. Esto permitirá a la interfaz de usuario fijar los mensajes enviados por los usuarios a la derecha y los mensajes recibidos a la izquierda.
El VGChatClientDelegate
La aplicación también debe reaccionar ante los eventos que se produzcan en una conversación una vez que se haya cargado por primera vez, por lo que debes implementar el VGChatClientDelegate didReceiveConversationEvent evento.
extension ChatViewModel: VGChatClientDelegate {
nonisolated func chatClient(_ client: VGChatClient, didReceiveConversationEvent event: VGConversationEvent) {
Task { @MainActor in
self.events.append(event as! VGPersistentConversationEvent)
}
}
nonisolated func client(_ client: VGBaseClient, didReceiveSessionErrorWith reason: VGSessionErrorReason) {}
}
Cuando se recibe un nuevo evento, éste se añade al archivo events que se publica automáticamente para que la interfaz de usuario se actualice.
Actualizar la interfaz de usuario
Ahora que el ChatViewModel Para poder recuperar y detectar nuevos eventos de conversación, actualiza el código de la vista para mostrarlos:
struct ChatView: View {
@StateObject var chatViewModel: ChatViewModel
@State private var message: String = ""
var body: some View {
VStack {
if chatViewModel.events.isEmpty {
ProgressView()
} else {
VStack {
List {
ForEach(chatViewModel.events, id: \.id) { event in
switch event.kind {
case .memberJoined, .memberLeft:
let displayText = chatViewModel.generateDisplayText(event)
Text(displayText.body)
.frame(maxWidth: .infinity, alignment: .center)
case.messageText:
let displayText = chatViewModel.generateDisplayText(event)
Text(displayText.body)
.frame(maxWidth: .infinity, alignment: displayText.isUser ? .trailing : .leading)
default:
EmptyView()
}
}.listRowSeparator(.hidden)
}.listStyle(.plain)
Spacer()
HStack {
TextField("Message", text: $message)
Button("Send") {
Task {
}
}.buttonStyle(.bordered)
}.padding(8)
}
}
}.onAppear {
Task {
await chatViewModel.getMemberIDIfNeeded()
await chatViewModel.getConversationEvents()
}
}
}
}
Ahora en el Listse ha actualizado la sentencia switch para llamar a generateDisplayText para los tres tipos diferentes de eventos de conversación que utiliza el tutorial. También hay un ProgressView porque cuando el ChatViewModel se está cargando. Cuando se carga la vista, onAppear que llama a las funciones creadas en el archivo ChatViewModel.
Construir y ejecutar
Pulse Cmd + R para compilarlo y ejecutarlo de nuevo. Una vez que hayas iniciado sesión, verás que Alice se ha unido a la conversación:

Crear una aplicación de chat para iOS
Crear una aplicación para iOS que permita a los usuarios enviarse mensajes entre sí.