Xcode 11 و XCFrameworks: تنسيق تغليف إطار جديد


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


في حالة تطوير نظام التشغيل iOS ، وبشكل عام ، نظام Apple البيئي ، هناك خياران لربط المكتبات كتبعية:


  1. جمعها في كل مرة تقوم فيها بإنشاء التطبيق.
  2. جمعها مقدما باستخدام التبعيات التي تم جمعها بالفعل.

عند اختيار الطريقة الثانية ، يصبح من المنطقي استخدام أنظمة CI / CD لتجميع المكتبات في الأعمال الفنية الجاهزة للاستخدام.


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


على هذه الخلفية ، كان من الصعب عدم ملاحظة ذلك وكان من المثير للاهتمام للغاية دراسة أحد الابتكارات من Apple المقدمة في WWDC 2019 كجزء من عرض Binary Frameworks في Swift - تنسيق عبوة الإطارات هو XCFramework.


XCFramework له العديد من المزايا مقارنة بالنُهج الثابتة:


  1. عبوة التبعية لجميع المنصات والبنى المستهدفة في حزمة واحدة خارج الصندوق.
  2. حزمة الاتصال بتنسيق XCFramework ، باعتبارها تبعية واحدة لجميع الأنظمة الأساسية والبنى المستهدفة.
  3. لا حاجة لبناء إطار سمين / عالمي.
  4. ليست هناك حاجة للتخلص من شريحة x86_64 قبل تحميل التطبيقات النهائية في AppStore.

في هذه المقالة ، سنشرح لماذا تم تقديم هذا التنسيق الجديد وما هو عليه وأيضًا ما الذي يقدمه للمطور.


كيف ظهر الشكل الجديد


أصدرت Apple سابقًا مدير التبعية Swift Package Manager .
خلاصة القول هي أن Swift PM يتيح لك تسليم المكتبات في شكل شفرة مفتوحة المصدر مع وصف التبعيات.


من وجهة نظر المطور الذي يزود المكتبة ، أود تسليط الضوء على جانبين من Swift PM.


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

تقدم XCFramework Apple تنسيقًا ثنائيًا جديدًا لمكتبات التعبئة ، معتبرة ذلك بديلاً عن حزم Swift.


يتوفر هذا التنسيق ، بالإضافة إلى القدرة على توصيل المكتبة التي تم تجميعها في XCFramework ، بدءًا من Xcode 11 وإصداراته التجريبية.


ما هو XCFramework


XCFramework في جوهرها ، طريقة جديدة لتعبئة المكتبات وإيصالها ، في إصداراتها المختلفة.


من بين أشياء أخرى ، يسمح التنسيق الجديد أيضًا بتعبئة المكتبات الثابتة إلى جانب ملفات الرأس الخاصة بها ، بما في ذلك تلك المكتوبة في C / Objective-C.


النظر في الشكل بمزيد من التفصيل.


  1. عبوة التبعية لجميع المنصات والبنى المستهدفة في حزمة واحدة خارج الصندوق


    يمكن الآن تجميع كل مجموعات المكتبات لكل من الأنظمة الأساسية والمعماريات المستهدفة في حزمة واحدة مع الامتداد .xcframework.
    ومع ذلك ، لهذا ، في هذه المرحلة الزمنية ، يجب عليك استخدام البرامج النصية لاستدعاء xcodebuild مع مفتاح التبديل -create-xcframework الجديد لـ Xcode 11.


    سيتم النظر في عملية التجميع والتغليف.


  2. حزمة الاتصال بتنسيق XCFramework ، باعتبارها تبعية واحدة لجميع الأنظمة الأساسية والبنى المستهدفة


    نظرًا لأن الحزمة .xcframework تحتوي على جميع خيارات تجميع التبعية اللازمة ، فلا داعي للقلق بشأن هيكلها ونظامها الأساسي المستهدف.


    في Xcode 11 ، ترتبط مكتبة تم حزمها في .xcframework مثلها مثل .framework العادية.
    بشكل أكثر تحديدًا ، يمكن تحقيق ذلك بالطرق التالية في الإعدادات الهدف:


    • إضافة .xcframework إلى قسم "الأُطُر والمكتبات" في علامة التبويب "عام"
    • إضافة .xcframework إلى "ربط الثنائي بالمكتبات" في علامة التبويب "إنشاء المراحل"

  3. لا حاجة لبناء الدهون / إطار عالمي


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


    يمكن العثور على مزيد من التفاصيل حول ذلك ، على سبيل المثال ، في المقالات التالية:



  4. ليست هناك حاجة للتخلص من شريحة x86_64 قبل تحميل التطبيقات النهائية في AppStore


    عادة ، يتم استخدام هذه الشريحة لتوفير مكتبات في محاكي iOS.
    عند محاولة تنزيل تطبيق ذي تبعيات تحتوي على شريحة x86_64 في AppStore ، قد تواجه الخطأ المعروف ITMS-90087 .



