คุณสมบัติของการสร้างและส่งมอบแอปพลิเคชัน iOS

ในบทความนี้ เราแบ่งปันประสบการณ์ในการประกอบและส่งมอบแอปพลิเคชัน iOS ให้กับผู้ใช้ ซึ่งสตูดิโอ Plarium Krasnodar ได้สั่งสมไว้ในกระบวนการดีบัก CI/CD

คุณสมบัติของการสร้างและส่งมอบแอปพลิเคชัน iOS

การอบรม

ทุกคนที่มีส่วนร่วมในการพัฒนาแอพพลิเคชั่นสำหรับอุปกรณ์ Apple ไม่ทางใดก็ทางหนึ่งต่างชื่นชมความสะดวกสบายของโครงสร้างพื้นฐานที่เป็นข้อโต้แย้งอยู่แล้ว พบปัญหาได้ทุกที่: ตั้งแต่เมนูโปรไฟล์นักพัฒนาไปจนถึงเครื่องมือแก้ไขข้อบกพร่องและเครื่องมือสร้าง

มีบทความมากมายเกี่ยวกับ "พื้นฐาน" บนอินเทอร์เน็ต ดังนั้นเราจะพยายามเน้นประเด็นหลัก ต่อไปนี้คือสิ่งที่คุณต้องมีเพื่อสร้างแอปพลิเคชันของคุณให้สำเร็จ:

  • บัญชีนักพัฒนาซอฟต์แวร์;
  • อุปกรณ์ที่ใช้ macOS ทำหน้าที่เป็นเซิร์ฟเวอร์บิลด์
  • สร้างขึ้น ใบรับรองนักพัฒนาซึ่งจะนำไปใช้ในการลงนามในใบสมัครต่อไป
  • สร้างแอพพลิเคชั่นที่มีเอกลักษณ์เฉพาะตัว ID (ควรสังเกตความสำคัญของ Bundle Identifier เนื่องจากการใช้ wildcard ID ทำให้ไม่สามารถใช้ฟังก์ชันต่างๆ ของแอปพลิเคชันได้ เช่น โดเมนที่เกี่ยวข้อง การแจ้งเตือนแบบพุช การลงชื่อเข้าใช้ของ Apple และอื่นๆ)
  • โปรไฟล์ ลายเซ็นแอปพลิเคชัน

ต้องสร้างใบรับรองนักพัฒนาผ่านพวงกุญแจบนอุปกรณ์ macOS ใด ๆ ประเภทของใบรับรองมีความสำคัญมาก ขึ้นอยู่กับสภาพแวดล้อมของแอปพลิเคชัน (Dev, QA, Staging, Production) ซึ่งจะแตกต่างกันไป (การพัฒนาหรือการจัดจำหน่าย) เช่นเดียวกับประเภทของโปรไฟล์ลายเซ็นแอปพลิเคชัน

โปรไฟล์ประเภทหลัก:

  • การพัฒนา - มีไว้สำหรับการลงนามในใบสมัครของทีมพัฒนา จะใช้ใบรับรองการพัฒนา (ชื่อประเภท นักพัฒนา iPhone: XXXXX)
  • เฉพาะกิจ - มีไว้สำหรับการลงนามในแอปพลิเคชันทดสอบและการตรวจสอบภายในโดยแผนก QA จะใช้ใบรับรองการจัดจำหน่ายของนักพัฒนา (ชื่อประเภท การจัดจำหน่าย iPhone: XXXXX)
  • App Store - รุ่นสำหรับการทดสอบภายนอกผ่าน TestFlight และอัปโหลดไปยัง App Store จะใช้ใบรับรองการจัดจำหน่ายของนักพัฒนา

เมื่อสร้างโปรไฟล์การพัฒนาและเฉพาะกิจ ระบบจะระบุด้วย รายการอุปกรณ์ซึ่งคุณสามารถติดตั้งบิลด์ซึ่งช่วยให้คุณสามารถจำกัดการเข้าถึงสำหรับผู้ใช้เพิ่มเติมได้ ไม่มีรายการอุปกรณ์ในโปรไฟล์ App Store เนื่องจาก TestFlight เป็นผู้จัดการการควบคุมการเข้าถึงในระหว่างการทดสอบเบต้าแบบปิด ซึ่งจะกล่าวถึงในภายหลัง

