Agregue una entrada al archivo .plist de iOS a través de Cordova config.xml


80

Soy nuevo en la CLI de Cordova.

Necesito realizar los siguientes pasos mediante programación a través de Cordova.

  1. En el proyecto .plist agregue una nueva fila
  2. Ingrese los siguientes valores en la nueva fila:
  3. Clave : GDLibraryMode Tipo : Cadena (predeterminado) Valor : GDEnterpriseSimulation

Creo que necesito hacer esto en el archivo config.xml en la raíz de mi proyecto (o tal vez en el de la carpeta "plataformas").

¿Alguien puede explicarme cómo agregar la entrada a través de config.xml para que la entrada anterior se agregue en tiempo de compilación?

Estoy usando Cordova 3.3.1-0.42 (sé que no es el último). Ya hice mi proyecto y todo está bien, solo necesito agregar esta entrada agregada a pList.


4
Para cualquiera que llegue tarde a esto, la configuración de valores en el plist del proyecto ahora es compatible con Cordova CLI 7 y superior .
decae

Respuestas:


67

No creo que puedas hacer esto mediante una config.xmlmodificación directa . Al menos, no vi ninguna mención de esto en los documentos: http://cordova.apache.org/docs/en/3.3.0/config_ref_index.md.html

Creo que debes crear un complemento, porque pueden insertar entradas plist: http://docs.phonegap.com/en/3.3.0/plugin_ref_spec.md.html#Plugin%20Specification

Consulte la sección 'elemento de archivo de configuración'. Aquí hay una suposición de cómo plugin.xmlse verá la sección relevante del :

<platform name="ios">
<config-file target="*-Info.plist" parent="CFBundleURLTypes">
<array>
    <dict>
        <key>GDLibraryMode</key>
        <string>GDEnterpriseSimulation</string>
    </dict>
</array>
</config-file>
</platform>

Entonces puedes instalar el complemento: cordova plugin add <your plugin name or file location>


1
@mooreds lo siento, entendí mal su respuesta ... Pensé que su solución estaba usando gap: config-file . Ahora, entendí su enfoque (crear un complemento dedicado para modificaciones particulares de plist), lo intentaré. ¡Gracias!
Fafaman

6
@mooreds, la documentación de Cordova / PhoneGap es engañosa. Descubrí que la clave debe especificarse en parent, mientras que la parte del valor debe ser el XML interno. En este caso particular, debería ser como sigue: <config-file target = "* - Info.plist" parent = "GDLibraryMode"> <string> GDEnterpriseSimulation </string> </config-file>
Herman Kan


1
Gracias @rjhilgefort, ¡mucho más fácil! :)
josebailo 11/11/15

2
Como referencia, a partir de Cordova CLI 7+, se puede hacer a config.xmltravés del <config-file>elemento; consulte otras respuestas para obtener detalles sobre cómo hacerlo.
decae

43

Realmente me gusta la solución de @ james usando un gancho Cordova. Sin embargo, existen dos cuestiones. Los documentos dicen:

  • "recomendamos encarecidamente escribir sus ganchos con Node.js "
  • "El /hooksdirectorio se considera obsoleto en favor de los elementos de enlace en config.xml"

Aquí hay una implementación de Node.js usando el paquete plist NPM:

var fs    = require('fs');     // nodejs.org/api/fs.html
var plist = require('plist');  // www.npmjs.com/package/plist

var FILEPATH = 'platforms/ios/.../...-Info.plist';

module.exports = function (context) {

    var xml = fs.readFileSync(FILEPATH, 'utf8');
    var obj = plist.parse(xml);

    obj.GDLibraryMode = 'GDEnterpriseSimulation';

    xml = plist.build(obj);
    fs.writeFileSync(FILEPATH, xml, { encoding: 'utf8' });

};

De todos los tipos de anzuelos proporcionados por Cordova, los relevantes para su situación son:

  • after_prepare
  • before_compile

Elija un tipo de gancho y luego agregue el gancho a su config.xmlarchivo:

