ميزات التجميع وتسليم تطبيقات iOS

في هذا المقال ، شارك مكسيم شيستاكوف ، مهندس DevOps في استوديو بلاريوم كراسنودار ، تجربته في بناء وتقديم تطبيقات iOS للمستخدمين الذين تراكموا أثناء تصحيح أخطاء CI / CD.



تدريب


تمكن جميع الأشخاص المرتبطين بتطوير التطبيقات لأجهزة Apple بالفعل من تقدير سهولة الاستخدام المثيرة للجدل للبنية التحتية. الصعوبات موجودة في كل مكان: من قائمة ملف تعريف المطور إلى أدوات التصحيح والتجميع.

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

  • حساب المطور ؛
  • جهاز يعمل بنظام macOS يعمل كخادم بناء ؛
  • شهادة المطور التي تم إنشاؤها ، والتي سيتم استخدامها لتوقيع التطبيق ؛
  • تطبيق تم إنشاؤه بمعرف فريد (يجب ملاحظة أهمية Bundle Identifier ، لأن استخدام معرف حرف البدل يجعل من المستحيل استخدام العديد من وظائف التطبيق ، على سبيل المثال: Associated Domains و Push Notifications و Apple Sign In وغيرها) ؛
  • الملف الشخصي لتوقيع التطبيق.

يجب إنشاء شهادة المطور من خلال Keychain على أي جهاز macOS. نوع الشهادة مهم جدا. اعتمادًا على بيئة التطبيق (Dev ، QA ، Staging ، الإنتاج) ، ستختلف (التطوير أو التوزيع) ، بالإضافة إلى نوع ملف تعريف توقيع التطبيق.

الأنواع الرئيسية من الملفات الشخصية:

  • التطوير - مصمم للتوقيع على طلب فريق التطوير ، باستخدام شهادة التطوير (اسم النموذج iPhone Developer: XXXXX) ؛
  • Ad Hoc - تم تصميمه للتوقيع على تطبيق اختبار والتحقق الداخلي من قبل قسم ضمان الجودة ، يتم استخدام شهادة توزيع المطور (اسم نوع توزيع iPhone: XXXXX)
  • App Store - بناء إصدار للاختبار الخارجي من خلال TestFlight وتحميله إلى App Store ، باستخدام شهادة التوزيع للمطور.

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

للتوضيح ، يمكنك تقديم ملف تعريف المطور في شكل جهاز لوحي أدناه. من السهل فهم معلمات التجميع التي نحتاجها وأين يمكن الحصول عليها.



المجسم


لتسهيل فصل التجميعات حسب المشروع والبيئة ، نستخدم أسماء ملفات تعريف العرض ${ProjectName}_${Instance}، أي اسم المشروع + المثيل (يعتمد على بيئة التطبيق: Dev و QA و GD و Staging و Live وما إلى ذلك).

عند الاستيراد إلى خادم إنشاء ، يغير ملف التعريف اسمه إلى معرف فريد وينتقل إلى المجلد /Users/$Username/Library/MobileDevice/Provisioning Profiles(حيث $Usernameيتوافق مع اسم حساب مستخدم خادم البناء).

هناك طريقتان لإنشاء ملف * .ipa - قديم (PackageApplication) وحديث (من خلال إنشاء XcAchive وتصديره). تعتبر الطريقة الأولى قديمة ، حيث أنه من الإصدار 8.3 تمت إزالة وحدة تغليف ملف التطبيق من توزيع Xcode. لاستخدامه ، تحتاج إلى نسخ الوحدة النمطية من Xcode القديم (الإصدار 8.2 والإصدارات السابقة) إلى المجلد:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/

ثم قم بتشغيل الأمر:

