How can I display the application version revision in my application's settings bundle?

前端 未结 13 716
一个人的身影
一个人的身影 2020-11-29 15:20

I would like to include the application version and internal revision, something like 1.0.1 (r1243), in my application\'s settings bundle.

The Root.plist file contai

相关标签:
13条回答
  • 2020-11-29 15:35

    Above answers did not work for me hence I created my custom script.

    This dynamically updates the entry from Root.plist

    Use run script below. W ill work for sure verified in xcode 10.3.

    "var buildVersion" is the version to be displayed in title.

    And identifier name is "var version" below for title in settings.bundle Root.plist

    cd "${BUILT_PRODUCTS_DIR}"
    
    #set version name to your title identifier's string from settings.bundle
    var version = "Version"
    
    #this will be the text displayed in title
    longVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${INFOPLIST_PATH}")
    shortVersion=$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" ${TARGET_BUILD_DIR}/${INFOPLIST_PATH})
    buildVersion="$shortVersion.$longVersion"
    
    path="${WRAPPER_NAME}/Settings.bundle/Root.plist"
    
    settingsCnt=`/usr/libexec/PlistBuddy -c "Print PreferenceSpecifiers:" ${path} | grep "Dict"|wc -l`
    
    for (( idx=0; idx<$settingsCnt; idx++ ))
    do
    #echo "Welcome $idx times"
    val=`/usr/libexec/PlistBuddy -c "Print PreferenceSpecifiers:${idx}:Key" ${path}`
    #echo $val
    
    #if ( "$val" == "Version" )
    if [ $val == "Version" ]
    then
    #echo "the index of the entry whose 'Key' is 'version' is $idx."
    
    # now set it
    /usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:${idx}:DefaultValue $buildVersion" $path
    
    # just to be sure that it worked
    ver=`/usr/libexec/PlistBuddy -c "Print PreferenceSpecifiers:${idx}:DefaultValue" $path`
    #echo 'PreferenceSpecifiers:$idx:DefaultValue set to: ' $ver
    
    fi
    
    done
    

    Example entry in Root.plist

        <dict>
            <key>Type</key>
            <string>PSTitleValueSpecifier</string>
            <key>Title</key>
            <string>Version</string>
            <key>DefaultValue</key>
            <string>We Rock</string>
            <key>Key</key>
            <string>Version</string>
        </dict>
    

    0 讨论(0)
  • 2020-11-29 15:36

    Based on the example here, here's the script I'm using to automatically update the settings bundle version number:

    #! /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)
    

    Here's the Root.plist I've got in 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>
    
    0 讨论(0)
  • 2020-11-29 15:37

    There is another solution that can be much simpler than either of the previous answers. Apple bundles a command-line tool called PlistBuddy inside most of its installers, and has included it in Leopard at /usr/libexec/PlistBuddy.

    Since you want to replace VersionValue, assuming you have the version value extracted into $newVersion, you could use this command:

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

    No need to fiddle with sed or regular expressions, this approach is quite straightforward. See the man page for detailed instructions. You can use PlistBuddy to add, remove, or modify any entry in a property list. For example, a friend of mine blogged about incrementing build numbers in Xcode using PlistBuddy.

    Note: If you supply just the path to the plist, PlistBuddy enters interactive mode, so you can issue multiple commands before deciding to save changes. I definitely recommend doing this before plopping it in your build script.

    0 讨论(0)
  • 2020-11-29 15:37

    I managed to do what I wanted by using the pListcompiler (http://sourceforge.net/projects/plistcompiler) open source porject.

    1. Using this compiler you can write the property file in a .plc file using the following format:

      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. I had a custom run script build phase that was extracting my repository revision to .h file as described by brad-larson here.

    3. The plc file can contain preprocessor directives, like #define, #message, #if, #elif, #include, #warning, #ifdef, #else, #pragma, #error, #ifndef, #endif, xcode environment variables. So I was able to reference the variable kRevisionNumber by adding the following directive

      #include "Revision.h"
      
    4. I also added a custom script build phase to my xcode target to run the plcompiler every time the project is beeing build

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

    And that was it!

    0 讨论(0)
  • 2020-11-29 15:40

    My lazy man's solution was to update the version number from my application code. You could have a default (or blank) value in the Root.plist and then, somewhere in your startup code:

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

    The only catch is that your app would have to be run at least once for the updated version to appear in the settings panel.

    You could take the idea further and update, for instance, a counter of how many times your app has been launched, or other interesting bits of information.

    0 讨论(0)
  • 2020-11-29 15:47

    I believe you can do this using a way that's similar to what I describe in this answer (based on this post).

    First, you can make VersionValue a variable within Xcode by renaming it to ${VERSIONVALUE}. Create a file named versionvalue.xcconfig and add it to your project. Go to your application target and go to the Build settings for that target. I believe that you need to add VERSIONVALUE as a user-defined build setting. In the lower-right-corner of that window, change the Based On value to "versionvalue".

    Finally, go to your target and create a Run Script build phase. Inspect that Run Script phase and paste in your script within the Script text field. For example, my script to tag my BUILD_NUMBER setting with the current Subversion build is as follows:

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

    This should do the trick of replacing the variable when these values change within your project.

    0 讨论(0)
提交回复
热议问题