ملاحظات مستقلة: تطوير التطبيق الأصلي رد الفعل

أصدر مؤلف المادة ، التي ننشر ترجمتها ، مؤخرًا أول تطبيق للهاتف المحمول كتبه في React Native. وحدث أن هذا التطبيق كان أيضًا أول مشروع له ، والذي أنشأه كمبرمج مستقل. سيتحدث هنا عما كان عليه مواجهته أثناء العمل - من تهيئة المشروع إلى نشره في متجر التطبيقات و Google Play.



لماذا اخترت العمل الحر؟


في شهر مايو الماضي ، وصلت إلى مشروع مستقل رائع. في ذلك الوقت ، كنت مطورًا متكاملاً في شركة ناشئة في ستوكهولم. كانت هذه أول وظيفة برمجة لدي ، لقد وصلت إلى هناك منذ عام واحد ( هنا أتحدث عن هذا بمزيد من التفصيل).

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

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

قد تتساءل هنا لماذا قد يحاول شخص ما القيام بتطوير الهاتف المحمول بعد عدم العمل كمطور محترف على الويب لمدة عام؟ ألن يكون من الحكمة الاستمرار في اكتساب الخبرة في مكان مختار ، والنمو المهني ، وخلق سيرة ذاتية رائعة؟

أوافق تمامًا على أن هذا سيكون أكثر عقلانية. لكنني "عامل متعدد المحطات" ميئوس منه ، فقد قرر قبل عدة سنوات اتخاذ قرارات مهنية لا تستند إلى استراتيجية معينة ، بل إلى تفضيلاتي الخاصة. قررت أن أفعل ما يجلب لي الفرح. بعبارة أخرى ، تبدو سيرتي الذاتية الآن بحيث لا يمكن إدخالها في حالة غير منتظمة.

بطبيعة الحال ، فإن القيام بما تحب واتباع إستراتيجية مهنية ليست بالضرورة ظواهر متبادلة. في الحقيقة ، لقد أحببت عملي السابق وصاحب العمل. لقد صادفت مشروعًا آخر ، اتضح أن الرغبة فيه كانت أقوى من الرغبة في فعل ما كنت أفعله من قبل.

ما الذي جعل هذا المشروع جذابًا جدًا بالنسبة لي؟ ما الذي جعله أكثر إثارة للاهتمام من العمل على منتج سريع التطور تستخدمه آلاف الشركات ، كجزء من فريق يتكون من أفضل الأشخاص الذين قابلتهم؟ يمكن الإجابة على هذا السؤال بهذه الطريقة: هذه هي الحرية ، هذا هو التحدي الذي منحني الحاجة إلى حل مشكلة صعبة ، وهذه هي الرغبة في تطوير الذات.

لماذا تقرر استخدام React Native؟


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

أرسلت إحدى الوكالات الخطوط العريضة لتصميم التطبيق ، والتي ، بالإضافة إلى البحث غير مرتب ، لم تتطابق أيضًا مع هوية الشركة المنعكسة على موقع العميل. آخر اقترح ارتفاع الأسعار - سواء بالنسبة للتنمية ودعم المشروع. ثالثًا ، على ما يبدو ، أرسل الاقتراح ، حتى دون أن يدرس حقًا متطلبات العميل. كان لدى جميع الوكالات التي قدمت المقترحات شيء واحد مشترك: أنها ستقوم بإنشاء تطبيق باستخدام إطار Cordova المختلط.

لكن هذا ليس كل شيء. على الرغم من أن Cordova أداة مجانية ومفتوحة المصدر تمامًا ، إلا أن إحدى الوكالات حاولت إخفاء معلومات حول التقنية المحددة التي تستخدمها. بدلاً من ذلك ، تحدث ممثلو الوكالة عن نظام أساسي لتطوير التطبيقات المحمولة داخل الشركة تم إنشاؤه داخليًا. يبدو أننا كنا نتحدث عن إضافة صغيرة على Cordova ، تم إنشاؤها فقط لتأمين الحقوق الحصرية بشكل حازم لهذه الوكالة لخدمة التطبيق وجعل عملية النقل المستقبلية الممكنة للعميل إلى مطور آخر صعبة ومكلفة. بشكل عام ، لم تكن المقترحات المعنية مثيرة للإعجاب بشكل خاص.

تجدر الإشارة إلى أنه ليس لدي أي شيء ضد الأطر المختلطة. أستخدم باستمرار التطبيقات التي تعتمد عليها. هذا ، على سبيل المثال ، Gmail و Slack و Atom و Figma. ومع ذلك ، فقد سمعت عن React Native لبعض الوقت ، حول الطريقة التي تسمح لك بها هذه المكتبة بإنشاء تطبيقات محمولة عبر الأنظمة الأساسية باستخدام JavaScript لم تكن مختلطة!

والآن ماذا؟ هل من الضروري ، بطريقة صعبة ، دعم iOS و Android عند تطوير تطبيقات JavaScript الأصلية؟ نشأ هذا السؤال بسبب حقيقة أنه عندما كنت مهتمًا بهذه التطبيقات ، اتضح أن تطبيقات iOS تمت كتابتها باستخدام Objective-C أو Swift ، وأن Java أو Kotlin كانت تستخدم لتطوير تطبيقات Android.

