> ## Documentation Index
> Fetch the complete documentation index at: https://docs.logbrew.co/llms.txt
> Use this file to discover all available pages before exploring further.

# الإبلاغ عن أعطال iOS: أعطال Apple وحالات التجمّد

> أعدّ الإبلاغ عن أعطال تطبيق iOS، وارفع ملفات dSYM المطابقة، واقرأ تقارير أعطال iOS محلَّلة الرموز من LogBrew.

استخدم سير العمل هذا لالتقاط الأعطال الأصلية (native) وحالات تجمّد الخيط
الرئيسي في تطبيق iOS. يتطلب التقاط التجمّد UIKit. ارفع ملف dSYM المطابق لترى
مواضع المصدر في إطارات المكدّس.

يحفظ التطبيق تقريرًا محليًا عندما يتعطّل. وعند تشغيل لاحق، يستدعي تطبيقك
إعادة الإرسال (replay) لإرسال أدلة التعطّل إلى LogBrew. لا يرسل LogBrew تقرير
Apple الخام.

<Note>
  استخدم LogBrew Swift 0.1.6 أو أحدث. واستخدم LogBrew CLI الأصلي 0.1.24 أو
  أحدث لرفع ملفات بناء التصحيح.
</Note>

<Warning>
  استخدم داخل التطبيق إعدادات استيعاب خاصة بالمشروع. واستخدم تسجيل الدخول
  بالحساب لرفع ملفات البناء وقراءة المشكلات. يمكن أيضًا لمفتاح ملفات البناء
  الخاص بالمشروع أن يرفع من جهاز البناء.
  لا تضع أبدًا رمز وصول الحساب المميز أو مفتاح ملفات البناء داخل التطبيق.
</Warning>

## خطّط لحدود الالتقاط

افحص متى يستطيع تطبيقك إعادة إرسال كل نوع من أنواع الأعطال.

| العطل | نتيجة الالتقاط | وقت التسليم |
| - | - | - |
| تعطّل Apple قاتل | حدث تعطّل أصلي غير معالَج | عند تشغيل لاحق للتطبيق |
| تجمّد في الخيط الرئيسي تعافى منه التطبيق | حدث تجمّد معالَج | عند إعادة الإرسال بعد التعافي |
| تجمّد تبعه إنهاء العملية | حدث تجمّد غير معالَج | عند تشغيل لاحق للتطبيق |

اضبط قيمة الإصدار قبل البناء. يجب أن تحدد إصدار التطبيق ورقم البناء. استخدم
القيمة نفسها في الـ SDK ورفع dSYM وعامل تصفية المشكلات.

لا ترفق بيانات المستخدم أو نصوص الطلبات أو الترويسات ببيانات التعطّل الوصفية.

## أضف منتج الأعطال

أولًا، [أعدّ القياس عن بُعد عبر SDK](/ar/guides/sdk-ingestion) لتطبيقك. تستخدم
إعادة الإرسال `client` و`transport` نفسيهما.

أضف الـ SDK العام عبر Swift Package Manager.

```swift theme={null}
.package(
    url: "https://github.com/LogBrewCo/sdk.git",
    from: "0.1.6"
)
```

أضف المنتج `LogBrew` لإرسال بيانات القياس عن بُعد. وأضف `LogBrewCrash` فقط
عندما يفعّل التطبيق صراحةً التقاط الأعطال الأصلية أو التجمّد.

يدعم تكامل الالتقاط iOS 15 أو أحدث. احتفظ بكائن التقاط واحد يملكه التطبيق،
لأن معالجات الأعطال القاتلة الأصلية تعمل على مستوى العملية كلها.

## اضبط هوية واحدة مطابقة تمامًا

استخدم المشروع والإصدار والبيئة والخدمة نفسها في إعداد وقت التشغيل وفي رفع
ملفات البناء. لا يشتق LogBrew هذه القيم ولا يستبدلها.

```swift theme={null}
import Foundation
import LogBrew
import LogBrewCrash

let applicationSupport = try FileManager.default.url(
    for: .applicationSupportDirectory,
    in: .userDomainMask,
    appropriateFor: nil,
    create: true
)

let identity = try NativeArtifactIdentity(
    projectId: "550e8400-e29b-41d4-a716-446655440000",
    release: "com.example.app@1.2.3+45",
    environment: "production",
    service: "ios-app"
)

let watchdog: NativeHangWatchdogConfiguration? = nil

let crashCapture = NativeCrashCapture(
    configuration: try NativeCrashConfiguration(
        storageDirectory: applicationSupport.appendingPathComponent(
            "LogBrewCrash",
            isDirectory: true
        ),
        artifactIdentity: identity,
        hangWatchdog: watchdog
    )
)

try crashCapture.install()
```

