> For the complete documentation index, see [llms.txt](https://docs.firework.com/firework-for-developers/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.firework.com/firework-for-developers/ios-sdk/crash-symbolication-dsyms-ios.md).

# Crash Symbolication & dSYMs (iOS)

FireworkVideo is distributed as a prebuilt binary `XCFramework`. Because your app does not compile the SDK, Xcode never generates a dSYM for it during your build or archive, and the `FireworkVideo.xcframework` itself does not bundle a `dSYMs/` folder. As a result, crash reporting tools (Embrace, Firebase Crashlytics, Sentry, Datadog, Bugsnag, etc.) will report **"missing dSYM"** for frames inside `FireworkVideo` unless you upload the SDK's dSYM yourself.

This page explains where to find the dSYMs and how to get them into your crash reporting tool.

## Where to find the dSYMs

Every SDK release on GitHub ships a separate `dSYMs-v<version>.zip` asset next to the `.xcframework.zip`:

```
https://github.com/loopsocial/firework_ios_sdk/releases/download/v<version>/dSYMs-v<version>.zip
```

For example, for SDK `1.44.3`:

```
https://github.com/loopsocial/firework_ios_sdk/releases/download/v1.44.3/dSYMs-v1.44.3.zip
```

The zip has the following layout:

```
dSYMs/
├── ios/
│   └── FireworkVideo.framework.dSYM        <- upload this one
└── simulator/
    └── FireworkVideo.framework.dSYM        <- simulator only, not needed for production crashes
```

{% hint style="warning" %}
**The dSYM must match the exact SDK version you ship.** A dSYM is matched to a binary by UUID, so the dSYM for `1.44.2` cannot symbolicate crashes from `1.44.3`. Download the zip whose version matches the version pinned in your `Package.resolved` / `Podfile.lock`, and repeat this whenever you bump the SDK.
{% endhint %}

You can verify the UUIDs match with `dwarfdump`:

```bash
# UUID of the binary you ship
dwarfdump --uuid FireworkVideo.xcframework/ios-arm64/FireworkVideo.framework/FireworkVideo

# UUID of the dSYM
dwarfdump --uuid dSYMs/ios/FireworkVideo.framework.dSYM
```

## Option 1: Upload manually

Download the zip for your SDK version, unzip it, and upload `dSYMs/ios/FireworkVideo.framework.dSYM` using your crash reporting tool's dSYM upload CLI or web UI. Refer to your vendor's documentation, for example:

* **Embrace**: `embrace upload` / dSYM upload endpoint
* **Firebase Crashlytics**: `upload-symbols -gsp GoogleService-Info.plist -p ios <path-to-dSYM>`
* **Sentry**: `sentry-cli debug-files upload <path-to-dSYM>`

This is the quickest way to unblock symbolication for a release that is already live.

## Option 2: Fetch automatically during archive (recommended)

Most crash reporting SDKs install a Run Script build phase that uploads every dSYM found in `$DWARF_DSYM_FOLDER_PATH` when you archive. You can add a script **before** that phase which downloads the matching FireworkVideo dSYM into the same folder, so it is picked up by your existing upload step and stays in sync with the SDK version automatically.

In Xcode, select your app target > **Build Phases** > **+** > **New Run Script Phase**. Rename the phase to **Fetch FireworkVideo dSYM** (double-click the phase title) and paste the following script. Keep it **after** the built-in phases (Compile Sources, Link Binary With Libraries, Copy Bundle Resources — the default position for a new phase) and **above** your crash reporter's dSYM upload phase (e.g. "Embrace Symbol Upload", "Upload Crashlytics dSYMs", "Sentry Upload Debug Symbols"):

```bash
#!/bin/bash
# Downloads the FireworkVideo dSYM matching the SDK version linked into this build
# and places it in DWARF_DSYM_FOLDER_PATH so crash-reporter upload scripts can find it.

set -euo pipefail

# Only needed when this build generates dSYMs (Debug Information Format = "DWARF with dSYM File",
# which is Xcode's default for Release / archive builds).
if [ "${DEBUG_INFORMATION_FORMAT:-}" != "dwarf-with-dsym" ]; then
  echo "FireworkVideo dSYM: skipping, DEBUG_INFORMATION_FORMAT is '${DEBUG_INFORMATION_FORMAT:-}' (no dSYM generated for this build)"
  exit 0
fi

# Locate the FireworkVideo framework that was actually linked into the app.
FRAMEWORK_PLIST=$(find "${BUILT_PRODUCTS_DIR}" -path "*FireworkVideo.framework/Info.plist" -print -quit)
if [ -z "${FRAMEWORK_PLIST}" ]; then
  echo "FireworkVideo dSYM: FireworkVideo.framework not found in ${BUILT_PRODUCTS_DIR}, skipping"
  exit 0
fi

SDK_VERSION=$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "${FRAMEWORK_PLIST}")
DSYM_DEST="${DWARF_DSYM_FOLDER_PATH}/FireworkVideo.framework.dSYM"

if [ -d "${DSYM_DEST}" ]; then
  echo "FireworkVideo dSYM: already present at ${DSYM_DEST}"
  exit 0
fi

ZIP_URL="https://github.com/loopsocial/firework_ios_sdk/releases/download/v${SDK_VERSION}/dSYMs-v${SDK_VERSION}.zip"
TMP_DIR=$(mktemp -d)
trap 'rm -rf "${TMP_DIR}"' EXIT

echo "FireworkVideo dSYM: downloading ${ZIP_URL}"
if ! curl -fsSL "${ZIP_URL}" -o "${TMP_DIR}/dSYMs.zip"; then
  # Do not fail the archive; just surface a warning in Xcode's issue navigator.
  echo "warning: FireworkVideo dSYM: failed to download ${ZIP_URL}. FireworkVideo crashes will not be symbolicated unless you upload the dSYM manually."
  exit 0
fi
unzip -q "${TMP_DIR}/dSYMs.zip" -d "${TMP_DIR}"

mkdir -p "${DWARF_DSYM_FOLDER_PATH}"
cp -R "${TMP_DIR}/dSYMs/ios/FireworkVideo.framework.dSYM" "${DSYM_DEST}"
echo "FireworkVideo dSYM: installed to ${DSYM_DEST}"
```

{% hint style="warning" %}
**Disable User Script Sandboxing.** Xcode 15+ enables `ENABLE_USER_SCRIPT_SANDBOXING` by default for new projects, which blocks this script from reading the build products directory and from accessing the network. In your app target's **Build Settings**, set **User Script Sandboxing** to **No** for every configuration you archive with. Otherwise the archive fails with errors like `Sandbox: find(...) deny(1) file-read-data ...` or `Sandbox: curl(...) deny(1) network-outbound`. Crash reporter upload scripts (Embrace, Crashlytics, Sentry) require the same setting.
{% endhint %}

Notes:

* The script runs only when **Debug Information Format** is set to **DWARF with dSYM File** (`dwarf-with-dsym`) for the current configuration — Xcode's default for Release — so it costs nothing on Debug builds and works with custom configuration names (e.g. `Staging`, `Production`). This is the same setting your crash reporter needs to produce your app's own dSYM.
* Leave **Based on dependency analysis** unchecked and the input/output file lists empty so the script runs on every archive.
* The script reads the SDK version from the `FireworkVideo.framework` that was linked into the build, so it works for both Swift Package Manager and CocoaPods installations and never drifts from the version you actually ship.
* The script targets stable releases only. Pre-release versions (`x.y.z-beta.N`) report their version as `x.y.z` in `Info.plist`, so the download will not find a matching asset; the script then emits a build warning and lets the archive continue. Upload the dSYM manually (Option 1) for beta builds.
* Your build machine (including CI) needs network access to `github.com`. The repository is public, so no token is required.
* If your archive pipeline uploads dSYMs from the `.xcarchive` instead of a build phase (e.g. Fastlane `download_dsyms` / `upload_symbols_to_crashlytics`), point that step at the extracted `dSYMs/ios/FireworkVideo.framework.dSYM` as an additional path.

## Static XCFramework

If you integrate the static variant manually (`FireworkVideo-static-v<version>.xcframework.zip`), no separate dSYM is needed: the static library's code is linked directly into your app binary, so its symbols are included in the dSYM that Xcode generates for your app during archive.

## Reporting a crash to Firework

When reporting a crash inside the SDK to Firework support, please include:

* The exact SDK version (from `Package.resolved` / `Podfile.lock`)
* The full crash report. A fully symbolicated report (including the `FireworkVideo` frames) is ideal. If the `FireworkVideo` frames are still unsymbolicated, also attach the original `.ips` / `.crash` file with the binary images and load addresses preserved, so we can symbolicate those frames with the matching dSYM on our side.
* iOS version and device model
* Reproduction steps, if known