بالطبع ، لا توجد حيل خاصة هنا. لذلك كان لدي سؤال آخر. كيف يمكن أن تسمى تطبيقات رد الفعل الأصلية التطبيقات الأصلية؟ إذا أجبت على هذا السؤال باختصار ، فقد تبين أن الأمر برمته موجود في واجهة برمجة التطبيقات. استغرق الأمر وقتًا طويلاً لفهم هذا أكثر مما أرغب في الاعتراف به ، ولكن الطريقة التي تعمل بها تطبيقات React Native ، التي تسمى الأصلية ، تعمل مع منصات متحركة ، لا تتمثل في إطلاق شفرة JavaScript أو تجميع هذه الشفرة في الكود الأصلي. الشيء هو أن هذه التطبيقات تنفذ طلبات API التي تعرض المكونات الأصلية باستخدام Objective-C على iPhone و Java على Android.

إذا كنت ترغب في الحصول على فهم أعمق لأساسيات React Native - أوصي بهذه الإجابة على Quora ، هذا عرض تقديمي مع React Conf ، وهذه المادة ، التي تحكي عن إصدار React Native.

على الرغم من أنني لم أكن أعرف في ذلك الوقت بالضبط ما كان يحدث في أحشاء تطبيقات React Native ، فقد علمت أن عمل هذه التطبيقات قد تم تقليله إلى تنفيذ الكود الأصلي. كانت هذه حجةي الرئيسية ضد اختيار أحد الحلول المستندة إلى Cordova التي تقدمها الوكالات. اعتقدت أنه إذا كانت الشركة تحتاج إلى تطبيق للهاتف المحمول ، فيجب أن يكون هذا التطبيق محليًا. إذا احتاج شخص ما إلى تطبيق مبني على أساس HTML / CSS / JS ، فمن الأفضل إنفاق المال ببساطة لتحسين إمكانات المحمول لتطبيقه على الويب.

عندما شاركت هذا المنطق مع عميل ، سألني سؤالًا عما إذا كنت أعرف شخصًا يمكنه إنشاء مثل هذا التطبيق. أجبت أنني لا أعرف. ثم سألوني إذا كان بإمكاني القيام بذلك بنفسي. "لا أستطيع ،" أجبت. ومع ذلك ، بحلول ذلك الوقت كنت مهتمًا بالفعل بكل هذا وببساطة لم أستطع المساعدة في تجربة React Native ، مع أخذ مواصفات التطبيق كأساس لتجاربي.

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

مواصفات التطبيق


قبل أن نتعمق في التفاصيل الفنية ، أريد أن أتحدث قليلاً عن نوع التطبيق الذي نتعامل معه.

العميل الذي تم تطوير التطبيق له هو شركة في ستوكهولم ، تعمل في إدارة المكاتب الجماعية. بمعنى آخر ، نحن نتحدث عن المساحات المكتبية التي يمكن أن تستأجرها شركات مختلفة. في الوقت الحالي ، لدى موكلي حوالي 10 مكاتب موجودة يستأجر فيها حوالي 400 شركة مع 1400 موظف مساحة. هؤلاء هم المستأجرون من المكاتب وهم الجمهور المستهدف للتطبيق.


منطقة الترفيه في واحدة من coworking

بعد مناقشة التطبيق المستقبلي مع مدير المشروع ، تمكنت من معرفة بعض متطلبات المشروع:

  • القدرة على تسجيل الدخول ، تسجيل الخروج وإعادة تعيين كلمة المرور. يرجى ملاحظة أن جميع حسابات المستخدمين يتم إنشاؤها من قبل المسؤولين وأن التطبيق لا يدعم التسجيل في النظام. لذلك ، إذا قررت تنزيل هذا التطبيق ، فلن تكون قادرًا على التعامل معه.
  • عرض وتعديل ملف تعريف المستخدم: الاسم ، عنوان البريد الإلكتروني ، كلمة المرور ، الصورة الرمزية.
  • دعم لدفع الإخطارات.
  • القسم الرئيسي ، والذي يمكن للمستخدم من خلاله الاطلاع على أخبار الشركة ككل ، وخاصةً الأخبار المتعلقة بقران العمل المستأجرة من قبل الشركة.
  • قسم المجتمع ، والذي يمكن للمستخدم من خلاله عرض معلومات حول مختلف أنواع العمل ، اتصل بمديريها وشاهد الشركات المشاركة في عملية معينة.
  • قسم المؤتمرات ، والذي يمكنك من خلاله حجز غرف الاجتماعات وإدارة الحجوزات.
  • اختيار القسم ، حيث يمكن للمستخدم العثور على خصومات وعروض حصرية.
  • تحتاج أولاً إلى إنشاء إصدار iOS ، ثم إضافة دعم Android.
  • تطبيق يستند إلى الويب للمسؤول ، والذي يسمح لك بإدارة المعلومات المعروضة في تطبيق React Native. على الرغم من أنني سأتحدث هنا أساسًا عن التطوير الأمامي ، أعتقد أنه سيكون من المناسب الإشارة إلى أن جزء الخادم من تطبيق المسؤول يستند إلى Ruby on Rails و Postgres و Heroku.

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


الإصدار الأول من التطبيق

هل ما زلت تقرأ؟ عظيم ، ثم دعنا ننتقل.

التعلم من الأفضل


تخيل أنك وعدت أصدقائك ببناء منزل لهم. لكنك لا تعرف كيف تفعل ذلك. أنت حقا لا تعرف من أين تبدأ. ما الذي يجب عمله أولاً في مثل هذه الحالة؟ الجواب واضح: ابحث عن شخص يمكنه بناء المنازل والتعلم منه.

