ืชื›ื•ื ื•ืช ืฉืœ ื‘ื ื™ื™ื” ื•ืืกืคืงื” โ€‹โ€‹ืฉืœ ื™ื™ืฉื•ืžื™ iOS

ื‘ืžืืžืจ ื–ื”, ืื ื• ื—ื•ืœืงื™ื ืืช ื”ื—ื•ื•ื™ื” ืฉืœ ื”ืจื›ื‘ื” ื•ืืกืคืงื” โ€‹โ€‹ืฉืœ ื™ื™ืฉื•ืžื™ iOS ืœืžืฉืชืžืฉื™ื, ืืฉืจ ืฆื‘ืจ ื”ืกื˜ื•ื“ื™ื• ืฉืœ Plarium Krasnodar ื‘ืชื”ืœื™ืš ืฉืœ ืื™ืชื•ืจ ื‘ืื’ื™ื CI/CD.

ืชื›ื•ื ื•ืช ืฉืœ ื‘ื ื™ื™ื” ื•ืืกืคืงื” โ€‹โ€‹ืฉืœ ื™ื™ืฉื•ืžื™ iOS

ื”ื“ืจื›ื”

ื›ืœ ืื“ื ืฉืขื•ืกืง ื‘ื“ืจืš ื–ื• ืื• ืื—ืจืช ื‘ืคื™ืชื•ื— ืืคืœื™ืงืฆื™ื•ืช ืœืžื›ืฉื™ืจื™ ืืคืœ ื›ื‘ืจ ื”ืขืจื™ืš ืืช ื”ื ื•ื—ื•ืช ื”ืฉื ื•ื™ื” ื‘ืžื—ืœื•ืงืช ืฉืœ ื”ืชืฉืชื™ืช. ืงืฉื™ื™ื ื ืžืฆืื™ื ื‘ื›ืœ ืžืงื•ื: ืžืชืคืจื™ื˜ ืคืจื•ืคื™ืœ ื”ืžืคืชื— ื•ืขื“ ืœื›ืœื™ ื ื™ืคื•ื™ ื•ื‘ื ื™ื™ื”.

ื™ืฉ ื”ืจื‘ื” ืžืืžืจื™ื ืขืœ ื”"ื™ืกื•ื“ื•ืช" ื‘ืื™ื ื˜ืจื ื˜, ืื– ื ื ืกื” ืœื”ื“ื’ื™ืฉ ืืช ื”ืขื™ืงืจ. ื”ื ื” ืžื” ืฉืืชื” ืฆืจื™ืš ื›ื“ื™ ืœื‘ื ื•ืช ืืช ื”ื™ื™ืฉื•ื ืฉืœืš ื‘ื”ืฆืœื—ื”:

  • ื—ืฉื‘ื•ืŸ ืžืคืชื—;
  • ืžื›ืฉื™ืจ ืžื‘ื•ืกืก macOS ื”ืคื•ืขืœ ื›ืฉืจืช build;
  • ื ื•ืฆืจ ืชืขื•ื“ืช ืžืคืชื—, ืืฉืจ ื™ืฉืžืฉ ืขื•ื“ ืœื—ืชื™ืžื” ืขืœ ื”ื‘ืงืฉื”;
  • ื ื•ืฆืจ ื™ื™ืฉื•ื ืขื ื™ื™ื—ื•ื“ื™ ID (ื™ืฉ ืœืฆื™ื™ืŸ ืืช ื”ื—ืฉื™ื‘ื•ืช ืฉืœ ืžื–ื”ื” ื”ื—ื‘ื™ืœื”, ืžื›ื™ื•ื•ืŸ ืฉื”ืฉื™ืžื•ืฉ ื‘ืžื–ื”ื” ื›ืœืœื™ ืœื ืžืืคืฉืจ ืœื”ืฉืชืžืฉ ื‘ืคื•ื ืงืฆื™ื•ืช ืจื‘ื•ืช ืฉืœ ื”ืืคืœื™ืงืฆื™ื”, ืœืžืฉืœ: ื“ื•ืžื™ื™ื ื™ื ืžืฉื•ื™ื›ื™ื, ื”ื•ื“ืขื•ืช ื“ื—ื™ืคื”, Apple Sign In ื•ืื—ืจื•ืช);
  • ืคืจื•ืคื™ืœ ื—ืชื™ืžื•ืช ืืคืœื™ืงืฆื™ื”.