<platform name="ios">
    <hook type="after_prepare" src="scripts/my-hook.js" />
</platform>

La plistbiblioteca de nodos tuvo algunos problemas al analizar mi archivo plist, por lo que no pude usar esta solución y fui con James ', que usa el ejecutable PListBuddy, que se incluye en Mac. Esta fue una buena solución, si tan solo la plistbiblioteca fuera más confiable. Hice referencia a mi secuencia de comandos del config.xmlarchivo como me recomendó.
Stephen.hanson

¡Agradable! ¡No es necesario utilizar ningún complemento adicional y funciona como un encanto! Todas las demás soluciones parecen obsoletas o demasiado complicadas para un problema tan simple.
Arno van Oordt

El módulo plist npm está seriamente dañado. Producirá un archivo .plist no válido cuando el archivo de origen contenga valores vacíos. En su lugar, utilice simple-plist.
cleong

Tuve muchos problemas para agregar un complemento local con cordova @ 8, esta solución funciona mucho mejor en mi caso y es más simple
Jean-Baptiste Martin

32

Puede utilizar la utilidad PlistBuddy dentro de un script de enlace de Cordova para modificar el archivo * -Info.plist.

Por ejemplo, tengo el siguiente script bajo el <project-root>/hooks/after_prepare/010_modify_plist.shcual agrega una propiedad de diccionario y agrega una entrada dentro de ese diccionario:

#!/bin/bash