بالمعنى الدقيق للكلمة ، هذا هو بالضبط ما حاولت القيام به. وكنت محظوظًا جدًا للعثور على ما تحتاجه بالضبط. لذلك ، بعد بضع ساعات فقط من البحث عن مواد تدريب React Native ، وجدت دورة فيديو من 13 جزءًا لجامعة Harvard React Native على YouTube. تم تخصيص كل محاضرة تستغرق 90-120 دقيقة لموضوع منفصل. وكنتيجة لذلك ، واجهت حوالي 23 ساعة من المواد التدريبية عالية الجودة.

بعد أن وجدت هذه الدورة ، قمت على الفور ، مثل مهووس ، بالدراسة. نتيجةً لذلك ، بعد عدة أسابيع من الدروس التي أمضيتها في المساء وعطلات نهاية الأسبوع ، أنهيت هذه الدورة التدريبية وأسست أساسًا جيدًا للتطبيق.

الآن أستطيع أن أقول أن هذا المسار ، بلا شك ، هو أفضل ما تمكنت من العثور عليه. بالطبع ، لعبت فصول موجزة وجيدة الإعداد دورًا إيجابيًا كبيرًا في المدرسة ، لكن لا يمكنني إلا أن أشير إلى مهارة المعلم. أود أن أصف أسلوب إجراء هذه الفئات بالكلمات التالية: السرعة ، والتطبيق العملي الشديد ، والتركيز. لا ماء ، لا نكت أو قصص غير ذات صلة من الحياة. على عكس ما يكتبه خادمك المتواضع هنا ...

بشكل أو بآخر ، كان هناك شعور بأن الكثير من المعلومات المفيدة كانت مكتظة في كل محاضرة بحيث يستغرق الأمر ضعف الوقت لتقديمها إلى العديد من المعلمين الآخرين. بمعنى آخر ، هذه الدورة تشبه إلى حد كبير جامعة هارفارد CS50 المعروفة.

نتيجةً لذلك ، إذا كنت ترغب في العثور على موطئ قدم لتطبيق React Native الأول الخاص بك ، فإنني أوصي بالتأكيد بهذه الدورة التدريبية لك. على الرغم من هنا تجدر الإشارة إلى ميزة واحدة. تستخدم هذه الدورة مجموعة أدوات المعرض . هذه أداة ممتازة مناسبة لمعظم التطبيقات البسيطة ، والتي تتعامل مع كل أنواع التفاصيل الدقيقة فيما يتعلق بالعمل مع المنصات المحمولة. ولكن إذا كنت مثلي تريد إنشاء أساس لمشروع يمكن ، عاجلاً وليس آجلاً ، أن يتحول إلى تطبيق كبير ومعقد إلى حد ما ، وأنت ، في الوقت نفسه ، تريد حرية تامة في العمل ، فمن الأفضل لك أن تبدأ المشروع عن طريق الرد الأم.

"مورد التدريب" الثاني الذي يمكنني استخدامه هو زملائي. لحسن الحظ ، بدأت الشركة التي عملت فيها أيضًا في تطوير مشروع React Native. على الرغم من أنني لم أشارك في هذا المشروع ، إلا أنني تعلمت الكثير ، فقط أتحدث إلى أولئك الذين عملوا في هذا المشروع وتحليل الكود الخاص بهم.

الآن وبعد أن ناقشنا كل ما يتناسب مع تطوير تطبيقات React Native ، فقد حان الوقت للانتقال إلى المشكلات الفنية.

بيئة التطوير


بعد استخدام فريق من النموذج react-native init MyApp ، قمت بإنشاء أساس التطبيق ، وكانت إحدى المهام الأولى التي واجهتني هي تطوير بيئة تطوير جديدة.

إذا جئت إلى React Native-environment من تطوير الويب المعتاد ، فيجب الإشارة إلى أن الكثير هنا سيبدو مألوفًا لك. بالنسبة لي ، هذا يعني أنني واصلت استخدام Atom كمحرر الشفرة ، و iTerm كمحطة طرفية ، و GitUp كواجهة للعمل مع git. (إذا كان عشاق Vim يقرؤون هذا الآن ، أقترح أن يظل الجميع غير مقتنعين.) ولكن ، بالإضافة إلى الأدوات المذكورة أعلاه ، كنت بحاجة إلى شيء آخر لتطوير تطبيقات React Native.

على سبيل المثال ، كنت بحاجة إلى التعود على محاكي iOS. في حين أن التنفيذ ، من خلال أدوات سطر الأوامر ، لأمر react-native run-ios ، يبدو بسيطاً بشكل خادع ، في بداية استدعاء بسيط لهذا الأمر لم يكن كافياً لكي يعمل المحاكي بشكل صحيح. نظرًا لأن حزم npm الجديدة تمت إضافتها إلى المشروع يوميًا تقريبًا (وفي وقت لاحق ، عدد قليل جدًا من وحدات CocoaPod الأصلية) ، فقد اضطررت ، أقرب بكثير مما أريد ، إلى التعرف على طقوس غير سارة تتمثل في مسح موارد Watchman وذاكرة التخزين المؤقت Haste ، وحذف مجلد node_modules ، إعادة تثبيت الوحدات النمطية وإعادة تعيين ذاكرة التخزين المؤقت للمترو Bundler. لحسن الحظ ، يمكن حل كل هذه المهام باستخدام الأمر التالي:

 watchman watch-del-all && rm -rf tmp/haste-map-react-native-packager && rm -rf node_modules && yarn && npm start --reset-cache 

