كيف يمكنني عرض نسخة إصدار التطبيق في حزمة إعدادات التطبيق الخاص بي؟

StackOverflow https://stackoverflow.com/questions/877128

سؤال

أرغب في تضمين إصدار التطبيق والمراجعة الداخلية، مثل 1.0.1 (r1243)، في حزمة إعدادات التطبيق الخاص بي.

يحتوي ملف Root.plist على جزء مثل هذا...

     <dict>
        <key>Type</key>
        <string>PSTitleValueSpecifier</string>
        <key>Title</key>
        <string>Version</string>
        <key>Key</key>
        <string>version_preference</string>
        <key>DefaultValue</key>
        <string>VersionValue</string>
        <key>Values</key>
        <array>
            <string>VersionValue</string>
        </array>
        <key>Titles</key>
        <array>
            <string>VersionValue</string>
        </array>
    </dict>

وأرغب في استبدال سلسلة "VersionValue" في وقت الإنشاء.

لدي برنامج نصي يمكنه استخراج رقم الإصدار من المستودع الخاص بي، وما أحتاج إليه هو طريقة لمعالجة (المعالجة المسبقة) لملف Root.plist، في وقت الإنشاء، واستبدال رقم المراجعة دون التأثير على الملف المصدر.

هل كانت مفيدة؟

المحلول 7

