Skip to main content
Version: Next 🚧

Getting Started

Android​

1. Add the dependency​

Add the Fedo artifact to your build.gradle.kts:

dependencies {
implementation("com.getfedo:sdk-android:0.4.3")
}

The artifact is published to Maven Central, so the default mavenCentral() repository is all you need.

2. Initialize the SDK​

Call Fedo.initialize once, early in your app's startup - typically in Application.onCreate() or your launcher Activity.

class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
Fedo.initialize(applicationContext, apiKey = "...")
}
}
warning

Fedo.initialize must be called before any other SDK method.

3. Set the current user​

Before showing the feedback screen, identify the user:

Fedo.setUserID("user-123") // recommended: call after login
Fedo.setUserDisplayName("Jane Doe") // optional
Fedo.setUserEmail("jane@example.com") // optional
Fedo.setUserProperty("tier", "gold") // optional

Without setUserID, Fedo uses an anonymous user. Call it as soon as you know who the user is: their anonymous feedback, votes and comments move to that ID. On logout, call Fedo.logout(). See User Management for details.

4. Add the feedback UI​

Fedo provides two entry points, depending on the experience you want:

Option A - Full feedback board: FedoFeedbackScreen() renders the complete board (list, details, editor) inside your Compose hierarchy:

@Composable
fun MyScreen() {
FedoFeedbackScreen(
onDismiss = { /* return to previous screen in host app */ }
)
}

Option B - Quick feedback sheet: FedoCreateFeedbackSheet() is a standalone bottom sheet with a title + details form and a Post button. No navigation setup required - ideal as a lightweight "suggest a feature" entry point from a menu or FAB:

@Composable
fun MyScreen() {
var showFeedbackSheet by remember { mutableStateOf(false) }

Button(onClick = { showFeedbackSheet = true }) {
Text("Suggest a feature")
}

if (showFeedbackSheet) {
FedoCreateFeedbackSheet(
onDismiss = { showFeedbackSheet = false }
)
}
}

With FedoFeedbackScreen(), the SDK handles:

  • Feedback list with status filter tabs (All, In review, Planned, In progress, Done, Closed)
  • Creating new feedback via FAB
  • Tapping a feedback item opens details with comments
  • Voting and commenting
  • Swipe-to-refresh

With FedoCreateFeedbackSheet(), the sheet handles:

  • Title + details form with validation
  • Submit state handling
  • Thank-you message + auto-dismiss on success

Integration example​

5. Build and run​

Run your app. You should see the feedback board rendered inside the composable slot you placed FedoFeedbackScreen() in (or the sheet when you trigger FedoCreateFeedbackSheet()).


iOS​

1. Add the package​

The SDK ships as a Swift package. In Xcode: File → Add Package Dependencies, then paste the repository URL:

https://github.com/getfedo/fedo-ios

Or in Package.swift:

dependencies: [
.package(url: "https://github.com/getfedo/fedo-ios", from: "0.4.0-beta.3")
],
targets: [
.target(
name: "YourApp",
dependencies: [.product(name: "FedoKit", package: "fedo-ios")]
)
]

Requires iOS 16+ and Swift 6.

2. Initialize the SDK​

Call Fedo.initialize once at app launch, before any other SDK method:

import FedoKit

@main
struct MyApp: App {
init() {
Fedo.initialize(
apiKey: "your-api-key",
config: .init(
networkTimeout: 5,
logLevel: .debug
)
)
}

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

config is optional — omit it to use FedoConfig.default (10s timeout, no logging).

3. Set the current user​

Fedo.setUserID("1") // recommended: call after login
Fedo.setUserEmail("whatever@gmail.com") // optional
Fedo.setUserDisplayName("Someone") // optional
Fedo.setUserProperty("key", value: "some-value") // optional

Call Fedo.logout() on sign-out to clear the session and start a fresh anonymous user. See User Management.

4. Add the feedback UI​

Option A — Full feedback board: FedoFeedbackView() is a SwiftUI view holding the whole flow (list, details, comments, editor). It pushes onto the enclosing NavigationStack:

NavigationLink("Feedbacks List") {
FedoFeedbackView()
}

To present it modally, wrap it in its own NavigationStack:

.sheet(isPresented: $showFeedbacks) {
NavigationStack {
FedoFeedbackView()
}
}

Option B — Quick feedback sheet: the .presentFedoCreateFeedback(isPresented:) modifier shows a submission-only sheet (title + details form), driven by a Bool binding like SwiftUI's own sheet:

struct SettingsView: View {
@State private var showFeedbackSheet = false

var body: some View {
Button("Suggest a feature") {
showFeedbackSheet = true
}
.presentFedoCreateFeedback(isPresented: $showFeedbackSheet)
}
}

The binding flips back to false on swipe-down, close button, or auto-dismiss after a successful submit.

info

If Fedo.initialize was not called, the UI shows a "Fedo not initialized" placeholder and every other SDK call is a silent no-op.

5. Build and run​

Run on a simulator or device. The board appears wherever you placed FedoFeedbackView(), and the sheet when the binding flips to true.

Troubleshooting​

Feedback appears under a random name. That is the anonymous user. If setUserID is never called, the SDK creates an anonymous identity on first open and caches it on the device. Call setUserID once you know who the user is, and their existing feedback, comments and votes are migrated onto the authenticated user.

A setUser* call had no effect. These calls go through an internal queue and are not retried. A failing operation is skipped and the queue continues with the next one, so a call that fails is silently lost until you make it again. There is no offline support yet. Set logHandler = FedoLogHandler.Logcat in the config to see what the SDK is doing — output is tagged Fedo. On iOS, set logLevel: .debug in FedoConfig. See Configuration.

Back navigation exits the whole feature instead of going up a screen (Android). onDismiss fires only when the user presses back on the root list screen. Back from the editor or the detail screen is handled inside the composable. If your app pops its stack on every back press, you are handling navigation the composable already owns.

setUserID seems to do nothing when called twice. Calling it with the same ID is a no-op by design.

Next steps​