في 9 من أصل 10 حالات ، سمح مثل هذا "الرقص مع الدف" للمحاكي بالعودة إلى الحياة. لكن في بعض الأحيان ، لم يكن هذا كافياً. ثم اضطررت إلى الخوض في وصف رسائل الخطأ على جيثب وقراءة المناقشات على StackOverflow.

كان السبب الجذري لبعض المشاكل الأخرى هو أنني اعتقدت لفترة طويلة أنه من أجل حل بعض المشاكل ، كان من الضروري تشغيل Xcode. وصدقوني ، سوف تسعى جاهدة للبقاء في IDE بيت الرعب هذا بأقل وقت ممكن.

وكانت قصة مماثلة مع إطلاق المحاكي مع إصدار معين من iPhone. إذا أخبرني أحدهم في وقت سابق أن الأمر أدناه يحل هذه المشكلة مباشرةً من سطر الأوامر ، فربما كنت أعيش قليلاً في الأشهر الأولى من تطوير React.

 react-native run-ios --simulator='iPhone X' 

تتضمن الأمثلة الأخرى لصعوبات التعود على بيئة التطوير الجديدة عملية من ثلاث خطوات لإعداد نسخة إصدار التطبيق (للتنسيب في متجر التطبيقات أو في بعض بيئة التكامل المستمر ، مثل Visual Studio App Center أو Firebase) وعملية الانتقال من إصدار الإصدار إلى الإصدار ، المعدة للتصحيح (لوضع التطوير). ربما يجد الكثيرون أنه من الواضح أنه يمكن إجراء التغييرات اللازمة للمشروع باستخدام أي محرر نصوص. في أي حال ، هذا مجرد مثال على بضعة أشياء صغيرة كان لها تأثير كبير بشكل غير متوقع على سير العمل عند العمل في وضع التطوير.

وأخيرًا ، استغرق الأمر بعض الوقت للتعود على الحاجة إلى التبديل بين تطبيقات macOS المختلفة اللازمة لحل المهام التي أقوم بحلها عادةً باستخدام Chrome وحده ، عند تطوير تطبيقات الويب.

لمشاهدة ما يكتبه كود JavaScript على وحدة التحكم وتحليله ، ولأغراض التصحيح ، خرج HTML / CSS ، التفتت إلى React Native Debugger . من أجل مراقبة حالة التطبيق والإجراءات المقدمة وطلبات واجهة برمجة التطبيقات والردود المستلمة ، استخدمت Reactotron . على الرغم من أنني وجدت كلا هذين التطبيقين مفيدًا للغاية ، إلا أنني لم أستطع إلا أن أفكر في سير العمل المعتاد الذي استخدمته لإنشاء تطبيقات Ember.js ، عندما أتمكن من حل جميع هذه المهام في نفس البيئة التي تم فيها تشغيل تطبيقاتي (باستخدام المكون الإضافي) Ember المفتش لكروم).

ملاحة


يبدو أن تنظيم التنقل / التوجيه مهمة صعبة للغاية لـ React Native. خلال وجود هذا الإطار ، ظهرت العديد من الحلول المختلفة لهذه المشكلة ، ولكن لا يزال هناك شيء يمكن أن يسمى معيار معترف به عالميا. قررت استخدام مكتبة التنقل التفاعلي ، تأثر اختياري بشكل أساسي بحقيقة أنهم تحدثوا عن هذه المكتبة في دورة React Native التي مررت بها ، وكذلك حقيقة استخدام زملائي لها.

إذا استثمرت بعض الوقت في دراسة عميقة بما فيه الكفاية لهذه المشكلة ، يمكنني معرفة ما يلي:

  • يحتوي مشروع تفاعل التنقل على ما يقرب من 15000 نجم على جيثب و 86 قضية لم تحل بعد. يعتمد بالكامل على جافا سكريبت ويتميز بالوثائق الأكثر تفصيلاً بين حلول التنقل التي رأيتها.
  • وسجلت مكتبة الملاحة التفاعلية حوالي 10000 نجمة ، وتبين أن لديها 162 مشكلة لم يتم حلها. ومع ذلك ، فإنه يستخدم ليس فقط JavaScript. للعمل معها تحتاج إلى تحرير الملفات الأصلية.
  • يمتلك مستودع رد فعل الموجه حوالي 35000 نجمًا وقائمة من 55 مشكلة معلقة على GitHub. صحيح أن هذه المؤشرات لا يمكن مقارنتها مباشرة بالمشروعات الأخرى الموضحة هنا ، لأن هذا المستودع يتضمن حزمًا مصممة ليس فقط لـ React Native ، ولكن أيضًا لـ React.
  • يحتوي مشروع الملاحة المحلية على حوالي 3000 نجم و 55 قضية لم يتم حلها. يجب على أولئك الذين يدرسون ويستخدمونها مراعاة أنه لا يزال في مرحلة تجريبية ، وأنه لا يستخدم جافا سكريبت فحسب ، وأنه مدعوم من Airbnb ( قررت هذه الشركة التخلي عن React Native ).

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

بعد العمل مع نظام الملاحة التفاعلي لمدة 9 أشهر تقريبًا ، يجب أن أقول أنه لا يوجد لدي شيء يشكو منه. إذا قارنت هذه المكتبة مع مكتبة router.js المألوفة المستخدمة في Ember.js ، يمكنني القول أن هذا شيء جديد تمامًا.

