أخطاء eas submit على iOS وطريقة إصلاحها
بقلم Mehdi Azizi
نُشر في ، 10 د
هل فشل eas submit؟ إليك رسائل EAS وApp Store Connect الحقيقية وسببها وطريقة إصلاحها: ascAppId ومفتاح API واتفاقية Apple وأكواد ITMS.
عندما يفشل eas submit --platform ios، تخبرك الرسالة في أغلب الأحيان أين تبحث. إما أن إعدادات EAS عندك ناقصة، أو أن حساب Apple هو ما يعيق العملية، أو أن Apple ترفض الملف التنفيذي. الحالتان الأوليان تُصلحان في دقائق، دون build جديد. أما الثالثة فتعرفها من كود ITMS، وتتطلب في الغالب build جديدًا.
أنشر تطبيقاتي على iOS، ومنها Solys وTradaZen وNolera، باستخدام Expo وEAS. الرسائل المذكورة هنا منسوخة من الكود المصدري لـ EAS CLI، من مستودع Expo الرسمي على GitHub، وقد راجعته في 3 نوفمبر 2026. منتدى Expo القديم يحيل الآن إلى Discord، لذلك يبقى الكود المصدر الأوثق. للمسار الكامل، من ملف eas.json حتى الإرسال للمراجعة، اقرأ أولًا EAS Submit على iOS: نشر تطبيق Expo على App Store. هنا سنصلح الأعطال.
ماذا يفعل eas submit، وماذا يحتاج
بحسب توثيق Expo، يرسل الأمر ملف .ipa إلى App Store Connect. يظهر الـ build في TestFlight بعد أن تعالجه Apple، وغالبًا يستغرق ذلك 10 إلى 15 دقيقة. الأمر لا يرسل تطبيقك للمراجعة: هذه الخطوة تبقى عليك في App Store Connect.
صفحة Expo الخاصة بالإرسال إلى iOS تذكر ثلاثة متطلبات:
- حساب Apple Developer مدفوع، وهو شرط لأي إرسال إلى App Store؛
- معرّف الحزمة (bundle identifier) في
ios.bundleIdentifier؛ - EAS CLI مثبّت ومتصل بحسابك على Expo.
للإرسال دون أي تفاعل، تضيف الصفحة نفسها إعدادين:
ascAppIdفي ملف التعريفsubmitداخلeas.json، وهو رقم صفحة تطبيقك في App Store Connect؛- مفتاح API لـ App Store Connect، يديره EAS أو توفّره أنت. إنشاؤه ودوره وإلغاؤه مشروحة بالتفصيل في مفتاح API لـ App Store Connect (.p8).
ملف التعريف الأدنى لا يتعدى بضعة أسطر. القيمة وهمية:
{
"submit": {
"production": {
"ios": {
"ascAppId": "1234567890"
}
}
}
}
إذا كان EAS يحتفظ بمفتاح API الخاص بك، فهذا الملف يكفي. وهذا هو الحال في معظم تطبيقاتي.
قراءة الرسالة: ثلاث عائلات من الأخطاء
قبل البحث عن الحل، حدّد اللحظة التي يتوقف فيها الأمر. هذا الجدول هو الشبكة التي أطبّقها عند كل فشل.
| لحظة الفشل | العائلة | build جديد؟ |
|---|---|---|
| قبل أي إرسال | إعدادات EAS | لا |
| الاتصال بـ Apple، إنشاء صفحة التطبيق | حساب Apple | لا |
| بعد الإرسال، كود ITMS-90xxx | ملف تنفيذي مرفوض | في الغالب نعم |
التفاصيل تجدها في صفحة الإرسال، داخل لوحة تحكم Expo. تنصح Expo بقراءة السجلات هناك والبحث عن فقاعة «Build Annotations»، التي تشير إلى أسباب الفشل الشائعة. في الطرفية، يعرض الخيار --verbose سجلات EAS Submit دائمًا، بحسب مرجع EAS CLI.
أخطاء إعدادات EAS
«Set ascAppId in the submit profile (eas.json) or re-run this command in interactive mode.»
شغّلت الأمر مع --non-interactive، في التكامل المستمر مثلًا، وملف التعريف لا يحتوي على ascAppId. عندها يتوقف كود EAS CLI: لا يستطيع أن يسألك، ولا أن ينشئ صفحة التطبيق بدلًا منك.
الحل: انسخ رقم صفحة تطبيقك في ascAppId. تشرح Expo أين تجده: في App Store Connect، افتح تطبيقك ثم App Information. إنه حقل Apple ID تحت General Information، وهو رقم من نحو عشرة أرقام. ليس بريدك الإلكتروني في Apple، وليس معرّف الحزمة.
في Nolera، ومن دون ascAppId، كان الأمر يطلب مني جلسة Apple Developer تنتهي صلاحيتها. منذ أن وضعت الرقم في eas.json، لم يعد الإرسال يطلب أي شيء.
أضف
ascAppIdقبل الـ build، لا بعده. حتى SDK 57، تتضمن البصمة التي تحسبها Expo ملفeas.jsonدائمًا. في Vigie، الذي تتبع نسخة التشغيل فيه سياسةfingerprint، أدت إضافة هذا الرقم بعد build إلى تغيير البصمة: أي تحديث يُنشر بعدها ما كان ليصل أبدًا إلى الـ build المثبّت. منذ SDK 58، يتجاهل الإعداد الافتراضي للبصمة،balanced، ملفeas.json، بحسب سجل إصدارات Expo.
«App Store Connect API Keys cannot be set up in --non-interactive mode.»
ملف التعريف لا يحتوي على مفتاح، وEAS لا يملك أي مفتاح مرتبط بتطبيقك. توضح Expo أن الأمر في الوضع غير التفاعلي لا يستطيع أن يطلب منك مفتاحًا، فيفشل بهذه الرسالة.
لديك حلّان:
- دع EAS ينشئ المفتاح ويحتفظ به. شغّل مرة واحدة
eas credentials --platform iosفي الوضع التفاعلي على جهازك، ودعه يضبط مفتاح API لـ App Store Connect لتطبيقك. - استخدم مفتاحك الخاص في
ascApiKeyPathوascApiKeyIssuerIdوascApiKeyId. بحسب مرجع eas.json، تقبل هذه الحقول الثلاثة متغيرات البيئة، مثل$ASC_API_KEY_PATH.
في تطبيقي الأخير، كان الخيار --auto-submit يريد معرّف Apple لإنشاء مفتاح الإرسال. وضعت الحقول الثلاثة لمفتاحي الخاص في ملف التعريف داخل نسختي المحلية، دون أن أعمل لها commit أبدًا. ثم أرسلت الـ build الجاهز باستخدام --id و--non-interactive.
«EXPO_APPLE_APP_SPECIFIC_PASSWORD must be in the format xxxx-xxxx-xxxx-xxxx, where x is a lowercase letter.»
المتغير يحتوي على شيء غير كلمة مرور خاصة بالتطبيق، وغالبًا هي كلمة مرور Apple نفسها. يتحقق EAS CLI من هذا الشكل قبل أي إرسال.
بحسب مساعدة Apple، تُنشأ كلمة المرور الخاصة بالتطبيق من account.apple.com، في قسم App-Specific Passwords، مع تفعيل المصادقة الثنائية. وتُلغى فور تغييرك كلمة مرور حساب Apple. ترى Expo أن هذه الطريقة أقل أمانًا من مفتاح API، وهو طريقتها الافتراضية والموصى بها.
أخطاء حساب Apple
«… agree to the latest Program License Agreement in your developer account.»
تبدأ الرسالة الكاملة بـ «You currently don't have access to this membership resource». من جهة Apple، قد يحتوي الرد الخام على «Unable to process request - PLA Update available». أما خطوات الإرسال الحديثة في EAS فتعرض غالبًا «A required Apple agreement is missing or has expired».
السبب واحد: حدّثت Apple اتفاقية ولم يوافق عليها أحد. وحده صاحب الحساب، أي Account Holder، يستطيع قبول الاتفاقيات، بحسب جدول الأدوار لدى Apple. يطلب منه كود EAS المرور بصفحة Business في App Store Connect، ثم بحسابه على developer.apple.com إن طلبت Apple ذلك. بعدها أعد تشغيل الأمر. لاتفاقية التطبيقات المدفوعة دليلها الخاص: Paid Apps Agreement في App Store Connect.
«App Store Connect rejected the API authentication credentials.»
ردّت Apple بخطأ 401، NOT_AUTHORIZED. يذكر EAS ثلاثة أسباب: مفتاح لم يعد نشطًا، أو مفتاح من حساب App Store Connect آخر، أو خطأ في Key ID أو محتوى المفتاح أو Issuer ID.
تحقق من المعرّفين في App Store Connect، قائمة Users and Access، تبويب Integrations. بحسب Apple، يظهر Issuer ID أعلى الصفحة، ويظهر Key ID في قائمة المفاتيح النشطة. المفتاح الملغى لا يُعاد تفعيله أبدًا. تعرضه Apple لمدة 30 يومًا تحت Revoked: عليك إنشاء مفتاح جديد.
«App Store Connect app for application identifier … was not found.»
صفحة التطبيق التي يشير إليها ascAppId غير موجودة بالنسبة لمفتاحك. يطلب منك EAS التحقق من هذا الرقم، ومن أن المفتاح يصل فعلًا إلى التطبيق في الحساب الصحيح. بل يعرض بعض التطبيقات الظاهرة بهذا المفتاح. مع أدوات الإرسال الخاصة بـ Apple، تظهر المشكلة نفسها بصيغة «No suitable application records were found».
تتكرر ثلاثة أسباب، اثنان منها مذكوران في هذا النقاش في منتديات Apple:
- صفحة التطبيق غير موجودة. أنشئها في App Store Connect، أو احذف
ascAppIdليُنشئها الأمر. - الرقم من حساب آخر. نسخت
ascAppIdمن فريق آخر أو من مشروع آخر. - المستخدم لا يملك صلاحية الوصول إلى التطبيق. قد يكون App Manager أو Developer مقيّدًا بتطبيقات معينة. أما مفتاح الفريق فـيصل إلى كل تطبيقات الحساب.
«… is not available to team» أو «… is not available to provider»
تظهر هذه الرسالة عندما ينشئ EAS صفحة التطبيق بدلًا منك، لغياب ascAppId. معرّف الحزمة محجوز مسبقًا من فريق آخر. يطلب منك EAS تغييره في إعدادات تطبيقك ثم إعادة المحاولة.
«App name "…" is already taken. Using generated name "…"»
هذا ليس فشلًا. عندما يكون الاسم مأخوذًا على App Store، يضيف EAS ستة أحرف عشوائية ويعيد المحاولة، حتى خمس مرات. ستغيّر اسم الصفحة لاحقًا في App Store Connect. لتتجنب ذلك، املأ appName وlanguage في ملف التعريف قبل أول إرسال: من دون language، تكون اللغة الأساسية en-US.
أخطاء الملف التنفيذي: أكواد ITMS
بعد الإرسال، تعالج Apple الـ build. إذا رفضته، يذكر السجل كودًا أو أكثر من أكواد ITMS. هذه هي الأكواد التي تتعرف عليها خطوة الإرسال في EAS وتشرحها:
| كود ITMS | ما ترفضه Apple | الحل |
|---|---|---|
| 90189 | رقم build مستخدم مسبقًا | autoIncrement |
| 90062, 90186, 90478 | نسخة مغلقة أو تم تجاوزها | رفع version |
| 90683 | عبارة الإذن غائبة | ios.infoPlist |
| 90725 | SDK iOS قديم جدًا | صورة iOS أو SDK Expo |
| 90054, 90055 | حزمة مختلفة عن الصفحة المستهدفة | تصحيح ascAppId |
| 90022, 90023, 90391, 90713 | أيقونات غائبة أو مصرّح عنها بشكل خاطئ | مراجعة الأيقونات |
| 90771 | معرّفات مهام الخلفية غائبة | ios.infoPlist |
ثلاث ملاحظات مأخوذة من هذه الرسائل:
- رقم الـ build فريد لكل نسخة. للكود 90189، يوصي EAS بـ
"autoIncrement": trueفيeas.json. كل شيء مشروح في رقم الـ build والنسخة. - للكود 90725، ينصح EAS باختيار صورة iOS أحدث في
eas.json، والانتقال عند الحاجة إلى SDK من Expo مدعوم. - للكود 90771، ملف Info.plist عندك يصرّح بوضع الخلفية
processing، لكنه لا يحتوي على المفتاحBGTaskSchedulerPermittedIdentifiers.
باستثناء 90054 و90055، حيث يكفي استهداف الصفحة الصحيحة أو build آخر، الحل يمسّ الملف التنفيذي: أعد بناء الـ build ثم أرسله من جديد. لكودين منها دليل خاص: ITMS-90683 مع Expo وITMS-90725.
في نهاية سبتمبر 2026، رُفض build لتطبيق Solys عند التسليم بسبب ITMS-90683. كنت قد حذفت عبارة إذن خاصة بالصور أثناء تنظيف ملف الإعدادات. Solys لا يستخدم الصور، لكن مكتبة في المشروع تستدعي واجهة Photos في iOS. Apple تحلل الملف التنفيذي، لا الاستخدام الفعلي: منذ ذلك الحين لم أعد أحذف هذه العبارات أبدًا.
أما الحالة Missing Compliance فليست خطأ إرسال. ينقصها تصريحك بشأن التشفير، وهو مشروح في دليل النشر باستخدام EAS.
قائمة التحقق قبل كل إرسال
ascAppIdموجود في ملف التعريفsubmit، وأُضيف قبل الـ build.- مفتاح API يديره EAS، أو حقوله الثلاثة تشير إلى ملف
.p8محفوظ خارج المستودع. - وافق Account Holder على آخر الاتفاقيات في App Store Connect.
autoIncrementمفعّل، مع"appVersionSource": "remote"، الذي توصي به Expo منذ EAS CLI 12.- قيمة
versionأعلى من آخر نسخة تمت الموافقة عليها. - كل واجهة API حساسة موجودة في الملف التنفيذي لها عبارة إذن.
- لتطبيق جديد،
appNameوlanguageمعبّآن قبل أول إرسال.
أرسل تطبيقك الأول دون أن تتعطل
الأمر مجرد خطوة. ينطلق Kit iOS من كود البداية الخاص بتطبيقاتي، بما فيه الاشتراكات، ويتبع أربع خطوات حتى App Store، بالسرعة التي تناسبك.
إذا كنت تحضّر لإطلاقك الأول، أجرِ التشخيص المجاني: يخبرك بما يعيقك فعلًا ويرسل لك قائمتي لتجنب رفض Apple. ولصفحة التطبيق ولقطات الشاشة والموافقة، تشرح صفحة نشر تطبيق على App Store كل خطوة.
الأسئلة الشائعة
لماذا يفشل eas submit في التكامل المستمر فقط؟
في وضع --non-interactive، لا يستطيع الأمر أن يسألك عن أي شيء. يحتاج إلى ascAppId في ملف التعريف ومفتاح API مرتبط مسبقًا بالتطبيق، أو حقوله الثلاثة في eas.json. على جهازك، كان سيطرح عليك هذه الأسئلة.
هل يجب إعادة بناء الـ build بعد خطأ في eas submit؟
فقط إذا رفضت Apple الملف التنفيذي بكود ITMS. استثناء: في ITMS-90054 و90055، كان الـ build يستهدف الصفحة الخطأ، ويكفي إرساله إلى الصفحة الصحيحة. أخطاء الإعدادات والحساب تُصلح في eas.json أو في App Store Connect أو في حساب Apple. بعدها ترسل الـ build نفسه، مثلًا باستخدام --latest أو --id.
أين أرى سجلات إرسال EAS Submit؟
في صفحة الإرسال، داخل لوحة تحكم Expo. تنصح Expo بقراءة السجلات هناك وفقاعة «Build Annotations». في الطرفية، أضف --verbose لعرض السجلات دائمًا.
هل يمكن استخدام eas submit بحساب Apple مجاني؟
لا. تشترط Expo حساب Apple Developer مدفوعًا لإرسال تطبيق إلى App Store. الحساب المجاني يتيح لك الاختبار على iPhone الخاص بك، لا استخدام App Store Connect.
ما الدور الذي أعطيه لمفتاح API من أجل eas submit؟
يعطي دليل Expo المفتاح دور Admin. بحسب جدول الأدوار لدى Apple، إرسال الـ builds متاح أيضًا لدوري App Manager وDeveloper. تعمل builds تطبيقاتي على Expo بمفتاح فريق بدور App Manager. وحدهم Account Holder والـ Admins يستطيعون إنشاء مفتاح فريق.
ماذا تعني «Increment Build Number» في EAS؟
رفضت Apple الـ build بالكود ITMS-90189: رقم الـ build هذا موجود مسبقًا لهذه النسخة. فعّل "autoIncrement": true في eas.json، أو ارفع ios.buildNumber، ثم أعد بناء الـ build.