إنشاء وتعبئة XCFramework: نظرية


في العرض التقديمي المذكور سابقًا ، هناك العديد من الخطوات المطلوبة لتجميع وحزم المكتبة بتنسيق XCFramework:


  1. إعداد المشروع


    بادئ ذي بدء ، في جميع المناطق المستهدفة في المشروع والمسؤولة عن بناء المكتبة للأنظمة الأساسية المستهدفة ، تحتاج إلى تمكين إعداد Build Libraries for Distribution الجديد لـ Xcode 11.



  2. مشروع تجميع لمنصات وهياكل الهدف


    بعد ذلك ، علينا أن نجمع كل الأهداف للمنصات والبنى المستهدفة.
    دعنا نفكر في أمثلة أوامر الاتصال باستخدام مثال لتكوين مشروع معين.


    دعنا نقول أنه في المشروع لدينا مخططان "XCFrameworkExample-iOS" و "XCFramework-macOS".



    يوجد أيضًا في المشروع هدفان يجمعان مكتبة iOS و macOS.



    لبناء كل تكوينات المكتبة المطلوبة ، نحتاج إلى جمع كلا الهدفين باستخدام المخططات المقابلة.
    ومع ذلك ، بالنسبة لنظام التشغيل iOS ، نحتاج إلى مجموعتين: الأولى للأجهزة الطرفية (ARM) والآخر للمحاكي (x86_64).


    في المجموع ، نحن بحاجة إلى جمع 3 أطر.


    للقيام بذلك ، يمكنك استخدام الأمر xcodebuild :


     # iOS devices xcodebuild archive \ -scheme XCFrameworkExample-iOS \ -archivePath "./build/ios.xcarchive" \ -sdk iphoneos \ SKIP_INSTALL=NO # iOS simulator xcodebuild archive \ -scheme XCFrameworkExample-iOS \ -archivePath "./build/ios_sim.xcarchive" \ -sdk iphonesimulator \ SKIP_INSTALL=NO # macOS xcodebuild archive \ -scheme XCFrameworkExample-macOS \ -archivePath "./build/macos.xcarchive" \ SKIP_INSTALL=NO 

    نتيجة لذلك ، حصلنا على 3 أطر مجمعة ، والتي سنقوم بتعبئتها في حاوية .xcframework.


  3. التعبئة تجميعها. الإطار في .xcframework


    يمكنك القيام بذلك باستخدام الأمر التالي:


     xcodebuild -create-xcframework \ -framework "./build/ios.xcarchive/Products/Library/Frameworks/XCFrameworkExample.framework" \ -framework "./build/ios_sim.xcarchive/Products/Library/Frameworks/XCFrameworkExample.framework" \ -framework "./build/macos.xcarchive/Products/Library/Frameworks/XCFrameworkExample.framework" \ -output "./build/XCFrameworkExample.xcframework" 

    يمكن أن يكون هناك الكثير من -framework المعلمة -framework التي تشير إلى كافة التجميعات .framework التي تريد إرفاقها بحاوية .xcframework.



إعداد مشروع مكتبة للتجميع والتعبئة المستقبلية لـ XCFramework