لقد كان من السهل حقًا التعامل مع الأنواع الرئيسية الثلاثة من أدوات التنقل التفاعلي. هذه هي StackNavigator و TabNavigator و DrawerNavigator . كان من الصعب للغاية فهم كيفية الجمع بين هذه الأدوات من أجل إنشاء نظام التنقل للتطبيق الذي أحتاجه.

على سبيل المثال ، حقيقة أن مكون DrawerNavigator يجب أن يكون العنصر الرئيسي لنظام التنقل (خطوة واحدة أعلى مكون TabNavigation الرئيسي) كانت غير واضحة تمامًا بالنسبة لي. إذا كان من الصعب تخيل ذلك ، فهذه هي الطريقة التي يبدو بها DrawerNavigator في العمل (في تطبيق حقيقي ، كل شيء يعمل بشكل أكثر سلاسة).


DrawerNavigator من رد فعل الملاحة في العمل

كما ترون ، كنت بحاجة إلى فتح شريط التنقل الجانبي بضغطة واحدة على أي شاشة تطبيق.

لقد نظرت إلى الشريط الجانبي على أنه شيء ثانوي مقارنة بشريط التنقل الرئيسي الموجود في أسفل التطبيق. لذلك ، يبدو لي أنه يجب وضع DrawerNavigator في شجرة المسار (كما هو موضح أدناه) إما أسفل BottomTabNavigator الرئيسي ، أو في نفس المستوى مثل هذا العنصر.

ومع ذلك ، بعد أن عانيت كثيرًا ، في محاولة لإجبار الشريط الجانبي على المكان الذي اتضح أنه غير مناسب ، أدركت أنه وفقًا لميزات التنقل DrawerNavigator ، يجب وضع BottomTabNavigator خطوة واحدة فوق BottomTabNavigator ، في جذر شجرة الملاحة. آمل أن يساعد هذا الاكتشاف الخاص بي أحد قراء هذه المواد على توفير الوقت الذي قد يتم إنفاقه في قراءة المستندات والمواد على جيثب.

إليك ما تبدو عليه شجرة التنقل في التطبيق. هنا ، كعنصر أساسي ، MainDraverNavigation استخدام MainDraverNavigation .


شجرة التنقل النهائية للإصدار الأول من التطبيق

قد تتساءل هنا عن سبب StackNavigator لكل من StackNavigator و TabNavigator . لا يمكنك إسقاط طبقة StackNavigator والانتقال مباشرة إلى TabNavigator ؟

الشيء هو ، أنا بحاجة إلى كل TabNavigator عناصر TabNavigator للحصول على اللقب. ها هم.


TabNavigator ، العنوان

هنا ، مرة أخرى ، تخميناتي لا تتوافق مع جهاز التنقل التفاعلي. اعتقدت أن MaterialTopTabNavigator يجب أن يكون مكون تنقل طبيعي تمامًا ، لذلك قررت أن يكون هناك بعض الخيارات المدمجة في إعداداته والتي تسمح لك بتعيين عنوان. كما اتضح ، لم يكن هناك شيء من هذا القبيل ، وهذا هو السبب في أنني اضطررت إلى استخدام StackNavigator كطبقة وسيطة ، ونتيجة لذلك ، مستوى إضافي من التعقيد في البنية التحتية للتطبيق وتسترشد باعتبارات "تجميلية" جميلة.

هذا الافتقار إلى رد فعل الملاحة ، بالإضافة إلى ذلك ، تسبب لي مشكلة أكثر خطورة. على وجه الخصوص ، كانت تتألف من الحاجة إلى تنظيم طي واختفاء صورة الرأس أثناء تمرير المستخدم من خلال قائمة العناصر التي تنظمها FlatList . نظرًا لأن عناوين قسمي Home و Selection تم عرضها داخل نفس StackNavigator مثل قوائم عناصرها ، فلن يكون من الصعب حل هذه المشكلة عن طريق السماح ببساطة بتمرير العنوان مع بقية القائمة.

لكن في حالة قسم المجتمع والمؤتمر ، لم أجد طريقة لتطبيق نفس الحل ، حيث يتم عرض الرؤوس باستخدام عناصر StackNavigator ، ويتم عرض القوائم باستخدام عناصر StackNavigator ، أعلى خطوة واحدة في شجرة التنقل. كنتيجة لذلك ، رفضت تمرير العنوان ، والذي أدخل عدم تجانس غير سارٍ في التطبيق.


التمرير في TabNavigator و StackNavigator

على الرغم من أن المشكلة الموضحة في العنوان في المحاكي الذي يحاكي Iphone X لا تبدو خطيرة ، يمكن أن يشغل العنوان على الشاشة الصغيرة حوالي 20٪ من مساحة الشاشة المتوفرة. إذا كان أي شخص يعرف كيفية حل هذه المشكلة ، اسمحوا لي أن أعرف.

تم الشعور بنفس المشكلة مع TabNavigator أيضًا في قسم الوجهة. كما هو موضح في الشكل التالي ، على اليمين ، أردت أن أضع عنصر TabNavigator آخر في علامة تبويب Coworking Spaces من أجل عرض علامات التبويب الثلاثة الأولى معلومات ، أعضاء وجهات اتصال.