تمكنت من القيام بما أردت باستخدام pListcompiler (http://sourceforge.net/projects/plistcompiler) مشروع مفتوح المصدر.

  1. باستخدام هذا المترجم يمكنك كتابة ملف الخاصية في ملف .plc باستخدام التنسيق التالي:

    plist {
        dictionary {
            key "StringsTable" value string "Root"
            key "PreferenceSpecifiers" value array [
                dictionary {
                    key "Type" value string "PSGroupSpecifier"
                    key "Title" value string "AboutSection"
                }
                dictionary {
                    key "Type" value string "PSTitleValueSpecifier"
                    key "Title" value string "Version"
                    key "Key" value string "version"
                    key "DefaultValue" value string "VersionValue"
                    key "Values" value array [
                        string "VersionValue"
                    ]
                    key "Titles" value array [
                        string "r" kRevisionNumber
                    ]
                }
            ]
        }
    }
    
  2. كانت لدي مرحلة إنشاء برنامج نصي مخصص للتشغيل والتي كانت تستخرج مراجعة المستودع الخاصة بي إلى ملف .h كما هو موضح بواسطة brad-larson هنا.

  3. يمكن أن يحتوي ملف plc على توجيهات المعالج المسبق، مثل #define و #message و #if و #elif و #include و #warning و #ifdef و #else و #pragma و #error و #ifndef و #endif وxcode متغيرات البيئة.لذلك تمكنت من الإشارة إلى المتغير kRevisionNumber عن طريق إضافة التوجيه التالي

    #include "Revision.h"
    
  4. لقد أضفت أيضًا مرحلة إنشاء برنامج نصي مخصص إلى هدف xcode الخاص بي لتشغيل برنامج التحويل البرمجي plcompiler في كل مرة يتم فيها إنشاء المشروع

    /usr/local/plistcompiler0.6/plcompile -dest Settings.bundle -o Root.plist Settings.plc
    

وأنه كان عليه!

نصائح أخرى

هناك حل آخر يمكن أن يكون أبسط بكثير من أي من الإجابات السابقة.تقوم Apple بتجميع أداة سطر أوامر تسمى PlistBuddy داخل معظم أدوات التثبيت الخاصة به، وقد تم تضمينه في Leopard at /usr/libexec/PlistBuddy.

منذ كنت تريد استبدال VersionValue, ، على افتراض أن لديك قيمة الإصدار المستخرجة $newVersion, ، يمكنك استخدام هذا الأمر:

/usr/libexec/PlistBuddy -c "Set :VersionValue $newVersion" /path/to/Root.plist

لا داعي للتلاعب بالتعبيرات العادية أو sed، فهذه الطريقة واضحة تمامًا.انظر صفحة الرجل للحصول على تعليمات مفصلة.يمكنك استخدام PlistBuddy لإضافة أو إزالة أو تعديل أي إدخال في قائمة الخصائص.على سبيل المثال، قام أحد أصدقائي بالتدوين عن زيادة أرقام البناء في Xcode باستخدام PlistBuddy.

ملحوظة: إذا قمت بتوفير المسار إلى القائمة فقط، فسيدخل PlistBuddy في الوضع التفاعلي، بحيث يمكنك إصدار أوامر متعددة قبل أن تقرر حفظ التغييرات.أوصي بالتأكيد بالقيام بذلك قبل وضعه في البرنامج النصي للبناء الخاص بك.

وكان الحل يا رجل كسول لتحديث رقم الإصدار من التعليمات البرمجية طلبي. هل يمكن أن يكون الافتراضي (أو فارغة) قيمة في Root.plist ومن ثم، في مكان ما في التعليمات البرمجية بدء التشغيل الخاص بك:

NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
[[NSUserDefaults standardUserDefaults] setObject:version forKey:@"version_preference"];

والصيد الوحيد هو أن التطبيق سيكون ليتم تشغيلها مرة واحدة على الأقل في نسخة محدثة لتظهر في لوحة الإعدادات.

هل يمكن أخذ فكرة أكثر والتحديث، على سبيل المثال، عداد من عدد المرات التي تم إطلاق التطبيق الخاص بك، أو أجزاء أخرى مثيرة للاهتمام من المعلومات.

استنادًا إلى إجابة @Quinn، إليك العملية الكاملة ورمز العمل الذي أستخدمه للقيام بذلك.

  • أضف حزمة الإعدادات إلى تطبيقك.لا إعادة تسميته.
  • افتح الإعدادات.bundle/Root.plist في محرر النصوص

استبدل المحتويات بـ:

<?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>PreferenceSpecifiers</key>
    <array>
        <dict>
            <key>Title</key>
            <string>About</string>
            <key>Type</key>
            <string>PSGroupSpecifier</string>
        </dict>
        <dict>
            <key>DefaultValue</key>
            <string>DummyVersion</string>
            <key>Key</key>
            <string>version_preference</string>
            <key>Title</key>
            <string>Version</string>
            <key>Type</key>
            <string>PSTitleValueSpecifier</string>
        </dict>
    </array>
    <key>StringsTable</key>
    <string>Root</string>
</dict>
</plist>
  • إنشاء النصي تشغيل مرحلة البناء، الانتقال إلى ما بعد انسخ موارد الحزمة مرحلة.أضف هذا الكود:

    cd "${BUILT_PRODUCTS_DIR}"
    buildVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${INFOPLIST_PATH}" )
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $buildVersion" "${WRAPPER_NAME}/Settings.bundle/Root.plist"
    
  • استبدل MyAppName باسم تطبيقك الفعلي، والرقم 1 بعد PreferenceSpecifiers ليكون فهرس إدخال الإصدار الخاص بك في الإعدادات.يحتوي مثال Root.plist أعلاه على الفهرس 1.

باستخدام قائمة بن كلايتون https://stackoverflow.com/a/12842530/338986

يضيف Run script مع المقتطف التالي بعد Copy Bundle Resources.

version=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$PROJECT_DIR/$INFOPLIST_FILE")
build=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$PROJECT_DIR/$INFOPLIST_FILE")
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $version ($build)" "$CODESIGNING_FOLDER_PATH/Settings.bundle/Root.plist"

إلحاق CFBundleVersion بالإضافة ل CFBundleShortVersionString.تنبعث منها نسخة مثل هذا:

بالكتابة إلى$CODESIGNING_FOLDER_PATH/Settings.bundle/Root.plistبدلا من الذي في $SRCROOT لديها بعض الفوائد.

  1. لا يقوم بتعديل الملفات في نسخة العمل من المستودع.
  2. لا تحتاج إلى مسار الحالة إلى Settings.bundle في $SRCROOT.قد يختلف المسار.

الاختبار على Xcode 7.3.1

وبناء على المثال هنا ، وهنا النصي I ' م تستخدم لتحديث تلقائيا إعدادات الحزمة رقم الإصدار:

#! /usr/bin/env python
import os
from AppKit import NSMutableDictionary

settings_file_path = 'Settings.bundle/Root.plist' # the relative path from the project folder to your settings bundle
settings_key = 'version_preference' # the key of your settings version

# these are used for testing only
info_path = '/Users/mrwalker/developer/My_App/Info.plist'
settings_path = '/Users/mrwalker/developer/My_App/Settings.bundle/Root.plist'

# these environment variables are set in the XCode build phase
if 'PRODUCT_SETTINGS_PATH' in os.environ.keys():
    info_path = os.environ.get('PRODUCT_SETTINGS_PATH')

if 'PROJECT_DIR' in os.environ.keys():
    settings_path = os.path.join(os.environ.get('PROJECT_DIR'), settings_file_path)

# reading info.plist file
project_plist = NSMutableDictionary.dictionaryWithContentsOfFile_(info_path)
project_bundle_version = project_plist['CFBundleVersion']

# print 'project_bundle_version: '+project_bundle_version

# reading settings plist
settings_plist = NSMutableDictionary.dictionaryWithContentsOfFile_(settings_path)
  for dictionary in settings_plist['PreferenceSpecifiers']:
    if 'Key' in dictionary and dictionary['Key'] == settings_key:
        dictionary['DefaultValue'] = project_bundle_version

# print repr(settings_plist)
settings_plist.writeToFile_atomically_(settings_path, True)

وهنا يكمن Root.plist لقد حصلت في Settings.bundle:

<?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>PreferenceSpecifiers</key>
    <array>
        <dict>
            <key>Title</key>
            <string>About</string>
            <key>Type</key>
            <string>PSGroupSpecifier</string>
        </dict>
        <dict>
            <key>DefaultValue</key>
            <string>1.0.0.0</string>
            <key>Key</key>
            <string>version_preference</string>
            <key>Title</key>
            <string>Version</string>
            <key>Type</key>
            <string>PSTitleValueSpecifier</string>
        </dict>
    </array>
    <key>StringsTable</key>
    <string>Root</string>
</dict>
</plist>

الإجابات الأخرى لا تعمل بشكل صحيح لسبب واحد:لا يتم تنفيذ مرحلة إنشاء البرنامج النصي للتشغيل إلا بعد تعبئة حزمة الإعدادات.لذلك، إذا كان إصدار Info.plist الخاص بك هو 2.0.11 وقمت بتحديثه إلى 2.0.12، ثم قم بإنشاء/أرشفة مشروعك، فستظل حزمة الإعدادات تقول 2.0.11.إذا قمت بفتح حزمة الإعدادات Root.plist، يمكنك أن ترى أن رقم الإصدار لا يتم تحديثه حتى نهاية عملية الإنشاء.يمكنك إنشاء المشروع مرة أخرى لتحديث حزمة الإعدادات بشكل صحيح، أو يمكنك إضافة البرنامج النصي إلى مرحلة ما قبل البناء بدلاً من ذلك...

  • في XCode، قم بتحرير المخطط لهدف مشروعك
  • انقر فوق سهم الكشف في مخطط البناء
  • ثم انقر فوق عنصر "الإجراءات المسبقة".
  • انقر فوق علامة الجمع واختر "إجراء تشغيل البرنامج النصي الجديد"
  • اضبط قيمة الصدفة على /bin/sh
  • قم بتعيين "توفير إعدادات البناء من" إلى هدف مشروعك
  • أضف البرنامج النصي الخاص بك إلى منطقة النص.البرنامج النصي التالي يعمل بالنسبة لي.قد تحتاج إلى تعديل المسارات لتتناسب مع إعداد مشروعك:

    versionString=$(/usr/libexec/PlistBuddy -c "طباعة CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}")

    /usr/libexec/PlistBuddy "$SRCROOT/Settings.bundle/Root.plist" -c "تعيين PreferenceSpecifiers:0:DefaultValue $versionString"

سيؤدي هذا إلى تشغيل البرنامج النصي بشكل صحيح قبل تجميع حزمة الإعدادات أثناء عملية الإنشاء/الأرشفة.إذا قمت بفتح حزمة الإعدادات Root.plist وقمت بإنشاء/أرشفة مشروعك، فسترى الآن أنه تم تحديث رقم الإصدار في بداية عملية الإنشاء وستعرض حزمة الإعدادات الخاصة بك الإصدار الصحيح.

وأعتقد يمكنك القيام بذلك باستخدام وسيلة وهذا على غرار ما أصف في <لأ href = "https://stackoverflow.com/questions/372218/insert-subversion-revision-number-in-xcode#414792" > هذه الإجابة (وبناء على هذا المنصب ).

أولا، يمكنك جعل VersionValue متغير داخل كسكودي بإعادة تسميته إلى $ {VERSIONVALUE}. قم بإنشاء ملف يسمى versionvalue.xcconfig وإضافته إلى المشروع. الذهاب إلى الهدف التطبيق الخاص بك والذهاب إلى الإعدادات بناء لهذا الهدف. وأعتقد أن تحتاج إلى إضافة VERSIONVALUE كإعداد بناء المعرفة من قبل المستخدم. في اليمين الزاوية السفلى من هذا الإطار، تغيير بناء على القيمة إلى "versionvalue".

وأخيرا، انتقل إلى الهدف الخاص بك، وخلق سيناريو تشغيل بناء المرحلة. تفقد تلك المرحلة تشغيل سيناريو ولصق في البرنامج النصي داخل حقل نص سيناريو. على سبيل المثال، مخطوطتي لوضع علامة بلدي الإعداد مع بناء التخريب الحالي BUILD_NUMBER كما يلي:

REV=`/usr/bin/svnversion -nc ${PROJECT_DIR} | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`
echo "BUILD_NUMBER = $REV" > ${PROJECT_DIR}/buildnumber.xcconfig

وهذا ينبغي أن تفعل خدعة استبدال متغير عندما تتغير هذه القيم ضمن المشروع.

مثال العمل الخاص بي يعتمد على إجابةBen Clayton وتعليقات @Luis Ascorbe وVahid Amiri:

ملحوظة:هذا النهج يعدل الإعدادات.حزمة/Root.plist الملف في نسخة العمل من المستودع

  1. أضف حزمة الإعدادات إلى جذر مشروعك.لا إعادة تسميته
  2. افتح الإعدادات.bundle/Root.plist كرمز المصدر

    استبدل المحتويات بـ:

    <?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>PreferenceSpecifiers</key>
        <array>
            <dict>
                <key>DefaultValue</key>
                <string></string>
                <key>Key</key>
                <string>version_preference</string>
                <key>Title</key>
                <string>Version</string>
                <key>Type</key>
                <string>PSTitleValueSpecifier</string>
            </dict>
        </array>
        <key>StringsTable</key>
        <string>Root</string>
    </dict>
    </plist>
    
  3. قم بإضافة البرنامج النصي التالي إلى قسم البناء والإجراءات المسبقة لنظام المشروع (الهدف).

    version=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "$PROJECT_DIR/$INFOPLIST_FILE")
    build=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$PROJECT_DIR/$INFOPLIST_FILE")
    
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:0:DefaultValue $version ($build)" "${SRCROOT}/Settings.bundle/Root.plist"
    
  4. بناء وتشغيل المخطط الحالي

scroll top