เพื่อความชัดเจน คุณสามารถนำเสนอโปรไฟล์ของนักพัฒนาซอฟต์แวร์ในรูปแบบตารางด้านล่างนี้ ซึ่งช่วยให้เข้าใจได้ง่ายขึ้นว่าเราต้องการพารามิเตอร์ใดในการประกอบและหาได้จากที่ไหน

คุณสมบัติของการสร้างและส่งมอบแอปพลิเคชัน iOS

การชุมนุม

เพื่อให้ง่ายต่อการแยกแอสเซมบลีตามโครงการและสภาพแวดล้อม เราใช้ชื่อโปรไฟล์เช่น ${ProjectName}_${Instance}นั่นคือชื่อโปรเจ็กต์ + อินสแตนซ์ (ขึ้นอยู่กับสภาพแวดล้อมของแอปพลิเคชัน: Dev, QA, GD, Staging, Live และอื่นๆ)

เมื่ออิมพอร์ตไปยังบิลด์เซิร์ฟเวอร์ โปรไฟล์จะเปลี่ยนชื่อเป็น ID เฉพาะและถูกย้ายไปยังโฟลเดอร์ /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 — ชื่อของบัญชีนักพัฒนา ซึ่งสามารถตรวจสอบได้ในพวงกุญแจ (นักพัฒนา iPhone: XXXX XXXXXXX โดยไม่มี TeamID ในวงเล็บ)

คุณสมบัติของการสร้างและส่งมอบแอปพลิเคชัน iOS

PROVISIONING_PROFILE — ID โปรไฟล์สำหรับการลงนามแอปพลิเคชัน ซึ่งสามารถรับได้ด้วยคำสั่ง:

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 - เฉพาะกิจ และสำหรับ App Store - app-store

$BundleID — ID แอปพลิเคชัน ซึ่งระบุไว้ในการตั้งค่าแอปพลิเคชัน คุณสามารถตรวจสอบด้วยคำสั่ง:

defaults read $ProjectDir/Info CFBundleIdentifier

$DevAccName и $ProfileId — การตั้งค่าชื่อนักพัฒนาและ ID โปรไฟล์ลายเซ็นที่ใช้ก่อนหน้านี้และจะต้องตรงกับค่าในการตั้งค่าการส่งออก

$TeamID — รหัสสิบหลักในวงเล็บหลังชื่อนักพัฒนา ตัวอย่าง: นักพัฒนา iPhone: …… (XXXXXXXXXX); สามารถตรวจสอบได้ในพวงกุญแจ

ต่อไป เมื่อใช้คำสั่งส่งออก เราได้รับไฟล์ *.ipa ที่จำเป็น:

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

จัดส่งสินค้า

ตอนนี้ไฟล์ที่รวบรวมจะต้องถูกส่งไปยังผู้ใช้ปลายทางซึ่งก็คือการติดตั้งบนอุปกรณ์

มีบริการมากมายสำหรับการเผยแพร่ Development และ Ad Hoc builds เช่น HockeyApp, AppBlade และอื่นๆ แต่ในบทความนี้ เราจะพูดถึงเซิร์ฟเวอร์แบบสแตนด์อโลนสำหรับการกระจายแอปพลิเคชัน

การติดตั้งแอปพลิเคชันสำหรับ iOS จะเกิดขึ้นใน 2 ขั้นตอน:

  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 เวอร์ชันที่ 7 จะต้องติดตั้งแอปพลิเคชันผ่าน HTTPS ในเวอร์ชันที่แปด รูปแบบของรายการมีการเปลี่ยนแปลงเล็กน้อย: บล็อกที่มีการตั้งค่าสำหรับไอคอนแอปพลิเคชันเช่น

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

ดังนั้นในการติดตั้งแอปพลิเคชันหน้า HTML ธรรมดาที่มีลิงก์เช่นนี้ก็เพียงพอแล้ว:

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