PLIST=platforms/ios/*/*-Info.plist

cat << EOF |
Add :NSAppTransportSecurity dict
Add :NSAppTransportSecurity:NSAllowsArbitraryLoads bool YES
EOF
while read line
do
    /usr/libexec/PlistBuddy -c "$line" $PLIST
done

true

Asegúrese de hacer que el script sea ejecutable ( chmod +x).

El trueal final del script se debe a que PlistBuddyregresa con un código de salida de error si la clave que se agrega ya existe y no proporciona una forma de detectar si la clave ya existe. Cordova informará de un error de compilación si el script de gancho sale con un estado de error. Es posible un mejor manejo de errores, pero es difícil implementarlo.


¡Funciona! Probé las soluciones tuyas y de TachyonVortex. La biblioteca node.js que usa la solución TachyonVortex no analizó correctamente mi archivo PList, mientras que el PListBuddy incluido en Mac que usó en su respuesta sí lo hizo. Sin embargo, hice referencia al gancho de config.xmlcomo TachyonVortex recomendó.
stephen.hanson

1
Si desea SIEMPRE actualizar el plist cada vez, incluso si la clave ya existe, agregue Remove : NSAppTransportSecurity justo antes de la declaración de adición y primero eliminará NSAppTransportSecurity y luego lo agregará. Esto no debería bloquear nada.
Samuel Thompson

22

Estos son los pasos que terminé haciendo para permitir que mi aplicación comparta archivos a través de iTunes entre dispositivos.

En su aplicación, navegue hasta su config.xml. Escriba esta pieza en su configuración bajo la etiqueta de plataforma <platform name="ios">.

 <config-file platform="ios" target="*-Info.plist" parent="UIFileSharingEnabled">
      <true/>
  </config-file>

2. Luego vaya a su herramienta de línea de comando y escriba: cordova prepare

  1. Desinstale y reinstale su aplicación en su dispositivo, y verá que su aplicación aparece en iTunes para que pueda compartir cualquier archivo entre sus dispositivos.

Algunas cosas, asegúrese de que cordova esté actualizado y de que haya agregado la plataforma para ios.

npm install -g cordova

Este comando instala cordova.

cordova platform add ios

Este comando agrega la plataforma para ios.

Lo que sucede es que cuando ejecuta el comando cordova prepare, está utilizando el SDK de Xcode de Apple que se genera en la carpeta platform / ios. Allí puede ver el archivo plist que se genera para su aplicación, que está etiquetado como "yourApp-info.plist". Allí puede ver la nueva clave y cadena producidas en el diseño xml que se ve así:

 <key>UIFileSharingEnabled</key>
 <true/>

También una advertencia, mi empresa dejó caer esta aplicación de marco iónico en mi regazo hace un par de semanas (con una fecha límite muy corta). Todo lo que les digo se basa en un par de semanas de aprendizaje. Así que esta puede no ser la mejor práctica, pero espero que ayude a alguien.

Editar

Enlace a los documentos


4
¿Se requiere algo más para que esto funcione? Estoy usando Cordova 6.2 (última producción) y aunque agregué la entrada en config.xml no la veo en plist. ¿Es posible que tenga el complemento de configuración personalizada de Cordova ( github.com/dpa99c/cordova-custom-config )?
Tomer Cagan

1
Funciona de maravilla. Gracias.
Logus

El <config-file>elemento se agregó en la versión 7 de la CLI de Cordova, por lo que con una versión reciente de la CLI de Cordova, esto funciona (consulte este problema de github para obtener una prueba reproducible del autor de cordova-custom-config ).
decae

¡Esto funcionó para mí! Sin embargo, especificar la plataforma como un atributo en la etiqueta parece redundante, especialmente porque ya está ubicada bajo la plataforma iOS. Funcionó sin eso en el mío.
Eric F.

14

Esto parece ser posible ahora usando config.xml: al menos algunos autores principales de complementos lo dicen. Por ejemplo, en los documentos del complemento de cámara Cordova , se analiza el nuevo requisito en iOS 10 de proporcionar una cadena de mensaje de permiso en plist. Para lograrlo, sugieren ejecutar el comando add del complemento con argumentos, así:

cordova plugin add cordova-plugin-camera --variable CAMERA_USAGE_DESCRIPTION="My App would like to access your camera, to take photos of your documents."

Esto tiene el resultado de que no solo obtiene un nuevo <plugin>agregado a config.xml, sino que tiene un <variable>hijo:

<plugin name="cordova-plugin-camera" spec="~2.3.0">
    <variable name="CAMERA_USAGE_DESCRIPTION" value="My App would like to access your camera, to take photos of your documents." />
</plugin>

¿Qué entonces parece correlacionarse con las nuevas claves en mi info.plist, quizás pasando de alguna manera los valores en tiempo de ejecución?

  <key>NSCameraUsageDescription</key>
  <string/>
  <key>NSPhotoLibraryUsageDescription</key>
  <string/>

Estaría mintiendo si dijera que sé exactamente cómo funciona, pero parece señalar el camino.


CAMERA_USAGE_DESCRIPTION se pasa a NSCameraUsageDescription. Si desea agregar un valor para NSPhotoLibraryUsageDescription, también debe agregar<variable name="PHOTOLIBRARY_USAGE_DESCRIPTION" value="whatever" />
Nico Westerdale

1
Si está utilizando el servicio PhoneGap Build, esta es la forma recomendada de establecer esos valores
Nico Westerdale

Tuve que agregar una <string>Random camera usage text</string>clave debajo de la clave para <key>NSCameraUsageDescription</key>que mi compilación fuera aceptada. La configuración no agrega el texto
Slartibartfast

9

ACTUALIZACIÓN: para las personas que desean usar la cámara con iOS> = 10. Esto significa que, por lo general, puede configurar el complemento como:

 <!-- ios -->
 <platform name="ios">

     <config-file target="*-Info.plist" parent="NSLocationWhenInUseUsageDescription">
         <string></string>
     </config-file>
     <config-file target="*-Info.plist" parent="NSCameraUsageDescription">
         <string></string>
     </config-file>
      <config-file target="*-Info.plist" parent="NSPhotoLibraryUsageDescription">
         <string></string>
     </config-file>

 </platform>

Pero por ahora, no puede configurar NSCameraUsageDescriptiony NSPhotoLibraryUsageDescriptionen plugin. Debe configurarlos en la plataforma -> proyecto iOS por Xcode o en *-Info.plistarchivo.

Desde iOS 10, es obligatorio agregar NSCameraUsageDescription y NSPhotoLibraryUsageDescription en info.plist.

Más información: https://www.npmjs.com/package/cordova-plugin-camera


8

Estoy usando lo siguiente en el ionic 3 sin ningún complemento o importación adicional y creo que esto podría ser útil para otros:

<platform name="ios">
    <edit-config file="*-Info.plist" mode="merge" target="NSLocationWhenInUseUsageDescription">
        <string>Location is required so we can show you your nearby projects to support.</string>
    </edit-config>
    <edit-config file="*-Info.plist" mode="merge" target="NSCameraUsageDescription">
        <string>Camera accesss required in order to let you select profile picture from camera.</string>
    </edit-config>
    <edit-config file="*-Info.plist" mode="merge" target="NSPhotoLibraryUsageDescription">
        <string>Photo library accesss required in order to let you select profile picture from gallery / library.</string>
    </edit-config>
</platform>

4

Puede establecer el nombre para mostrar en la lista de aplicaciones editando directamente ios.json en el directorio de complementos.

Agregar lo siguiente a la sección config_munge.files del archivo ios.json hará el truco y se mantendrá incluso cuando se use la CLI.

"*-Info.plist": {

    "parents": {
        "CFBundleDisplayName": [
            {
                "xml": "<string>RevMob Ads Cordova Plugin Demo</string>",
                "count": 1
            }
        ]
    }
}

Aquí tienes un ejemplo completo


1
Tenga en cuenta que esto no funciona cuando se ejecuta desde Visual Sutdio Tools para Cordova, ya que las herramientas sobrescriben ios.json.
Herman Kan

2
Hay dos problemas con esta respuesta. Primero, las ediciones manuales de /plugins/ios.jsonse perderán cuando se ejecute cordova platform remove iosseguido de cordova platform add ios. En segundo lugar, @ Red2678 solicitó una solución para "realizar la edición mediante programación a través de Cordova ... para que la nueva entrada se agregue en tiempo de compilación".
TachyonVortex

3

La solución @TachyonVortex parece ser la mejor opción, pero en mi caso se estaba derrumbando. El problema fue causado por un campo NSMainNibFile vacío que el paquete plist NPM no convirtió correctamente. En el archivo .plist

    <key>NSMainNibFile</key>
    <string></string>
    <key>NSMainNibFile~ipad</key>
    <string></string>

se convierte en:

    <key>NSMainNibFile</key>
    <string>NSMainNibFile~ipad</string>

Lo arreglé agregando al script:

    obj.NSMainNibFile = '';
    obj['NSMainNibFile~ipad'] = '';

El script finalmente se ve así (scripts / my-hook.js):

var fs    = require('fs');     // nodejs.org/api/fs.html
var plist = require('plist');  // www.npmjs.com/package/plist

var FILEPATH = 'platforms/ios/***/***-Info.plist';