TL ؛ DR: يمكن تنزيل المشروع النهائي من المستودع على جيثب .


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


هل ستزودنا المكتبة نفسها بامتداد بسيط لـ String? ( Optional where Wrapped == String ) ، مع خاصية واحدة.


نحن نسمي هذه الخاصية isNilOrEmpty ، وكما يوحي الاسم ، فهل لنا أن نعرف عندما داخل String? القيمة المفقودة أو السلسلة المخزنة داخل فارغة.


يمكن تنفيذ الرمز على النحو التالي:


 public extension Optional where Wrapped == String { var isNilOrEmpty: Bool { if case let .some(string) = self { return string.isEmpty } return true } } 

ننتقل مباشرة إلى إنشاء وتكوين المشروع.


  1. بادئ ذي بدء ، نحتاج إلى إنشاء مشروع من النوع "Framework" لإحدى نظامين أساسيين مستهدفين من اختيارك: iOS أو macOS.


    يمكنك القيام بذلك في Xcode عبر عنصر القائمة "File" => "New" => "Project" ، أو باستخدام اختصار لوحة المفاتيح ⇧ + + N (بشكل افتراضي).


    بعد ذلك ، في الجزء العلوي من مربع الحوار ، حدد النظام الأساسي المطلوب (iOS أو macOS) ، حدد نوع مشروع Framework ، وانتقل إلى الزر "التالي".


    في الشاشة التالية ، نحتاج إلى تعيين اسم المشروع في حقل "اسم المنتج".


    بدلاً من ذلك ، يمكنك استخدام اسم "الأساس" للمشروع ، في التكوين المذكور سابقًا هو "XCFrameworkExample".


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


  2. بعد ذلك ، تحتاج إلى إنشاء هدف آخر من النوع "Framework" في المشروع لآخر من المنصات المدرجة (باستثناء الهدف الذي تم إنشاء المشروع من أجله في الأصل).


    للقيام بذلك ، استخدم عنصر القائمة "ملف" => "جديد" => "هدف".


    بعد ذلك ، نختار في مربع حوار آخر (نسبة إلى المحدد في الفقرة 1) من النظامين الأساسيين ، وبعد ذلك نختار مرة أخرى نوع المشروع "الإطار".


    بالنسبة إلى حقل "اسم المنتج" ، يمكننا على الفور استخدام الاسم مع لاحقة النظام الأساسي ، الذي نضيف له هدفًا في هذه الفقرة. لذلك ، إذا كان النظام الأساسي هو نظام ماكنتوش ، فيمكن أن يكون الاسم "XCFrameworkExample-macOS" (٪ base_name٪ -٪ platform٪).


  3. سنقوم بإعداد أهداف ومخططات لجعلها أسهل في التمييز.


    أولاً ، أعد تسمية مخططاتنا والأهداف المرتبطة بها حتى تعكس أسمائها الأنظمة الأساسية ، على سبيل المثال ، مثل:


    • «XCFrameworkExample-دائرة الرقابة الداخلية»
    • «XCFrameworkExample-ماك»

  4. بعد ذلك ، أضف الملف الذي يحتوي على رمز ملحق لدينا لـ String? إلى المشروع. swift String?


    إضافة ملف. swift جديد إلى المشروع باسم "اختياري. SWIFT".
    وفي الملف نفسه وضعنا الامتداد المذكور سابقًا لـ Optional .


    من المهم ألا تنسى إضافة ملف التعليمات البرمجية إلى كلا الهدفين.




الآن لدينا مشروع يمكننا وضعه في XCFramework باستخدام أوامر من المرحلة السابقة.


عملية تجميع وتعبئة المكتبة بتنسيق .xcframework


في هذه المرحلة ، يمكنك استخدام البرنامج النصي bash في ملف منفصل لإنشاء المكتبة وحزمه بتنسيق .xcframework. بالإضافة إلى ذلك ، سيسمح هذا في المستقبل باستخدام هذه التطورات لدمج الحل في نظام CI / CD.


