melhor maneira de adicionar seção de licença ao pacote de configurações do iOS

116

Meu aplicativo iOS usa vários componentes de terceiros licenciados sob Apache 2.0 e licenças semelhantes, o que exige que eu inclua vários pedaços de texto, este tipo de coisa:

* Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.

Parece haver um precedente razoável para colocar essas informações sob uma subentrada 'Licença' no pacote de configurações (no ipad facebook, páginas, keynote, números e wikipanion parecem fazer isso).

Estou lutando um pouco para realmente conseguir o mesmo; Parece que preciso dividir o texto linha por linha e inserir no xcode uma linha por vez (e o xcode4 parece ter um problema de travamento ao editar as plists).

Parece o tipo de coisa que quase certamente existe um script de algum lugar a ser feito, ou alguma maneira simples de fazer isso que eu perdi.

JosephH
fonte

Respostas:

192

Acho que agora consegui resolver todos os problemas que estava enfrentando.

  • Parece ser melhor usar títulos de elemento de grupo para manter as licenças (isso é o que a Apple faz nos aplicativos iWork). No entanto, há um limite para o comprimento deles (e ainda não descobri exatamente qual é o limite), então você precisa dividir cada arquivo de licença em várias sequências.
  • Você pode criar uma quebra de linha dentro deles incluindo um retorno de carro literal (ou seja, também conhecido como ^ M, \ r ou 0x0A)
  • Certifique-se de não incluir nenhum texto do meio literal. Se você fizer isso, algumas ou todas as strings no arquivo serão ignoradas silenciosamente.

Eu tenho um script de conveniência que uso para ajudar a gerar o arquivo .plist e .strings, mostrado abaixo.

Para usá-lo:

  1. Crie um diretório de 'licenças' em seu projeto
  2. Coloque o script nesse diretório
  3. Coloque cada licença nesse diretório, uma por arquivo, com nomes de arquivo que terminam .license
  4. Execute qualquer reformatação necessária nas licenças. (por exemplo, remova os espaços extras no início das linhas, certifique-se de que não haja quebras de linha no meio do parágrafo). Deve haver uma linha em branco entre cada parágrafo
  5. Mude para o diretório de licenças e execute o script
  6. Edite seu pacote de configurações Root.plist para incluir uma seção secundária chamada 'Agradecimentos'

Aqui está o script:

#!/usr/bin/perl -w

use strict;

my $out = "../Settings.bundle/en.lproj/Acknowledgements.strings";
my $plistout =  "../Settings.bundle/Acknowledgements.plist";

unlink $out;

open(my $outfh, '>', $out) or die $!;
open(my $plistfh, '>', $plistout) or die $!;

print $plistfh <<'EOD';
<?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>StringsTable</key>
        <string>Acknowledgements</string>
        <key>PreferenceSpecifiers</key>
        <array>
EOD
for my $i (sort glob("*.license"))
{
    my $value=`cat $i`;
    $value =~ s/\r//g;
    $value =~ s/\n/\r/g;
    $value =~ s/[ \t]+\r/\r/g;
    $value =~ s/\"/\'/g;
    my $key=$i;
    $key =~ s/\.license$//;

    my $cnt = 1;
    my $keynum = $key;
    for my $str (split /\r\r/, $value)
    {
        print $plistfh <<"EOD";
                <dict>
                        <key>Type</key>
                        <string>PSGroupSpecifier</string>
                        <key>Title</key>
                        <string>$keynum</string>
                </dict>
EOD

        print $outfh "\"$keynum\" = \"$str\";\n";
        $keynum = $key.(++$cnt);
    }
}

print $plistfh <<'EOD';
        </array>
</dict>
</plist>
EOD
close($outfh);
close($plistfh);

Configurando seu Settings.bundle

Se você não criou um Settings.bundle, vá para Arquivo -> Novo -> Novo arquivo ...

Na seção Recursos, encontre o Pacote de configurações. Use o nome padrão e salve-o na raiz do seu projeto.

Expanda o Settings.bundlegrupo e selecione Root.plist. Você precisará adicionar uma nova seção onde sua chave será Preference Itemsdo tipo Array. Adicione as seguintes informações:

insira a descrição da imagem aqui

A Filenamechave aponta para o plist que foi criado por este script. Você pode alterar o titlepara o que quiser.

Executar script em tempo de construção

Além disso, se você deseja que este script seja executado sempre que construir seu projeto, você pode adicionar uma fase de construção ao seu destino:

  1. Vá para o arquivo do seu projeto
  2. Selecione o alvo
  3. Clique na guia Build Phases
  4. No canto inferior direito desse painel, clique em 'Adicionar fase de construção'
  5. Selecione 'Adicionar Script de Execução'
  6. Arraste e solte seu script perl na seção de seu script. Modifique para se parecer com isto:
  1. cd $SRCROOT/licenses( $SRCROOTaponta para a raiz do seu projeto)
  2. ./yourScriptName.pl

