Como posso exibir a versão de revisão aplicação nas configurações do meu aplicativo de pacote?

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

Pergunta

Eu gostaria de incluir a versão da aplicação e revisão interna, algo como 1.0.1 (r1243), nas configurações do meu aplicativo de pacote.

O arquivo Root.plist contém um fragmento assim ...

     <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>

e eu gostaria de substituir a string "VersionValue" em tempo de compilação.

Eu tenho um script que pode extrair o número da versão do meu repositório, o que eu preciso é uma maneira de processo (pré-processo) o arquivo Root.plist, em tempo de compilação, e substituir o número de revisão sem afetar o arquivo de origem .

Foi útil?

Solução 7

Eu consegui fazer o que eu queria, utilizando o pListcompiler ( http://sourceforge.net/projects/plistcompiler ) porject código aberto.

  1. Usando este compilador você pode escrever o arquivo de propriedade em um arquivo .plc usando o seguinte formato:

    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. Eu tive uma fase de construção script personalizado de execução que foi extrair a minha revisão do repositório para arquivo .h como descrito por brad-Larson aqui .

  3. O arquivo plc pode conter directivas de pré-processamento, como #define, #message, #if, #elif, #include, #WARNING, #ifdef, #else, #pragma, #error, #ifndef, #endif , variáveis ??de ambiente Xcode. Então, eu era capaz de fazer referência a variável kRevisionNumber adicionando a seguinte diretiva

    #include "Revision.h"
    
  4. Eu também acrescentou uma fase de construção script personalizado para o meu alvo xcode para executar o plcompiler cada vez que o projeto é beeing construção

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

E foi isso!

Outras dicas

Há uma outra solução que pode ser muito mais simples do que qualquer uma das respostas anteriores. A Apple empacota uma ferramenta de linha de comando chamado PlistBuddy dentro a maioria de seus instaladores, e incluiu-a no Leopard em /usr/libexec/PlistBuddy.

Uma vez que você deseja substituir VersionValue, supondo que você tenha o valor da versão extraído em $newVersion, você pode usar este comando:

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

Não há necessidade de mexer com expressões sed ou regulares, esta abordagem é bastante simples. Veja a página de manual para instruções detalhadas. Você pode usar PlistBuddy para adicionar, remover ou modificar qualquer entrada em uma lista de propriedades. Por exemplo, um amigo meu blog sobre incrementar números de compilação no Xcode utilizando PlistBuddy.

Nota: Se você fornecer apenas o caminho para o plist, PlistBuddy entra no modo interativo, para que possa emitir vários comandos antes de decidir para salvar as alterações. Eu definitivamente recomendo fazer isso antes de plopping-lo em seu script de construção.

solução do meu homem preguiçoso foi atualizar o número da versão do meu código do aplicativo. Você poderia ter um valor padrão (ou em branco) na Root.plist e, em seguida, em algum lugar em seu código de inicialização:

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

O único problema é que a sua aplicação teria de ser executado pelo menos uma vez para a versão atualizada para aparecer no painel de configurações.

Você poderia levar a idéia adiante e atualização, por exemplo, um contador de quantas vezes foi lançado a sua aplicação, ou outros interessantes bits de informações.

Com base na resposta da @ Quinn, aqui todo o processo e código de trabalho que eu uso para fazer isso.

  • Adicione uma configuração pacote para seu aplicativo. Não renomeá-lo.
  • Open Settings.bundle / Root.plist em um editor de texto

Substitua o conteúdo com:

<?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>
  • Criar um Executar script fase de construção, movimento para ser após o Copiar Bundle Recursos de fase. Adicione este código:

    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"
    
  • Substitua MyAppName com o nome de seu aplicativo real, ea 1 após PreferenceSpecifiers ser o índice de sua entrada Versão em Configurações. O acima Root.plist exemplo tem-no índice 1.

Usando de Ben Clayton plist https://stackoverflow.com/a/12842530/338986

Adicionar Run script com seguinte trecho após 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"

Appending CFBundleVersion além de CFBundleShortVersionString. Ele emite versão como esta:

por escrito para $CODESIGNING_FOLDER_PATH/Settings.bundle/Root.plist em vez de um em $SRCROOT ter alguns benefícios.

  1. É dose não modificar arquivos na cópia do repositório de trabalho.
  2. Você não precisa caminho caso para Settings.bundle em $SRCROOT. O caminho pode variar.

Testing no Xcode 7.3.1

Com base no exemplo aqui , aqui está o script que eu' m usando para atualizar automaticamente as configurações número versão pacote:

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

Aqui está o Root.plist eu tenho em 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>

As outras respostas não funcionam corretamente por uma razão: A fase de construção executar script não é executado até depois do Bundle Configurações foi empacotado. Então, se a sua versão Info.plist é 2.0.11 e você atualizá-lo para 2.0.12, em seguida, construir / arquivar o seu projecto, o pacote Configurações ainda vai dizer 2.0.11. Se você abrir as configurações do bundle Root.plist, você pode ver que o número da versão não é atualizado até o final do processo de criação. Você pode construir o projeto novamente para obter as configurações do bundle atualizado corretamente, ou você pode adicionar o script para a fase de pré-construção, em vez ...

  • No Xcode, Edita o esquema para o seu alvo do projeto
  • Clique na seta divulgação sobre o esquema de BUILD
  • Em seguida, clique no botão "Pré-ações" item
  • Clique no sinal de mais e escolha "New Run Action Script"
  • Defina o valor de shell de / bin / sh
  • Set "Fornecer configurações de compilação de" para o seu alvo do projeto
  • Adicionar o seu roteiro para a área de texto. O script a seguir trabalhou para mim. Pode ser necessário modificar os caminhos para corresponder à sua configuração do projeto:

    versionString = $ (/ usr / libexec / PlistBuddy -c "Imprimir CFBundleVersion" "$ {project_dir} / $ {INFOPLIST_FILE}")

    / usr / libexec / PlistBuddy "$ SRCROOT / Settings.bundle / Root.plist" -c "set PreferenceSpecifiers: 0: DefaultValue $ versionString"

Isto irá executar corretamente o script antes de o pacote de configurações é embalado durante o processo de build / arquivo. Se você abrir as configurações do bundle Root.plist e build / arquivar o seu projecto, agora você vai ver o número da versão é atualizado no início do processo de construção e suas configurações do bundle irá exibir a versão correta.

Eu acredito que você pode fazer isso usando uma forma que é semelhante ao que eu descrevo em esta resposta (baseado em este post ).

Em primeiro lugar, você pode fazer VersionValue uma variável dentro de Xcode renomeando-o para $ {VERSIONVALUE}. Crie um arquivo chamado versionvalue.xcconfig e adicioná-lo ao seu projeto. Vá para o seu destino de aplicativo e vá para as configurações de compilação para esse alvo. Eu acredito que você precisa adicionar VERSIONVALUE como uma configuração de compilação definida pelo usuário. No canto inferior direito do canto dessa janela, alterar a base no valor de "versionvalue".

Finalmente, vá para o seu alvo e criar uma fase de construção Run Script. Inspecione essa fase Run Script e cole no seu script dentro do campo de texto Script. Por exemplo, o meu script para marcar minha configuração BUILD_NUMBER com a construção Subversion atual é a seguinte:

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

Isso deve fazer o truque de substituir a variável quando esses valores mudam dentro do seu projeto.

O meu trabalho Exemplo baseado em @ Ben Clayton resposta e os comentários de @Luis Ascorbe e @Vahid Amiri:

Nota: Esta abordagem modifica o Settings.bundle / Root.plist arquivo na cópia de trabalho do repositório

  1. Adicionar configurações pacote à sua raiz do projeto. Não mude o nome
  2. Open Settings.bundle / Root.plist como SourceCode

    Substitua o conteúdo com:

    <?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. Adicione o seguinte script para o Build, seção pré-ações do projeto (alvo) esquema

    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. Criar e executar o esquema atual

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top