Այս հոդվածում մենք կիսում ենք iOS հավելվածները օգտատերերին հավաքելու և առաքելու փորձը, որը Plarium Krasnodar ստուդիան կուտակել է CI/CD-ի վրիպազերծման գործընթացում։

Ուսուցում
Յուրաքանչյուր մարդ, ով այս կամ այն կերպ ներգրավված է Apple սարքերի համար հավելվածների մշակման մեջ, արդեն գնահատել է ենթակառուցվածքի հակասական հարմարավետությունը: Դժվարությունները հանդիպում են ամենուր՝ մշակողի պրոֆիլի ընտրացանկից մինչև վրիպազերծման և կառուցման գործիքներ:
Ինտերնետում կան բազմաթիվ հոդվածներ «հիմունքների» մասին, ուստի մենք կփորձենք ընդգծել հիմնականը: Ահա թե ինչ է ձեզ անհրաժեշտ ձեր հավելվածը հաջողությամբ ստեղծելու համար.
- ;
- macOS-ի վրա հիմնված սարք, որը գործում է որպես կառուցման սերվեր;
- առաջացած , որը հետագայում կօգտագործվի դիմումը ստորագրելու համար.
- ստեղծվել է եզակի հավելված (Պետք է նշել Bundle Identifier-ի կարևորությունը, քանի որ wildcard ID-ի օգտագործումը անհնարին է դարձնում հավելվածի բազմաթիվ գործառույթների օգտագործումը, օրինակ՝ Associated Domains, Push Notifications, Apple Sign In և այլն);
- դիմումի ստորագրությունները.
Մշակողի վկայականը պետք է ստեղծվի Keychain-ի միջոցով ցանկացած macOS սարքի վրա: Հավաստագրի տեսակը շատ կարևոր է։ Կախված հավելվածի միջավայրից (Dev, QA, Staging, Production) այն կտարբերվի (Զարգացում կամ բաշխում), ինչպես նաև հավելվածի ստորագրության պրոֆիլի տեսակը:
Պրոֆիլների հիմնական տեսակները.
- Մշակում - նախատեսված է մշակողների թիմի դիմումը ստորագրելու համար, օգտագործվում է Զարգացման վկայագիր (տիպի անունը iPhone Developer: XXXX);
- Ad Hoc - նախատեսված է թեստային հավելվածի ստորագրման և ՈԱ բաժնի կողմից ներքին ստուգման համար, օգտագործվում է մշակողի բաշխման վկայականը (տիպի անունը iPhone Distribution՝ XXXX);
- App Store - թողարկվել է արտաքին փորձարկման համար TestFlight-ի միջոցով և վերբեռնել App Store, օգտագործվում է մշակողի բաշխման վկայագիրը:
Զարգացման և ժամանակավոր պրոֆիլներ ստեղծելիս այն նաև նշվում է , որի վրա կարող եք տեղադրել build, որը թույլ է տալիս սահմանափակել օգտվողների մուտքը։ App Store-ի պրոֆիլում սարքերի ցանկ չկա, քանի որ փակ բետա փորձարկման ժամանակ մուտքի վերահսկումը կառավարվում է TestFlight-ի կողմից, որը կքննարկվի ավելի ուշ:
Պարզության համար կարող եք ներկայացնել մշակողի պրոֆիլը ստորև բերված աղյուսակի տեսքով: Սա հեշտացնում է հասկանալ, թե ինչ պարամետրեր են մեզ անհրաժեշտ հավաքման համար և որտեղից դրանք ստանալ:

Ասամբլեան
Որպեսզի ավելի դյուրին դարձնենք հավաքների առանձնացումը ըստ նախագծի և միջավայրի, մենք օգտագործում ենք պրոֆիլների անուններ, ինչպիսիք են ${ProjectName}_${Instance}, այսինքն՝ նախագծի անվանում + օրինակ (կախված է հավելվածի միջավայրից՝ Dev, QA, GD, Staging, Live և այլն)։
Երբ ներմուծվում է build սերվեր, պրոֆիլը փոխում է իր անունը եզակի 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 — ծրագրավորողի հաշվի անունը, որը կարելի է ստուգել Keychain-ում (iPhone Developer՝ XXXX XXXXXXX, առանց TeamID-ի փակագծերում):