عند العمل مع TabNavigator كان من الصعب وضع عرض شرائح في الجزء العلوي من العنصر دون الحاجة إلى تعقيد القرار وعدم التسبب في الكثير من مشكلات التنقل (المرتبطة أساسًا بخيارات التنقل). لذلك اضطررت إلى اللجوء إلى حزمة JS تدعى رد فعل swiper من أجل العمل مع علامات التبويب الثلاث هذه. تجدر الإشارة إلى أن هذا الحل يناسبني تمامًا إذا كان تطبيقه لن يؤدي إلى رسم متحرك مفاجئ للخطوط التي تؤكد رؤوس علامات التبويب. في أي حال ، لقد اعتبرت أن هذا العيب هو دفعة عادلة للحصول على فرصة لتجنب المشاكل مع نظام الملاحة البديل.


مقارنة TabNavigator من التنقل التفاعلي مع swiper رد الفعل الأصلي (لاحظ الفرق في الرسوم المتحركة للخطوط الذهبية أسفل أسماء علامات التبويب)

فيما يلي الاستنتاجات التي خلصت إليها بعد تطبيق النظام الفرعي للتنقل في التطبيق:

  • هناك العديد من الحلول الموثقة جيدًا لتنظيم التنقل في تطبيقات React Native ، ومن بينها اخترت التنقل التفاعلي. انها تناسب احتياجاتي.
  • تعمل مكتبة تفاعل التنقل على تبسيط بداية العمل في المشروع إلى حد كبير إذا كان المطور لا يعرف الكثير عن كيفية عمل أنظمة التنقل في الأنظمة الأساسية المحمولة.
  • تحتوي مكتبة التفاعل التفاعلي على بعض الميزات غير البديهية (على الأقل لمطور الويب) ، ولكن لا يوجد شيء لا يمكن التحايل عليه ، وإن لم يكن بالطريقة الأكثر فعالية.

شاشة البداية


من خلال تشغيل تطبيق جديد في المحاكي الذي تم إنشاؤه بواسطة أمر react-native init ، وإعادة تحميله باستمرار أثناء إجراء التغييرات عليه ، ستدرك بسرعة كبيرة أن التطبيق يحتاج إلى شاشة البداية الجميلة (يطلق عليها أيضًا "شاشات البداية").

كيفية كتابة شاشة البداية مكتوبة بشكل جيد هنا ، لذلك لن أكرر كلمات مؤلف هذه المادة. سأتحدث فقط عن المشكلة التي واجهتها ، والتي لا يوجد عنها شيء في هذا الدليل. إليك ما تبدو عليه هذه المشكلة:


شاشة البداية مع مشكلة

تظهر هذه المشكلة في حالات نادرة على نظام التشغيل iOS ، ولكن من المحتمل أن يواجهها بعض مستخدمي التطبيق. اكتشفت هذه المشكلة لأول مرة عندما عملت في مكان واحد ، حيث لم أتمكن من استخدام WiFi وتوصيل جهاز الكمبيوتر المحمول الخاص بي بشبكة 4G عبر الهاتف. يعرف مستخدمو IPhone أنه عندما يوزع الهاتف الإنترنت ، يتحول شريط الحالة إلى اللون الأزرق ويصبح أعلى. هذا "كسر" الصورة على شاشة البداية عندما أطلقت التطبيق على الهاتف. نشأت نفس المشكلة عند الاتصال.

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

الأمر بسيط جدًا - ما UIStatusBarHidden سوى إضافة مفتاح UIStatusBarHidden إلى UIStatusBarHidden ، مع تعيين القيمة المنطقية إلى true ، ثم بعد استدعاء SplashScreen.hide() ، قم بتعيين الخاصية hidden لمكون React Native StatusBar إلى StatusBar .

إدارة الدولة


لدي شعور بأنه خلال العامين الأخيرين ، كنت أسمع كل يوم حول أولوية الاتفاق على التكوين ، ومبدأ اتفاقية التكوين الزائد (CoC). لذلك كان في وظيفتي السابقة. وهذا ليس مفاجئًا ، نظرًا لأنه على الخادم ، استخدمنا Ruby on Rails ، وعلى العميل - Ember.js - إطاران ، يتطابق جوهرهما مع مبدأ CoC قدر الإمكان. ظننت أنني أعرف ما يعنيه ذلك ، لكن عملية استكشاف إدارة الدولة في React Native أعطاني فهمًا جديدًا بالكامل لهذا المبدأ.

على الرغم من أنني ، في العديد من التطبيقات البسيطة جدًا ، جربت مكتبة React المتأثرة بهذا المبدأ ، إلا أنني لم أقوم أبدًا بإنشاء شيء كبير بما يكفي بناءً على ذلك من شأنه أن يسمح لي بتقدير مزايا استخدام حاويات الحالة مثل Redux أو MobX . معظم تجربتي في إدارة حالة تطبيقات JS هي مع Ember Data (هذا هو نظام Ember المدمج لإدارة الحالة وتنظيم تخزين البيانات المستمر).

نظرًا لأن مكتبة Redux تبدو لي واحدة من أفضل الحلول لمشكلة إدارة الولاية التي سمعتها منذ سنوات عديدة (والتي تمت مناقشتها في دورة React Native التي غطتها) ، بشكل عام ، لم أكن أتطلع إلى منافسيها . أردت فقط أن أجهز طلبي بأفضل أنظمة إدارة الحالة الحالية وأن أفعل ذلك دون بذل الكثير من الجهد.

