Work with multiple documents in AI Assistant using SwiftUI

SwiftUI

This guide shows how to use AI Assistant with multiple documents, enabling users to ask questions and get insights across their entire document collection using AIAssistantView.

When working with multiple documents, AI Assistant enables users to:

  • Ask questions that span across multiple documents in your app
  • Get contextual answers that reference specific content from any document
  • Navigate seamlessly between documents based on links

Working with multiple documents is particularly powerful for apps that handle document workflows, research materials, or any scenario where users require the content of multiple related documents simultaneously.

Before starting, ensure you have a working setup running AI Assistant for your project.

Using AI Assistant with multiple documents requires a new license component for AI Assistant, which will be available in the AI Assistant 1.5 release. Contact our Sales team for more information.

Creating the configuration

To support multiple documents, create an AIAssistantConfiguration that includes all document IDs in its JSON Web Token (JWT). This token authorizes the session and tells the AI Assistant server which documents are available for the session. You can read more about JWTs and supported claims in the generate a JWT guide.

func createAIAssistantConfiguration(for documents: [Document]) -> AIAssistantConfiguration {
let sessionID = "multi-document-ios-session"
let claims: [String: Any] = [
"document_ids": documents.compactMap { $0.documentId?.hexadecimalEncodedString() },
"session_ids": [sessionID]
]
// In production, generate JWT server-side for security.
let jwt = generateJWT(claims: claims)
// Use the server URL where your AI Assistant is hosted.
let serverURL = URL(string: "http://localhost:4000")!
return AIAssistantConfiguration(serverURL: serverURL, jwt: jwt, sessionID: sessionID)
}

Presenting the UI

Create an AIAssistantSession with the document collection you want to make available to AI Assistant and your configuration. Then embed an AIAssistantView in your SwiftUI hierarchy:

func setupAIAssistant(with documents: [Document]) -> AIAssistantSession {
let configuration = createAIAssistantConfiguration(for: documents)
return AIAssistantSession(documents: documents, configuration: configuration)
}

With the session prepared, create your SwiftUI view:

struct MultiDocumentAIAssistantView: View {
let documents: [Document]
@ObservedObject var aiAssistantSession: AIAssistantSession
@State private var selectedDocument: Document
// Publishes navigation actions for the PDF view.
private let pdfActionEventPublisher = PassthroughSubject<PDFView.ActionEvent, Never>()
init(documents: [Document], session: AIAssistantSession) {
self.documents = documents
self.aiAssistantSession = session
_selectedDocument = State(initialValue: documents.first!)
}
var body: some View {
PDFView(document: selectedDocument,
actionEventPublisher: pdfActionEventPublisher)
.inspector(isPresented: .constant(true)) {
AIAssistantView(session: aiAssistantSession)
.onDocumentNavigationAction { document, pageIndex, rects in
// Switch to the requested document.
selectedDocument = document
// Jump to the page and highlight the areas.
pdfActionEventPublisher.send(.setPageIndexWithHighlights(pageIndex, rects))
}
}
}
}

AIAssistantView handles setting up the connection to AI Assistant and shows the chat interface to start interacting with the documents once it’s ready.

Handling document navigation

Add the onDocumentNavigationAction modifier to handle navigation when AI Assistant directs users to specific content. This modifier is called whenever AI Assistant wants to show the user relevant information in a particular document:

AIAssistantView(session: aiAssistantSession)
.onDocumentNavigationAction { document, pageIndex, rects in
// Switch to the document and navigate.
selectedDocument = document
pdfActionEventPublisher.send(.setPageIndexWithHighlights(pageIndex, rects))
}

The rects parameter contains the exact areas on the page that AI Assistant wants to highlight in the PDF coordinate space.

Managing document changes

When your document collection changes, you need to recreate the AIAssistantSession with an updated JWT that reflects the new document set. This ensures AI Assistant has access to the correct documents.

In SwiftUI, this can be handled by a session manager with a @Published property of type AIAssistantSession. The AIAssistantView must use the session from the session manager. When the property updates, SwiftUI automatically refreshes the view, and AIAssistantView uses the new session with the updated document collection.

To ensure the AIAssistantView properly reinitializes when the document collection changes, use a sessionID property with the .id() modifier. This forces SwiftUI to recreate the view completely when the session changes, ensuring a clean state for the new document set:

class AIAssistantSessionManager: ObservableObject {
@Published var session: AIAssistantSession
@Published var sessionID = UUID()
init(documents: [Document]) {
self.session = Self.createSession(for: documents)
}
func loadNewDocuments() {
let newDocuments = ... // Load new documents from your data source.
session = Self.createSession(for: newDocuments)
sessionID = UUID()
}
private static func createSession(for documents: [Document]) -> AIAssistantSession {
let configuration = createAIAssistantConfiguration(for: documents)
return AIAssistantSession(documents: documents, configuration: configuration)
}
}
struct MultiDocumentAIAssistantView: View {
@StateObject private var sessionManager: AIAssistantSessionManager
init(documents: [Document]) {
self._sessionManager = StateObject(wrappedValue: AIAssistantSessionManager(documents: documents))
}
var body: some View {
// ... existing PDFView and inspector code ...
AIAssistantView(session: sessionManager.session)
.id(sessionManager.sessionID)
.toolbar {
Button("Change Documents") {
sessionManager.loadNewDocuments()
}
}
}
}