PROVISIONING_PROFILE — Դիմումի ստորագրման պրոֆիլի ID-ն, որը կարելի է ձեռք բերել հրամանով.
cd "/Users/$Username/Library/MobileDevice/Provisioning Profiles/" && find *.mobileprovision -type f | xargs grep -li ">${ProjectName}_${Instance}<" | sed -e 's/.mobileprovision//' Եթե հավելվածն օգտագործում է լրացուցիչ պրոֆիլ (օրինակ՝ Push Notifications-ի համար), ապա դրա փոխարեն 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 — Հավելվածի ID-ն, որը նշված է հավելվածի կարգավորումներում: Դուք կարող եք ստուգել հրամանով.
defaults read $ProjectDir/Info CFBundleIdentifier $DevAccName и $ProfileId — ծրագրավորողի անունը և ստորագրության պրոֆիլի ID-ի կարգավորումները, որոնք նախկինում օգտագործվել են և պետք է համապատասխանեն արտահանման կարգավորումներում նշված արժեքներին:
$TeamID — տասը նիշանոց ID-ն՝ փակագծերում՝ մշակողի անունից հետո, օրինակ՝ iPhone Մշակող՝ …… (XXXXXXXXXX); կարելի է ստուգել Keychain-ում:
Հաջորդը, օգտագործելով արտահանման հրամանը, մենք ստանում ենք անհրաժեշտ *.ipa ֆայլը.
xcodebuild
-exportArchive
-archivePath $ProjectDir/build/$ProjectName.xcarchive
-exportPath $ProjectDir
-exportOptionsPlist $ExportSettingsДоставка
Այժմ հավաքված ֆայլը պետք է առաքվի վերջնական օգտագործողին, այսինքն՝ տեղադրվի սարքի վրա։
Կան բազմաթիվ ծառայություններ, որոնք կարող են բաշխել «Developer» և «Ad Hoc builds», ինչպիսիք են HockeyApp, AppBlade և այլն, բայց այս հոդվածում մենք կխոսենք հավելվածների բաշխման համար ինքնուրույն սերվերի մասին:
iOS-ի համար հավելվածի տեղադրումը տեղի է ունենում 2 փուլով.
- Հավելվածի տեղադրման մանիֆեստի ստացում Items Service-ի միջոցով:
- *.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 Parameter $ipaUrl պարունակում է ուղիղ հղում՝ *.ipa ֆայլը ներբեռնելու համար: iOS-ի յոթերորդ տարբերակից հավելվածը պետք է տեղադրվի HTTPS-ի միջոցով։ Ութերորդ տարբերակում մանիֆեստի ձևաչափը փոքր-ինչ փոխվել է՝ բլոկներ՝ հավելվածի պատկերակների նման կարգավորումներով
<images>
<image>...</image>
</images>Այսպիսով, հավելվածը տեղադրելու համար բավական է մի պարզ HTML էջ՝ այսպիսի հղումով.
itms-services://?action=download-manifest&url=https://$ServerUrl/$ProjectName/$Instance/iOS/$AppVersion/manifest.plistԶարգացման և թեստավորման բաժինների կարիքների համար Plarium-ը ստեղծել է սեփական build-ի տեղադրման հավելվածը, որը մեզ տալիս է.
- ինքնավարություն և անկախություն,
- մուտքի վերահսկման կենտրոնացում և հավելվածների անվտանգ տեղադրում «ժամանակավոր» դինամիկ կերպով ստեղծված հղումների միջոցով,
- ընդլայնվող ֆունկցիոնալություն (այսինքն, մշակման թիմը, անհրաժեշտության դեպքում, կարող է ինտեգրել բացակայող գործառույթները գոյություն ունեցող հավելվածում):
Փորձարկում
Այժմ մենք կխոսենք հավելվածի նախնական թողարկման փորձարկման մասին, օգտագործելով .
Ներբեռնման համար պահանջվող պայմաններն են՝ App Store-ի ստորագրության պրոֆիլի տեսակը և ստեղծված API ստեղների առկայությունը:
Հավելվածը ներբեռնելու մի քանի եղանակ կա.
- Xcode-ի միջոցով (Կազմակերպիչ),
- գործիքի միջոցով,
- Application Loader-ի միջոցով Xcode-ի (այժմ՝ Transporter) հին տարբերակների համար:
Ավտոմատ ներբեռնման համար օգտագործվում է altool, որն ունի նաև թույլտվության երկու եղանակ.
- Հավելվածի հատուկ գաղտնաբառ,
- 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-ի միջոցով ներբեռնելու մեկ այլ միջոց է օգտագործել App-Specific Password-ը:
Հավելվածին հատուկ գաղտնաբառ ստանալու համար պետք է գնալ և ստեղծեք այն Անվտանգության բաժնում:

Հաջորդը, այս գաղտնաբառով դուք պետք է ստեղծեք սերվերի կառուցման գրառում Keychain-ում: 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Ինչպես տեսնում եք, Short Name-ի պահանջվող արժեքը (asc-provider) համընկնում է $TeamID պարամետրի հետ, որը մենք օգտագործել ենք հավելվածը կառուցելիս:
Հավելվածը TestFlight-ում վավերացնելու և բեռնելու համար օգտագործեք հրամանը.
xcrun altool
--(validate|upload)-app
-f $(find "$ProjectDir" -name "*.ipa")
-u "$DeveloperName"
-p "@keychain:Altool" Որպես պարամետրի արժեք -p կարող եք վերցնել արժեքը $AppPswd չգաղտնագրված (բացահայտ) ձևով:
Այնուամենայնիվ, ինչպես արդեն նշվեց, կատարողականի տեսանկյունից ավելի լավ է ընտրել API Key-ը altool-ի թույլտվության համար, քանի որ Xcode-ի տարբեր տարբերակները որոշակի խնդիրներ ունեն («չի տեսնում» Keychain, թույլտվության սխալներ վերբեռնման ժամանակ և այլն):
Այսքանը, իրականում: Մաղթում եմ բոլոր ներգրավվածներին հաջող կառուցումներ և առանց խնդիրների թողարկումներ App Store-ում:
Source: www.habr.com
