Налаштування завантаження dSYM для деобфускації крахів iOS
Firebase Crashlytics показує 0x000000010034a5c8 замість PaymentViewController.swift:142 — і розробник витрачає годину на розуміння того, що насправді обвалилося. dSYM-файли (debug symbol maps) вирішують цю проблему, але їхнє завантаження в crash reporting регулярно ламається з кількох невоч евидних причин.
Чому dSYM не потрапляють в Crashlytics
Найчастіша ситуація: Bitcode був увімкнений, Apple перекомпілювала бінарник на своїх серверах — і dSYM для цієї конкретної збірки живе вже не в Xcode Organizer, а в App Store Connect. Crashlytics отримує застаріли символи з локальної збірки та не може зіставити адреси. Результат — усі краші в production приходять без деобфускації.
Друга проблема — автоматичне завантаження через Run Script не працює при збірці на CI. Скрипт ${PODS_ROOT}/FirebaseCrashlytics/run виконується в Build Phase, але на агенті без keychain Firebase CLI не може аутентифікуватися. Краші починають накопичуватися неденозифікованими з першого ж релізу.
Як ми налаштовуємо завантаження dSYM
Базове налаштування через Run Script
Для проектів без Bitcode та ручного CI достатньо правильно налаштованої Build Phase:
# Build Phase: Run Script
"${PODS_ROOT}/FirebaseCrashlytics/run"
У полі Input Files обов'язково вказати:
${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}
$(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)
Без Input Files Xcode пропускає скрипт при інкрементальних збірках — Crashlytics не отримує нові символи.
Завантаження dSYM з App Store Connect
Коли Bitcode увімкнений (або для App Clips), dSYM потрібно завантажувати окремо:
# Fastlane: download_dsyms + upload_symbols_to_crashlytics
lane :refresh_dsyms do
download_dsyms(
app_identifier: "com.example.app",
version: "2.1.0",
build_number: "210"
)
upload_symbols_to_crashlytics(
dsym_paths: Actions.lane_context[SharedValues::DSYM_PATHS]
)
clean_build_artifacts
end
Цю lane можна запускати за розкладом через CI (наприклад, раз на день після випуску нової збірки в App Store) або як крок після деплою.
Ручне завантаження через Firebase CLI
Якщо Fastlane не використовується:
firebase crashlytics:symbols:upload \
--app=1:123456789:ios:abcdef \
MyApp.app.dSYM.zip
Файл dSYM знаходиться в ~/Library/Developer/Xcode/Archives/ після архівування, або його можна завантажити з Xcode Organizer → Archives → Download Debug Symbols.
Перевірка коректності символів
Після завантаження перевіряємо через Firebase Console: Crashlytics → вибрати краш → переконатися, що стектрейс показує імена методів та рядки кода. Якщо все ще адреси — UUID dSYM не співпадає з UUID бінарника.
Перевірити UUID:
# UUID бінарника
dwarfdump --uuid MyApp.app/MyApp
# UUID dSYM
dwarfdump --uuid MyApp.app.dSYM
Обидва мають співпадати. Розбіжність означає, що завантажено dSYM від іншої збірки.
Інтеграція з Sentry
Для проектів на Sentry замість Firebase процес аналогічний, але через sentry-cli:
sentry-cli upload-dif \
--org my-org \
--project ios-app \
--include-sources \
MyApp.app.dSYM
Прапор --include-sources дозволяє показувати вихідний код прямо в Sentry — зручно для команд без доступу до локального репозиторія під час на-call-дежурства.
Налаштування на CI/CD
На Bitrise, GitHub Actions або GitLab CI завантаження dSYM встраюється в pipeline після кроку архівування:
# GitHub Actions приклад
- name: Upload dSYM to Crashlytics
env:
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
run: |
fastlane run upload_symbols_to_crashlytics \
dsym_path:"./MyApp.app.dSYM.zip" \
gsp_path:"./GoogleService-Info.plist"
FIREBASE_TOKEN отримується через firebase login:ci — токен не закінчується та безпечний для зберігання в секретах CI.
Процес роботи
Аудит поточного налаштування: перевіряємо Build Phase, наявність Input Files, історію завантажень у Firebase Console.
Визначаємо джерело dSYM: локальна збірка або App Store Connect (залежить від наявності Bitcode/App Clip).
Налаштовуємо автоматичне завантаження: Fastlane lane або крок CI після кожного релізного білда.
Верифікуємо: створюємо тестовий краш через fatalError() у Debug-збірці, перевіряємо символізацію в Console.
Орієнтири по строкам
Налаштування для проекту без Bitcode з уже робочим CI — 2–4 години. Якщо потрібно налаштувати регулярне завантаження з App Store Connect та інтеграцію з кількома сервісами crash-reporting — 1 робочий день.







