हमारे उदाहरण प्रोजेक्ट में दो निर्मित लक्ष्य हैं: HelloWorld.app और हेल्पर.app। हम प्रत्येक के लिए एक घटक पैकेज बनाते हैं और उन्हें एक उत्पाद संग्रह में जोड़ते हैं ।
एक घटक पैकेज में OS X इंस्टालर द्वारा स्थापित किया जाने वाला पेलोड शामिल है। हालांकि एक घटक पैकेज को अपने दम पर स्थापित किया जा सकता है, इसे आमतौर पर उत्पाद संग्रह में शामिल किया जाता है ।
एक सफल "बिल्ड एंड आर्काइव" के बाद टर्मिनल में $ BUILT_PRODUCT_DIR खोलें।
$ cd ~/Library/Developer/Xcode/DerivedData/.../InstallationBuildProductsLocation
$ pkgbuild --analyze --root ./HelloWorld.app HelloWorldAppComponents.plist
$ pkgbuild --analyze --root ./Helper.app HelperAppComponents.plist
इससे हमें कंपोनेंट-प्लिस्ट मिलता है, आपको "कंपोनेंट प्रॉपर्टी लिस्ट" सेक्शन में वैल्यू डिस्क्रिप्शन मिलता है । pkgbuild -root घटक पैकेज उत्पन्न करता है , यदि आपको किसी भी डिफ़ॉल्ट गुण को बदलने की आवश्यकता नहीं है, तो आप निम्नलिखित कमांड में --component-plist पैरामीटर को छोड़ सकते हैं ।
productbuild - synthesize परिणाम वितरण परिभाषा में ।
$ pkgbuild --root ./HelloWorld.app \
--component-plist HelloWorldAppComponents.plist \
HelloWorld.pkg
$ pkgbuild --root ./Helper.app \
--component-plist HelperAppComponents.plist \
Helper.pkg
$ productbuild --synthesize \
--package HelloWorld.pkg --package Helper.pkg \
Distribution.xml
में Distribution.xml आप शीर्षक, पृष्ठभूमि, स्वागत, रीडमी, लाइसेंस, और इतने पर जैसी चीज़ों को बदल सकते हैं। आप अपने घटक पैकेज और वितरण परिभाषा को इस आदेश के साथ उत्पाद संग्रह में बदलते हैं :
$ productbuild --distribution ./Distribution.xml \
--package-path . \
./Installer.pkg
मैं देख लेने की सलाह देता हूं यह देखने के लिए कि क्या संभव है iTunes Installers Distribution.xml हैं। आप "iTunes.pkg इंस्टॉल करें" को इसके साथ निकाल सकते हैं:
$ pkgutil --expand "Install iTunes.pkg" "Install iTunes"
चलो इसे एक साथ रखा
मेरे पास आमतौर पर मेरे प्रोजेक्ट में पैकेज नाम का एक फोल्डर होता है जिसमें डिस्ट्रीब्यूशन.एक्सएमएल, कंपोनेंट-प्लिस्ट, रिसोर्सेज और स्क्रिप्ट जैसी चीजें शामिल होती हैं।
"जनरेट पैकेज" नाम से एक रन स्क्रिप्ट बिल्ड फेज जोड़ें , जो इंस्टॉल करते समय केवल स्क्रिप्ट चलाने के लिए सेट है :
VERSION=$(defaults read "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/Contents/Info" CFBundleVersion)
PACKAGE_NAME=`echo "$PRODUCT_NAME" | sed "s/ /_/g"`
TMP1_ARCHIVE="${BUILT_PRODUCTS_DIR}/$PACKAGE_NAME-tmp1.pkg"
TMP2_ARCHIVE="${BUILT_PRODUCTS_DIR}/$PACKAGE_NAME-tmp2"
TMP3_ARCHIVE="${BUILT_PRODUCTS_DIR}/$PACKAGE_NAME-tmp3.pkg"
ARCHIVE_FILENAME="${BUILT_PRODUCTS_DIR}/${PACKAGE_NAME}.pkg"
pkgbuild --root "${INSTALL_ROOT}" \
--component-plist "./Package/HelloWorldAppComponents.plist" \
--scripts "./Package/Scripts" \
--identifier "com.test.pkg.HelloWorld" \
--version "$VERSION" \
--install-location "/" \
"${BUILT_PRODUCTS_DIR}/HelloWorld.pkg"
pkgbuild --root "${BUILT_PRODUCTS_DIR}/Helper.app" \
--component-plist "./Package/HelperAppComponents.plist" \
--identifier "com.test.pkg.Helper" \
--version "$VERSION" \
--install-location "/" \
"${BUILT_PRODUCTS_DIR}/Helper.pkg"
productbuild --distribution "./Package/Distribution.xml" \
--package-path "${BUILT_PRODUCTS_DIR}" \
--resources "./Package/Resources" \
"${TMP1_ARCHIVE}"
pkgutil --expand "${TMP1_ARCHIVE}" "${TMP2_ARCHIVE}"
# Patches and Workarounds
pkgutil --flatten "${TMP2_ARCHIVE}" "${TMP3_ARCHIVE}"
productsign --sign "Developer ID Installer: John Doe" \
"${TMP3_ARCHIVE}" "${ARCHIVE_FILENAME}"
यदि आपको उत्पाद के निर्माण के बाद पैकेज को बदलना नहीं है, तो आप इससे छुटकारा पा सकते हैं pkgutil --expand
और pkgutil --flatten
कदम बढ़ा सकते हैं । इसके अलावा, आप इस्तेमाल कर सकते हैं --sign पर paramenter productbuild बजाय चलाने का productsign ।
एक OS X इंस्टॉलर साइन इन करें
डेवलपर आईडी इंस्टालर प्रमाणपत्र के साथ पैकेज पर हस्ताक्षर किए जाते हैं जिसे आप डेवलपर प्रमाणपत्र उपयोगिता से डाउनलोड कर सकते हैं ।
वे हस्ताक्षर करने के साथ किया जाता है --sign "Developer ID Installer: John Doe"
के पैरामीटर pkgbuild , productbuild या productsign ।
ध्यान दें कि यदि आप productbuild का उपयोग करके एक हस्ताक्षरित उत्पाद संग्रह बनाने जा रहे हैं , तो घटक संकुल पर हस्ताक्षर करने का कोई कारण नहीं है ।
सभी तरह: Xcode संग्रह में पैकेज की प्रतिलिपि बनाएँ
Xcode संग्रह में कुछ कॉपी करने के लिए हम रन स्क्रिप्ट बिल्ड चरण का उपयोग नहीं कर सकते हैं । इसके लिए हमें एक स्कीम एक्शन का उपयोग करने की आवश्यकता है।
योजना संपादित करें और पुरालेख का विस्तार करें। फिर पोस्ट-एक्शन पर क्लिक करें और एक नया रन स्क्रिप्ट एक्शन जोड़ें :
Xcode 6 में:
#!/bin/bash
PACKAGES="${ARCHIVE_PATH}/Packages"
PACKAGE_NAME=`echo "$PRODUCT_NAME" | sed "s/ /_/g"`
ARCHIVE_FILENAME="$PACKAGE_NAME.pkg"
PKG="${OBJROOT}/../BuildProductsPath/${CONFIGURATION}/${ARCHIVE_FILENAME}"
if [ -f "${PKG}" ]; then
mkdir "${PACKAGES}"
cp -r "${PKG}" "${PACKAGES}"
fi
Xcode 5 में, PKG
इसके बजाय इस मान का उपयोग करें :
PKG="${OBJROOT}/ArchiveIntermediates/${TARGET_NAME}/BuildProductsPath/${CONFIGURATION}/${ARCHIVE_FILENAME}"
यदि आपका संस्करण नियंत्रण Xcode योजना की जानकारी संग्रहीत नहीं करता है, तो मैं सुझाव देता हूं कि इसे अपनी परियोजना में शेल स्क्रिप्ट के रूप में जोड़ा जाए ताकि आप कार्यक्षेत्र से स्क्रिप्ट को पोस्ट-एक्शन में खींचकर कार्रवाई को सरल रूप से बहाल कर सकें।
स्क्रिप्टिंग
स्क्रिप्टिंग के दो अलग-अलग प्रकार हैं: जावास्क्रिप्ट इन डिस्ट्रीब्यूशन डेफिनिशन फाइल्स और शेल स्क्रिप्ट।
व्हाइटबॉक्स में पाए गए शेल लिपियों के बारे में सबसे अच्छा प्रलेखन - पैकेजमेकर हाउ-टू , लेकिन इसे सावधानी से पढ़ें क्योंकि यह पुराने पैकेज प्रारूप को संदर्भित करता है।
अतिरिक्त पढ़ना
ज्ञात समस्याएँ और समाधान
गंतव्य चयन फलक
उपयोगकर्ता को केवल एक ही विकल्प के साथ गंतव्य चयन विकल्प के साथ प्रस्तुत किया जाता है - "इस कंप्यूटर के सभी उपयोगकर्ताओं के लिए इंस्टॉल करें"। विकल्प नेत्रहीन रूप से चयनित दिखाई देता है, लेकिन उपयोगकर्ता को स्थापना के साथ आगे बढ़ने के लिए उस पर क्लिक करने की आवश्यकता होती है, जिससे कुछ भ्रम होता है।
सेब प्रलेखन उपयोग करने की सलाह देता है <domains enable_anywhere ... />
करता है, लेकिन यह नए और अधिक छोटी गाड़ी गंतव्य चयन फलक को चलाता है जिसे Apple अपने किसी भी पैकेज में उपयोग नहीं करता है।
डेप्रिसिएट का उपयोग करने से <options rootVolumeOnly="true" />
आपको पुराना डेस्टिनेशन सेलेक्ट पेन मिलेगा।
आप आइटम को वर्तमान उपयोगकर्ता के होम फ़ोल्डर में स्थापित करना चाहते हैं।
संक्षिप्त उत्तर: यह कोशिश मत करो!
लंबे उत्तर: वास्तव में; यह कोशिश मत करो! इंस्टालर की समस्याएं और समाधान पढ़ें । आप जानते हैं कि मैंने इसे पढ़कर भी क्या किया? मैं इसे आजमाने के लिए काफी बेवकूफ था। अपने आप को बताने से मुझे यकीन है कि उन्होंने 10.7 या 10.8 में मुद्दे तय किए हैं।
सबसे पहले मैंने समय-समय पर उपर्युक्त गंतव्य चयन फलक बग को देखा। मुझे रोकना चाहिए था, लेकिन मैंने इसे नजरअंदाज कर दिया। यदि आप समर्थन ई-मेल का जवाब देने वाले अपने सॉफ़्टवेयर को जारी करने के बाद सप्ताह नहीं बिताना चाहते हैं, तो उन्हें एक बार अच्छे नीले चयन पर क्लिक करना होगा।
अब आप सोच रहे हैं कि आपके उपयोगकर्ता पैनल का पता लगाने के लिए पर्याप्त स्मार्ट हैं, क्या आप नहीं हैं? अच्छी तरह से यहाँ घर फ़ोल्डर स्थापना के बारे में एक और बात है, वे काम नहीं करते हैं!
मैंने इसे दो हफ्तों तक लगभग 10 अलग-अलग मशीनों पर अलग-अलग ओएस संस्करणों के साथ परीक्षण किया और क्या नहीं, और यह कभी विफल नहीं हुआ। इसलिए मैंने इसे भेज दिया। रिलीज के एक घंटे के भीतर मैं उन उपयोगकर्ताओं से वापस दिल मिला जो इसे स्थापित नहीं कर सके। लॉग उन मुद्दों की अनुमति देने के संकेत देता है जिन्हें आप ठीक करने में सक्षम नहीं हैं।
तो चलिए इसे एक बार फिर से दोहराते हैं: हम होम फोल्डर इंस्टालेशन के लिए इंस्टॉलर का उपयोग नहीं करते हैं!
वेलकम, रीड-मी, लाइसेंस और निष्कर्ष के लिए RTFD द्वारा स्वीकार नहीं किया जाता है productbuild
।
आरटीएफडी फ़ाइलों के साथ शुरुआत से समर्थित इंस्टॉलर, छवियों के साथ सुंदर स्वागत स्क्रीन बनाने के लिए, लेकिन उत्पाद निर्माण उन्हें स्वीकार नहीं करता है।
वर्कअराउंड: एक डमी आरटीएफ फ़ाइल का उपयोग करें और बाद में इसे पैकेज में बदल दें productbuild
।
नोट: आप रेटिना छवियों को RTFD फ़ाइल के अंदर भी रख सकते हैं। इसके लिए मल्टी-इमेज टिफ़ फ़ाइलों का उपयोग करें tiffutil -cat Welcome.tif Welcome_2x.tif -out FinalWelcome.tif
:। अधिक जानकारी ।
जब स्थापना एक साथ किया जाता है एक आवेदन शुरू BundlePostInstallScriptPath स्क्रिप्ट:
#!/bin/bash
LOGGED_IN_USER_ID=`id -u "${USER}"`
if [ "${COMMAND_LINE_INSTALL}" = "" ]
then
/bin/launchctl asuser "${LOGGED_IN_USER_ID}" /usr/bin/open -g PATH_OR_BUNDLE_ID
fi
exit 0
एप्लिकेशन को उपयोगकर्ता के रूप में लॉग इन करना महत्वपूर्ण है, इंस्टॉलर उपयोगकर्ता के रूप में नहीं। यह लॉन्चर एक्ट्यूसर यूआईडी पथ के साथ किया जाता है । इसके अलावा हम इसे केवल तब चलाते हैं जब यह इंस्टॉलर टूल या Apple रिमोट डेस्कटॉप के साथ कमांड लाइन इंस्टॉलेशन नहीं होता है ।