ื™ืฉ ืœื”ืคื™ืง ืื™ืฉื•ืจ ืžืคืชื— ื‘ืืžืฆืขื•ืช ืžื—ื–ื™ืง ืžืคืชื—ื•ืช ื‘ื›ืœ ืžื›ืฉื™ืจ macOS. ืกื•ื’ ื”ืชืขื•ื“ื” ื—ืฉื•ื‘ ืžืื•ื“. ื‘ื”ืชืื ืœืกื‘ื™ื‘ืช ื”ืืคืœื™ืงืฆื™ื” (Dev, QA, Staging, Production) ื–ื” ื™ื”ื™ื” ืฉื•ื ื” (ืคื™ืชื•ื— ืื• ื”ืคืฆื”), ื•ื›ืš ื’ื ืกื•ื’ ืคืจื•ืคื™ืœ ื—ืชื™ืžืช ื”ืืคืœื™ืงืฆื™ื”.

ืกื•ื’ื™ ืคืจื•ืคื™ืœื™ื ืขื™ืงืจื™ื™ื:

  • ืคื™ืชื•ื— - ืžื™ื•ืขื“ ืœื—ืชื™ืžื” ืขืœ ื”ืืคืœื™ืงืฆื™ื” ืฉืœ ืฆื•ื•ืช ื”ืคื™ืชื•ื—, ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘ืชืขื•ื“ืช ืคื™ืชื•ื— (ืฉื ืกื•ื’ ืื™ื™ืคื•ืŸ ืžืคืชื—: XXXXX);
  • ืื“ ื”ื•ืง - ืžื™ื•ืขื“ ืœื—ืชื™ืžื” ืขืœ ืืคืœื™ืงืฆื™ื™ืช ื‘ื“ื™ืงื” ื•ืื™ืžื•ืช ืคื ื™ืžื™ ืขืœ ื™ื“ื™ ืžื—ืœืงืช QA, ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘ืชืขื•ื“ืช ื”ืคืฆื” ืฉืœ ื”ืžืคืชื— (ืฉื ืกื•ื’ iPhone Distribution: XXXXX);
  • App Store - ืฉื—ืจื•ืจ build ืœื‘ื“ื™ืงื” ื—ื™ืฆื•ื ื™ืช ื‘ืืžืฆืขื•ืช TestFlight ื•ื”ืขืœืื” ืœ-App Store, ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘ืชืขื•ื“ืช ื”ื”ืคืฆื” ืฉืœ ื”ืžืคืชื—.

ื‘ืขืช ื™ืฆื™ืจืช ืคืจื•ืคื™ืœื™ ืคื™ืชื•ื— ื•ืื“ ื”ื•ืง, ื–ื” ื’ื ืžืฆื•ื™ืŸ ืจืฉื™ืžืช ื”ืžื›ืฉื™ืจื™ื, ืฉื‘ื• ืืชื” ื™ื›ื•ืœ ืœื”ืชืงื™ืŸ build, ื”ืžืืคืฉืจ ืœืš ืœื”ื’ื‘ื™ืœ ืขื•ื“ ื™ื•ืชืจ ืืช ื”ื’ื™ืฉื” ืœืžืฉืชืžืฉื™ื. ืื™ืŸ ืจืฉื™ืžื” ืฉืœ ืžื›ืฉื™ืจื™ื ื‘ืคืจื•ืคื™ืœ App Store, ืฉื›ืŸ ื‘ืงืจืช ื”ื’ื™ืฉื” ื‘ืžื”ืœืš ื‘ื“ื™ืงื•ืช ื‘ื˜ื ืกื’ื•ืจื•ืช ืžื˜ื•ืคืœืช ืขืœ ื™ื“ื™ TestFlight, ืขืœื™ื” ื ื“ื•ืŸ ื‘ื”ืžืฉืš.

ืœืฉื ื”ื‘ื”ื™ืจื•ืช, ืืชื” ื™ื›ื•ืœ ืœื”ืฆื™ื’ ืืช ืคืจื•ืคื™ืœ ื”ืžืคืชื— ื‘ืฆื•ืจื” ืฉืœ ื˜ื‘ืœื” ืœืžื˜ื”. ื›ืš ืงืœ ื™ื•ืชืจ ืœื”ื‘ื™ืŸ ืื™ืœื• ืคืจืžื˜ืจื™ื ืื ื• ืฆืจื™ื›ื™ื ืœื”ืจื›ื‘ื” ื•ืžืื™ืคื” ืœื”ืฉื™ื’ ืื•ืชื.

ืชื›ื•ื ื•ืช ืฉืœ ื‘ื ื™ื™ื” ื•ืืกืคืงื” โ€‹โ€‹ืฉืœ ื™ื™ืฉื•ืžื™ iOS

ื”ืขืฆืจืช