في Ember ، 90 ٪ من البنية التحتية للبيانات في أيدي مبرمج جاهزة للاستخدام. لم أكن أظن أن كل شيء في مشروعي الحالي سيكون عكس ذلك تمامًا. كما اتضح ، ليس React فقط ، ولكن Redux ، مكتبة إدارة الدولة الأكثر شعبية ، لا تعطي أي شيء مفيد للمحافظة على الحالة العالمية. هذه المكتبة خفيفة الوزن لدرجة أن المبرمج عليه أن يتحمل 90٪ من المخاوف بشأن العمل مع البيانات داخل التطبيق من أجل إنشاء نظام إدارة حالة لائق.

بعد أن اكتشفت أنني مطور أقل خبرة من الآن ، كان أصعب شيء بالنسبة لي هو التعود على الوظائف الجديدة ومبادئ المناعة. بعد أن أتحمل هذا الكم الهائل من العمل المثير للدهشة الذي يجب القيام به من أجل تنزيل البيانات من الخادم أو إرسالها إلى الخادم ، كل هذا تضافرت في شكل 7 خطوات بسيطة إلى حد ما:

  1. أضف ثلاثة ثوابت إلى الملف مع الثوابت: SOME_ACTION_REQUEST ، SOME_ACTION_FAILED ، SOME_ACTION_SUCCEEDED .
  2. إضافة منشئ الإجراء إلى ملف الإجراء.
  3. قم بمعالجة ثلاثة إجراءات في مخفض مناسب ، وإذا لزم الأمر ، أضف مخفضًا جديدًا إلى النظام وأدرجه في مخفض الجذر.
  4. أضف عمالًا إلى ملحمة مناسبة ، وإذا لزم الأمر ، أضفوا ملحمة جديدة إلى النظام وأدرجوها في ملحمة الجذر (يمكنني استخدام مكتبة redux-saga لمعالجة الإجراءات غير المتزامنة).
  5. أضف وظيفة للتعامل مع أي طلبات API ممكنة.
  6. قم بتعيين البيانات الضرورية من الحالة إلى الخصائص في مكون React المقابل.
  7. SOME_ACTION_REQUEST إجراء SOME_ACTION_REQUEST من مكون SOME_ACTION_REQUEST المقابل.

لدى Redux و reux-saga ، بالطبع ، ميزات أكثر شمولاً ، لكن بالنظر إلى ما أهتم به حاليًا ، فإن الخطوات السبع المذكورة أعلاه هي ما Redux بالنسبة لي.

جلسة


لذلك ، أنشأنا بيئة التطوير لتطبيقات React Native ، وأنشأنا شجرة تنقل ، وأعدنا البنية التحتية لإدارة الدولة. ما الذي سيكون من الجيد القيام به في الخطوة التالية من المشروع؟ بالنسبة لي ، كان إنشاء نظام مصادقة مستخدم إجابة طبيعية تمامًا على هذا السؤال. الآن سنتحدث عن الجلسات.

إذا جئت إلى React Native sphere من تطوير الويب ، فسوف تتعامل مع الجلسات دون صعوبة كبيرة. إذا كنت على دراية بالمفاهيم التي يستند إليها تخزين LocalStorage ، فأنت بحاجة فقط إلى معرفة أنه عند العمل مع React Native ، يجب استبدال الوصول إلى هذا التخزين بمكالمة إلى AsyncStorage . هذا هو مستوى التجريد الذي يسمح لك بتخزين البيانات بتنسيق قيمة المفتاح بين الجلسات. بمعنى آخر ، هنا يمكنك تخزين رمز المصادقة الذي تم إنشاؤه على الخادم ، والذي يتم إرساله إلى العميل بعد قيام المستخدم بتسجيل الدخول بنجاح إلى النظام.

القوائم


إذا تحدثنا عن العمل مع القوائم ، شعرت أنه في React Native تم حل هذه المشكلة جيدًا. بشكل عام ، يمكن الإشارة إلى أن المطور لديه ثلاثة احتمالات. إذا كان يعمل مع قوائم ثابتة ، فإن البيانات المقدمة التي لا تتغير فيها ، فمن المرجح أن يحتوي ScrollView على ما يكفي منها.إذا كنت بحاجة إلى العمل مع قوائم أطول ، والتي ، علاوة على ذلك ، ديناميكية ، فمن الجدير النظر في FlatList . إذا كنا نتحدث عن قوائم أكبر ، والتي ، بالإضافة إلى ذلك ، يمكن تقسيمها إلى أقسام ، فسيكون من المفيد اللجوء إلى SectionList .

أنا ، لقوائم ديناميكية ، واستخدام حصرا FlatList. وعلى الرغم من أنني ، على مستوى حدسي ، مثل هذه القوائم والقدرة على تكوينها ، إلا أنني واجهت العديد من المشاكل عند العمل معهم. الآن سأتحدث عنها.

listDraw قائمة لتحديث محتوياته


FlatList , refreshControl . , , , , . , React Native , . — RefreshControl . , .


RefreshControl

, , , refreshControl , RefreshControl , , . , , :

  • , , . , handleRefresh() .
  • , , « » ( ).

— .

, , , , . , , , GitHub.

, refreshControl onEndReached ( ) fetching . , - , false true , — , , 250 , RefreshControl , .

, setTimeout() fetching 350 . . , , setTimeout — , , handleRefresh() handleLoadMore()refreshing loadingMore . , , , , - .

, onRefresh refreshing refreshControl . , refreshControl , , , , .


, . — , , Load More , , , , .


