Skip to content

Example app #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions example/BugsnagExample/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
*.iml
.kotlin
.gradle
**/build/
xcuserdata
!src/**/build/
local.properties
.idea
.DS_Store
captures
.externalNativeBuild
.cxx
*.xcodeproj/*
!*.xcodeproj/project.pbxproj
!*.xcodeproj/xcshareddata/
!*.xcodeproj/project.xcworkspace/
!*.xcworkspace/contents.xcworkspacedata
**/xcshareddata/WorkspaceSettings.xcsettings
8 changes: 8 additions & 0 deletions example/BugsnagExample/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
plugins {
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.androidLibrary) apply false
alias(libs.plugins.composeMultiplatform) apply false
alias(libs.plugins.composeCompiler) apply false
alias(libs.plugins.kotlinMultiplatform) apply false
alias(libs.plugins.bugsnag.gradle) apply false
}
101 changes: 101 additions & 0 deletions example/BugsnagExample/composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig

plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidApplication)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
alias(libs.plugins.bugsnag.gradle)
}

kotlin {
androidTarget {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
}
}

listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64(),
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "ComposeApp"
isStatic = true
}
}

js(IR) {
moduleName = "composeApp"
useEsModules()
browser {
commonWebpackConfig {
mode = KotlinWebpackConfig.Mode.PRODUCTION
}
}
binaries.executable()
}

applyDefaultHierarchyTemplate()

sourceSets {
androidMain.dependencies {
implementation(compose.preview)
implementation(libs.androidx.activity.compose)
}
commonMain.dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview)
implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.lifecycle.runtimeCompose)
implementation(libs.bugsnag.kmp)
}
jsMain.dependencies {
implementation(libs.compose.html)
implementation(npm("@bugsnag/browser", "=${libs.versions.bugsnag.js.get()}"))
}
}
}

android {
namespace = "com.example.bugsnag.kmp.android"
compileSdk = 35
defaultConfig {
applicationId = "com.example.bugsnag.kmp.android"
minSdk = 24
targetSdk = 35
versionCode = 1
versionName = "1.0"
}
buildFeatures {
compose = true
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}

dependencies {
debugImplementation(compose.uiTooling)

implementation(libs.androidx.appcompat)
implementation(libs.bugsnag.android)
implementation(libs.bugsnag.kmp)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:name="com.example.bugsnag.kmp.KmpApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@android:style/Theme.Material.Light.NoActionBar">
<activity
android:exported="true"
android:name="com.example.bugsnag.kmp.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.example.bugsnag.kmp

import android.app.Application
import com.bugsnag.kmp.Configuration

class KmpApplication : Application() {
override fun onCreate() {
super.onCreate()
val config = Configuration(applicationContext, BUGSNAG_API_KEY)
startBugsnag(config)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.example.bugsnag.kmp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background,
) {
App()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#010E44</color>
<color name="colorPrimaryDark">#20212C</color>
<color name="colorAccent">#5BB6CB</color>
<color name="headingColor">#010E44</color>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#010E44</color>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">Bugsnag Example</string>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<resources>

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>

<style name="ButtonTheme" parent="Widget.AppCompat.Button.Colored">
</style>

<style name="header_text">
<item name="android:textSize">18sp</item>
<item name="android:textStyle">bold</item>
<item name="android:gravity">center</item>
<item name="android:textColor">@color/headingColor</item>
</style>

<style name="separator">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">16dp</item>
</style>

</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.example.bugsnag.kmp

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.bugsnag.kmp.Bugsnag
import kotlinx.coroutines.delay

@Composable
fun App() {
var message by remember { mutableStateOf("") }

MaterialTheme {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement
.spacedBy(12.dp),
) {
Text("Bugsnag KMP - Example app")

TextButton(
text = "Throw An Unhandled Exception",
onClick = {
message = "Unhandled Kotlin Exception triggered"
throw RuntimeException("Unhandled Kotlin Exception")
},
)
TextButton(
text = "A Handled Exception",
onClick = {
Bugsnag.notify(RuntimeException("Handled Kotlin Exception"))
message = "Handled Kotlin Exception reported"
},
)

TextButton(
text = "Attach Custom Breadcrumbs",
onClick = {
Bugsnag.leaveBreadcrumb(
"WebAuthFailure",
mapOf("reason" to "incorrect password"),
)
Bugsnag.notify(RuntimeException("Error Report with Breadcrumbs"))
message = "Custom Breadcrumbs attached"
},
)

if (message.isNotEmpty()) {
Text(
text = message,
modifier = Modifier.padding(top = 16.dp),
style = MaterialTheme.typography.bodyLarge,
color = Color.Red,
)
LaunchedEffect(message) {
delay(1500)
message = ""
}
}
}
}
}

@Composable
fun TextButton(
text: String,
onClick: () -> Unit,
) {
Button(
onClick = { onClick() },
modifier = Modifier.fillMaxWidth(),
) {
Text(text)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.example.bugsnag.kmp

const val BUGSNAG_API_KEY = "add_your_bugsnag_api_key_here"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.bugsnag.kmp

import com.bugsnag.kmp.Bugsnag
import com.bugsnag.kmp.Configuration

fun startBugsnag(configuration: Configuration) {
Bugsnag.start(configuration)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.example.bugsnag.kmp

import androidx.compose.ui.window.ComposeUIViewController
import com.bugsnag.kmp.Configuration

@Suppress("FunctionName", "unused")
fun MainViewController() = ComposeUIViewController {
startBugsnag(Configuration(BUGSNAG_API_KEY))
App()
}
Loading