ื›ื“ื™ ืœื”ืงืœ ืขืœ ื”ืคืจื“ืช ืžื›ืœื•ืœื™ื ืœืคื™ ืคืจื•ื™ืงื˜ ื•ืกื‘ื™ื‘ื”, ืื ื• ืžืฉืชืžืฉื™ื ื‘ืฉืžื•ืช ืคืจื•ืคื™ืœื™ื ื›ืžื• ${ProjectName}_${Instance}, ื›ืœื•ืžืจ, ืฉื ื”ืคืจื•ื™ืงื˜ + ืžื•ืคืข (ืชืœื•ื™ ื‘ืกื‘ื™ื‘ืช ื”ืืคืœื™ืงืฆื™ื”: Dev, QA, GD, Staging, Live ื•ื›ืŸ ื”ืœืื”).

ื›ืืฉืจ ืžื™ื•ื‘ื ืœืฉืจืช ื”-build, ื”ืคืจื•ืคื™ืœ ืžืฉื ื” ืืช ืฉืžื• ืœืžื–ื”ื” ื™ื™ื—ื•ื“ื™ ื•ืžื•ืขื‘ืจ ืœืชื™ืงื™ื” /Users/$Username/Library/MobileDevice/Provisioning Profiles (ืื™ืคื” $Username ืžืชืื™ื ืœืฉื ื—ืฉื‘ื•ืŸ ื”ืžืฉืชืžืฉ ืฉืœ ืฉืจืช ื”-build).

ื™ืฉื ืŸ ืฉืชื™ ื“ืจื›ื™ื ืœื‘ื ื•ืช ืงื•ื‘ืฅ *.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 - ืฉื ื—ืฉื‘ื•ืŸ ื”ืžืคืชื—, ืฉื ื™ืชืŸ ืœืืžืช ื‘ืžื—ื–ื™ืง ืžืคืชื—ื•ืช (ืžืคืชื— ืื™ื™ืคื•ืŸ: XXXX XXXXXXX, ืœืœื TeamID ื‘ืกื•ื’ืจื™ื™ื).

ืชื›ื•ื ื•ืช ืฉืœ ื‘ื ื™ื™ื” ื•ืืกืคืงื” โ€‹โ€‹ืฉืœ ื™ื™ืฉื•ืžื™ iOS

PROVISIONING_PROFILE - ืžื–ื”ื” ืคืจื•ืคื™ืœ ืœื—ืชื™ืžื” ืขืœ ื”ื‘ืงืฉื”, ืฉื ื™ืชืŸ ืœื”ืฉื™ื’ ื‘ืืžืฆืขื•ืช ื”ืคืงื•ื“ื”:

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"

ืขื ื–ืืช, ืฉื™ื˜ื” ื–ื• ื ื—ืฉื‘ืช ืœืžื™ื•ืฉื ืช ืžื ืงื•ื“ืช ืžื‘ื˜ื” ืฉืœ โ€‹โ€‹ืืคืœ. ืจืœื•ื•ื ื˜ื™ ืœื”ืฉื™ื’ *.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 - ื—ื ื•ืช ืืคืœื™ืงืฆื™ื•ืช.

$BundleID โ€” ืžื–ื”ื” ื™ื™ืฉื•ื, ื”ืžืฆื•ื™ืŸ ื‘ื”ื’ื“ืจื•ืช ื”ื™ื™ืฉื•ื. ืืชื” ื™ื›ื•ืœ ืœื‘ื“ื•ืง ืขื ื”ืคืงื•ื“ื”:

defaults read $ProjectDir/Info CFBundleIdentifier

$DevAccName ะธ $ProfileId - ื”ื’ื“ืจื•ืช ืฉื ืžืคืชื— ื•ืžื–ื”ื” ืคืจื•ืคื™ืœ ื—ืชื™ืžื” ืฉื”ื™ื• ื‘ืฉื™ืžื•ืฉ ื‘ืขื‘ืจ ื•ื—ื™ื™ื‘ื•ืช ืœื”ืชืื™ื ืœืขืจื›ื™ื ื‘ื”ื’ื“ืจื•ืช ื”ื™ื™ืฆื•ื.

$TeamID - ืžื–ื”ื” ื‘ืŸ ืขืฉืจ ืกืคืจื•ืช ื‘ืกื•ื’ืจื™ื™ื ืื—ืจื™ ืฉื ื”ืžืคืชื—, ื“ื•ื’ืžื”: ืžืคืชื— iPhone: โ€ฆโ€ฆ (XXXXXXXXXX); ื ื™ืชืŸ ืœื‘ื“ื•ืง ื‘ืžื—ื–ื™ืง ืžืคืชื—ื•ืช.

ืœืื—ืจ ืžื›ืŸ, ื‘ืืžืฆืขื•ืช ืคืงื•ื“ืช ื”ื™ื™ืฆื•ื, ื ืงื‘ืœ ืืช ืงื•ื‘ืฅ *.ipa ื”ื“ืจื•ืฉ:

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

ืžืฉืœื•ื—