module.exports = function (context) {

    var xml = fs.readFileSync(FILEPATH, 'utf8');
    var obj = plist.parse(xml);

    obj.GDLibraryMode = 'GDEnterpriseSimulation';
    obj.NSMainNibFile = '';
    obj['NSMainNibFile~ipad'] = '';

    xml = plist.build(obj);
    fs.writeFileSync(FILEPATH, xml, { encoding: 'utf8' });

};

y config.xml:

<platform name="ios">
    <hook type="before_build" src="scripts/my-hook.js" />
</platform>

Escribí un patch_plist.jsen el hooks/after_platform_adddirectorio con este código. Pero sigo <key>NSMainNibFile</key><string>NSMainNibFile~ipad</string>en mi archivo plist. ¿Alguna idea de cómo podría resolver este problema, por favor?
Romain R.


2

¡Sí, es posible!

Estoy usando Cordova 9.0.0 (cordova-lib@9.0.1).

Por ejemplo, este es el archivo de configuración que utilicé para insertar un nuevo valor de cadena en Info.plist:

<platform name="ios">
    <edit-config file="*-Info.plist" mode="merge" target="NSMicrophoneUsageDescription">
        <string>My awesome app wish to hear your awesome voice through Microphone. Not for fancy stuff, just want to hear you.</string>
    </edit-config>
    <edit-config file="*-Info.plist" mode="merge" target="---Key configuration---">
        <string>---string value---</string>
    </edit-config>