ثبّت كائن الالتقاط على الخيط الرئيسي قبل أن تنشئ واجهة المستخدم الجذرية. أنشئ
المجلد الأب له أولًا. اجعل مجلد التخزين ملكًا للتطبيق وخاصًا به.

يدوّن كائن الالتقاط استثناءات Mach والإشارات (signals) واستثناءات C++
واستثناءات Objective-C. لا يتضمن التقرير المحلي محتويات الذاكرة أو أسماء
الطوابير أو سجلات وحدة التحكم.

قد يحتوي تقرير التعطّل المحلي على تفاصيل حساسة عن التطبيق والجهاز. أبقِه خارج
النسخ الاحتياطية السحابية والمجلدات المشتركة. يرسل LogBrew معرّفات UUID
للإطارات والمعماريات والإزاحات بدل التقرير الخام.

يحتوي `NativeCrashConfiguration` على حدّين اختياريين:

| المعامل | القيمة الافتراضية | النطاق | الأثر |
| - | - | - | - |
| `maxStoredReports` | `5` | من 1 إلى 32 | عدد التقارير المحلية التي يحتفظ بها التطبيق. |
| `maxReplayBytes` | 4 MiB | من 1 KiB إلى 16 MiB | تتجاهل إعادة الإرسال أي تقرير أكبر من هذا الحجم. |

القيمة خارج نطاقها تجعل الإعدادات تطرح `crash_invalid_configuration`.

## فعّل التقاط التجمّد

يكون التقاط التجمّد متوقفًا عندما تكون قيمة `watchdog` هي `nil`. لتفعيله،
استبدل تعريف `watchdog` أعلاه قبل أن تستدعي `install()`:

```swift theme={null}
let watchdog = try NativeHangWatchdogConfiguration(
    threshold: 2
)
```

الحد بالثواني، من 1 إلى 30. يتطلب التقاط التجمّد أيضًا `artifactIdentity`.
ومن دونه تطرح الإعدادات `crash_invalid_configuration`.

احتفظ بكائن `crashCapture` واحد طوال عمر العملية. لا يمكن تثبيت كائن التقاط
ثانٍ، إذ يطرح استدعاء `install()` الخاص به `crash_capture_owned`. لتغيير
الحد، استخدم القيمة الجديدة عند التشغيل التالي للتطبيق.

يُعاد إرسال التجمّد الذي تعافى منه التطبيق مع ضبط `crash.handled` على `true`.
ويُعاد إرسال التجمّد الجاري الذي انتهى بإنهاء العملية مع ضبط `crash.handled`
على `false`.

يتضمن الشكلان كلاهما بيانات وصفية رقمية `durationMs`. ويحتفظان بهوية ملف
البناء نفسها التي تستخدمها إطارات الأعطال القاتلة.

يتوقف المراقب (watchdog) مؤقتًا عندما يكون التطبيق غير نشط أو يعمل تحت مصحّح
أخطاء. ويوقف الالتقاط أيضًا أثناء الضغط الحراري الشديد.

قد يجعل الحد القصير العمل العادي على الخيط الرئيسي يظهر في التقارير كأنه
تجمّد. اختبر الحد بإعدادات البناء التي تطلقها. تصف الحالة «معالَج» التعافي،
ولا تجعل المشكلة محلولة. التجمّد المعالَج أوقف استجابة الواجهة مع ذلك، فراجعه أيضًا.

## أعِد الإرسال بعد التشغيل

بعد تثبيت الالتقاط، أعِد إرسال التقارير المعلّقة عبر عميل الـ SDK.

```swift theme={null}
let replay = try crashCapture.replayPendingReports(
    in: client,
    transport: transport
)

print(
    "acknowledged=\(replay.acknowledged) " +
    "discarded=\(replay.discarded) " +
    "pending=\(replay.pending)"
)
```

يجب أن يستدعي تطبيقك إعادة الإرسال. التعافي من التجمّد وحده لا يرسل حدثًا.
استدعِ الدالة نفسها بعد التعافي أو عند التشغيل التالي.

تعالج إعادة الإرسال التقارير الصالحة من الأقدم إلى الأحدث، وتحتفظ بمعرّفات
أحداثها الثابتة. التسليم الفاشل يُبقي تقريره معلّقًا. والتسليم المقبول يحذفه.

تتجاهل إعادة الإرسال التقارير التي لا تستطيع قراءتها والتقارير الأكبر من
`maxReplayBytes`. افحص الأعداد الثلاثة كلها. عدد التقارير المعلّقة الصفري وحده
لا يثبت التسليم.

