> For the complete documentation index, see [llms.txt](https://docs.luciq.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.luciq.ai/ios/setup-luciq-for-ios/setup-crash-reporting/troubleshooting-missing-crashes.md).

# Troubleshooting Missing Crashes

Find out why iOS crashes show in Xcode Organizer but not in Luciq, and fix late SDK start, conflicting crash handlers, and debugger-attached testing.

If crashes appear in Xcode Organizer, App Store Connect, or another tool but are missing from your Luciq dashboard, the cause is usually one of these:

1. Luciq is started too late.
2. Another SDK has taken over crash handling.
3. The app was running with the Xcode debugger attached.

This page explains how to find and fix each cause.

## Why Only One Crash Reporter Works

iOS lets an app have only **one** active handler for each type of crash. When another SDK installs its crash handler after Luciq, it **replaces** the Luciq handler. Luciq only receives the crash if that SDK passes it on to the previous handler. Many SDKs don't, so the crash never reaches Luciq.

This isn't limited to crash reporting tools. Ad and social SDKs such as **Google Mobile Ads** and the **Meta (Facebook) SDK** ship their own crash reporting and install handlers without telling you.

{% hint style="warning" %}

#### One Crash Reporter Only

Keep **one** active crash reporter in your app, and disable crash reporting in every other SDK that has it.
{% endhint %}

## Quick Checklist

* [ ] `Luciq.start` is called at the very start of `application(_:didFinishLaunchingWithOptions:)`.
* [ ] No other crash reporting SDK is active (for example, Firebase Crashlytics).
* [ ] Google Mobile Ads crash reporting is disabled.
* [ ] Meta (Facebook) SDK crash reporting is disabled.
* [ ] Test crashes are triggered **without** the Xcode debugger attached.

## Start Luciq Early

Luciq only captures crashes that happen **after** `Luciq.start` runs. If you start it late, crashes during launch are lost. Common examples of starting too late:

* After a remote config fetch
* After the user logs in
* Inside an `async` task
* Inside a view controller

Call it first in `application(_:didFinishLaunchingWithOptions:)`:

{% tabs %}
{% tab title="Swift" %}
{% code overflow="wrap" %}

```swift
import LuciqSDK

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Start Luciq before anything that can crash
    Luciq.start(withToken: "YOUR-TOKEN-HERE", invocationEvents: [.shake])

    // ...rest of your setup
    return true
}
```

{% endcode %}
{% endtab %}

{% tab title="Objective-C" %}
{% code overflow="wrap" %}

```objectivec
#import <LuciqSDK/LuciqSDK.h>

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Start Luciq before anything that can crash
    [Luciq startWithToken:@"YOUR-TOKEN-HERE" invocationEvents:LCQInvocationEventShake];

    // ...rest of your setup
    return YES;
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

For SwiftUI apps, start Luciq as the first line of your `App` struct's `init()`:

{% code overflow="wrap" %}

```swift
import SwiftUI
import LuciqSDK

@main
struct YourApp: App {
    init() {
        // Start Luciq before any other initialization
        Luciq.start(withToken: "YOUR-TOKEN-HERE", invocationEvents: [.shake])
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
```

{% endcode %}

Don't start Luciq in a view's `init` or `onAppear`. Views are created and recreated throughout the app's lifetime, so anything that crashes before the first view appears is missed.

{% hint style="info" %}

#### Launch Crashes

For crashes that happen during app startup, also enable [Capturing Launch Crashes](/ios/setup-luciq-for-ios/setup-crash-reporting/capturing-launch-crashes.md).
{% endhint %}

## Remove Other Crash Reporting SDKs

If your app also uses a dedicated crash reporter such as **Firebase Crashlytics**, both SDKs compete for the same handlers, and whichever registers last wins.

We recommend removing the other crash reporter from your project.

{% hint style="warning" %}

#### Disabling Collection Isn't Enough

Turning off data collection in another crash reporter (for example, `FirebaseCrashlyticsCollectionEnabled = NO`) may stop it from uploading reports, but it doesn't guarantee the SDK stops installing its handlers. Removing the dependency is the only reliable fix.
{% endhint %}

## Disable Crash Reporting in Third-Party SDKs

Some SDKs that aren't crash reporters still install crash handlers. Disable their crash reporting **before** you start them.

| SDK                 | How to disable crash reporting                |
| ------------------- | --------------------------------------------- |
| Google Mobile Ads   | `MobileAds.shared.disableSDKCrashReporting()` |
| Meta (Facebook) SDK | `CrashHandler.disable()`                      |

### Google Mobile Ads

By default, Google Mobile Ads replaces the app's uncaught exception handler when it starts, and it doesn't forward exceptions to the previous handler. If it starts after Luciq, uncaught exceptions never reach Luciq.

Call `disableSDKCrashReporting()` **before** you start the Google Mobile Ads SDK:

{% tabs %}
{% tab title="Swift" %}
{% code overflow="wrap" %}

```swift
import GoogleMobileAds
import LuciqSDK

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    Luciq.start(withToken: "YOUR-TOKEN-HERE", invocationEvents: [.shake])

    // Disable Google's crash handler before starting the Ads SDK
    MobileAds.shared.disableSDKCrashReporting()
    MobileAds.shared.start(completionHandler: nil)

    return true
}
```

{% endcode %}
{% endtab %}

{% tab title="Objective-C" %}
{% code overflow="wrap" %}

```objectivec
@import GoogleMobileAds;
#import <LuciqSDK/LuciqSDK.h>

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [Luciq startWithToken:@"YOUR-TOKEN-HERE" invocationEvents:LCQInvocationEventShake];

    // Disable Google's crash handler before starting the Ads SDK
    [GADMobileAds.sharedInstance disableSDKCrashReporting];
    [GADMobileAds.sharedInstance startWithCompletionHandler:nil];

    return YES;
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}

#### Older Google Mobile Ads Versions

On Google Mobile Ads SDK versions earlier than 12, the Swift API is `GADMobileAds.sharedInstance().disableSDKCrashReporting()`.
{% endhint %}

### Meta (Facebook) SDK

The Meta SDK installs its own crash handler through `FBSDKCrashHandler`. Disable it at launch, before you initialize the Meta SDK:

{% tabs %}
{% tab title="Swift" %}
{% code overflow="wrap" %}

```swift
import FBSDKCoreKit_Basics

CrashHandler.disable()
```

{% endcode %}
{% endtab %}

{% tab title="Objective-C" %}
{% code overflow="wrap" %}

```objectivec
#import <FBSDKCoreKit_Basics/FBSDKCrashHandler.h>

[FBSDKCrashHandler disable];
```

{% endcode %}
{% endtab %}
{% endtabs %}

For more details, see [FBSDKCrashHandler.h](https://github.com/facebook/facebook-ios-sdk/blob/3870e0153cc791b411d0087d211e9d1aca1b20a9/FBSDKCoreKit_Basics/FBSDKCoreKit_Basics/include/FBSDKCrashHandler.h#L24) in the Meta SDK repository.

### Recommended Startup Order

Putting it together, your `application(_:didFinishLaunchingWithOptions:)` should follow this order:

{% tabs %}
{% tab title="Swift" %}
{% code overflow="wrap" %}

```swift
// 1. (Optional) Enable launch crash capture, before Luciq.start
CrashReporting.enableSendingLaunchCrashesSynchronously()

// 2. Start Luciq
Luciq.start(withToken: "YOUR-TOKEN-HERE", invocationEvents: [.shake])

// 3. Disable crash reporting in third-party SDKs, before they start
CrashHandler.disable()                          // Meta
MobileAds.shared.disableSDKCrashReporting()     // Google Mobile Ads

// 4. Start the other SDKs
MobileAds.shared.start(completionHandler: nil)
ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
```

{% endcode %}
{% endtab %}

{% tab title="Objective-C" %}
{% code overflow="wrap" %}

```objectivec
// 1. (Optional) Enable launch crash capture, before startWithToken:
[LCQCrashReporting enableSendingLaunchCrashesSynchronously];

// 2. Start Luciq
[Luciq startWithToken:@"YOUR-TOKEN-HERE" invocationEvents:LCQInvocationEventShake];

// 3. Disable crash reporting in third-party SDKs, before they start
[FBSDKCrashHandler disable];                              // Meta
[GADMobileAds.sharedInstance disableSDKCrashReporting];   // Google Mobile Ads

// 4. Start the other SDKs
[GADMobileAds.sharedInstance startWithCompletionHandler:nil];
[[FBSDKApplicationDelegate sharedInstance] application:application
                         didFinishLaunchingWithOptions:launchOptions];
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="warning" %}

#### SDKs Without a Disable Option

If an SDK doesn't let you disable its crash reporting, start it **before** Luciq. This way, Luciq registers its handler last and keeps it.
{% endhint %}

### Check Whether Luciq's Crash Reporter Is Active

To confirm that no other SDK replaced Luciq's crash reporter, check `crashReporterState` after all your SDKs have started. It returns `nil` if Luciq hasn't started yet.

{% tabs %}
{% tab title="Swift" %}
{% code overflow="wrap" %}

```swift
if let state = CrashReporting.crashReporterState(), !state.isLuciqCrashReporterActive {
    print("Another SDK replaced Luciq's crash reporter")
}
```

{% endcode %}
{% endtab %}

{% tab title="Objective-C" %}
{% code overflow="wrap" %}

```objectivec
LCQCrashReporterState *state = [LCQCrashReporting crashReporterState];
if (state && !state.isLuciqCrashReporterActive) {
    NSLog(@"Another SDK replaced Luciq's crash reporter");
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

To find out which SDK took over, compare `state.currentHandlers` with `state.luciqHandlers`. Each one lists the signal handler and the uncaught exception handler, including the binary they belong to.

Run this check without the Xcode debugger attached. While debugging, the result doesn't tell you whether crashes will actually be captured.

## Test Without the Xcode Debugger

When your app runs from Xcode with the debugger attached, the debugger catches crashes **before** any in-app crash handler sees them. The app pauses in Xcode and **no crash report is created**. This is expected behavior, not an SDK issue.

To test Crash Reporting:

1. Build and run the app from Xcode.
2. Stop the app in Xcode (**⌘ + .**).
3. Launch the app from the device or simulator home screen.
4. Trigger the crash.
5. Relaunch the app. Luciq sends the crash report on the next launch.

You can also turn off the debugger for your scheme: go to **Edit Scheme** > **Run** > **Info** and uncheck **Debug executable**.

## Verify the Integration

Add a temporary test crash, run the app without the debugger, relaunch it, and check your dashboard. Test both crash types, since each one uses a different handler.

Trigger one of these at a time, relaunching the app in between. Code after the first crash never runs, so putting both in the same place only tests the first one.

### Uncaught Exception

This tests the uncaught exception handler:

{% tabs %}
{% tab title="Swift" %}
{% code overflow="wrap" %}

```swift
NSException(name: .genericException, reason: "Luciq test exception", userInfo: nil).raise()
```

{% endcode %}
{% endtab %}

{% tab title="Objective-C" %}
{% code overflow="wrap" %}

```objectivec
[NSException raise:NSGenericException format:@"Luciq test exception"];
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Signal Crash

This tests the signal handlers:

{% tabs %}
{% tab title="Swift" %}
{% code overflow="wrap" %}

```swift
fatalError("Luciq test crash")
```

{% endcode %}
{% endtab %}

{% tab title="Objective-C" %}
{% code overflow="wrap" %}

```objectivec
__builtin_trap();
```

{% endcode %}
{% endtab %}
{% endtabs %}

If the signal crash shows up but the `NSException` crash doesn't, another SDK is most likely replacing the uncaught exception handler. See [Disable Crash Reporting in Third-Party SDKs](#disable-crash-reporting-in-third-party-sdks).

## Still Missing Crashes?

Contact our support team at <support@luciq.ai> and include:

* Your Luciq SDK version
* The full list of third-party SDKs in your app and their versions
* Your `application(_:didFinishLaunchingWithOptions:)` code, showing the order SDKs are started in
* A sample crash from Xcode Organizer that is missing from Luciq


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.luciq.ai/ios/setup-luciq-for-ios/setup-crash-reporting/troubleshooting-missing-crashes.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
