Kotlin SDK v1.0.1

Android API 24+ Jetpack Compose Maven Central GitHub

Android-native SDK with Jetpack Compose UI components, Material 3 theming, and Kotlin coroutines for async operations. Add feedback collection to your Android app in minutes.

Installation

Gradle (Kotlin DSL)

Add the dependency to your module-level build.gradle.kts:

build.gradle.kts
dependencies {
    implementation("com.swiftlydeveloped:feedbackkit:1.0.1")
}

Gradle (Groovy)

Alternatively, if using Groovy-based Gradle:

build.gradle
implementation 'com.swiftlydeveloped:feedbackkit:1.0.1'

Quick Start

Configure FeedbackKit in your main activity and display the feedback list with Jetpack Compose:

MainActivity.kt
import com.swiftlydeveloped.feedbackkit.*

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        FeedbackKit.configure(this, "your-api-key") {
            userId("user_12345")
            environment(Environment.PRODUCTION)
        }

        setContent {
            FeedbackList(
                onFeedbackClick = { feedback ->
                    // Navigate to detail
                }
            )
        }
    }
}

Configuration

The FeedbackKitConfig class accepts the following options:

Option Type Default Description
apiKey String Required Project API key
userId String? null User identifier
timeout Long 30000 Request timeout in milliseconds
debug Boolean false Enable debug logging

Environment

The Environment enum controls the target server:

Value Description
PRODUCTION Production server (default)
STAGING Staging environment
LOCAL Local development (localhost)
LOCAL_DEVICE Local development from physical device

Builder Pattern

You can configure FeedbackKit using the builder pattern or pass a config object directly:

Configuration.kt
// Option 1: Builder pattern with trailing lambda
FeedbackKit.configure(context, "your-api-key") {
    userId("user_12345")
    environment(Environment.PRODUCTION)
    timeout(60000L)
    debug(true)
}

// Option 2: Config object
val config = FeedbackKitConfig(
    apiKey = "your-api-key",
    userId = "user_12345",
    environment = Environment.PRODUCTION,
    debug = true
)
FeedbackKit.configure(context, config)

// Access the shared singleton
val kit = FeedbackKit.shared

API Reference

All API methods are suspend functions designed for use with Kotlin coroutines. Access them via FeedbackKit.shared.

Feedback API

Access via FeedbackKit.shared.feedback:

Method Description
suspend fun list(options: ListFeedbackOptions? = null): List<Feedback> List all feedback with optional filters
suspend fun get(feedbackId: String): Feedback Get a single feedback by ID
suspend fun create(request: CreateFeedbackRequest): Feedback Submit new feedback
FeedbackExample.kt
// List all feedback
val feedbacks = FeedbackKit.shared.feedback.list()

// List with filters
val filtered = FeedbackKit.shared.feedback.list(
    ListFeedbackOptions(
        status = FeedbackStatus.APPROVED,
        category = FeedbackCategory.FEATURE_REQUEST
    )
)

// Get single feedback
val feedback = FeedbackKit.shared.feedback.get("feedback-id")

// Create feedback
val newFeedback = FeedbackKit.shared.feedback.create(
    CreateFeedbackRequest(
        title = "Add dark mode",
        description = "Would love dark mode support",
        category = FeedbackCategory.FEATURE_REQUEST
    )
)

Votes API

Access via FeedbackKit.shared.votes:

Method Description
suspend fun vote(feedbackId: String, userId: String, email: String? = null, notifyStatusChange: Boolean = false): VoteResponse Vote on feedback
suspend fun unvote(feedbackId: String, userId: String): VoteResponse Remove vote
VotesExample.kt
// Vote on feedback
val result = FeedbackKit.shared.votes.vote(
    feedbackId = "feedback-id",
    userId = "user_12345",
    email = "user@example.com",
    notifyStatusChange = true
)

// Remove vote
val unvoteResult = FeedbackKit.shared.votes.unvote(
    feedbackId = "feedback-id",
    userId = "user_12345"
)

Comments API

Access via FeedbackKit.shared.comments:

Method Description
suspend fun list(feedbackId: String): List<Comment> List comments for a feedback item
suspend fun create(feedbackId: String, request: CreateCommentRequest): Comment Add a comment to feedback
CommentsExample.kt
// List comments
val comments = FeedbackKit.shared.comments.list("feedback-id")

// Add a comment
val comment = FeedbackKit.shared.comments.create(
    feedbackId = "feedback-id",
    request = CreateCommentRequest(
        content = "Great idea! We'll look into this.",
        userId = "user_12345"
    )
)

Users API

Access via FeedbackKit.shared.users:

Method Description
suspend fun register(request: RegisterUserRequest): SDKUser Register an SDK user
UsersExample.kt
// Register a user
val user = FeedbackKit.shared.users.register(
    RegisterUserRequest(
        userId = "user_12345",
        email = "user@example.com"
    )
)

Events API

Access via FeedbackKit.shared.events:

Method Description
suspend fun track(eventName: String, userId: String, properties: Map<String, String>? = null): TrackedEvent Track a custom event
EventsExample.kt
// Track an event
val event = FeedbackKit.shared.events.track(
    eventName = "feedback_viewed",
    userId = "user_12345",
    properties = mapOf(
        "screen" to "detail",
        "feedback_id" to "abc123"
    )
)

Composables

Pre-built Jetpack Compose UI components for common feedback patterns. All composables support Material 3 theming.

FeedbackList

Displays a scrollable list of feedback items with search, filtering, and sorting.

Parameter Type Description
onFeedbackClick (Feedback) -> Unit Callback when a feedback item is tapped
modifier Modifier Compose modifier for layout customization

FeedbackDetailView