يبدو البرنامج النصي بسيطًا قبيحًا ، وفي الواقع ، يجمع الأوامر المذكورة سابقًا للتجميع:


 #!/bin/sh # ---------------------------------- # BUILD PLATFORM SPECIFIC FRAMEWORKS # ---------------------------------- # iOS devices xcodebuild archive \ -scheme XCFrameworkExample-iOS \ -archivePath "./build/ios.xcarchive" \ -sdk iphoneos \ SKIP_INSTALL=NO # iOS simulator xcodebuild archive \ -scheme XCFrameworkExample-iOS \ -archivePath "./build/ios_sim.xcarchive" \ -sdk iphonesimulator \ SKIP_INSTALL=NO # macOS xcodebuild archive \ -scheme XCFrameworkExample-macOS \ -archivePath "./build/macos.xcarchive" \ SKIP_INSTALL=NO # ------------------- # PACKAGE XCFRAMEWORK # ------------------- xcodebuild -create-xcframework \ -framework "./build/ios.xcarchive/Products/Library/Frameworks/XCFrameworkExample.framework" \ -framework "./build/ios_sim.xcarchive/Products/Library/Frameworks/XCFrameworkExample.framework" \ -framework "./build/macos.xcarchive/Products/Library/Frameworks/XCFrameworkExample.framework" \ -output "./build/XCFrameworkExample.xcframework" 

.Xcframework المحتوى


نتيجة لبرمجة التجميع من الفقرة السابقة من المقالة ، نحصل على الحزمة xxframework المرغوب فيها ، والتي يمكن إضافتها إلى المشروع.


إذا نظرنا إلى داخل هذه الحزمة ، والتي ، مثل .framework ، هي في الأساس مجلد بسيط ، فسنرى الهيكل التالي:



نرى هنا أن .xcframework داخلها عبارة عن تجميعات بتنسيق .framework ، مقسمة حسب النظام الأساسي والهندسة المعمارية. أيضًا لوصف محتويات الحزمة .xcframework ، يوجد ملف Info.plist بداخله.


يحتوي ملف Info.plist على المحتويات التالية
 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>AvailableLibraries</key> <array> <dict> <key>LibraryIdentifier</key> <string>ios-arm64</string> <key>LibraryPath</key> <string>XCFrameworkExample.framework</string> <key>SupportedArchitectures</key> <array> <string>arm64</string> </array> <key>SupportedPlatform</key> <string>ios</string> </dict> <dict> <key>LibraryIdentifier</key> <string>ios-x86_64-simulator</string> <key>LibraryPath</key> <string>XCFrameworkExample.framework</string> <key>SupportedArchitectures</key> <array> <string>x86_64</string> </array> <key>SupportedPlatform</key> <string>ios</string> <key>SupportedPlatformVariant</key> <string>simulator</string> </dict> <dict> <key>LibraryIdentifier</key> <string>macos-x86_64</string> <key>LibraryPath</key> <string>XCFrameworkExample.framework</string> <key>SupportedArchitectures</key> <array> <string>x86_64</string> </array> <key>SupportedPlatform</key> <string>macos</string> </dict> </array> <key>CFBundlePackageType</key> <string>XFWK</string> <key>XCFrameworkFormatVersion</key> <string>1.0</string> </dict> </plist> 

قد تلاحظ أنه بالنسبة لمفتاح "CFBundlePackageType" ، على عكس تنسيق .framework ، يتم استخدام القيمة الجديدة "XFWK" ، وليس "FMWK".


النتائج


لذلك ، تنسيق حزم المكتبة في XCFramework ليس أكثر من حاوية عادية للمكتبات المترجمة بتنسيق .framework.


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


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


لهذه الأغراض ، يتم استخدام Swift PM و Carthage و CocoaPods وأنظمة إدارة التبعية الأخرى وتجميعاتها بشكل اعتيادي. لذلك ، ليس من المستغرب أن يتم بالفعل دعم التنسيق الجديد بالفعل في مشاريع CocoaPods و Carthage .

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


All Articles