Xcode खोले बिना Mac·iOS ऐप्स को build और deploy करना
(scottwillsey.com)- शुरुआती Apple अकाउंट और certificate सेटअप पूरा होने पर Xcode.app के अंदर मौजूद CLI tools से ही Mac और iOS ऐप्स के build, signing और deployment को automate किया जा सकता है
project.ymlमें XcodeGen से.xcodeprojदोबारा generate किया जाता है, औरxcodebuild,notarytool,stapler,devicectlसे project generation से लेकर Mac notarization और iPhone install तक संभाला जाता है- Mac deployment में
scripts/release.shएक ही स्क्रिप्ट से archive, Developer ID signing, notarization, ticket stapling, Gatekeeper verification और/Applicationsinstall को क्रम से चलाता है, और failure होने पर तुरंत रुक जाता है - तेज compile और test के लिए
CODE_SIGNING_ALLOWED=NOइस्तेमाल किया जा सकता है, लेकिन यह ad-hoc signed build Gatekeeper पार नहीं कर पाता और iCloud KVS व App Group permissions भी असली team ID से bind नहीं होतीं - signing private key और notarization password को login keychain में रखा जाता है, और
CLAUDE.mdयाAGENTS.mdमें commands और deployment rules लिख देने पर Claude Code जैसे agents पूरे workflow को बार-बार चला सकते हैं
Xcode GUI के बिना क्या-क्या किया जा सकता है
- Xcode install होना ज़रूरी है, लेकिन उसे चलाने की ज़रूरत नहीं है;
xcodebuild,notarytool,stapler,devicectlसभी Xcode.app के अंदर मौजूद shell tools हैं और अलग से चल सकते हैं - Apple ID login, Developer ID certificate बनाना, notarization password save करना जैसी पहली बार की सेटिंग के लिए GUI या interactive terminal चाहिए
- शुरुआती सेटअप के बाद project generation, build, archive, signed app export, notarization, verification, install, और असली iPhone deployment तक सब कुछ mouse के बिना किया जा सकता है
- जब configuration या scripts लिखने में अड़चन आए, तो Claude Code या किसी दूसरे LLM coding tool को काम की requirements और project-specific values देकर workflow बनवाया जा सकता है
पूरा Xcode toolchain चुनना
- पहले यह जांचना चाहिए कि
xcode-select -pका result/Applications/Xcode.app/Contents/Developerहै या नहीं - अगर standalone Command Line Tools चुने गए हों, तो नीचे दिए command से पूरा Xcode toolchain चुनें
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
xcode-select --installसे install होने वाले/Library/Developer/CommandLineToolsमेंclangऔरgitहोते हैं, लेकिन iOS SDK,notarytool,devicectlजैसे पूरे app development tools नहीं होते- अगर Xcode पहले से install है, तो अलग Command Line Tools package की ज़रूरत नहीं है
- license स्वीकार करना और अतिरिक्त components install करना भी CLI से किया जा सकता है
sudo xcodebuild -license accept
sudo xcodebuild -runFirstLaunch
XcodeGen से project को दोबारा बनाना
- XcodeGen Xcode project settings को YAML में manage करता है और हर build पर
.xcodeprojफिर से generate करता है - इसे GitHub से download किया जा सकता है या Homebrew से install किया जा सकता है
brew install xcodegen
.xcodeprojmacOS में file जैसा दिखने वाला folder होता है, और Xcode लगातार उसके अंदर की files और references बदलता रहता है, इसलिए Git repository में conflicts या बेवजह changes आ सकते हैं- सिर्फ
project.ymlको Git में commit करके और generated.xcodeprojको ignore करके project settings को reproducible रखा जा सकता है
xcodegen generate
Apple developer account और certificate सेटअप
- Xcode के
Settings → Accountsमें Apple ID जोड़नी होती है - app deployment और notarization के लिए paid Apple Developer account चाहिए
Settings → Accounts → Apple ID → Manage Certificates… → + → Developer ID Applicationमें deployment certificate बनाया जाता है- Apple Development और Developer ID Application के काम अलग-अलग हैं
- Apple Development का इस्तेमाल अपने device पर चलाने या iPhone पर भेजकर local debugging के लिए होता है
- Developer ID Application की ज़रूरत notarized
.appको दूसरे लोगों के Mac पर भी Gatekeeper के साथ distribute करने के लिए होती है
- Developer ID Application certificate बनाते समय certificate और उससे जुड़ी private key login keychain में install हो जाती है
- असली signing में private key इस्तेमाल होती है और उसे दोबारा download नहीं किया जा सकता, इसलिए उसे delete नहीं करना चाहिए और keychain का backup रखना चाहिए
notarization credentials को keychain में सहेजना
- Mac app notarization वह प्रक्रिया है जिसमें signed app को Apple पर upload करके malware scan कराया जाता है
notarytoolkeychain में stored profile से authenticate करता है, और profile पहली बार बनाते समय app-specific password interactive तरीके से डालना पड़ता है
xcrun notarytool store-credentials App-Name \
--apple-id "you@example.com" \
--team-id YOUR-TEAM-ID
- notarization profile किसी दूसरे app का उधार लेकर इस्तेमाल नहीं करना चाहिए; app के नाम के हिसाब से अलग बनाना चाहिए ताकि दूसरी environment में चुपचाप failure न हो
- app-specific password, Apple ID password से अलग होता है, और इसे Apple ID site के
Sign-In & Security → App-Specific Passwordsमें बनाया जाता है - Apple ID password बदलने पर app-specific password बिना अलग warning के expire हो सकता है
- अगर notarization के दौरान
401 invalid credentialsआए, तो पूरी setup पर शक करने से पहले app-specific password expiry जांचनी चाहिए
- अगर notarization के दौरान
- profile save हुई है या नहीं, इसे नीचे दिए command से verify किया जा सकता है
xcrun notarytool history --keychain-profile App-Name
- अगर app-specific password को ऐसे 1Password vault में रखा जाए जिसे Claude Code access कर सके, तो नए app के notarization profile creation का काम भी agent से कराया जा सकता है
--passwordसे password input तक automate किया जा सकता है, लेकिन shell history में password रह सकता है, इसलिए एक बार manually डालकर उसे keychain या 1Password में रखना बेहतर है
local signing settings और secrets को अलग रखना
- असली signing के लिए चाहिए team ID और bundle prefix को
Local.xcconfigमें रखा जाता है
cp Local.xcconfig.example Local.xcconfig
BUNDLE_PREFIX = your.real.prefix
DEVELOPMENT_TEAM = YOUR-TEAM-ID
Local.xcconfigको.gitignoreमें जोड़ देना चाहिए ताकि project-specific local settings repository में न जाएं- signing private key login keychain में रहती है, और notarization के लिए app-specific password
notarytoolkeychain profile में रहता है, इसलिए secret data Git में रिकॉर्ड नहीं होता
release.sh से Mac deployment automate करना
- repository का
scripts/release.shMac app की पूरी deployment pipeline को एक command से चलाता है
./scripts/release.sh
-
स्क्रिप्ट इस क्रम में काम करती है
- पहले से जांचती है कि
xcodegenऔर notarization profile मौजूद हैं या नहीं xcodegen generateसे project दोबारा generate करती हैxcodebuild archiveसे Release archive बनाती हैExportOptions.plistऔरxcodebuild -exportArchiveसे Developer ID signed app export करती है- app को ZIP में बांधकर
notarytool submit --waitसे Apple को submit करती है stapler stapleसे notarization ticket attach करती हैspctlसे verify करती है कि Gatekeeper allow करेगा या नहीं- चल रही पुरानी process बंद करके app को
/Applicationsमें copy करती है lsregisterसे installed app register करती है- installed bundle के ticket और Gatekeeper status को फिर से verify करती है
- पहले से जांचती है कि
-
model को सामान्य deployment प्रक्रिया पता हो, तब भी scheme name, team ID, notarization profile name, install location जैसी project-specific जानकारी user को देनी होगी
-
पहली script fail हो सकती है, और output के आधार पर उसे सुधारने की iteration करनी पड़ती है; लेकिन workflow stable होने के बाद बिना अतिरिक्त बदलाव के सिर्फ deployment command चलाया जा सकता है
-
failure और अधूरे deployment से बचाव
set -euo pipefailयह सुनिश्चित करता है कि एक भी command fail होने पर script तुरंत रुक जाए, ताकि अधूरी स्थिति को success न माना जाएcd "$(dirname "$0")/.."script को किसी भी directory से चलाने पर repository root में ले जाता है- preflight check block लंबे archive process से पहले
xcodegenऔर notarization profile की जांच करता है - केवल exported app ही नहीं,
/Applicationsमें copied app को भी फिर से जांचा जाता है ताकि copy के दौरान bundle corruption पकड़ में आ सके - अगर दूसरी notarization profile चाहिए, तो environment variable से override किया जा सकता है
TZED_NOTARY_PROFILE=<name> ./scripts/release.sh
agent को deployment rules बताना
- अगर
release.shएक command में deployment कर देता है, तोCLAUDE.mdयाAGENTS.mdagent को यह सिखा सकता है कि हर session में अलग निर्देशों के बिना वही command इस्तेमाल करे - document में project regenerate करना, unit tests, तेज macOS build, और असली deployment command लिखी जाती हैं
xcodegen generate
swift test
xcodebuild -project YOUR-APP-NAME.xcodeproj \
-scheme YOUR-APP-NAME-macOS \
-destination 'platform=macOS' \
CODE_SIGNING_ALLOWED=NO build
./scripts/release.sh
- दोनों build paths का फर्क भी document में साफ लिखना चाहिए
CODE_SIGNING_ALLOWED=NObuild CI और तेज local verification के लिए ठीक है- असली menu bar app deployment, quarantine attributes पार करना, और iCloud sync के लिए Developer ID signing और notarization करने वाला
release.shचाहिए
- अगर agent को कहा जाए कि एक app में बना तरीका दूसरे repository में भी refer करे, तो Claude Code बाद के apps में भी वही setup replicate कर सकता है
तेज unsigned build और testing
- Swift Package Manager पर आधारित unit tests, Xcode build के बिना चलाए जा सकते हैं
swift test
- macOS app के लिए तेज compile verification, signing बंद करके की जा सकती है
xcodebuild -project TZed.xcodeproj \
-scheme TZed-macOS \
-destination 'platform=macOS' \
CODE_SIGNING_ALLOWED=NO build
- iOS app और widget extension के simulator builds भी इसी तरीके से चलाए जा सकते हैं
xcodebuild -project TZed.xcodeproj \
-scheme TZed-iOS \
-destination 'generic/platform=iOS Simulator' \
CODE_SIGNING_ALLOWED=NO build
CODE_SIGNING_ALLOWED=NOसे बने ad-hoc signed builds compile और simulator run के लिए इस्तेमाल किए जा सकते हैं- लेकिन इन्हें Gatekeeper reject करता है, और team prefix न होने की वजह से iCloud KVS और App Group जैसी permissions bind नहीं होतीं, इसलिए ये deployment के लिए उपयोगी नहीं हैं
असली iPhone पर headless deployment
- iOS device deployment में Mac app जैसी notarization step नहीं होती; इसके लिए
xcodebuildऔरdevicectlका इस्तेमाल होता है - असली device के लिए app को Apple Development certificate और development provisioning profile से build और sign किया जाता है
xcodebuild -project TZed.xcodeproj \
-scheme TZed-iOS \
-destination 'generic/platform=iOS' \
-allowProvisioningUpdates \
-derivedDataPath build/ios \
archive -archivePath build/TZed-iOS.xcarchive
- बनी हुई
.appको connected device की UDID देकर install किया जाता है
xcrun devicectl device install app \
--device <DEVICE-UDID> build/ios/…/TZed.app
devicectl list devicesconnected और paired devices के साथ उनकी UDID दिखाता है-allowProvisioningUpdatesदेने पर ज़रूरी development provisioning profile fetch हो जाती है
GUI के बिना code signing कैसे काम करता है
-
Developer ID Application certificate बनाते समय Apple certificate issue करता है, और Mac उससे जुड़ी private key generate करके दोनों को login keychain में रखता है
-
xcodebuildद्वारा call किया गयाcodesignprivate key से binary sign करता है, और Apple root certificate chain तक पहुंचने वाला certificate app में include करता है ताकि signer verify किया जा सके -
signingStyle: automaticइस्तेमाल करने परxcodebuildteam ID के हिसाब से सही certificate चुन लेता है और ज़रूरी provisioning profiles Apple से ले आता है -
इसलिए provisioning profiles को repository में commit करने की ज़रूरत नहीं पड़ती
-
permissions, notarization, stapling
- हर target की
.entitlementsfile में sandbox, network client, iCloud KVS, App Group जैसी permissions होती हैं - permissions असली team ID से sign होने पर bind होती हैं, इसलिए ad-hoc signed build में iCloud और App Group सही से काम नहीं करते
- signing और notarization अलग-अलग steps हैं
- signing यह साबित करता है कि app किसने बनाया
- notarization वह प्रक्रिया है जिसमें Apple signed app को malware scan करने के बाद ticket जारी करता है
- stapling उस ticket को app में attach करता है ताकि Gatekeeper offline होने पर भी उस पर भरोसा करे
- hidden UI इस्तेमाल करने वाले menu bar app, यानी
LSUIElementapp, में notarization XProtect detection से बचने के लिए ज़रूरी है
- हर target की
-
manual verification commands
codesign -dv --verbose=4 /Applications/TZed.app spctl -a -vvv -t exec /Applications/TZed.app stapler validate /Applications/TZed.appcodesignsigner और certificate की जांच करता हैspctlजांचता है कि Gatekeeper execution allow करेगा या नहींstapler validateverify करता है कि notarization ticket attach हुई है या नहीं
वे standard tools जिन्हें agent चलाता है
- अलग build MCP server या dedicated plugin की ज़रूरत नहीं है; Claude Code non-interactive shell में standard CLI चलाता है
- इस्तेमाल होने वाले tools हैं
xcodebuild,xcrun notarytool,xcrun stapler,spctl,codesign,devicectl,xcodegen,swift CLAUDE.mdagent को notarization profile naming rules, तेज build और असली deployment के फर्क, और deployment के समयrelease.shका इस्तेमाल करने का नियम बताता है- शुरुआती
notarytool store-credentialsही केवल interactive step रहता है; उसके बाद की पूरी प्रक्रिया automate की जा सकती है
Xcode GUI के कामों को CLI से बदलना
- Xcode द्वारा manage होने वाले
.xcodeprojgeneration कोproject.ymlऔरxcodegen generateसे बदला जा सकता है ⌘Bया Run button का समकक्षxcodebuild … buildहैProduct → Archiveकोxcodebuild … archiveसे किया जा सकता है- Organizer से app deployment को
xcodebuild -exportArchiveसे बदला जा सकता है - Organizer upload,
xcrun notarytool submit --waitसे किया जाता है - automatic ticket attach करने के लिए
xcrun stapler stapleइस्तेमाल होता है /Applicationsमें drag-and-drop install प्रक्रिया कोcp -Rऔरlsregisterसे बदला जा सकता है- असली iPhone पर Run action को
xcodebuild archiveऔरdevicectl device installसे बदला जा सकता है - Xcode और XcodeGen install करना, शुरुआती credential setup,
release.shऔरCLAUDE.mdलिखना पूरा होने के बाद, आगे के नए build deployment एक वाक्य या एक command से चलाए जा सकते हैं
1 टिप्पणियां
Hacker News की राय
Sandbox में हल न हो पाने वाली कई चीज़ों के लिए मैं AI agent को सीधे Mac पर चलाता हूँ, लेकिन xAI द्वारा SSH keys तक शामिल home directory upload करने वाली घटना देखकर इस चुनाव पर गंभीरता से दोबारा सोचने लगा हूँ
मशीन खुद खराब हो जाए, इसकी मुझे बहुत चिंता नहीं है। ज़्यादातर चीज़ें backup होती हैं या Git में commit की हुई होती हैं, इसलिए कुछ घंटों में restore की जा सकती हैं। लेकिन मैं बिल्कुल नहीं चाहता कि
.sshdirectory AI agent को भेजी जाए, और इसे prompt से रोकने की कोशिश करने के बजाय system level पर block करना चाहिए। मैं अलग user बनाने और home directory पर700permission लागू करने पर विचार कर रहा हूँ। Security जैसे 1990s में पीछे चली गई हो, लेकिन बदले में अभूतपूर्व तेज़ी से काम खत्म कर पाने की दोधारी स्थिति है। मैं भी यह जोखिम भरा तरीका इस्तेमाल कर रहा हूँ, इसलिए किसी और को दोष देने का इरादा नहीं हैpackaged solution के तौर पर open source Tart https://tart.run/ या VirtualBuddy https://github.com/insidegui/VirtualBuddy इस्तेमाल कर सकते हैं, या OS API https://developer.apple.com/documentation/virtualization को wrap करने वाला tool खुद vibe coding से बना सकते हैं। हाल में Apple container https://github.com/apple/container भी आया है
agentनाम के अलग user के रूप में चलाने वाला wrapper tool बना रहा हूँ। एक साल पहले OAuth और keychain की वजह से असफल रहा था, लेकिन हाल में Claude के इस guidance से किCLAUDE_CODE_OAUTH_TOKENइस्तेमाल किया जा सकता है, implementation सफल हो गयाACL से permissions set करने वाला helper tool चाहिए, लेकिन अभी यह macOS पर काम करता है। Risk level default Claude sandbox और पूर्ण container/machine isolation के बीच का है। Claude के अपने sandbox में सुधार के साथ इस defense-in-depth project के ROI पर शक हुआ था, लेकिन home directory leak की संभावना देखते हुए इसे जारी रखने की पर्याप्त वजह है। अभी open source के रूप में release नहीं किया है, लेकिन रुचि रखने वालों से बात करने को तैयार हूँ
मज़े के लिए मैं सिर्फ Linux इस्तेमाल करके iOS app build और test कर रहा हूँ, और यह हैरानीजनक रूप से आसान है; https://github.com/xtool-org/xtool बहुत अच्छी तरह काम करता है
TestFlight या App Store पर upload करने की ज़रूरत नहीं, Linux से भी USB के ज़रिए सीधे iPhone पर install किया जा सकता है। अगर भरोसा न हो तो coding agent से Hello World iOS app बनाने और upload करने को कहें, शुरुआत आसानी से हो जाएगी
मेरा open source project Axiom coding execution tools को Apple operating systems के लिए development tasks प्रभावी ढंग से करने में मदद करता है
इसमें विभिन्न technologies और agents के अलावा LLM tools
xclog,xcprof,xcsym,xcuiभी शामिल हैं। ये ज़रूरी functionality को token-efficient तरीके से expose करते हैं और Axiom के बाहर की technologies या agents के लिए भी उपयोगी हैं। Axiom: https://charleswiltgen.github.io/Axiom/, CLI tools: https://charleswiltgen.github.io/Axiom/tools/;“मैंने Claude Code से ऐसा script बनवाया जो Xcode खोले बिना archive, Developer ID signing, notarization, stapling,
/Applicationsinstallation तक करे और किसी भी step में failure हो तो स्पष्ट रूप से रुक जाए” यह वाक्य पढ़कर अजीब लगा। क्योंकि अभी जो लेख पढ़ रहा हूँ, वह भी जैसे Claude हमसे बात कर रहा होलेख के लगभग हर step में “Claude Code या अपनी पसंद के LLM coding tool को यह लेख दिखाएँ और उससे खुद solve करवाएँ”, “समझ न आए तो LLM से पूछकर setup में मदद लें”, “LLM इस्तेमाल करने का उद्देश्य अनचाहा manual work टालना है”, “workflow बनवाएँ” जैसे LLM से फिर पूछने के निर्देश बार-बार आते हैं, यह भी अजीब लगता है
एक साल से अधिक समय तक एजेंट्स के साथ Mac और iOS ऐप्स डेवलप करने के अनुभव से मुझे यह लेख अच्छी सलाह नहीं लगता। खासकर बेहतरीन Xcode MCP के लिए Xcode का चलना जरूरी है
MCP टूल इस्तेमाल करने पर
xcodebuildकी तुलना में कई फ़ीचर्स तक कहीं तेज़ और संक्षिप्त तरीके से पहुँचा जा सकता है, और Xcode बंद करने पर जो संभव नहीं होता, वह#Previewबनाना और रेंडर करना भी संभव हो जाता है। Xcode 27 का MCP और बिल्ट-इन एजेंट DeviceHub के ज़रिए simulator को भी बहुत अच्छी तरह कंट्रोल करते हैं। DeviceHub, Simulator.app की जगह लेता है, और ऐसा लगता है कि एजेंट इसे समझ और संभाल सकता है, बिनाaxeजैसे टूल से accessibility API को workaround के तौर पर छेड़ने की जरूरत केXcode MCP परफेक्ट नहीं है। हर बार एजेंट चलाने पर permission window दिखने की समस्या को मैंने Keyboard Maestro से auto-approve करवाकर बायपास किया। फिर भी Xcode 27 ने Xcode vibe coding की usability को काफी बेहतर किया है। अब मैं MCP को अलग से नहीं संभालता, बल्कि Xcode के अपने agent UI में Codex चलाता हूँ, और यह execution environment मॉडल को बेहतर तरीके से guide करता है ताकि वह उपलब्ध टूल्स का उपयोग करे। आखिर में सबसे अहम चीज़ मिलती है: तेज़ feedback और ज्यादा मजबूत validation
Xcode-mcp-proxyनाम का टूल है, जो Xcode MCP को proxy करते हुए dialog box क्लिक करता है और connection भी recover कर देता है। macOS ऐप testing में Peekaboo इस्तेमाल करते हैं या सामान्य screenshot automation, यह जानने की उत्सुकता हैअगर आप iOS और Android IDE को जितना हो सके छूना नहीं चाहते, तो React Native और Expo भी अच्छा विकल्प हैं
Xcode और Android Studio का उपयोग सिर्फ device simulator install करते समय होता है, और store deployment तक बाकी सब Expo toolchain संभालती है। Windows पर भी, जहाँ Xcode install नहीं किया जा सकता, Expo के managed apps का उपयोग करके iOS ऐप को सीधे iPhone पर चलाया जा सकता है। RN और Expo आधारित starting point के तौर पर अच्छी तरह maintained Ignite शानदार है: https://github.com/infinitered/ignite
सख्ती से कहें तो अब भी Xcode का ही उपयोग हो रहा है। Xcode मूलतः कई system-level UNIX utilities और apps के ऊपर लिपटा हुआ, बहुत bugs वाला GUI है, जो आम तौर पर स्थिर होते हैं
CLI से ऐप रिलीज़ करना पुरानी practice है, और कम-से-कम 2012 से संभव था, जब मैंने अपना पहला Xcode ऐप रिलीज़ किया था
कम-से-कम कुछ debugging के लिए हर किसी को Xcode इस्तेमाल करना ही पड़ता है
builds को एजेंट पहले ही command line से ज्यादातर संभाल सकता है, और context के हिसाब से explicit instructions देने पर वह और तेज़ build कर सकता है। अगर Xcode के file system sync groups का इस्तेमाल करते हैं, तो XcodeGen शायद अनावश्यक extra work हो सकता है
iOS में मैं सबसे ज्यादा यही recommend करूँगा कि एजेंट में App Store Connect functionality जोड़ी जाए: https://github.com/rorkai/App-Store-Connect-CLI. तब न सिर्फ Xcode को हमेशा चालू रखने की जरूरत नहीं रहती, बल्कि MacBook के पास होना भी जरूरी नहीं रहता। iPhone पर Codex से बदलाव करें, फिर
ascको build और TestFlight upload करने को कहें, नया version download करके चलाएँ और इसी तरह iterate करेंयह बात लगातार खटकती है कि कम budget की वजह से Mac न खरीद सकने वाले developers व्यावहारिक रूप से iOS development से बाहर रह जाते हैं। Apple products की कीमत बढ़ने पर हर बार development में हिस्सा न ले पाने वाले लोगों की संख्या और बढ़ती है
अगर ऐप को vibe coding से बनाना है, तो long term में Expo बेहतर विकल्प था। React-based होने के कारण LLM training data में Swift की तुलना में React code कहीं ज्यादा है, और resulting code की quality भी बेहतर होती है
सारे काम command line से किए जा सकते हैं और web view होने से debugging भी आसान है। native iOS ऐप के रूप में compile करने के बाद यह दूसरे native apps जैसा ही महसूस होता है। Expo और Fastlane को मिलाकर iOS submission और deployment को पूरी तरह automate किया जा सकता है, ताकि एक command से App Store पर नया version upload हो जाए