chmod +x /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/*

بعد ذلك ، تحتاج إلى جمع ملف التطبيق * .app:

xcodebuild \
-workspace $ProjectDir/$ProjectName.xcworkspace \
-scheme $SchemeName \
-sdk iphoneos \
build \
-configuration Release \
-derivedDataPath build \
CODE_SIGN_IDENTITY=”$DevAccName”\
PROVISIONING_PROFILE=”$ProfileId
DEPLOYMENT_POSTPROCESSING=YES \
SKIP_INSTALL=YES \
ENABLE_BITCODE=NO

حيث:

-workspace- المسار إلى ملف المشروع.

-scheme- الدائرة المستخدمة المحددة في المشروع.

-derivedDataPath- مسار تفريغ التطبيق المجمع (* .app).

CODE_SIGN_IDENTITY- اسم حساب المطور الذي يمكن التحقق منه في Keychain (مطور iPhone: XXXX XXXXXXX ، بدون TeamID بين قوسين).



PROVISIONING_PROFILE- معرف ملف التعريف لتوقيع التطبيق ، والذي يمكن الحصول عليه عن طريق الأمر:

cd "/Users/$Username/Library/MobileDevice/Provisioning Profiles/" && find *.mobileprovision -type f | xargs grep -li ">${ProjectName}_${Instance}<" | sed -e 's/.mobileprovision//'

إذا كان التطبيق يستخدم ملف تعريف إضافي (على سبيل المثال ، لإشعارات الدفع) ، فبدلاً من ذلك ، حدد PROVISIONING_PROFILE:

APP_PROFILE=”$AppProfile” \
EXTENSION_PROFILE=”$ExtProfile” \

بعد ذلك ، يجب حزم ملف * .app الناتج في * .ipa. للقيام بذلك ، يمكنك استخدام أمر من النموذج:

/usr/bin/xcrun --sdk iphoneos PackageApplication \
-v $(find "$ProjectDir/build/Build/Products/Release-iphoneos" -name "*.app") \
-o "$ProjectDir/$ProjectName_$Instance.ipa"

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

تحتاج أولاً إلى جمع الأرشيف باستخدام الأمر:

xcodebuild \
-workspace $ProjectDir/$ProjectName.xcworkspace \
-scheme $SchemeName \
-sdk iphoneos \
-configuration Release \
archive \
-archivePath $ProjectDir/build/$ProjectName.xcarchive \
CODE_SIGN_IDENTITY=”$DevAccName” \
PROVISIONING_PROFILE=”$ProfileId
ENABLE_BITCODE=NO \
SYNCHRONOUS_SYMBOL_PROCESSING=FALSE

الاختلافات في طريقة التجميع والخيار SYNCHRONOUS_SYMBOL_PROCESSINGالذي يعطل تفريغ الأحرف أثناء التجميع.

بعد ذلك ، نحتاج إلى إنشاء ملف بإعدادات التصدير:

ExportSettings="$ProjectDir/exportOptions.plist"

cat << EOF > $ExportSettings
<?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>compileBitcode</key>
<false/>
<key>uploadBitcode</key>
<false/>
<key>uploadSymbols</key>
<false/>
<key>method</key>
<string>$Method</string>
<key>provisioningProfiles</key>
<dict>
<key>$BundleID</key>
<string>$ProfileId</string>
</dict>
<key>signingCertificate</key>
<string>$DevAccName</string>
<key>signingStyle</key>
<string>manual</string>
<key>stripSwiftSymbols</key>
<true/>
<key>teamID</key>
<string>$TeamID</string>
<key>thinning</key>
<string><none></string>
</dict>
</plist>
EOF

حيث:

$Method- تتوافق طريقة التسليم مع نوع ملف تعريف توقيع التطبيق ، أي بالنسبة للتطوير ، ستكون القيمة هي التطوير ، لـ Ad Hoc - ad-hoc ، و App Store - app-store.

$BundleID- معرف التطبيق المحدد في إعدادات التطبيق. يمكنك التحقق من الأمر:

defaults read $ProjectDir/Info CFBundleIdentifier

$DevAccName $ProfileId- إعدادات اسم المطور ومعرف ملف تعريف التوقيع التي تم استخدامها سابقًا ويجب أن تتطابق مع القيم الموجودة في إعدادات التصدير.

$TeamID- معرف مكون من عشرة أرقام بين قوسين بعد اسم المطور ، على سبيل المثال: مطور iPhone: ....... (XXXXxx) ؛ يمكن التحقق في Keychain.

بعد ذلك ، باستخدام أمر التصدير ، نحصل على ملف * .ipa الضروري:

xcodebuild \
-exportArchive \
-archivePath $ProjectDir/build/$ProjectName.xcarchive \
-exportPath $ProjectDir \
-exportOptionsPlist $ExportSettings

توصيل


الآن يجب تسليم الملف المجمع إلى المستخدم النهائي ، أي أنه مثبت على الجهاز.

لتوزيع تطوير وبناء Ad Hoc ، هناك العديد من الخدمات مثل HockeyApp و AppBlade وغيرها ، ولكن في هذه المقالة سنتحدث عن خادم مستقل لتوزيع التطبيقات.

يتم تثبيت التطبيق لنظام iOS على مرحلتين:

  1. الحصول على بيان تثبيت التطبيق من خلال خدمة العناصر.
  2. تثبيت ملف * .ipa وفقًا للمعلومات المحددة في البيان عبر HTTPS.

وبالتالي ، بالنسبة للمبتدئين ، نحتاج إلى إنشاء بيان التثبيت (نوع الملف * .plist) باستخدام الأمر:

cat << EOF > $manifest
<?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>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>$ipaUrl</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>bundle-identifier</key>
<string>$BundleID</string>
<key>bundle-version</key>
<string>$AppVersion</string>
<key>kind</key>
<string>software</string>
<key>title</key>
<string>$ProjectName_$Instance</string>
<key>subtitle</key>
<string>$Instance</string>
</dict>
</dict>
</array>
</dict>
</plist>
EOF

كما ترى ، يحتوي البيان على جميع المعلمات تقريبًا المتضمنة في تجميع التطبيق. يمكن التحقق من

إصدار التطبيق ( $AppVersion) باستخدام الأمر:

defaults read $ProjectDir/Info CFBundleVersion

$ipaUrlتحتوي المعلمة على ارتباط مباشر لتنزيل ملف * .ipa. من الإصدار السابع من iOS ، يجب تثبيت التطبيق عبر HTTPS. في الإصدار الثامن ، تغير تنسيق البيان بشكل طفيف: تمت إزالة الكتل ذات الإعدادات لرموز التطبيق للنموذج

<images>
   <image>...</image>
</images>

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

itms-services://?action=download-manifest&url=https://$ServerUrl/$ProjectName/$Instance/iOS/$AppVersion/manifest.plist

لتلبية احتياجات أقسام التطوير والاختبار ، قامت بلاريوم بإنشاء تطبيق التثبيت للبناء ، والذي يمنحنا:

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

اختبارات


الآن سنتحدث عن اختبار التطبيق قبل الإصدار باستخدام TestFlight .

المتطلبات الأساسية للتنزيل هي نوع ملف تعريف توقيع App Store ووجود مفاتيح API التي تم إنشاؤها.

هناك عدة طرق لتنزيل التطبيق:

  • عبر Xcode (المنظم) ،
  • من خلال المول ،
  • عبر تطبيق Loader للإصدارات القديمة من Xcode (الآن Transporter).

للتحميل التلقائي ، يتم استخدام أدوات بديلة ، والتي لديها أيضًا طريقتين للترخيص:

  • كلمة المرور الخاصة بالتطبيقات ،
  • مفتاح API

يفضل تنزيل التطبيق باستخدام مفتاح API.

للحصول على مفتاح API ، اتبع الرابط وقم بإنشاء المفتاح. بالإضافة إلى المفتاح نفسه بتنسيق * .p8 ، سنحتاج إلى معلمتين: IssuerID و KeyID.



بعد ذلك ، نستورد المفتاح الذي تم تنزيله إلى خادم الإنشاء:

mkdir -p ~/.appstoreconnect/private_keys
mv ~/Downloads/AuthKey_${KeyID}.p8 ~/.appstoreconnect/private_keys/

قبل تحميل التطبيق في TestFlight ، تحتاج إلى التحقق من صحة التطبيق ، وذلك من خلال الأمر:

xcrun altool \
--validate-app \
-t ios \
-f $(find "$ProjectDir" -name "*.ipa") \
--apiKey “$KeyID” \
--apiIssuer “$IssuerID

حيث apiKeyو apiIssuerلها قيمة حقل من الصفحة جيل مفتاح API.

بعد ذلك ، عند التحقق من الصحة بنجاح ، نقوم بتحميل التطبيق بأمر --upload-appبنفس المعلمات.

ستقوم Apple باختبار التطبيق في غضون يوم إلى يومين وبعد ذلك سيكون متاحًا للمختبرين الخارجيين: سيتم إرسال روابط البريد الإلكتروني للتثبيت.

هناك طريقة أخرى لتنزيل التطبيق من خلال altool وهي استخدام كلمة المرور الخاصة بالتطبيق.

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



بعد ذلك ، أنشئ سجل خادم إنشاء في Keychain باستخدام كلمة المرور هذه. من الإصدار 11 من Xcode ، يمكن القيام بذلك باستخدام الأمر:

xcrun altool --store-password-in-keychain-item "Altool" -u "$DeveloperName" -p $AppPswd

المكان:

$DeveloperNameهو اسم حساب مطور iOS المستخدم لتسجيل الدخول إلى خدمات Apple.

$AppPswd- إنشاء كلمة مرور خاصة بالتطبيقات.

بعد ذلك ، نحصل على قيمة معلمة asc-Provider والتحقق من نجاح استيراد كلمة المرور باستخدام الأمر:

xcrun altool --list-providers -u "$DeveloperName" -p "@keychain:Altool"

نحصل على الاستنتاج:

Provider listing:
- Long Name - - Short Name -
XXXXXXX        XXXXXXXXX

كما ترى ، تتطابق قيمة الاسم المختصر (موفر تصاعدي) المطلوب مع المعلمة $ TeamID التي استخدمناها عند إنشاء التطبيق.

للتحقق من صحة التطبيق وتحميله في TestFlight ، استخدم الأمر:

xcrun altool \
--(validate|upload)-app \  
-f $(find "$ProjectDir" -name "*.ipa") \
-u "$DeveloperName" \
-p "@keychain:Altool" \

كقيمة معلمة ، -pيمكنك أخذ القيمة $AppPswdفي شكل غير مشفر (صريح).

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

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

All Articles