SPM: وحدات المشروع لزيادة سرعة البناء

مرحبا هبر! اسمي Eric Basargin وأنا مطور iOS في Surf .



في مشروع واحد كبير ، واجهنا سرعة إنشاء منخفضة - من ثلاث دقائق أو أكثر. عادة ، في مثل هذه الحالات ، تمارس الاستوديوهات مشاريع معيارية حتى لا تعمل مع متراصة ضخمة. قررنا في Surf تجربة المشروع وتصميمه باستخدام Swift Package Manager - مدير التبعية في Apple.



سنتحدث عن النتائج في مقال آخر ، والآن سنجيب على الأسئلة الرئيسية: لماذا كل هذا مطلوب ، ولماذا اخترنا SPM وكيف اتخذنا الخطوات الأولى.







لماذا SPM



الجواب بسيط - إنه أصلي وجديد. لا يُنشئ xcworkspace النفقات العامة مثل Cocoapods ، على سبيل المثال. بالإضافة إلى ذلك ، فإن SPM هو مشروع مفتوح المصدر يتطور بنشاط. تعمل Apple والمجتمع على إصلاح الأخطاء وإصلاح الثغرات الأمنية والتحديث لمتابعة Swift.



هل هذا يجعل بناء المشروع أسرع



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



ملاحظة: تعتمد فعالية النمذجة بشكل مباشر على التقسيم الصحيح للمشروع إلى وحدات.



كيفية عمل تقسيم فعال



تعتمد طريقة التقسيم على البنية المختارة ونوع التطبيق وحجمه وخططه لمزيد من التطوير. لذلك سوف أتحدث عن ثلاث قواعد نحاول الالتزام بها عند الانقسام.



مشاركة الوظائف العامة. كل وحدة مسؤولة عن فئة ، على سبيل المثال:



  • CommonAssets - مجموعة من الأصول الخاصة بك وواجهة عامة للوصول إليها. عادة ما يتم إنشاؤه باستخدام SwiftGen.
  • CommonExtensions - مجموعة من الامتدادات ، على سبيل المثال Foundation و UIKit وتبعيات إضافية.


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



  • NewFlow - شاشات الأخبار ونظرة عامة على أخبار محددة.
  • FavoritesFlow — .
  • SettingsFlow — , , . .


reusable :



  • CommonUIComponents — , UI-. .
  • UI . , , , . .




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



هذا النهج يحل مشكلة المكونات المفقودة. يحدث هذا في المشاريع الكبيرة ، وإذا لم يتم توثيق المكون ، فإن صيانته وتصحيحه سيصبح لاحقًا غير مربح.



قم بإنشاء مشروع باستخدام SPM



ضع في اعتبارك إنشاء مشروع اختبار تافه. أنا أستخدم مشروع تطبيق Multiplatform على SwiftUI. النظام الأساسي والواجهة غير ذي صلة هنا.



ملاحظة: لإنشاء تطبيق متعدد الأنظمة بسرعة ، تحتاج إلى XCode 12.2 beta. دعنا ننشئ



مشروعًا ونرى ما يلي:







لنقم الآن بإنشاء أول وحدة مشتركة:



  • إضافة مجلد Frameworks دون إنشاء دليل ؛
  • إنشاء حزمة SPM مشتركة.






  • أضف الأنظمة الأساسية المدعومة إلى ملف Package.swift. لديناplatforms: [.iOS(.v14), .macOS(.v10_15)]






  • الآن نضيف الوحدة الخاصة بنا إلى كل هدف. لدينا SPMExampleProject لنظام iOS و SPMExampleProject لنظام التشغيل macOS.






ملاحظة: يكفي توصيل وحدات الجذر فقط بالأهداف. لم يتم إضافتها كوحدات فرعية.



اكتمل الاتصال. الآن تحتاج فقط إلى تكوين وحدة نمطية بواجهة عامة - وفويلا ، الوحدة الأولى جاهزة.



كيفية إضافة تبعية لحزمة SPM محلية



دعنا نضيف حزمة AdditionalInfo - مثل Common ، لكن دون إضافتها إلى الأهداف. الآن دعنا نغير Package.swift من الحزمة المشتركة.







لا تحتاج إلى إضافة أي شيء آخر. يمكن استعماله.



مثال قريب من الواقع



دعنا نربط SwiftGen بمشروعنا التجريبي ونضيف وحدة Palette - ستكون مسؤولة عن الوصول إلى لوحة الألوان المعتمدة من قبل المصمم.



  1. قم بإنشاء وحدة جذر جديدة باتباع الإرشادات أعلاه.

  2. قم بإضافة الدلائل الجذرية للبرامج النصية والقوالب إليها.

  3. أضف ملف Palette.xcassets إلى جذر الوحدة واكتب أي مجموعات ألوان.

  4. أضف ملف Palette.swift فارغًا إلى Sources / Palette.

  5. أضف قالب palette.stencil إلى مجلد القوالب .

  6. أنت الآن بحاجة إلى تسجيل ملف التكوين لـ SwiftGen. للقيام بذلك ، أضف ملف swiftgen.yml إلى مجلد البرامج النصية واكتب ما يلي فيه:



xcassets:
  inputs:
    - ${SRCROOT}/Palette/Sources/Palette/Palette.xcassets
  outputs:
    - templatePath: ${SRCROOT}/Palette/Templates/palette.stencil
      params:
        bundle: .module
        publicAccess: true
      output: ${SRCROOT}/Palette/Sources/Palette/Palette.swift




المظهر النهائي



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



نكتب الآن دعوة SwiftGen:



cd ${SRCROOT}/Palette
/usr/bin/xcrun --sdk macosx swift run -c release swiftgen config run --config ./Scripts/swiftgen.yml


ملحوظة: /usr/bin/xcrun --sdk macosxهي بادئة مهمة جدا. بدونها ، سينتج عن الإصدار خطأ: "يتعذر تحميل مكتبة قياسية للهدف 'x86_64-apple-macosx10.15".





نموذج طلب SwiftGen



Done - يمكن الوصول إلى الألوان على النحو التالي:

Palette.myGreen(نوع اللون في SwiftUI) و PaletteCore.myGreen(UIColor / NSColor).



صخور تحت الماء



سأدرج ما واجهناه.



  • .
  • SwiftLint & SwiftGen SPM. yml.
  • Cocoapods. — , SPM . SPM Cocoapods - : «MergeSwiftModule failed with a nonzero exit code». , .
  • SPM . -L$(BUILD_DIR).


SPM — Bundler?



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



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



swift run swiftlint --autocorrect.



All Articles