Depois de terminar isso, você pode arrastar a Run Scriptfase de construção mais cedo no processo de construção. Você vai querer movê-lo antes Compile Sourcespara que as atualizações de seu pacote de configurações sejam compiladas e copiadas.

Atualização para iOS 7: o iOS 7 parece lidar com a chave "Título" de maneira diferente e bagunça o texto renderizado. Para corrigir que o Acknowledgements.plist gerado precisa usar a chave "FooterText" em vez de "Title". Veja como alterar o script:

for my $str (split /\r\r/, $value)
{
    print $plistfh <<"EOD";
            <dict>
                    <key>Type</key>
                    <string>PSGroupSpecifier</string>
                    <key>FooterText</key> # <= here is the change
                    <string>$keynum</string>
            </dict>
 EOD

    print $outfh "\"$keynum\" = \"$str\";\n";
    $keynum = $key.(++$cnt);
}
JosephH
fonte
1
Que ideia fantástica! Comecei a fazer isso manualmente antes de perceber rapidamente que precisava de uma solução automatizada, principalmente por causa do limite draconiano de tamanho do título do grupo.
Hilton Campbell
9
Uma coisa a ser observada: "Nome do arquivo" é a forma de exibição da chave. A chave real é "Arquivo". Se o painel filho não estiver aparecendo, clique com o botão direito e selecione "Mostrar chaves / valores brutos" e certifique-se de que o nome da chave seja "Arquivo".
atticus de
10
Isso é fantástico, obrigado. Usei 'cd "$ SRCROOT / Licenses /"' no bloco Run Script, que funciona um pouco melhor se você tiver várias pessoas trabalhando em um projeto.
Chris
9
Leia devforums.apple.com/message/894791#894791 se você estiver usando isso com iOS7. Especificamente, você pode precisar alterar <key> Título </key> para <key> FooterText </key> para que pareça normal.
esilver
2
Como torná-lo um painel filho: Crie o Item 0 dentro de Itens de preferência. Parece que você não pode selecionar Painel Filho como o tipo, mas o que você faz é criar um item no Item 0 (s subitem do Item 0) e esse primeiro item tem a chave “Tipo”. Para tornar mais fácil, clique com o botão direito e selecione Mostrar chaves / valores brutos. Você deseja definir o valor de Type como PSChildPaneSpecifier. Depois de cancelar a configuração de Mostrar chaves / valores brutos, agora aparecerá Painel filho, mesmo no nome do item 0, ou seja, “É 0 (painel filho -)”. Isso é o que você quer.
Marc
36

Esta é a mesma solução que @JosephH forneceu (sem traduções), mas feita em Python para quem prefere python em vez de perl

import os
import sys
import plistlib
from copy import deepcopy

os.chdir(sys.path[0])

plist = {'PreferenceSpecifiers': [], 'StringsTable': 'Acknowledgements'}
base_group = {'Type': 'PSGroupSpecifier', 'FooterText': '', 'Title': ''}

for filename in os.listdir("."):
    if filename.endswith(".license"):
        current_file = open(filename, 'r')
        group = deepcopy(base_group)
        title = filename.split(".license")[0]
        group['Title'] = title
        group['FooterText'] = current_file.read()
        plist['PreferenceSpecifiers'].append(group)

plistlib.writePlist(
    plist,
    "../Settings.bundle/Acknowledgements.plist"
)
Sean
fonte
Esta resposta precisa de mais votos positivos. Sintaxe do Python Sintaxe do <3Perl. ;)
Ricardo Sanchez-Saez
5
current_file = codecs.open(filename, 'r', 'utf-8')para licenças Unicode.
user2821144
Obrigado! Eu criei uma nova versão baseada nesta que é ótima para Cartago. Ele também remove algumas novas linhas desnecessárias do texto da licença. Confira: gist.github.com/Zyphrax/0d015c618d46093b4f815e62a6a33969
Zyphrax
1
Eu coloquei um pouco mais de trabalho nisso, veja: github.com/Building42/AckAck
Zyphrax
15

Como alternativa, para aqueles que usam CocoaPods, ele gerará uma plist de 'Reconhecimentos' para cada destino especificado em seu Podfile, que contém os detalhes da licença para cada Pod usado nesse destino (assumindo que os detalhes foram especificados na especificação do Pod). O arquivo de lista de propriedades que pode ser adicionado ao pacote de configurações do iOS.

Também há projetos em andamento para permitir que esses dados sejam convertidos e exibidos no aplicativo:

https://github.com/CocoaPods/cocoapods-install-metadata

https://github.com/cocoapods/CPDAcknowledgements

