Documentation Index
Fetch the complete documentation index at: https://docs.grantiva.io/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
1. Show feature requests
let requests = try await grantiva.feedback.getFeatureRequests(sort: "votes")
for request in requests {
print("\(request.title) — \(request.voteCount) votes (\(request.status))")
}
2. Let users submit ideas
let newRequest = try await grantiva.feedback.submitFeatureRequest(
title: "Dark Mode Support",
description: "Please add a dark mode option to reduce eye strain."
)
3. Add voting
// Vote
try await grantiva.feedback.vote(for: feature.id)
// Unvote
try await grantiva.feedback.removeVote(for: feature.id)
Each user/device gets one vote per feature. feature.hasVoted tells you if the current user already voted.
let comments = try await grantiva.feedback.getComments(for: feature.id)
try await grantiva.feedback.addComment(to: feature.id, body: "Love this idea!")
5. Support tickets
// Submit a ticket
let ticket = try await grantiva.feedback.submitTicket(
subject: "App crashes on launch",
body: "After updating to v2.1, the app crashes on my iPhone 15...",
email: "user@example.com"
)
// List user's tickets
let tickets = try await grantiva.feedback.getUsersTickets()
// View conversation
let (ticket, messages) = try await grantiva.feedback.getTicket(id: ticketId)
// Reply
try await grantiva.feedback.reply(to: ticketId, body: "Here's the crash log...")
6. With user identity (optional)
If you identify users, feedback persists across devices:
await grantiva.identify("user_123")
// Now all feedback calls are scoped to this user
let tickets = try await grantiva.feedback.getUsersTickets()
SwiftUI example
struct FeatureListView: View {
@State private var features: [FeatureRequest] = []
let grantiva: Grantiva
var body: some View {
List(features) { feature in
HStack {
VStack(alignment: .leading) {
Text(feature.title).font(.headline)
Text(feature.status.rawValue)
.font(.caption)
.foregroundStyle(.secondary)
}
Spacer()
Button {
Task {
if feature.hasVoted {
try await grantiva.feedback.removeVote(for: feature.id)
} else {
try await grantiva.feedback.vote(for: feature.id)
}
await loadFeatures()
}
} label: {
Label("\(feature.voteCount)", systemImage: feature.hasVoted ? "hand.thumbsup.fill" : "hand.thumbsup")
}
.buttonStyle(.bordered)
}
}
.task { await loadFeatures() }
}
func loadFeatures() async {
features = (try? await grantiva.feedback.getFeatureRequests()) ?? []
}
}
Next steps