فعّل التسليم الدائم قبل إعادة الإرسال عندما يجب أن ينجو الطلب الفاشل من إعادة
تشغيل أخرى. لا تستدعِ `purge()` أثناء التعافي المعتاد من مشكلات الشبكة أو
المصادقة.

## ارفع ملف dSYM المطابق

أنشئ أرشيف التطبيق مع تفعيل معلومات التصحيح. احتفظ بملف dSYM من البناء نفسه
الذي يشغّله المستخدمون.

افحص معرّفات UUID للصور (image) فيه.

```bash theme={null}
xcrun dwarfdump --uuid "path/to/App.app.dSYM"
```

تحقّق من ملف البناء محليًا قبل الرفع.

```bash theme={null}
logbrew debug-artifacts upload "path/to/App.app.dSYM" \
  --project "<project UUID>" \
  --release "com.example.app@1.2.3+45" \
  --environment "production" \
  --service "ios-app" \
  --expect-image-uuid "<Mach-O UUID>" \
  --dry-run \
  --json
```

كرّر `--expect-image-uuid` لكل معمارية مطلوبة. يفشل الأمر عندما تختلف مجموعة
معرّفات UUID المكتشفة عن المجموعة المتوقعة.

افحص وصول الحساب. ثم شغّل الأمر نفسه دون `--dry-run`.

```bash theme={null}
logbrew status --json

logbrew debug-artifacts upload "path/to/App.app.dSYM" \
  --project "<project UUID>" \
  --release "com.example.app@1.2.3+45" \
  --environment "production" \
  --service "ios-app" \
  --expect-image-uuid "<Mach-O UUID>" \
  --json
```

يتحقق أمر الرفع من كائنات Apple المدعومة، ويتأكد من كل هوية مرفوعة. ولا يضع
المسارات المحلية أو أسماء الملفات في البيانات الوصفية لـ API.

يعرض الحقل `status` في JSON النتيجة:

| `status` | المعنى |
| - | - |
| `validated` | وجد التشغيل التجريبي الكائنات المتوقعة. لم يُرفع شيء. |
| `verified` | رفع وصول الحساب كل هوية وتأكد منها. |
| `already_present` | لدى LogBrew كل هوية بالفعل. |
| `uploaded` | رفع مفتاح ملفات البناء الخاص بالمشروع الملفات. لم يستطع CLI التأكد منها. |

