B4i Library KSCrash - simple and powerful crash reports framework

KSCrash is an open source crash reports framework: https://github.com/kstenerud/KSCrash

It is simple to use and looks like it works very good.
The app collects the crash reports and tries to send them when the app is started again. There are several ways to send the crash reports, including sending to a http server and sending an email.

The following code uses the email method.

1595924652055.png

The report includes a stack trace with the sub names.

How to use?

1.
B4X:
#AdditionalLib: KSCrash.framework.3
#AdditionalLib: MessageUI.framework
#AdditionalLib: SystemConfiguration.framework
#AdditionalLib: libc++.dylib
#AdditionalLib: libz.dylib

2.
In Process_Globals:
B4X:
Private xui As XUI
Private reporter As NativeObject

3. In Application_Start:
B4X:
#if RELEASE
If App.IsSimulator = False Then
    CreateReporter
    SendReportsIfNeeded
End If
#end if

As you can see in the code above, it will only be activated in release mode on a real device.

4.
B4X:
Sub SendReportsIfNeeded As ResumableSub
    Dim no As NativeObject
    no = no.Initialize("KSCrash").RunMethod("sharedInstance", Null)
    Dim reports As Int = no.GetField("reportCount").AsNumber
    Log($"Number of reports: ${reports}"$)
    'Page1.Title = reports
    If reports > 0 Then
        Sleep(0)
        Dim sf As Object = xui.Msgbox2Async("The app crashed last time it was launched. Please help us improve and send a crash report?", _
            "", "Yes", "No", "", Null)
        Wait For (sf) Msgbox_Result (Result As Int)
        If Result = xui.DialogResponse_Positive Then
            Dim nme As NativeObject = Me
            nme.RunMethod("sendReports:", Array(reporter))
        Else
            no.RunMethod("deleteAllReports", Null)
        End If
    End If
    Return True
End Sub

Sub CreateReporter
    reporter = reporter.Initialize("KSCrashInstallationEmail").RunMethod("sharedInstance", Null)
    Dim recipients As List = Array("[email protected]") '<-------------------------------------------  change!!!!!!!!!!!!!
    reporter.SetField("recipients", recipients)
    reporter.SetField("reportStyle", 1) 'KSCrashEmailReportStyleApple
    reporter.SetField("subject", "Crash Report")
    reporter.SetField("message", "This Is a crash report")
    reporter.SetField("filenameFmt", "crash-report-%d.txt.gz")
    reporter.RunMethod("install", Null)
End Sub

#if OBJC
#import <KSCrash/KSCrashFramework.h>

- (void) sendReports:(KSCrashInstallation*)installation {
[installation sendAllReportsWithCompletion:^(NSArray* reports, BOOL completed, NSError* error)
     {
         if(completed)
         {
             NSLog(@"Sent %d reports", (int)[reports count]);
         }
         else
         {
             NSLog(@"Failed to send reports: %@", error);
         }
     }];
}
#End If

If you are using a local Mac then you need to download the framework and copy it to the libs folder: www.b4x.com/b4i/files/KSCrash.zip

Don't forget to change the email address.

Example of handling the reports programmatically: https://www.b4x.com/android/forum/t...ul-crash-reports-framework.120644/post-842685
 
Last edited:

Sandman

Expert
Licensed User
Longtime User
As you can see in the code above, it will only be activated in release mode on a real device
For development and testing purposes, would it still work as expected if one remove the #if RELEASE?
 

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
A minor documentation update,

you need to define
B4X:
Private reporter as nativeobject
private xui as xui
in the Process_globals
 

Erel

B4X founder
Staff member
Licensed User
Longtime User

CaptKronos

Active Member
Licensed User
Longtime User
Just tested and I received the expected crash report via email.:)
I understand the reports can be configured by modifying the KSCrash.h file. Can anyone offer some guidance on a configuration that would work well for B4i apps?
 

CaptKronos

Active Member
Licensed User
Longtime User
Yes, the default template is very useful. I was just wondering whether any of the other optional settings in KSCrash.h would be relevant to a b4i app.
 

luc-dev

