la mejor manera de agregar la sección de licencia al paquete de configuración de iOS


116

Mi aplicación iOS utiliza una serie de componentes de terceros con licencia de Apache 2.0 y licencias similares, lo que me obliga a incluir varios fragmentos de texto, este tipo de cosas:

* 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 haber un precedente razonable para poner esta información bajo una subentrada de 'Licencia' en el paquete de configuración (en el facebook del iPad, las páginas, la nota clave, los números y wikipanion parecen hacer esto).

Sin embargo, estoy luchando un poco para lograr lo mismo; Parece que necesito dividir el texto línea por línea e ingresar en xcode una línea a la vez (y xcode4 parece tener un problema de bloqueo al editar las listas).

Parece el tipo de cosas que casi con certeza hay un guión en algún lugar para hacer, o alguna forma sencilla de hacerlo que me he perdido.

Respuestas:


192

Creo que ahora me las arreglé para resolver todos los problemas que tenía.

  • Parece ser mejor utilizar títulos de elementos de grupo para mantener las licencias (esto es lo que hace Apple en las aplicaciones de iWork). Sin embargo, existe un límite en la longitud de estos (y aún no he descubierto exactamente cuál es el límite), por lo que debe dividir cada archivo de licencia en varias cadenas.
  • Puede crear un salto de línea dentro de estos incluyendo un retorno de carro literal (es decir, también conocido como ^ M, \ r o 0x0A)
  • Asegúrese de no incluir ningún texto a mitad de texto literal. Si lo hace, algunas o todas las cadenas del archivo se ignorarán silenciosamente.

Tengo un script de conveniencia que utilizo para ayudar a generar el archivo .plist y .strings, que se muestra a continuación.

Para usarlo:

  1. Cree un directorio de 'licencias' en su proyecto
  2. Ponga el script en ese directorio
  3. Coloque cada licencia en ese directorio, una por archivo, con nombres de archivo que terminen .license
  4. Realice cualquier reformateo necesario en las licencias. (por ejemplo, elimine los espacios adicionales al comienzo de las líneas, asegúrese de que no haya saltos de línea en la mitad del párrafo). Debe haber una línea en blanco entre cada párrafo
  5. Cambie al directorio de licencias y ejecute el script
  6. Edite su paquete de configuración Root.plist para incluir una sección secundaria llamada 'Agradecimientos'

Aquí está el guión:

#!/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 su Settings.bundle

Si no ha creado un Settings.bundle, vaya a Archivo -> Nuevo -> Nuevo archivo ...

En la sección Recursos, busque el Paquete de configuración. Utilice el nombre predeterminado y guárdelo en la raíz de su proyecto.

Expanda el Settings.bundlegrupo y seleccione Root.plist. Deberá agregar una nueva sección donde su clave será Preference Itemsde tipo Array. Agregue la siguiente información:

ingrese la descripción de la imagen aquí

La Filenameclave apunta al plist que fue creado por este script. Puedes cambiar el titlea lo que quieras.

Ejecutar secuencia de comandos en el momento de la compilación

Además, si desea que este script se ejecute cada vez que construya su proyecto, puede agregar una fase de construcción a su objetivo:

  1. Ve a tu archivo de proyecto
  2. Seleccione el objetivo
  3. Haga clic en la pestaña Build Phases
  4. En la esquina inferior derecha de ese panel, haga clic en 'Agregar fase de construcción'
  5. Seleccione 'Agregar secuencia de comandos de ejecución'
  6. Arrastre y suelte su script de Perl en la sección de su script. Modifíquelo para lucir algo como esto:
  1. cd $SRCROOT/licenses( $SRCROOTapunta a la raíz de su proyecto)
  2. ./yourScriptName.pl

Una vez que haya terminado, puede arrastrar la Run Scriptfase de compilación antes en el proceso de compilación. Deberá moverlo hacia arriba antes Compile Sourcespara que las actualizaciones de su Paquete de configuración se compilen y se copien.