FlatList. , , 2, onEndReached , 2-

, onEndReached . .

onEndReachedThreshold , FlatList , , onEndReached . .

100 , , 10 , 1, onEndReachedThreshold , , onEndReached , , 90-. 2, , 2- , — 80- , .

, , , , FlatList . , , , , handleLoadMore() , onEndReached , , — 10 .

, , loadingMore , , handleLoadMore() , , , !loadingMore . , , .


ListLoadingComponent FlatList , , ListHeaderComponent , ListEmptyComponent ListFooterComponent , , - , , , .

, render() .


, , , . , , .

, scrollToOffset FlatList , , . , . ref FlatList :

 <FlatList ref={(ref) => { this.newsListRef = ref; }} ... /> 

, . ScrollToOffset handleScrollToTop() , , , react-navigation, , :

 componentDidMount() { this.props.navigation.setParams({   scrollToTop: this.handleScrollToTop, }); } handleScrollToTop = () => { this.newsListRef.ScrollToOffset({   x: 0, y: 0, animated: true, }); }; 

, react-navigation 3 ref , BottomTabNavigator .


, , . , , 4G- ( , , 3G), , , , , .

, , , , , , , . . , , , , .

, , . 7 , image , , ( , ).


, , . react-native-image-picker , Cloudinary Carrierwawe Rails-.

, Node-API Cloudinary react-native-fetch-blob . , , , , , .

, , react-native-fetch-blob, . , react-native-fetch-blob , API JS FormData . , react-native-fetch-blob rn-fetch-blob , .


, React Native Image style , source resizeMode . , , - , , , .

, , , . , , , . . Avatar react-native-elements.

, Image . , - , .

, , . .


react-native-slideshow

react-native-slideshow , , . , , , , , , .


7 , , . , — , , . , - . .

, , -, , , , - ( — ), , , , Facebook . , .

, , React Native-. , . — react-native-loading-placeholder , , , . — react-native-linear-gradient , . , , , , , , , , .


react-native-loading-placeholder react-native-linear-gradient


— . , React Native Image . , - CachedImage react-native-cached-image .

npm- Image , , , CachedImage . Reactotron , , .

, , , . , , Cloudinary, 95% , , 4%. .

, . CachedImage activityIndicatorProps={{ animating: false }} , .



React Native - Picker . - , ( - ), JS-, . , react-native-picker-select , <select> iOS Android .

JS-, React Native- ( lodash , ), , , , . , , - . , .


react-native-calendars Wix. :

  • iOS , . , , , -, — .
  • React Native — DatePickerIOS DatePickerAndroid , , .
  • , , , Apple Google.

, . , , — .


react-native-calendars react-native-picker-select


— , .
SaaS-, . SOAP, API Conference. , , , , .

, , , 5 . - , JavaScript Date UTC, , . , , , , , - . « », — .

, , moment-js , React Native, timezone , :

 const timeSthlmAfterFive = moment().isAfter(moment.tz('17:00:00', 'HH:mm:ss', 'Europe/Stockholm'), 'second'); 


, , , . React Native -, , , , , , font-face CSS.

. , . , 10 -. react-native-vector-icons .

, ,


CI/CD, DevOps- -, .

( ) , - . , . GitHub- . , :

  • . , , .
  • , - , , .

. , , , , , , push-. , , , , .

Visual Studio App Center (VSAC). Chain React 2017 . , , , DevOps-, . , , , , push-, Codepush . -. , , , , iOS, Android. , - , , , , , - .


Visual Studio App Center ( )

« », — , . , (API — ). , , , , -, (, , ).

? Microsoft, , VSAC « ». , , Codepush ( React Native-) HockeyApp ( ), - . , «developers, developers, developers, developers» .

, VSAC , - Fastlane , BuddyBuild Firebase ? , , , VSAC , , , . , , ? , VSAC, , .

VSAC. , , , .

, , , VSAC Apple Developers (Apple, , , ). , , , .

, VSAC, , , CI/CD- .

Android


, iOS- , Android . Android Studio Android React Native Platform . , Platform.select() . - , , , Platform.OS .

, , Google Play , App Store. لماذا؟ , App Store Apple.

Apple


, -, React Native, . , Apple. , , , , , .


Apple

, — « ». -, , iOS-, , , , .

— Apple. , , , . Dun & Bradstreet, Apple, . , , , Apple (, , Apple , — ).

, Apple , , — , -. . , — ?

, .

, , Apple Developer . .

. . provisioning-, iOS-, , Apple .p12 push-, dSym-. , , , .

Apple, 50% 24 , 90% — 48 . , , — , , Apple-.

, . «Metadata Rejected». , - . , 5 ( App Store Review Guidelines ), .

, , , — . , , , , , . , — , () .

iOS, . , , , . , , . . , , .

النتائج


, React Native- . React Native-. -. , : . .

, , , , . , , — , .

, - , . . , , , 8 . . .

, . , , - .

, , , 6-7 , . , , , :

  • , (iOS Android), , , .
  • JavaScript. , , Ember.js.
  • React.js, , React-, . , JS-/.
  • , Redux.
  • DevOps .
  • , .
  • UI/UX.
  • , , , , , , , , .

JS- , Flutter , NativeScript , Objective-C, Swift, Java Kotlin, React Native .

, -, , React Native , , , . , React Native — , . React Native .

أعزائي القراء! ?

Source: https://habr.com/ru/post/ar447574/


All Articles