Member
Licensed User
Longtime User
If you are using a local Mac then you need to download the framework and copy it to the libs folder
Hi,
Sorry for the question but could you explain where exactly do we need to copy the library? As you can guess I don't know much about XCode.
 

luc-dev

Member
Licensed User
Longtime User
Thank you Erel,
I tested the crash reporting and it works very well. The log has very helpful information.
I wish you all a nice day
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Untested code:
B4X:
Sub CreateReporter
    reporter = reporter.Initialize("KSCrashInstallationStandard").RunMethod("sharedInstance", Null)
    Dim url As NativeObject
    url = url.Initialize("NSURL").RunMethod("URLWithString:", Array("https://your.link.com"))
    reporter.SetField("url", url)
    reporter.RunMethod("install", Null)
End Sub
 
Last edited:

John Sturt

Active Member
Licensed User
Longtime User
Does this run on a published ios app?
I can not find the answer in any of the docs
Thanks
 
D

Deleted member 103

Guest
Hi Erel,

does the whole thing work if I put it in a class together?
Is there anything where I have to pay attention?

Classe clsCrashReport:
B4X:
'Für crash reports framework
#AdditionalLib: KSCrash.framework.3
#AdditionalLib: MessageUI.framework
#AdditionalLib: SystemConfiguration.framework
#AdditionalLib: libc++.dylib
#AdditionalLib: libz.dylib

Sub Class_Globals
    'Für crash reports framework
    Private xui As XUI
    Private reporter As NativeObject
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
#if RELEASE
    If App.IsSimulator = False Then
        CreateReporter
        SendReportsIfNeeded
    End If
#end if  
End Sub

Sub SendReportsIfNeeded As ResumableSub
    Dim no As NativeObject
    no = no.Initialize("KSCrash").RunMethod("sharedInstance", Null)
    Dim reports As Int = no.GetField("reportCount").AsNumber
    Log($"Number of reports: ${reports}"$)
    'Page1.Title = reports
    If reports > 0 Then
        Sleep(0)
        Dim sf As Object = xui.Msgbox2Async("The app crashed last time it was launched. Please help us improve and send a crash report?", _
            "", "Yes", "No", "", Null)
        Wait For (sf) Msgbox_Result (Result As Int)
        If Result = xui.DialogResponse_Positive Then
            Dim nme As NativeObject = Me
            nme.RunMethod("sendReports:", Array(reporter))
        Else
            no.RunMethod("deleteAllReports", Null)
        End If
    End If
    Return True
End Sub

Sub CreateReporter
    reporter = reporter.Initialize("KSCrashInstallationEmail").RunMethod("sharedInstance", Null)
    Dim recipients As List = Array("[email protected]") '<-------------------------------------------  change!!!!!!!!!!!!!
    reporter.SetField("recipients", recipients)
    reporter.SetField("reportStyle", 1) 'KSCrashEmailReportStyleApple
    reporter.SetField("subject", "Crash Report")
    reporter.SetField("message", "This Is a crash report")
    reporter.SetField("filenameFmt", "crash-report-%d.txt.gz")
    reporter.RunMethod("install", Null)
End Sub

#if OBJC
#import <KSCrash/KSCrashFramework.h>

- (void) sendReports:(KSCrashInstallation*)installation {
[installation sendAllReportsWithCompletion:^(NSArray* reports, BOOL completed, NSError* error)
     {
         if(completed)
         {
             NSLog(@"Sent %d reports", (int)[reports count]);
         }
         else
         {
             NSLog(@"Failed to send reports: %@", error);
         }
     }];
}
#End If
 
Last edited by a moderator:
D

Deleted member 103

Guest
You will need to test it. Better to do exactly as I did in the first post.
I know I can test it.
The problem are these 5 entries because you can not integrate it in the classe.
B4X:
'Für crash reports framework
#AdditionalLib: KSCrash.framework.3
#AdditionalLib: MessageUI.framework
#AdditionalLib: SystemConfiguration.framework
#AdditionalLib: libc++.dylib
#AdditionalLib: libz.dylib
 
D

Deleted member 103

Guest
If you want to create a class and use it in multiple projects then create a b4xlib and set the dependencies in the manifest.txt

Thanks, that's exactly what I wanted to know.
 
Top