Хусусиятҳои сохтан ва расонидани замимаҳои iOS

Дар ин мақола мо таҷрибаи ҷамъоварӣ ва расонидани замимаҳои iOS-ро ба корбарон мубодила мекунем, ки студияи Plarium Краснодар дар ҷараёни ислоҳи CI/CD ҷамъ кардааст.

Хусусиятҳои сохтан ва расонидани замимаҳои iOS

Омодагӣ

Ҳар як шахсе, ки ба ин ё он роҳ дар таҳияи замимаҳо барои дастгоҳҳои Apple машғул аст, аллакай бароҳатии баҳсбарангези инфрасохторро қадр кардааст. Мушкилот дар ҳама ҷо пайдо мешаванд: аз менюи профили таҳиякунанда то абзорҳои ислоҳ ва сохтани.

Дар Интернет мақолаҳои зиёде дар бораи "асосиҳо" мавҷуданд, аз ин рӯ мо кӯшиш мекунем, ки чизи асосиро таъкид кунем. Ин аст он чизе ки ба шумо барои бомуваффақият сохтани аризаи худ лозим аст:

  • ҳисоби таҳиякунанда;
  • дастгоҳи дар MacOS асосёфта, ки ҳамчун сервери сохта амал мекунад;
  • тавлидшуда шаҳодатномаи таҳиякунанда, ки минбаъд барои имзои ариза истифода мешавад;
  • замимаи бо беназир сохташуда ID (аҳамияти Идентификатори маҷмӯаро бояд қайд кард, зеро истифодаи ID аломати ваҳшӣ истифодаи бисёр функсияҳои барномаро ғайриимкон месозад, масалан: Доменҳои алоқаманд, Огоҳиҳои Push, Sign In Apple ва ғайра);
  • профил имзоҳои ариза.

Шаҳодатномаи таҳиягар бояд тавассути Keychain дар ҳама гуна дастгоҳи macOS тавлид карда шавад. Навъи шаҳодатнома хеле муҳим аст. Вобаста аз муҳити барнома (Dev, QA, Staging, Production) он фарқ мекунад (таҳия ё тақсимот), инчунин намуди профили имзои барнома.

Намудҳои асосии профилҳо:

  • Таҳия - барои имзои аризаи дастаи таҳиякунанда пешбинӣ шудааст, шаҳодатномаи рушд истифода мешавад (номи навъи iPhone Developer: XXXXXX);
  • Ad Hoc - барои имзои аризаи санҷишӣ ва санҷиши дохилӣ аз ҷониби шӯъбаи QA пешбинӣ шудааст, шаҳодатномаи тақсимоти таҳиякунанда истифода мешавад (номи навъи iPhone Distribution: XXXXX);
  • Дӯкони App - сохтани релиз барои санҷиши беруна тавассути TestFlight ва боргузорӣ ба Дӯкони App, шаҳодатномаи тақсимоти таҳиягар истифода мешавад.

Ҳангоми тавлиди профилҳои рушд ва махсус, он инчунин нишон дода мешавад рӯйхати дастгоҳ, ки дар он шумо метавонед сохтаеро насб кунед, ки ба шумо имкон медиҳад, ки дастрасии корбаронро минбаъд маҳдуд кунед. Рӯйхати дастгоҳҳо дар профили Store App мавҷуд нест, зеро назорати дастрасӣ ҳангоми санҷиши бета пӯшида аз ҷониби 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 — номи ҳисоби таҳиягар, ки онро дар Keychain тафтиш кардан мумкин аст (Developer 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//'

Агар барнома профили иловагиро истифода барад (масалан, барои огоҳиҳои Push), ба ҷои 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 даҳ рақам дар қавс пас аз номи таҳиякунанда, мисол: Developer iPhone: …… (XXXXXXXXX); дар Keychain тафтиш кардан мумкин аст.

Баъдан, бо истифода аз фармони содирот, мо файли зарурии *.ipa -ро мегирем:

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

Маълумоти интиқол

Акнун файли ҷамъшуда бояд ба корбари ниҳоӣ расонида шавад, яъне дар дастгоҳ насб карда шавад.

Хидматҳои зиёде барои паҳн кардани сохторҳои таҳия ва Ad Hoc мавҷуданд, ба монанди HockeyApp, AppBlade ва дигарон, аммо дар ин мақола мо дар бораи сервери мустақил барои паҳн кардани барномаҳо сӯҳбат хоҳем кард.

Насби барнома барои iOS дар 2 марҳила сурат мегирад:

  1. Қабули манифести насби барнома тавассути хидмати Items.
  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

Барои эҳтиёҷоти шӯъбаҳои таҳия ва озмоиш, Plarium барномаи насби худро эҷод кардааст, ки ба мо медиҳад:

  • мустақилият ва мустақилият,
  • мутамарказкунии назорати дастрасӣ ва насби бехатари барномаҳо тавассути истинодҳои динамикии "муваққатӣ",
  • функсияи васеъшаванда (яъне дастаи таҳиякунанда, агар лозим бошад, метавонад вазифаҳои норасидаро ба замимаи мавҷуда муттаҳид кунад).

санҷиши

Ҳоло мо дар бораи санҷиши пеш аз барориши барнома истифода мебарем парвози озмоишӣ.

Шартҳои зарурӣ барои зеркашӣ намуди профили имзои App Store ва мавҷудияти калидҳои тавлидшудаи API мебошанд.

Якчанд роҳҳо барои зеркашии барнома вуҷуд доранд:

  • тавассути Xcode (ташкилгар),
  • тавассути altool,
  • тавассути 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

Баъдан, шумо бояд бо ин парол дар 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

Тавре ки шумо мебинед, арзиши лозимии Номи кӯтоҳ (asc-provider) бо параметри $TeamID, ки мо ҳангоми сохтани барнома истифода мебурдем, мувофиқат мекунад.

Барои тасдиқ ва бор кардани барнома ба TestFlight, фармонро истифода баред:

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

Ҳамчун арзиши параметр -p шумо метавонед арзишро гиред $AppPswd дар шакли рамзнашуда (равшан).

Аммо, тавре ки аллакай зикр гардид, аз нуқтаи назари иҷроиш, беҳтар аст, ки API Калиди авторизатсияро интихоб кунед, зеро версияҳои гуногуни Xcode мушкилоти муайян доранд (" Keychain намебинад, хатогиҳои авторизатсия ҳангоми боргузорӣ ва ғайра).

Дар асл, ҳамааш ҳамин аст. Ман ба ҳама хоҳишмандам, ки дар Дӯкони Барномасозони бомуваффақият ва нашрҳои бе мушкилот иштирок кунанд.

Манбаъ: will.com

Илова Эзоҳ