Documentation Swift SDK

Swift SDK v1.0.1

Native Swift SDK for integrating FeedbackKit into iOS, macOS, and visionOS applications. Built with SwiftUI and modern Swift concurrency.

iOS 15+ macOS 12+ visionOS 1+ Swift Package Manager GitHub
$ .package(url: "https://github.com/Swiftly-Developed/SwiftlyFeedbackKit-Swift-SDK.git", from: "1.0.1")

Installation

Add the FeedbackKit Swift SDK to your project using Swift Package Manager.

Xcode

  1. 1 Open your project in Xcode
  2. 2 Go to File → Add Package Dependencies
  3. 3 Enter the repository URL: https://github.com/Swiftly-Developed/SwiftlyFeedbackKit-Swift-SDK.git
  4. 4 Set the version to 1.0.1 or "Up to Next Major"
  5. 5 Select the FeedbackKit library for your target

Package.swift

Package.swift
dependencies: [
    .package(
        url: "https://github.com/Swiftly-Developed/SwiftlyFeedbackKit-Swift-SDK.git",
        from: "1.0.1"
    )
],
targets: [
    .target(
        name: "YourApp",
        dependencies: [
            .product(name: "SwiftlyFeedbackKit", package: "SwiftlyFeedbackKit")
        ]
    )
]

Quick Start

Initialize the SDK with your project API key in your app's entry point and start using the pre-built SwiftUI views.

MyApp.swift
import SwiftUI
import SwiftlyFeedbackKit

@main
struct MyApp: App {
    init() {
        // Configure SDK per build environment
        #if DEBUG
        SwiftlyFeedback.configure(
            environment: .development,
            key: "your-dev-api-key"
        )
        #elseif TESTFLIGHT
        SwiftlyFeedback.configure(
            environment: .testflight,
            key: "your-staging-api-key"
        )
        #else
        SwiftlyFeedback.configure(
            environment: .production,
            key: "your-prod-api-key"
        )
        #endif
    }

    var body: some Scene {
        WindowGroup {
            FeedbackListView()
        }
    }
}

Auto-Detection Configuration

Alternatively, use configureAuto to automatically detect the build environment and select the appropriate API key.

MyApp.swift
import SwiftlyFeedbackKit

@main
struct MyApp: App {
    init() {
        // Auto-detect environment and use appropriate key
        SwiftlyFeedback.configureAuto(keys: EnvironmentAPIKeys(
            debug: "your-dev-key",         // Optional: localhost
            testflight: "your-staging-key",  // Staging server
            production: "your-prod-key"      // App Store
        ))
    }

    var body: some Scene {
        WindowGroup {
            FeedbackListView()
        }
    }
}

Configuration

Customize the SDK behavior with various configuration options.

Option Type Default Description
loggingEnabled Bool false Enable debug logging
userEmail String? Default user email for submissions
showVoteEmailField Bool true Show email field when voting
voteNotificationDefaultOptIn Bool false Default value for notification opt-in
allowFeedbackSubmission Bool true Allow users to submit feedback
feedbackSubmissionDisabledMessage String Default message Message shown when submission disabled
enableAutomaticViewTracking Bool true Automatically track view events

Configuration Example

config.swift
// Get shared instance after configuration
let feedback = SwiftlyFeedback.shared

// Enable debug logging
feedback.loggingEnabled = true

// Set default user email
feedback.userEmail = "user@example.com"

// Disable feedback submission
feedback.allowFeedbackSubmission = false
feedback.feedbackSubmissionDisabledMessage = "Coming soon!"

// Customize voting behavior
feedback.showVoteEmailField = false
feedback.voteNotificationDefaultOptIn = true

Views

The SDK provides pre-built SwiftUI views that can be easily integrated into your app.

FeedbackListView

Displays a list of all feedback items with voting, filtering, and sorting capabilities.

ContentView.swift
import SwiftUI
import SwiftlyFeedbackKit

struct ContentView: View {
    var body: some View {
        // Use default instance
        FeedbackListView()

        // Or pass a custom instance
        FeedbackListView(swiftlyFeedback: SwiftlyFeedback.shared)
    }
}

SubmitFeedbackView

Form for submitting new feedback with title, description, and category selection.

ContentView.swift
import SwiftUI
import SwiftlyFeedbackKit

struct ContentView: View {
    @State private var showingSubmitForm = false

    var body: some View {
        Button("Submit Feedback") {
            showingSubmitForm = true
        }
        .sheet(isPresented: $showingSubmitForm) {
            SubmitFeedbackView {
                showingSubmitForm = false
            }
        }
    }
}

FeedbackDetailView

Detailed view showing feedback information, voting, and comments.

FeedbackRow.swift
import SwiftUI
import SwiftlyFeedbackKit

struct FeedbackRow: View {
    let feedback: Feedback