Actualización para iOS 7: iOS 7 parece manejar la tecla "Título" de manera diferente y está arruinando el texto renderizado. Para arreglar eso, el Acknowledgements.plist generado necesita usar la clave "FooterText" en lugar de "Título". Así es como se cambia el 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);
}

1
¡Qué idea tan fantástica! Comencé a hacer esto manualmente antes de darme cuenta rápidamente de que necesitaba una solución automatizada, particularmente debido al límite de longitud del título del grupo draconiano.
Hilton Campbell

9
Una cosa a tener en cuenta: "Nombre de archivo" es la forma de visualización de la clave. La clave real es "Archivo". Si el panel secundario no aparece, haga clic con el botón derecho y seleccione "Mostrar claves / valores sin procesar" y asegúrese de que el nombre de la clave sea "Archivo".
Ático

10
Esto es fantástico, gracias. Usé 'cd "$ SRCROOT / Licenses /"' en el bloque Ejecutar script, que funciona un poco mejor si hay varias personas trabajando en un proyecto.
chris

9
Lea devforums.apple.com/message/894791#894791 si está usando esto con iOS7. Específicamente, es posible que deba cambiar <key> Título </key> a <key> FooterText </key> para que se vea normal.
esilver

2
Cómo convertirlo en un panel secundario: cree el elemento 0 dentro de los elementos de preferencia. Parece que no puede seleccionar Panel secundario como el tipo, pero lo que debe hacer es crear un elemento en el Elemento 0 (sub-elemento del Elemento 0) y ese primer elemento tiene la clave "Tipo". Para hacerlo más fácil, haga clic derecho en esto y seleccione Mostrar claves / valores sin procesar. Desea establecer el valor de Tipo para que sea PSChildPaneSpecifier. Una vez que desactive Mostrar claves / valores sin procesar, ahora dirá Panel secundario, incluso en el nombre del Elemento 0, es decir, "Su 0 (Panel secundario -)". Esto es lo que quieres.
Marc

36

Aquí está la misma solución que @JosephH proporcionó (sin traducciones), pero hecha en Python para cualquiera que prefiera Python sobre 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"
)

Esta respuesta necesita más votos a favor. Sintaxis de Python Sintaxis de <3Perl. ;)
Ricardo Sanchez-Saez

5
current_file = codecs.open(filename, 'r', 'utf-8')para licencias Unicode.
user2821144

¡Gracias! He creado una nueva versión basada en esta que es genial para Carthage. También elimina algunas líneas nuevas innecesarias del texto de la licencia. Échale un vistazo: gist.github.com/Zyphrax/0d015c618d46093b4f815e62a6a33969
Zyphrax

1
He trabajado un poco más en él, consulte: github.com/Building42/AckAck
Zyphrax

15

Como alternativa, para aquellos que usan CocoaPods, generará una lista de 'Reconocimientos' para cada objetivo especificado en su Podfile que contiene los detalles de la licencia para cada Pod utilizado en ese objetivo (asumiendo que los detalles se han especificado en la especificación del Pod). El archivo de lista de propiedades que se puede agregar al paquete de configuración de iOS.

También hay proyectos en marcha para permitir que estos datos se conviertan y se muestren dentro de la aplicación:

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

https://github.com/cocoapods/CPDAcknowledgements


3
Aquí hay más información al respecto: github.com/CocoaPods/CocoaPods/wiki/Acknowledgements
Oren

Tenga en cuenta que el wiki de Cocoapods tiene el nombre del archivo de entrada como Pods-Acknowledgements.plist, pero el archivo en realidad se genera como Pods -cknowledgements.plist (minúscula 'a'). Usar el caso incorrecto interrumpirá la instalación del pod si su sistema de archivos distingue entre mayúsculas y minúsculas.
Keller

14

Pensé en lanzar mi iteración sobre el increíble código de Python de Sean en la mezcla. La principal diferencia es que toma un directorio de entrada y luego lo busca de forma recursiva en busca de archivos de LICENCIA. Deriva el valor del título del directorio principal del archivo LICENSE, por lo que funciona bien con cocoapods.