يمكن لجهاز البناء أن يرفع باستخدام مفتاح ملفات البناء الخاص بالمشروع في
`LOGBREW_TOKEN` بدل وصول الحساب. أنشئ المفتاح كما في
[إنشاء مفتاح ملفات البناء](/ar/guides/source-maps#create-an-artifact-key).
يعرض هذا الرفع `uploaded`. تأكد من كل هوية لاحقًا باستخدام وصول الحساب:

```bash theme={null}
logbrew debug-artifacts lookup \
  --project "<project UUID>" \
  --release "com.example.app@1.2.3+45" \
  --environment "production" \
  --service "ios-app" \
  --image-uuid "<Mach-O UUID>" \
  --architecture arm64 \
  --json
```

`status: "found"` يؤكد وجود ملف البناء. و`status: "missing"` يعني أن LogBrew
ليس لديه ملف بناء لتلك الهوية.

تعتمد المطابقة على UUID الصورة وهوية ملف البناء الكاملة، لا على اسم ملف
المصدر. قد تختلف معرّفات UUID عند إعادة بناء المصدر نفسه. ارفع حزمة dSYM
المطابقة تمامًا، لا مجلد البناء كله.

## تحقّق من القراءة المستضافة

صفِّ قائمة المشكلات بنطاق وقت التشغيل نفسه. يختار هذا المثال المشكلات
`unresolved`. لا تظهر المشكلة المحلولة أو المؤرشفة.

```bash theme={null}
logbrew read issues \
  --project "<project UUID>" \
  --release "com.example.app@1.2.3+45" \
  --environment "production" \
  --service "ios-app" \
  --status "unresolved" \
  --since "24h" \
  --json
```

تحدد استجابة القائمة المشكلة المجمّعة. اقرأ تفاصيلها لتطلب تحليل الإطارات على
الخادم المستضاف.

```bash theme={null}
logbrew read issue "<issue UUID>" --json
```

يضيف ملف البناء المطابق كائن `symbolication`. يعرض هذا المثال حقولًا مختارة من
مشكلة فيها إطار محلَّل، لا الاستجابة الكاملة.

```json theme={null}
{
  "severity": "critical",
  "attributes": {
    "metadata": {
      "crash.replayed": true
    }
  },
  "symbolication": {
    "status": "resolved",
    "frames": [
      {
        "index": 0,
        "status": "resolved",
        "resolved": {
          "source": "AppRuntime.swift",
          "line": 42,
          "column": 1,
          "name": "terminateForCrash()"
        }
      }
    ]
  }
}
```

## اقرأ أدلة التعطّل

لكل إطار حقل `status` خاص به. يستخدم الحقل `symbolication.status` القيم
نفسها:

| `status` | المعنى |
| - | - |
| `resolved` | حلّل ملف بناء مطابق الإطار. يحتوي `resolved` على المصدر أو السطر أو العمود أو اسم الدالة الذي يوفره ملف البناء. |
| `artifact_not_found` | لا يوجد ملف بناء مرفوع يطابق هوية الحدث وUUID الصورة. |
| `source_not_resolved` | يوجد ملف بناء مطابق، لكنه لم يحلّل هذا الإطار. |
| `invalid_metadata` | البيانات الوصفية لملف البناء في الحدث ناقصة أو غير متسقة. |
| `unavailable` | لم تكتمل قراءة تحليل الإطار. |

أبقِ الإطار غير المحلَّل غير محلَّل في ملاحظاتك. لا تبلّغ عنه كأنه مكدّس فارغ.

يحلّل LogBrew الإطارات عندما تقرأ المشكلة. يمكن لملف dSYM مرفوع لاحقًا أن
يحلّل إطارات حدث سابق. ولا يمكنه إضافة إطارات لم يلتقطها الحدث.

يضيّق إطار التطبيق نطاق البحث في الشيفرة، لكنه لا يثبت السبب. للاطلاع على
الـ Breadcrumbs وسلسلة الاستثناءات وأدلة التتبّع، اقرأ تحقيق المشكلة:

```bash theme={null}
logbrew investigate issue "<issue UUID>" --json
```

في تلك الاستجابة، الإطار الذي فيه `source: "symbolicated"` جاء من ملف بناء
مرفوع. والإطار الذي فيه `source: "captured"` هو الموضع الذي أرسله التطبيق.
راجع [التحقيق في مشكلة](/ar/guides/investigate-an-issue) لمعرفة حقول الاستجابة.

احتفظ بنطاق المشروع والإصدار والبيئة والخدمة كاملًا في كل قراءة. لا توسّع
بحثًا فاشلًا ليشمل مشاريع أخرى.

## تحقّق من إعداد بيئة الإنتاج

استخدم عطلًا تجريبيًا معتمدًا في البناء المنشور. لا تستخدم أبدًا إجراءً من
عميل محفّزًا. افحص كل بند بالترتيب، وتوقف عند أول فشل:

1. هوية وقت التشغيل تطابق هوية ملف البناء المرفوع.
2. تشغيل لاحق يعيد إرسال حدث واحد مؤكَّد الاستلام، مع صفر تقارير متجاهَلة وصفر
   تقارير معلّقة.
3. تعيد قائمة المشكلات المحددة النطاق المشكلةَ التجريبية بحالة المعالجة المتوقعة.
4. يُحلَّل إطار التطبيق المتوقع.
5. لا يضيف تشغيل نظيف لاحق حدوثًا آخر.

## تعافَ بأمان

| النتيجة | التعافي |
| - | - |
| تفشل مصادقة الرفع | شغّل `logbrew login`، وتأكد من `logbrew status --json`، ثم كرّر الرفع نفسه تمامًا. |
| يفشل التحقق من UUID عند الرفع | اختر ملف dSYM من البناء المنشور، وكرّر التشغيل التجريبي. |
| `artifact_not_found` | تحقّق من هوية الحدث، وارفع ملف dSYM المطابق بالنطاق نفسه. |
| `source_not_resolved` | احتفظ بمعلومات التصحيح الكاملة للبناء، وافحص إعدادات البناء المنشور. |
| `invalid_metadata` | تأكد من استخدام LogBrew Swift 0.1.6 أو أحدث. التقط حدثًا جديدًا بهوية مطابقة تمامًا. |
| `unavailable` | أبقِ المشكلة ظاهرة، وأعد المحاولة لاحقًا لقراءة التفاصيل نفسها بالنطاق نفسه. |
| تبقى إعادة الإرسال معلّقة | صحّح حالة النقل أو المصادقة، ثم أعد تشغيل التطبيق دون حذف التقرير. |
| تبلّغ إعادة الإرسال عن إدخالات متجاهَلة | لا تحسبها مسلَّمة. افحص إعدادات الالتقاط، وأعد إنتاج العطل بحدث تجريبي معتمد جديد. |

للتحقيق العام في المشكلات، استخدم
[التحقيق في مشكلة باستخدام API](/ar/guides/investigate-an-issue).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.