    var body: some View {
        NavigationLink {
            FeedbackDetailView(feedback: feedback)
        } label: {
            Text(feedback.title)
        }
    }
}

API Reference

The SwiftlyFeedback class provides methods for interacting with the FeedbackKit API.

Method Description
getFeedback() async throws -> [Feedback] Fetch all feedback items
submitFeedback(...) async throws -> Feedback Submit new feedback
vote(for:email:notifyStatusChange:) async throws -> VoteResult Vote for feedback
removeVote(for:) async throws -> VoteResult Remove vote
getComments(for:) async throws -> [Comment] Get feedback comments
addComment(to:content:) async throws -> Comment Add a comment
view(_:properties:) Track analytics event
api-usage.swift
import SwiftlyFeedbackKit

// Get all feedback
let feedbacks = try await SwiftlyFeedback.shared.getFeedback()

// Submit feedback
let feedback = try await SwiftlyFeedback.shared.submitFeedback(
    title: "Add dark mode",
    description: "Please add dark mode support",
    category: .featureRequest,
    email: "user@example.com"
)

// Vote for feedback
let result = try await SwiftlyFeedback.shared.vote(
    for: feedback.id,
    email: "user@example.com",
    notifyStatusChange: true
)

// Remove vote
try await SwiftlyFeedback.shared.removeVote(for: feedback.id)

// Get comments
let comments = try await SwiftlyFeedback.shared.getComments(for: feedback.id)

// Add comment
let comment = try await SwiftlyFeedback.shared.addComment(
    to: feedback.id,
    content: "Great idea!"
)

// Track analytics event
SwiftlyFeedback.shared.view("onboarding_completed", properties: [
    "steps": 5,
    "duration": 120
])

Models

Feedback

Property Type Description
id UUID Unique identifier
title String Feedback title
description String Detailed description
status FeedbackStatus Current status
category FeedbackCategory Feedback category
voteCount Int Total vote count
hasVoted Bool User voted status
commentCount Int Total comment count
createdAt Date Creation timestamp
updatedAt Date Last update timestamp

Enums

FeedbackStatus

Case Raw Value
pending "pending"
approved "approved"
inProgress "in_progress"
testflight "testflight"
completed "completed"
rejected "rejected"

FeedbackCategory

Case Raw Value
featureRequest "feature_request"
bugReport "bug_report"
improvement "improvement"
other "other"

Comment

Property Type Description
id UUID Unique identifier
content String Comment text
userId String User identifier
isAdmin Bool Admin comment flag
createdAt Date Creation timestamp

VoteResult

Property Type Description
feedbackId UUID Feedback identifier
voteCount Int Updated vote count
hasVoted Bool Current vote status

Theming

Customize the appearance of FeedbackKit views with the SwiftlyFeedbackTheme class.

ThemeColor

Case Description
.default Use system default color
.color(Color) Use specific SwiftUI Color
.adaptive(light: Color, dark: Color) Different colors for light/dark mode

Theme Customization

theme.swift
import SwiftUI
import SwiftlyFeedbackKit

// Access shared theme
let theme = SwiftlyFeedbackTheme.shared

// Customize accent color
theme.accentColor = .color(.purple)

// Use adaptive colors
theme.accentColor = .adaptive(
    light: .blue,
    dark: .cyan
)

// Customize status colors
theme.statusColors.pending = .color(.gray)
theme.statusColors.approved = .color(.blue)
theme.statusColors.inProgress = .color(.orange)
theme.statusColors.completed = .color(.green)

// Customize category colors
theme.categoryColors.featureRequest = .color(.blue)
theme.categoryColors.bugReport = .color(.red)
theme.categoryColors.improvement = .color(.purple)
theme.categoryColors.other = .color(.gray)

Error Handling

The SDK uses the SwiftlyFeedbackError enum for error handling.

Error Description
invalidResponse Invalid server response
badRequest Invalid request parameters
unauthorized Authentication failed
invalidApiKey Invalid or missing API key
notFound Resource not found
conflict Conflicting operation (e.g., duplicate vote)
serverError Internal server error
networkError Network connectivity error
decodingError Failed to decode response
feedbackLimitReached Feedback limit exceeded (upgrade required)

Error Handling Example

error-handling.swift
import SwiftlyFeedbackKit

do {
    let feedbacks = try await SwiftlyFeedback.shared.getFeedback()
    // Process feedbacks
} catch SwiftlyFeedbackError.invalidApiKey {
    print("Invalid API key")
} catch SwiftlyFeedbackError.networkError {
    print("Check your internet connection")
} catch SwiftlyFeedbackError.feedbackLimitReached {
    print("Please upgrade your plan")
} catch SwiftlyFeedbackError.notFound {
    print("Feedback item not found")
} catch SwiftlyFeedbackError.conflict {
    print("You've already voted")
} catch {
    print("An error occurred: \(error.localizedDescription)")
}