# ITMS-91053: إصلاح Missing API declaration في Expo

> ITMS-91053 يعني أن الـ build يستخدم API تتطلب سببًا دون التصريح به. أضف الفئة ورمز السبب في ios.privacyManifests ثم أعد بناء التطبيق.

الصفحة الأصلية: [ITMS-91053: إصلاح Missing API declaration في Expo](https://devoria.fr/ar/blog/itms-91053-missing-api-declaration-expo)
الكاتب: [Mehdi Azizi](https://devoria.fr/ar/mehdi-azizi)
النشر: 2026-10-25
آخر مراجعة للمحتوى: 2026-10-25


ITMS-91053 فحص آلي من Apple يصلك بالبريد الإلكتروني بعد [تسليم الـ build](https://devoria.fr/ar/blog/eas-submit-ios-publish-expo-app-store). معناه أن كود تطبيقك يستخدم API "تتطلب سببًا" (التفضيلات، تواريخ الملفات، الوقت منذ الإقلاع، مساحة القرص أو لوحات المفاتيح) دون أن يشرح السبب في بيان الخصوصية. **في Expo يتم الإصلاح داخل `ios.privacyManifests`: تضيف الفئة التي ذكرتها Apple، ثم الرمز الذي يصف استخدامك الفعلي، ثم تبني build جديدًا.**

في Solys، تطبيق المنبّه بالألعاب الصغيرة الذي طوّرته، هذه الأسباب مصرَّح بها في إعدادات التطبيق. ستجد هنا تصريحه الحقيقي، والأمر الذي يعرض ما تستخدمه الحزم التي يعتمد عليها مشروعك، والفحص الذي يجب إجراؤه على الملف النهائي قبل الإرسال.

## ما معنى الخطأ ITMS-91053؟

عنوان الرسالة هو "ITMS-91053: Missing API declaration". تقول إن الكود في ملف محدد من الـ build يشير إلى API واحدة أو أكثر تتطلب سببًا. ثم تذكر الفئات المعنية، مثل `NSPrivacyAccessedAPICategoryUserDefaults`.

هذه الـ API لا تطلب أي إذن من المستخدم. لكن يمكن استخدامها للتعرّف على الجهاز، وهو ما تسميه Apple الـ fingerprinting. وهذا ممنوع حتى لو وافق المستخدم على التتبّع. تشرح Apple ذلك في صفحتها عن [الـ API التي تتطلب سببًا](https://developer.apple.com/documentation/bundleresources/describing-use-of-required-reason-api): كل تطبيق وكل SDK يجب أن يصرّح بسبب استخدامها.

الصفحة نفسها تحدد القاعدة: **منذ 1 مايو 2024، لم يعد App Store Connect يقبل تطبيقًا لا يصف هذه الاستخدامات في بيانه.** بعض المطورين قالوا إن هذه الرسالة وصلتهم كمجرد تحذير على build تم قبوله. لا تعتمد على ذلك: تعامل معها كأنها حظر، وأصلحها قبل الإرسال التالي.

مثل باقي أخطاء ITMS، هذا ليس رفضًا من مراجع. لم يفتح أحد تطبيقك: Apple حلّلت الملف التنفيذي.

## بيان الخصوصية في iOS: ملف PrivacyInfo.xcprivacy

بيان الخصوصية ملف اسمه `PrivacyInfo.xcprivacy` يوضع في جذر الـ bundle الخاص بالتطبيق. حسب [توثيق Apple عن الـ privacy manifests](https://developer.apple.com/documentation/bundleresources/privacy-manifest-files)، يصف البيانات المجمّعة والتتبّع والـ API التي تتطلب سببًا. هذه الأخيرة توضع في المصفوفة `NSPrivacyAccessedAPITypes`: عنصر لكل فئة، فيه نوعها وقائمة أسبابها.

النقطة التي توقع الكثيرين: **البيان لا يغطي إلا الـ bundle الخاص به.** Apple تكتب ذلك صراحة: كل ملف تنفيذي أو مكتبة ديناميكية تستخدم هذه الـ API يجب أن يكون لها بيان داخل الـ bundle الخاص بها. بيان تطبيقك لا يغطي framework مضمَّنًا، والـ SDK لا يمكنه الاعتماد على بيان تطبيقك.

لا تخلط بينه وبين جُمل الـ Info.plist التي يطلبها [ITMS-90683](https://devoria.fr/ar/blog/itms-90683-missing-purpose-string-expo). تلك تظهر للمستخدم عند طلب الإذن. أما البيان فلا تقرؤه إلا Apple.

## الفئات الخمس للـ API ورموز أسبابها

الاسم الكامل لكل فئة يبدأ بـ `NSPrivacyAccessedAPICategory`. قائمة الـ API والأسباب موجودة في صفحة المفتاح [NSPrivacyAccessedAPIType](https://developer.apple.com/documentation/bundleresources/app-privacy-configuration/nsprivacyaccessedapitypes/nsprivacyaccessedapitype)، وقد اطّلعت عليها في 15 أكتوبر 2026.

| الفئة           | API نموذجية                  | السبب الشائع |
| --------------- | ---------------------------- | ------------ |
| UserDefaults    | `UserDefaults`               | CA92.1       |
| FileTimestamp   | `creationDate`               | C617.1       |
| SystemBootTime  | `systemUptime`               | 35F9.1       |
| DiskSpace       | `volumeAvailableCapacityKey` | E174.1       |
| ActiveKeyboards | `activeInputModes`           | 54BD.1       |

الرموز التي ستصادفها أكثر من غيرها:

- **CA92.1**: التطبيق يقرأ ويكتب تفضيلاته الخاصة، ولا تصل إليها التطبيقات الأخرى.
- **1C8F.1**: تفضيلات مشتركة مع widget أو extension في نفس الـ App Group.
- **C617.1**: تواريخ أو أحجام ملفات محفوظة داخل حاوية التطبيق.
- **3B52.1**: ملفات اختارها المستخدم، مثلًا من نافذة اختيار المستندات.
- **35F9.1**: قياس الوقت المنقضي بين حدثين في التطبيق، أو تشغيل مؤقّت.
- **E174.1**: التحقق من المساحة الحرة قبل كتابة ملفات، مع أثر يراه المستخدم.
- **85F4.1**: عرض مساحة القرص للمستخدم.

**صرّح بالسبب الذي يطابق استخدامك الفعلي، لا بالسبب الذي يبدو أوسع.** توضّح Apple أن هذه الـ API وبياناتها لا تُستخدم إلا للأسباب المصرَّح بها، وأبدًا للتتبّع. هناك رمزان مخصصان للـ SDK الخارجية: C56D.1 و0A2A.1. لا مكان لهما في بيان تطبيقك.

## التصريح ببيان الخصوصية في Expo

في Expo لا تكتب الملف بنفسك. تصفه تحت `expo.ios.privacyManifests` في app.json أو app.config، والـ prebuild يولّد `PrivacyInfo.xcprivacy`. هذه هي الطريقة الموجودة في [توثيق Expo عن الـ privacy manifests](https://docs.expo.dev/guides/apple-privacy/).

هذا هو المقتطف الحقيقي من إعدادات Solys. المفتاح يحتوي أيضًا على التتبّع والبيانات المجمّعة، وقد حذفتهما هنا:

```json
{
  "expo": {
    "ios": {
      "privacyManifests": {
        "NSPrivacyAccessedAPITypes": [
          {
            "NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryUserDefaults",
            "NSPrivacyAccessedAPITypeReasons": ["CA92.1", "1C8F.1"]
          },
          {
            "NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryFileTimestamp",
            "NSPrivacyAccessedAPITypeReasons": ["C617.1"]
          },
          {
            "NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategorySystemBootTime",
            "NSPrivacyAccessedAPITypeReasons": ["35F9.1"]
          }
        ]
      }
    }
  }
}
```

الرموز CA92.1 وC617.1 و35F9.1 تكرّر ما تصرّح به React Native ووحدات Expo في التطبيق. أما 1C8F.1 فمصدره Solys نفسه: التطبيق يشارك إعدادات مع الـ widget الخاص به عبر App Group.

فخّ يجب أن تعرفه: إذا كان مجلد `ios` مولَّدًا ومتجاهَلًا في git، **فإن ملف `PrivacyInfo.xcprivacy` الذي تكتبه يدويًا في هذا المجلد لن يصل أبدًا إلى الـ build.** فـ EAS يعيد تشغيل الـ prebuild ويولّد المجلد من جديد. لاحظت ذلك في أحد مشاريعي يوم 9 سبتمبر 2026: البيان المكتوب يدويًا اختفى بعد prebuild. يجب أن يكون التصريح داخل الإعدادات.

نقطة أخيرة: البيان جزء من الملف التنفيذي. التحديث عن بُعد لا يغيّره. يجب أن تبني build جديدًا وترسله.

## الـ SDK الخارجية التي تأتي ببيانها الخاص

معظم المكتبات الحديثة توفّر بيانها. حزم Expo التي تستخدم هذه الـ API فيها ملف `PrivacyInfo.xcprivacy` داخل مجلد `ios` الخاص بها، وكذلك React Native. المشكلة تأتي من طريقة ربطها بتطبيقك.

يحذّر توثيق Expo: لا تقرأ Apple بشكل صحيح كل بيانات الحزم المعتمدة عبر CocoaPods والمربوطة ربطًا ثابتًا (static)، وهذه حال حزم Expo. لذلك قد تحتاج إلى نسخ أسبابها في إعدادات تطبيقك.

لتقليل هذا العمل، الإعداد `ios.privacyManifestAggregationEnabled` في [expo-build-properties](https://docs.expo.dev/versions/latest/sdk/build-properties/) يدمج بيانات حزم CocoaPods في ملف واحد. في الـ Podfile الذي يولّده Expo في مشاريعي (SDK 57)، هذا الدمج مفعّل ما لم تعطّله.

للدمج حدود: لا يرى إلا الحزم التي توفّر بيانًا. المكتبة القديمة التي لا تملك بيانًا تبقى غير مرئية. **لذلك اقرأ مسار الملف المذكور في الرسالة**: فهو يخبرك أين تُصلح.

| الملف المذكور          | أين تُصلح              |
| ---------------------- | ---------------------- |
| الملف التنفيذي للتطبيق | `ios.privacyManifests` |
| ملف `.framework`       | حدّث الـ SDK           |
| extension `.appex`     | بيان الـ extension     |

## التحقق قبل الإرسال

يقترح Expo انتظار رسالة Apple بعد الإرسال. هذا يعمل، لكن كل محاولة تكلّفك build. هذه الفحوص الأربعة التي أجريها قبل ذلك.

**1. اعرض ما تصرّح به الحزم التي تعتمد عليها.** من جذر المشروع:

```bash
find node_modules -name PrivacyInfo.xcprivacy -not -path '*/example/*' \
  -exec grep -ho "NSPrivacyAccessedAPICategory[A-Za-z]*" {} + | sort | uniq -c
```

في Solys، يوم 15 أكتوبر 2026، وجد الأمر 13 بيانًا وأربع فئات: تواريخ الملفات، التفضيلات، الوقت منذ الإقلاع ومساحة القرص. كل فئة تظهر هنا يجب أن تجدها في البيان النهائي للتطبيق، أو في بيان الـ framework الذي يستخدمها.

**2. ابحث في الكود الأصلي (native) الخاص بك.** الوحدات التي كتبتها، الـ plugins، الأهداف مثل الـ widget: هذا الكود لن يصرّح به أي SDK بدلًا منك.

```bash
grep -rlE "UserDefaults|systemUptime|mach_absolute_time|creationDate|modificationDate|volumeAvailableCapacity|activeInputModes" \
  --include='*.swift' --include='*.m' --include='*.mm' modules plugins targets
```

عدّل المجلدات حسب مشروعك. في Solys، هذا البحث هو الذي كشف التفضيلات المشتركة عبر App Group، ومن هنا جاء الرمز 1C8F.1.

**3. اقرأ البيان المولَّد.** شغّل `npx expo prebuild -p ios`، ثم افتح `ios/<YourAppName>/PrivacyInfo.xcprivacy`. انتبه: هذا الأمر قد يحذف مجلد `ios` ثم يعيد إنشاءه. إذا عدّلت فيه شيئًا يدويًا، فاعمل على نسخة من المشروع.

**4. افحص الـ build النهائي.** هذا هو الدليل الوحيد الذي يُعتدّ به. نزّل ملف الـ IPA من صفحة الـ build على expo.dev، ثم شغّل على جهاز Mac:

```bash
unzip -q MyApp.ipa -d ipa
find ipa/Payload -name PrivacyInfo.xcprivacy
plutil -p ipa/Payload/*.app/PrivacyInfo.xcprivacy
```

السطر الثاني يعرض كل البيانات المضمَّنة: بيان التطبيق وبيانات الـ frameworks. والسطر الثالث يعرض بيان التطبيق، لتقارنه بقائمة الخطوة 1.

## ما يجب أن يتوافق فيه البيان مع صفحة تطبيقك

البيان لا يعمل وحده. إذا صرّح بتتبّع أو ببيانات مجمّعة، فيجب أن تقول صفحتك في App Store وسياسة الخصوصية الشيء نفسه. أي تعارض بين الثلاثة قد يكلّفك لاحقًا رفضًا من مراجع بشري بموجب [الـ guideline 5.1.1](https://devoria.fr/ar/blog/guideline-5-1-1-app-store-rejection-fix). ستجد تفاصيل ما يجب توحيده في [سياسة الخصوصية لتطبيق](https://devoria.fr/ar/blog/ios-app-privacy-policy-guide).

## أرسل الـ build دون مفاجآت

أخطاء ITMS تُصلح بسرعة عندما تعرف كيف تقرؤها. أما حالات الرفض التي تأتي بعدها فتحتاج إلى نظرة أوسع: الخطوات موجودة في صفحة [تطبيق رفضته Apple](https://devoria.fr/ar/expertise/app-rejected-by-apple)، وأكثر الأسباب شيوعًا في [لماذا ترفض Apple تطبيقًا](https://devoria.fr/ar/blog/apple-app-rejection-reasons-real-cases).

لتتحقق من ملفك قبل الإرسال، يجمع [Apple Review Kit](https://devoria.fr/ar/kits/review-apple) قائمة التحقق الخاصة بي وskills لـ Claude Code تراجع مشروعك. إذا تعثّر الإرسال وأردت رأيًا بشريًا، [احجز ساعة معي](https://devoria.fr/ar/coaching): نراجع مشروعك معًا عبر مكالمة فيديو، على شاشتك. وإذا كنت تحضّر لإطلاقك الأول، [أجرِ التشخيص المجاني](https://devoria.fr/ar/diagnostic): يرتّب لك الخطوات ويرسل لك قائمة التحقق الخاصة بي لتجنّب رفض Apple.

## الأسئلة الشائعة

### هل يمنع ITMS-91053 إرسال الـ build؟

تكتب Apple أنه منذ 1 مايو 2024 لم يعد App Store Connect يقبل التطبيقات التي لا تصف استخدامها لهذه الـ API. ومع ذلك وصلت هذه الرسالة لبعض المطورين على build تم قبوله، كتحذير. في الحالتين، أصلح البيان قبل الـ build التالي.

### أي رمز سبب أختار لـ UserDefaults؟

CA92.1 إذا كان التطبيق يقرأ ويكتب تفضيلاته الخاصة فقط. أضف 1C8F.1 إذا كان يشاركها مع widget أو extension عبر App Group. الرمز C56D.1 مخصّص للـ SDK الخارجية: لا تضعه في بيان تطبيقك.

### هل يجب نسخ بيان كل SDK في app.json؟

ليس بالضرورة. إذا كان دمج البيانات مفعّلًا، فإن بيانات حزم CocoaPods تُجمع عند تثبيت الـ pods. انسخ فئة فقط إذا كانت غائبة عن البيان النهائي، مع السبب الذي يصف الاستخدام الفعلي.

### هل يحتاج الـ widget أو الـ extension إلى بيان خاص به؟

حسب Apple، كل bundle يحتوي على ملف تنفيذي يستخدم هذه الـ API يجب أن يملك بيانه الخاص. الـ extension ملف تنفيذي مستقل في bundle خاص به: بيان التطبيق لا يغطيه.

### هل يمكن إصلاح ITMS-91053 دون بناء build جديد؟

لا. بيان الخصوصية جزء من الملف التنفيذي. أصلح الإعدادات، وابنِ build جديدًا، ثم جرّبه في [TestFlight](https://devoria.fr/ar/blog/testflight-test-iphone-app-before-submission) قبل إرساله للمراجعة.


## مشروعك

[Apple Review Kit](https://devoria.fr/ar/kits/review-apple): قائمة تحقق مراجعة App Store التي أستخدمها، وحالات رفض Apple التي صححتها، وملاحظات للمراجع، ومهارتان في Claude Code تراجعان تطبيقك. 29 €.

[iOS Kit](https://devoria.fr/ar/kits/ios): أنشئ تطبيق iPhone مع Claude Code: الكود الأساسي لتطبيقاتي، والمهارات التي تتحقق من عمله، وحزم Apple Review Kit وApp Store Screenshots Kit وASO Kit. 129,99 €.