La motivación fue crear un script de compilación para mantener automáticamente actualizada la sección legal de mi aplicación a medida que agrego o elimino pods. También hace algunas otras cosas como eliminar las nuevas líneas forzadas de las licencias para que los párrafos se vean un poco mejor en los dispositivos.

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

ingrese la descripción de la imagen aquí


8

Hice un guión en Ruby inspirado en el guión de @JosephH. Esta versión, en mi opinión, representará mejor los proyectos individuales de código abierto.

Wisit iOS-AcknowledgementGenerator para descargar el script y el proyecto de muestra.

Así es como se verán los reconocimientos en su aplicación:

Settings.app Settings.bundle Agradecimientos ingrese la descripción de la imagen aquí


2

Este es un apéndice a la respuesta de JosephH. (No tengo el representante para comentar)

Tuve que moverme <key>StringsTable</key> <string>Acknowledgements</string> por encima del último</dict> en el script de Perl.

Antes de esta modificación, la sección de agradecimientos de la aplicación estaba vacía y XCode no podía leer el archivo Acknowledgements.plist resultante. ("Los datos no se pudieron leer porque no están en el formato correcto").

(XCode 6.3.2 iOS 8.3)


2

El script Python de Sean en este hilo funciona. Pero hay un par de cosas básicas que debes saber.

  1. en Xcode, haga clic derecho en la parte superior del árbol del Navegador de proyectos, en el nombre de su proyecto y agregue un Grupo nuevo. Esto coloca una nueva carpeta en su proyecto.
  2. Agregue el script de Sean allí y asegúrese de guardarlo como: Acknowledgements.py.
  3. Asegúrese de tener Python instalado en su sistema. Estoy usando una Mac.
  4. Agregue un primer archivo de licencia a la carpeta que creó en 1. Hágalo simple como tener una palabra en el archivo, diga: Prueba. Guárdelo en la carpeta como Test1.license.
  5. Configure su Settings.bundle según JosephH arriba.
  6. Use su aplicación Terminal en CD a la carpeta que creó en 1.
  7. Ejecute el script. Escriba: python Acknowledgements.py. Si no obtiene ningún error, volverá inmediatamente al indicador de Terminal. Haga todo esto antes de agregar cualquier script de ejecución a Build.
  8. Cree y ejecute su aplicación.
  9. Toque dos veces el botón de inicio del iPhone y elimine Configuración. No suele detectar el cambio de configuración de su aplicación hasta que se reinicia.
  10. Después de reiniciar la Configuración, vaya a su aplicación y observe si funcionó.
  11. Si todo eso funcionó, agregue lentamente más archivos de licencia pero ejecute el script cada vez. Puede obtener errores al ejecutar el script debido a ciertos caracteres en el archivo, por lo que la forma más fácil de depurar es agregar un archivo, ejecutar el script, ver si funcionó y continuar. De lo contrario, edite los caracteres especiales del archivo .license.
  12. No obtuve el funcionamiento de Run Build Script según las instrucciones anteriores. Pero este proceso funciona bien si no cambia los archivos .license con tanta frecuencia.

1

Ack Ack: Generador de listas de reconocimiento
un tiempo, creé un script de Python que busca archivos de licencia y crea una lista de reconocimientos agradable que puede usar en su Settings.plist. Hace mucho del trabajo por ti.

https://github.com/Building42/AckAck

Caracteristicas

  • Detecta carpetas Carthage y CocoaPods
  • Detecta plists existentes para licencias personalizadas
  • Limpia los textos de la licencia eliminando nuevas líneas y saltos de línea innecesarios
  • Ofrece muchas opciones de personalización (consulte --help detalles)
  • Soporta Python v2 y v3

Instalar en pc

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

correr

./ackack.py

Captura de pantalla

Agradecimientos

Si tiene sugerencias de mejora, no dude en publicar un problema o solicitar una solicitud en GitHub.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.