في هذا المقال ، شارك مكسيم شيستاكوف ، مهندس 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 على مرحلتين:- الحصول على بيان تثبيت التطبيق من خلال خدمة العناصر.
- تثبيت ملف * .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 ، أخطاء التفويض أثناء التفريغ ، إلخ).هذا ، في الواقع ، كل شيء. أتمنى لجميع المشاركين في إصدارات ناجحة وإصدارات خالية من المتاعب على متجر التطبيقات.