Skip to main content

Features

Freeze detection

A call to LastCrash.applicationInitialized() must be made after your app is initialized in order to track freeze (application not responding or ANR) errors.

The reason this call to LastCrash.applicationInitialized() is required is to starting Freeze monitoring only after everything in your app is initialized/loaded so false positives can be avoided.

Masking

All text that isn't part of the app's localization files will be redacted on device to prevent any user or customer PII from being captured. Ensure that all user interface elements are utilizing localization strings to get the most value out of the recorded crash videos.

SwiftUI masking

In order to mask SwiftUI views copy the LastCrashMasking.swift file into your application.

Add the following overlay to the view you would like to mask:

Image(systemName: "heart.fill")
.imageScale(.large)
.foregroundStyle(.tint)
.overlay(LastCrashMask("MaskedImage"))

Then add the following onPreferenceChange to the container view detect masked views via preferences and the onDisappear block to remove the masked views:

View {
VStack {
// content
}.onPreferenceChange(LastCrashMaskPositionKey.self, perform: lastCrashOnPreferenceChange)
.onDisappear {
LastCrash.removeMaskRect("MaskedImage")
}
}

View based masking

Views can be explicitly masked by passing a View object reference or by view id. An important note: it is your responsibility to manage the masked view lifecycle to add and remove masked views as they are shown on the screen.

A best practice is to add masked views in viewWillAppear of a UIViewController.

// Mask view by UIView object reference
LastCrash.addMaskView(view)

Masked views should be removed in the viewDidDisappear of a UIViewController.

// Remove mask view by UIView object reference
LastCrash.removeMaskView(view)

Rectangle based masking

Sections of the screen can be masked by rectangles relative to the app's container view frame. An important note: it is your responsibility to manage the masked rect lifecycle to add and remove masked rects.

A best practice is to add masked views in viewWillAppear of a UIViewController.

// Mask view by rect
LastCrash.addMaskRect(CGRect(0,0,100,100), maskId: "masked_rect")

Masked views should be removed in the viewDidDisappear of a UIViewController.

// Remove mask rect
LastCrash.removeMaskRect("masked_rect")

Networking

A call to LastCrash.addNetworkTrackingToDefaultSession() must be made to track networking errors and get summarized networking statistics including bytes sent/recieveed and response time.

The call to LastCrash.addNetworkTrackingToDefaultSession() will add support to any usage of the default URLSession URLSession.shared.

If a custom URLSession is used then the URLSessionConfiguration used during creation must have the LastCrashURLProtocol class configured.

let configuration = URLSessionConfiguration.default
configuration.protocolClasses = [LastCrashURLProtocol.self] + configuration.protocolClasses!
let myURLSession = URLSession(configuration: configuration)

Swift

import LastCrash
...
class AppDelegate: UIResponder, UIApplicationDelegate, LastCrashReportSenderDelegate {

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
...
LastCrash.configure("LASTCRASH_API_KEY")
LastCrash.enabledLogging()
LastCrash.setCrashReportSenderDelegate(self)
LastCrash.addNetworkTrackingToDefaultSession()
LastCrash.applicationInitialized()
...
}

func lastCrashReportSenderHandleCrash() {
// logic to handle crash here
LastCrash.sendCrashes()
}

}

Objective-C

AppDelegate.h:

#import <LastCrash/LastCrash.h>
...
@interface AppDelegate : UIResponder <UIApplicationDelegate, LastCrashReportSenderDelegate>

AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[LastCrash configure:@"LASTCRASH_API_KEY"];
[LastCrash enabledLogging];
[LastCrash setCrashReportSenderDelegate:self];
[LastCrash addNetworkTrackingToDefaultSession];
[LastCrash applicationInitialized];
...
}

- (void)lastCrashReportSenderHandleCrash {
// logic here to handle crash
[LastCrash sendCrashes];
}
...