Swift

Chat-Ereignisse

Zuvor haben Sie in der Vonage-Befehlszeilenschnittstelle eine Unterhaltung erstellt und die beiden Benutzer zu dieser Unterhaltung hinzugefügt. Konversationen sind die Art und Weise, wie die Benutzer miteinander kommunizieren. Weitere Informationen zu Konversationen finden Sie in der Conversation API-Dokumentation. Chat-Ereignisse, oder VGConversationEvent Objekte werden über die von Ihnen erstellte Konversation gesendet. Um ein Chat-Ereignis zu erhalten, müssen Sie also zunächst der Konversation beitreten. Um dies zu implementieren, aktualisieren Sie die ChatViewModel Klasse.

Fügen Sie die getMemberIDIfNeeded Funktion:

@MainActor
final class ChatViewModel: NSObject, ObservableObject {
    ...
    
    func getMemberIDIfNeeded() async {
        guard memberID == nil else { return }
        await getMemberID()
    }   
}

Damit wird geprüft, ob die memberIDdie generiert wird, wenn Sie einer Unterhaltung beitreten, noch nicht festgelegt wurde. Wenn nicht, ruft es getMemberID. erstellen 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)
        }
    }
}

Diese Funktion versucht zunächst, die Mitglieds-ID dieses Benutzers mit getConversationMemberWenn es nicht klappt, wird es sich an der Unterhaltung mit joinConversation die die Mitglieds-ID zurückgibt.

Nun, da dieser Benutzer garantiert ein Mitglied der Konversation ist, können Sie die Konversationsereignisse über den Client abrufen. Erstellen Sie eine Funktion namens 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 nimmt eine Gesprächs-ID und VGGetConversationEventsParameters. Mit den Parametern können Sie festlegen, wie die Ereignisse an Sie zurückgegeben werden sollen. Diese Funktion gibt eine paginierte Antwort zurück. Um mehr über Paginierung zu erfahren, lesen Sie bitte die Paginierungsanleitung. Um die Ereignisse anzuzeigen, erstellen Sie eine Hilfsfunktion, die die Ereignisobjekte in einen Anzeige-String umwandelt:

@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)
        }
    }
}

Die drei Ereignisse, die in diesem Lernprogramm verwendet werden, sind memberJoined, memberLeftund messageText. Im Fall von messageText verwendet die Funktion die memberID Eigenschaft, um festzustellen, ob die Nachricht vom aktuell angemeldeten Benutzer gesendet wurde. Dadurch kann die Benutzeroberfläche die gesendeten Nachrichten des Benutzers rechts und die empfangenen Nachrichten links anordnen.

Die VGChatClientDelegate

Die Anwendung muss auch auf Ereignisse in einer Konversation nach dem anfänglichen Laden reagieren, daher müssen Sie die VGChatClientDelegate didReceiveConversationEvent Veranstaltung.

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) {}
}

Wenn ein neues Ereignis empfangen wird, wird es an die events die automatisch veröffentlicht wird, damit die Benutzeroberfläche aktualisiert werden kann.

Aktualisierung der Benutzeroberfläche

Nun, da die ChatViewModel kann neue Konversationsereignisse abrufen und abhören und den Code der Ansicht aktualisieren, um sie anzuzeigen:

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()
            }
        }
    }
}

Jetzt im Listwurde die switch-Anweisung aktualisiert und ruft nun generateDisplayText für die drei verschiedenen Arten von Konversationsereignissen, die in diesem Lernprogramm verwendet werden. Außerdem gibt es eine ProgressView denn wenn die ChatViewModel wird geladen. Wenn die Ansicht geladen wird, onAppear aufgerufen wird, die dann die Funktionen aufruft, die Sie auf der Seite ChatViewModel.

Bauen und Ausführen

Presse Cmd + R zu erstellen und erneut auszuführen. Nachdem Sie sich angemeldet haben, sehen Sie, dass Alice der Unterhaltung beigetreten ist:

Chat interface with connection events