JosephH
fonte
3
Mais informações sobre ele: github.com/CocoaPods/CocoaPods/wiki/Acknowledgements
Oren,
Esteja ciente de que o wiki do Cocoapods tem o nome do arquivo de entrada como Pods-Acknowledgements.plist, mas o arquivo é realmente gerado como Pods -knowledgements.plist ('a' minúsculo). Usar o caso errado interromperá a instalação do pod se o sistema de arquivos fizer distinção entre maiúsculas e minúsculas.
Keller
14

Pensei em lançar minha iteração no incrível código python de Sean na mistura. A principal diferença é que ele pega um diretório de entrada e então procura recursivamente por arquivos de LICENÇA. Ele deriva o valor do título do diretório pai do arquivo LICENSE, portanto, funciona bem com cocoapods.

A motivação era criar um script de compilação para manter automaticamente a seção jurídica do meu aplicativo atualizada conforme adiciono ou removo pods. Ele também faz algumas outras coisas, como remover novas linhas forçadas das licenças para que os parágrafos fiquem um pouco melhores nos dispositivos.

https://github.com/carloe/LicenseGenerator-iOS

insira a descrição da imagem aqui

Carlota
fonte
8

Fiz um script em Ruby inspirado pelo script @JosephH. Esta versão irá, na minha opinião, representar melhor os projetos individuais de código aberto.

Wisit iOS-AcknowledgementGenerator para baixar o script e o projeto de amostra.

Esta é a aparência dos reconhecimentos em seu aplicativo:

Settings.app Settings.bundle Reconhecimentos insira a descrição da imagem aqui

cvknage
fonte
2

Este é um adendo à resposta de JosephH. (Não tenho representante para comentar)

Tive que <key>StringsTable</key> <string>Acknowledgements</string> descer para acima do último </dict>no script Perl.

Antes dessa modificação, a seção Agradecimentos no aplicativo estava vazia e o XCode não conseguia ler o Acknowledgements.plist resultante. ("Os dados não puderam ser lidos porque não estão no formato correto.")

(XCode 6.3.2 iOS 8.3)

Mattti
fonte
2

O script Python de Sean neste tópico funciona. Mas há algumas coisas básicas a saber.

  1. no Xcode, clique com o botão direito no topo da árvore do Project Navigator, no nome do seu projeto, e adicione um Novo Grupo. Isso coloca uma nova pasta em seu projeto.
  2. Adicione o script de Sean lá e certifique-se de salvá-lo como: Acknowledgements.py.
  3. Certifique-se de ter o Python instalado em seu sistema. Estou usando um Mac.
  4. Adicione um primeiro arquivo de licença à pasta que você criou em 1. Torne-o simples como se tivesse apenas uma palavra no arquivo, diga: Teste. Salve-o na pasta Test1.license.
  5. Configure seu Settings.bundle de acordo com JosephH acima.
  6. Use seu aplicativo Terminal para o CD para a pasta que você criou em 1.
  7. Execute o script. Digite: python Acknowledgements.py. Se você não receber nenhum erro, ele retornará ao prompt do Terminal. Faça tudo isso antes de adicionar qualquer script de execução ao Build.
  8. Construa e execute seu aplicativo.
  9. Toque duas vezes no botão inicial do iPhone e elimine as configurações. Muitas vezes, ele não pega a alteração nas configurações do seu aplicativo até que as configurações sejam reiniciadas.
  10. Depois de reiniciar as configurações, vá até seu aplicativo e veja se funcionou.
  11. Se tudo funcionou, adicione lentamente mais arquivos de licença, mas execute o script a cada vez. Você pode obter erros ao executar o script por causa de certos caracteres no arquivo, então a maneira mais fácil de depurar é adicionar um arquivo, executar o script, ver se funcionou e continuar. Caso contrário, edite quaisquer caracteres especiais do arquivo .license.
  12. Não obtive o funcionamento do Run Build Script de acordo com as instruções acima. Mas esse processo funciona bem se você não alterar os arquivos .license com frequência.
D. Rothschild
fonte
1

Ack Ack: Acknowledgement Plist Generator
Há algum tempo, criei um script Python que verifica os arquivos de licença e cria um plist de Agradecimentos que você pode usar em Settings.plist. Isso faz muito trabalho para você.

https://github.com/Building42/AckAck

Recursos

  • Detecta as pastas Carthage e CocoaPods
  • Detecta plists existentes para licenças personalizadas
  • Limpa os textos da licença removendo novas linhas e quebras de linha desnecessárias
  • Oferece muitas opções de personalização (consulte --helppara obter detalhes)
  • Suporta Python v2 e v3

Instalar

wget https://raw.githubusercontent.com/Building42/AckAck/master/ackack.py
chmod +x ackack.py

Corre

./ackack.py

Captura de tela

Reconhecimentos

Se você tiver sugestões de melhorias, fique à vontade para postar um problema ou solicitar solicitação no GitHub!

Zyphrax
fonte