Shows full feedback details including description, votes, comments, and status.

Parameter Type Description
feedbackId String The ID of the feedback to display
modifier Modifier Compose modifier for layout customization

SubmitFeedbackView

A form for submitting new feedback with title, description, and category picker.

Parameter Type Description
onSuccess (Feedback) -> Unit Called after successful submission
onDismiss () -> Unit Called when the form is dismissed
modifier Modifier Compose modifier for layout customization

FeedbackCard

A single feedback item card with title, status, vote count, and category.

Parameter Type Description
feedback Feedback The feedback data to display
onClick () -> Unit Callback when the card is tapped
modifier Modifier Compose modifier for layout customization

VoteButton

A toggle button for voting/unvoting on feedback items.

Parameter Type Description
feedback Feedback The feedback item to vote on
onVoteChange (Boolean) -> Unit Called when vote state changes
modifier Modifier Compose modifier for layout customization

StatusBadge

Displays a colored badge for a feedback status.

Parameter Type Description
status FeedbackStatus The status to display
modifier Modifier Compose modifier for layout customization

CategoryBadge

Displays a badge for a feedback category.

Parameter Type Description
category FeedbackCategory The category to display
modifier Modifier Compose modifier for layout customization

Usage Example

ComposablesExample.kt
@Composable
fun FeedbackScreen() {
    var selectedFeedback by remember { mutableStateOf<Feedback?>(null) }
    var showSubmit by remember { mutableStateOf(false) }

    if (showSubmit) {
        SubmitFeedbackView(
            onSuccess = { feedback ->
                showSubmit = false
                // Handle new feedback
            },
            onDismiss = { showSubmit = false }
        )
    } else if (selectedFeedback != null) {
        FeedbackDetailView(
            feedbackId = selectedFeedback!!.id
        )
    } else {
        FeedbackList(
            onFeedbackClick = { feedback ->
                selectedFeedback = feedback
            }
        )
    }
}

Models

Core data classes used throughout the SDK.

Feedback

The primary model representing a feedback item.

Field Type Description
id String Unique identifier
title String Feedback title
description String Detailed description
status FeedbackStatus Current status
category FeedbackCategory Feedback category
voteCount Int Total number of votes
hasVoted Boolean Whether the current user has voted
commentCount Int Number of comments
createdAt String ISO 8601 creation timestamp
updatedAt String ISO 8601 update timestamp
userId String? Creator's user ID
email String? Creator's email address

Helper Methods

Method Returns Description
canVote Boolean Whether voting is allowed based on status
withVote() Feedback Returns copy with vote toggled
withCommentCount() Feedback Returns copy with incremented comment count
withStatus() Feedback Returns copy with updated status

FeedbackStatus

Enum representing the lifecycle status of a feedback item.

Value Display Name Can Vote JSON Value
PENDING Pending Yes pending
APPROVED Approved Yes approved
IN_PROGRESS In Progress Yes in_progress
TESTFLIGHT TestFlight Yes testflight
COMPLETED Completed No completed
REJECTED Rejected No rejected

Properties: canVote: Boolean, displayName: String, jsonValue: String

FeedbackCategory

Enum representing the type of feedback.

Value Display Name JSON Value
FEATURE_REQUEST Feature Request feature_request
BUG_REPORT Bug Report bug_report
IMPROVEMENT Improvement improvement
OTHER Other other

Properties: displayName: String, jsonValue: String

Comment

Represents a comment on a feedback item.

Field Type Description
id String Unique identifier
content String Comment text content
userId String Author's user ID
isAdmin Boolean Whether the author is a project admin
createdAt String ISO 8601 creation timestamp

VoteResponse

Returned after voting or unvoting on a feedback item.

Field Type Description
feedbackId String The feedback that was voted on
voteCount Int Updated total vote count
hasVoted Boolean Current user's vote state

Other Models

SDKUser

Registered SDK user with userId and email.

RegisterUserRequest

Request body for registering a new user.

TrackedEvent

Represents a tracked analytics event.

CreateFeedbackRequest

Request body with title, description, and category.

CreateCommentRequest

Request body with content and userId.

ListFeedbackOptions

Filter options for listing feedback (status, category).

Error Handling

The SDK uses a sealed class hierarchy for type-safe error handling. All API errors extend FeedbackKitError.

Error Description
FeedbackKitError Base sealed class for all SDK errors
ValidationError Invalid request data (400)
AuthenticationError Invalid or missing API key (401)
PaymentRequiredError Subscription tier limit exceeded (402)
ForbiddenError Insufficient permissions (403)
NotFoundError Resource not found (404)
ConflictError Resource conflict, e.g. duplicate vote (409)
NetworkError Network connectivity issue
ServerError(statusCode: Int) Unexpected server error (5xx)

Usage with Coroutines

Use standard Kotlin try/catch with when expressions for exhaustive error handling:

ErrorHandling.kt
import kotlinx.coroutines.*

fun loadFeedback() {
    viewModelScope.launch {
        try {
            val feedbacks = FeedbackKit.shared.feedback.list()
            // Update UI with feedbacks
        } catch (e: FeedbackKitError) {
            when (e) {
                is FeedbackKitError.AuthenticationError -> {
                    // Invalid API key
                    showError("Authentication failed")
                }
                is FeedbackKitError.PaymentRequiredError -> {
                    // Subscription limit reached
                    showUpgradePrompt()
                }
                is FeedbackKitError.NetworkError -> {
                    // No internet connection
                    showError("Check your connection")
                }
                is FeedbackKitError.ServerError -> {
                    // Server-side issue
                    showError("Server error: ${e.statusCode}")
                }
                else -> {
                    showError(e.message ?: "Unknown error")
                }
            }
        }
    }
}