Skip to content

Commit 40ad70c

Browse files
committed
Merge branch 'mrf/crashlytics-tutorial' into main
2 parents 5665d85 + bfea7e5 commit 40ad70c

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

website/docs/BugsnagTutorial.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Setting Up CrashKiOS with Bugsnag
2+
If you use Bugsnag and an uncaught exception gets thrown from shared Kotlin code running on iOS, the crash report generated
3+
won't be very helpful in determining the cause, see [The Problem](THE_PROBLEM.md) for more details. CrashKiOS was made
4+
to remedy this issue and provide meaningful stack traces for Kotlin crashes.
5+
6+
## Step 1 - Add Bugsnag to Your Apps
7+
First you'll need to set up Bugsnag for your Android and iOS individually. Follow the steps in the [bugsnag docs](https://docs.bugsnag.com/platforms/)
8+
to set up Bugsnag with your Android app the normal way then do the same for your iOS app.
9+
10+
Make sure to force a crash on both apps from non-shared code and ensure the crash shows up on the Bugsnag Console.
11+
If you're testing a crash on an iOS simulator, you'll need to hit run to build your changes, then close and reopen the app. Otherwise,
12+
Xcode will catch and swallow your crash and it won't get reported. You'll also need to reopen the app after crashing it because
13+
crash reports are sent at app startup. You'll also need to make sure you aren't crashing the app at app start which can cause it to
14+
not get reported. Make sure the crash is triggered by some action like a button click. Also don't forget to set up automatic
15+
dSYM uploading, so you can see proper stack traces for Swift code.
16+
17+
## Step 2 - Add CrashKiOS
18+
Once you've verified Bugsnag is working for both platforms, you can add the CrashKiOS dependency to `commonMain` in your
19+
shared module.
20+
```kotlin
21+
val commonMain by sourceSets.getting {
22+
dependencies {
23+
api("co.touchlab.crashkios:bugsnag:x.y.z") // More on why api later
24+
}
25+
}
26+
```
27+
Then disable caching in your `gradle.properties` file. We're currently working to update things to avoid this, for now
28+
we need it to deal with iOS linking issues.
29+
TODO: WHATS THE M1 ONE?
30+
```
31+
kotlin.native.cacheKind.iosX64=none
32+
```
33+
34+
After a Gradle sync, make a call to `enableBugsnag()` somewhere in your startup code for each app. This switches from the
35+
default no-op implementations to real implementations which avoid issues in testing. Depending on how the `cacheKind` issue
36+
above is fixed this may no longer be necessary.
37+
38+
```kotlin
39+
Bugsnag.sendHandledException(Exception("Some exception"))
40+
```
41+
42+
On iOS, there's a few more things to do at startup for Bugsnag to work. These are all wrapped in a helper function `startBugsnag(config: BugsnagConfiguration)`.
43+
Where `config` is a configuration created in Swift for your Bugsnag setup. If you don't need to do any other config for Bugsnag
44+
you can create an empty config like this:
45+
```swift
46+
let config = BugsnagConfiguration.loadConfig()
47+
```
48+
49+
Then, in your shared module's `build.gradle` you can expose the CrashKiOS api to Swift and call `startBugsnag()` directly.
50+
This is why we need to add the CrashKiOS dependency with `api()` rather than `implementation()`
51+
```kotlin
52+
cocoapods {
53+
framework {
54+
export("co.touchlab.crashkios:bugsnag:0.8.1")
55+
}
56+
...
57+
}
58+
```
59+
60+
Now that it's exported, you should be able to call `startBugsnag()` from app startup in Swift:
61+
```swift
62+
let config = BugsnagConfiguration.loadConfig()
63+
BugsnagConfigKt.startBugsnag(config: config)
64+
```
65+
66+
Once this is done, throw an uncaught exception from Kotlin code on iOS. Reminder this needes to happen through user action,
67+
not in startup code, and you need to relaunch the app after building and after crashing to send the report. The crash should show
68+
up on the dashboard and should now have Kotlin line numbers
69+
70+
## Step 3 - Setup Dynamic Linking (Optional)
71+
If you're ok with using static frameworks for your shared code, you're done with setup. If you want to export a dynamic framework then you'll see an error like this:
72+
```
73+
Undefined symbols for architecture x86_64:
74+
"_OBJC_CLASS_$_BugsnagFeatureFlag", referenced from:
75+
objc-class-ref in libco.touchlab.crashkios:bugsnag-cache.a(result.o)
76+
"_OBJC_CLASS_$_BugsnagStackframe", referenced from:
77+
objc-class-ref in libco.touchlab.crashkios:bugsnag-cache.a(result.o)
78+
"_OBJC_CLASS_$_BugsnagError", referenced from:
79+
objc-class-ref in libco.touchlab.crashkios:bugsnag-cache.a(result.o)
80+
"_OBJC_CLASS_$_Bugsnag", referenced from:
81+
objc-class-ref in libco.touchlab.crashkios:bugsnag-cache.a(result.o)
82+
objc-class-ref in libco.touchlab:kermit-bugsnag-cache.a(result.o)
83+
ld: symbol(s) not found for architecture x86_64
84+
```
85+
86+
This is because on iOS only the definitions for Bugsnag are added when comiling the Kotlin code and building the framework. The binary (the actual Bugsnag library) isn't added until later when you build the iOS app. When building a dynamic framework, the Kotlin compile expects to be able to resolve everything, so you'll see the above error because Bugsnag isn't there yet.
87+
88+
To work around this, we need to tell the compiler that these symbols are find and will be there later. Doing it manually is a bit messy so you can just add our gradle plugin to handle it
89+
```kotlin
90+
id("co.touchlab.crashkios.bugsnaglink") version "x.y.z"
91+
```
92+
93+
## Sending Extra Info to Bugsnag
94+
CrashKiOS-bugsnag also provides shared code wrappers for manually sending info to Bugsnag. When there is a crash,
95+
these will show up in with the crash in the dashboard
96+
```kotlin
97+
BugsnagKotlin.logMessage("Some message")
98+
BugsnagKotlin.sendHandledException(Exception("Some exception"))
99+
BugsnagKotlin.sendFatalException(Exception("Some exception"))
100+
BugsnagKotlin.setCustomValue("someKey", "someValue")
101+
```

0 commit comments

Comments
 (0)