</platform>

Después de eso, no olvide reconstruir su archivo de ensayo ejecutando estos dos comandos en su terminal:

cordova platform rm ios
cordova platform add ios

Para confirmar el cambio, puede verificar el archivo .plist recién generado abriéndolo con xCode.

-Archivo de información.plist ubicado en:

./platform/ios/[your app name]/[your app name]-Info.plist

edit-configasume que el objetivo ya existe en su plist. Para que quede claro, si desea agregar un nuevo par de clave / cadena, debe usar config-fileen su lugar, que agrega nuevos hijos al árbol xml
Daniel Lizik

1

Si está intentando modificar un .plisten un complemento nativo de iOS con una <config-file>etiqueta en su plugin.xml, esto es lo que debe hacer:

  1. ¡Asegúrate de que .plistsea ​​xml, no binario! Puede usar plutilpara convertir un binario .plisten xml y enviarlo al control de versiones.

    plutil -convert xml1 Info.plist

  2. Las instrucciones para <config-file>indican que target=son relativas al proyecto xcode generado en platforms/ios/<project>/, pero descubrí que necesitaba anteponer un carácter comodín a mi ruta para que funcione:

    target="*/Resources/MyResources.bundle/Info.plist"

  3. Si desea agregar una clave en el nivel superior del .plist, debe establecer un padre igual al nombre de la clave y luego anidar una <string>etiqueta con el valor. El uso de <array>o, <dict>como muestran los ejemplos, hará que estas claves se aniden debajo parent .

Aquí hay un ejemplo completo que me funciona para agregar múltiples propiedades de nivel superior:

<platform name="ios">
    <config-file target="*/Resources/MyResources.bundle/Info.plist" parent="MyDistribution">
        <string>Cordova</string>
    </config-file>
    <config-file target="*/Resources/MyResources.bundle/Info.plist" parent="MyVersion">
        <string>3.2.0</string>
    </config-file>
</platform>

Esto no funcionó para mí. Intenté agregar lo que tiene arriba, y nada cambió en mi lista
Samuel Thompson

Intente reducir la causa colocando el plist en el directorio raíz al principio. Desafortunadamente, esta función falla silenciosamente hasta donde yo sé.
Sky Kelsey

0

Prefiero el gancho after_prepare para proyectos más grandes o si tiene varios complementos con los mismos permisos. Pero siempre puedes seguir el camino más simple:

simplemente: - elimine el complemento que requiere el permiso deseado - agréguelo nuevamente con --save - en config.xml, el complemento ahora tiene una nueva variable con una descripción en blanco que puede completar - ahora compile ios con - release y se establecerán.


-4

solo necesita seguir los pasos 1.

Ir al navegador de proyectos Seleccione el destino Haga clic en la opción de información de la pestaña otra opción es configuración de compilación fase de compilación verá el valor del tipo de clave Cuando señale el nombre de cualquier clave, encontrará el signo + y - haga clic en el signo + escriba la Key: GDLibraryModesección clave Type:Stringen tyoe sección Value:GDEnterpriseSimulationen la sección de valor


1
Quiero hacer esto totalmente, pero cuando compilo la aplicación Cordova desde la CLI, la carpeta del proyecto básicamente se elimina y se vuelve a crear. Entonces tendría que hacer lo anterior cada vez que compile (no es que eso sea difícil), pero esperaba usar el config.xml de Cordova para hacerlo por mí.
Red 2678

¿Puede decirme por qué es necesario compilar si ejecuta la aplicación a través de xcode, entonces esta solución funciona para usted?
Nitin

2
Hola @Nitin, Bueno, no es tanto un "requisito", ya que es la forma estándar de usar la CLI de Cordova. Si utilizo el "comando Cordova build", la carpeta del proyecto se elimina y se vuelve a crear cada vez que ejecuta ese comando.
Red 2678
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.