Skip to content

Mobile client crash

In solo development, setting up Firebase Crashlytics for 10 users is not worth it. It’s enough to add a try/catch at the very top of the app — and POST to Notifly:

Application.onCreate
Thread.setDefaultUncaughtExceptionHandler { t, e ->
val sw = StringWriter().also { e.printStackTrace(PrintWriter(it)) }
OkHttpClient().newCall(
Request.Builder()
.url("$NOTIFLY_URL/message?token=$TOKEN")
.post(JSONObject(mapOf(
"title" to "📱 Crash: ${e.javaClass.simpleName}",
"message" to "Build: $VERSION_CODE\nDevice: ${Build.MODEL}\n\n${sw.toString().take(1500)}",
"priority" to 10,
)).toString().toRequestBody("application/json".toMediaType()))
.build()
).execute()
System.exit(2)
}
// iOS / Swift
NSSetUncaughtExceptionHandler { exception in
let body: [String: Any] = [
"title": "📱 iOS crash: \(exception.name.rawValue)",
"message": "Build: \(Bundle.main.infoDictionary?["CFBundleVersion"] ?? "?")\n\n\(exception.callStackSymbols.joined(separator: "\n"))",
"priority": 10,
]
var req = URLRequest(url: URL(string: "\(notiflyURL)/message?token=\(token)")!)
req.httpMethod = "POST"
req.httpBody = try? JSONSerialization.data(withJSONObject: body)
URLSession.shared.dataTask(with: req).resume()
sleep(1)
}

In the push include Build, Device, OS version and the first 30 frames of the stacktrace — that’s almost always enough to understand the issue without the UI.