ื›ืขืช ื™ืฉ ืœื”ืขื‘ื™ืจ ืืช ื”ืงื•ื‘ืฅ ืฉื ืืกืฃ ืœืžืฉืชืžืฉ ื”ืงืฆื”, ื›ืœื•ืžืจ ืœื”ืชืงื™ืŸ ื‘ืžื›ืฉื™ืจ.

ื™ืฉื ื ืฉื™ืจื•ืชื™ื ืจื‘ื™ื ืœื”ืคืฆืช ืคื™ืชื•ื— ื•ื‘ื ื™ื™ืช ืื“ ื”ื•ืง, ื›ืžื• 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 (ืžืืจื’ืŸ),
  • ื“ืจืš altool,
  • ื‘ืืžืฆืขื•ืช Application Loader ืขื‘ื•ืจ ื’ืจืกืื•ืช ื™ืฉื ื•ืช ื™ื•ืชืจ ืฉืœ Xcode (ื›ื™ื•ื Transporter).

ืœื”ื•ืจื“ื” ืื•ื˜ื•ืžื˜ื™ืช, ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘-altool, ืฉื™ืฉ ืœื• ื’ื ืฉืชื™ ืฉื™ื˜ื•ืช ื”ืจืฉืื”:

  • ืกื™ืกืžื” ืกืคืฆื™ืคื™ืช ืœืืคืœื™ืงืฆื™ื”,
  • ืžืคืชื— API.

ืขื“ื™ืฃ ืœื”ื•ืจื™ื“ ืืช ื”ืืคืœื™ืงืฆื™ื” ื‘ืืžืฆืขื•ืช ืžืคืชื— ื”-API.

ื›ื“ื™ ืœืงื‘ืœ ืืช ืžืคืชื— ื”-API, ืขื‘ื•ืจ ืืœ ืงืฉืจ ื•ืœื™ืฆื•ืจ ืžืคืชื—. ื‘ื ื•ืกืฃ ืœืžืคืชื— ืขืฆืžื• ื‘ืคื•ืจืžื˜ *.p8, ื ืฆื˜ืจืš ืฉื ื™ ืคืจืžื˜ืจื™ื: IssuerID ื•-KeyID.

ืชื›ื•ื ื•ืช ืฉืœ ื‘ื ื™ื™ื” ื•ืืกืคืงื” โ€‹โ€‹ืฉืœ ื™ื™ืฉื•ืžื™ iOS

ืœืื—ืจ ืžื›ืŸ, ื™ื™ื‘ื ืืช ื”ืžืคืชื— ืฉื”ื•ืจื“ ืœืฉืจืช ื”-build:

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 ืขื ืื•ืชื ืคืจืžื˜ืจื™ื.

ื”ืืคืœื™ืงืฆื™ื” ืชื™ื‘ื“ืง ืขืœ ื™ื“ื™ ืืคืœ ืชื•ืš ื™ื•ื ืื• ื™ื•ืžื™ื™ื ื•ืœืื—ืจ ืžื›ืŸ ืชื”ืคื•ืš ืœื–ืžื™ื ื” ืœื‘ื•ื“ืงื™ื ื—ื™ืฆื•ื ื™ื™ื: ื”ื ื™ืงื‘ืœื• ืงื™ืฉื•ืจื™ื ื‘ื“ื•ื"ืœ ืœื”ืชืงื ื”.

ื“ืจืš ื ื•ืกืคืช ืœื”ื•ืจื™ื“ ืืคืœื™ืงืฆื™ื” ื“ืจืš altool ื”ื™ื ืœื”ืฉืชืžืฉ ื‘ืกื™ืกืžื” ืกืคืฆื™ืคื™ืช ืœืืคืœื™ืงืฆื™ื”.

ื›ื“ื™ ืœืงื‘ืœ ืืช ื”ืกื™ืกืžื” ื”ืกืคืฆื™ืคื™ืช ืœืืคืœื™ืงืฆื™ื” ืขืœื™ืš ืœืขื‘ื•ืจ ืืœ ืงืฉืจ ื•ื”ืคืง ืื•ืชื• ื‘ืกืขื™ืฃ ืื‘ื˜ื—ื”.

ืชื›ื•ื ื•ืช ืฉืœ ื‘ื ื™ื™ื” ื•ืืกืคืงื” โ€‹โ€‹ืฉืœ ื™ื™ืฉื•ืžื™ iOS

ืœืื—ืจ ืžื›ืŸ, ืขืœื™ืš ืœื™ืฆื•ืจ ืจืฉื•ืžืช ืฉืจืช ืœื‘ื ื•ืช ื‘ืžื—ื–ื™ืง ืžืคืชื—ื•ืช ืขื ืกื™ืกืžื” ื–ื•. ืžื’ืจืกื” 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

ื›ืคื™ ืฉืืชื” ื™ื›ื•ืœ ืœืจืื•ืช, ืขืจืš ื”-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.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”