สำหรับความต้องการของแผนกพัฒนาและทดสอบ Plarium ได้สร้างแอปพลิเคชันการติดตั้งแบบบิวด์ของตัวเอง ซึ่งทำให้เรา:

  • เอกราชและความเป็นอิสระ
  • การรวมศูนย์การควบคุมการเข้าถึงและการติดตั้งแอปพลิเคชันที่ปลอดภัยผ่านลิงก์ที่สร้างขึ้นแบบไดนามิก "ชั่วคราว"
  • ฟังก์ชันการทำงานที่ขยายได้ (นั่นคือ หากจำเป็น ทีมพัฒนาสามารถรวมฟังก์ชันที่ขาดหายไปเข้ากับแอปพลิเคชันที่มีอยู่ได้)

การทดสอบ

ตอนนี้เราจะพูดถึงการทดสอบแอปพลิเคชันก่อนเผยแพร่โดยใช้ TestFlight.

เงื่อนไขที่จำเป็นสำหรับการดาวน์โหลดคือประเภทของโปรไฟล์ลายเซ็น App Store และการมีอยู่ของคีย์ API ที่สร้างขึ้น

มีหลายวิธีในการดาวน์โหลดแอปพลิเคชัน:

  • ผ่าน Xcode (ออแกไนเซอร์)
  • ผ่านทางอัลทูล
  • ผ่าน Application Loader สำหรับ Xcode เวอร์ชันเก่า (ปัจจุบันคือ Transporter)

สำหรับการดาวน์โหลดอัตโนมัติ จะใช้ altool ซึ่งมีวิธีการอนุญาตสองวิธี:

  • รหัสผ่านเฉพาะแอป
  • คีย์ API

ขอแนะนำให้ดาวน์โหลดแอปพลิเคชันโดยใช้คีย์ API

หากต้องการรับคีย์ API ให้ไปที่ ลิงค์ และสร้างคีย์ นอกจากคีย์ในรูปแบบ *.p8 แล้ว เรายังต้องมีพารามิเตอร์สองตัว: IssuerID และ KeyID

คุณสมบัติของการสร้างและส่งมอบแอปพลิเคชัน iOS

ถัดไป นำเข้าคีย์ที่ดาวน์โหลดไปยังเซิร์ฟเวอร์บิลด์:

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 คือการใช้รหัสผ่านเฉพาะแอป

หากต้องการรับรหัสผ่านเฉพาะแอป คุณต้องไปที่ ลิงค์ และสร้างมันขึ้นมาในส่วนความปลอดภัย

คุณสมบัติของการสร้างและส่งมอบแอปพลิเคชัน iOS

ถัดไป คุณควรสร้างบันทึกเซิร์ฟเวอร์บิลด์ในพวงกุญแจด้วยรหัสผ่านนี้ จาก Xcode เวอร์ชัน 11 สามารถทำได้ด้วยคำสั่ง:

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

อย่างที่คุณเห็น ค่าชื่อย่อที่ต้องการ (asc-provider) เกิดขึ้นพร้อมกับพารามิเตอร์ $TeamID ที่เราใช้เมื่อสร้างแอปพลิเคชัน

ในการตรวจสอบและโหลดแอปพลิเคชันลงใน TestFlight ให้ใช้คำสั่ง:

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

เป็นค่าพารามิเตอร์ -p คุณสามารถรับค่านั้นได้ $AppPswd ในรูปแบบที่ไม่เข้ารหัส (ชัดเจน)

อย่างไรก็ตาม ดังที่กล่าวไปแล้ว จากมุมมองของประสิทธิภาพ เป็นการดีกว่าที่จะเลือกคีย์ API สำหรับการอนุญาต altool เนื่องจาก Xcode เวอร์ชันต่างๆ มีปัญหาบางอย่าง ("ไม่เห็น" พวงกุญแจ ข้อผิดพลาดในการอนุญาตระหว่างการอัปโหลด ฯลฯ )

นั่นคือทั้งหมดจริงๆ ฉันขอให้ทุกคนมีส่วนร่วมในการสร้างที่ประสบความสำเร็จและการเปิดตัวที่ไร้ปัญหาใน App Store

ที่มา: will.com

เพิ่มความคิดเห็น