Dodaj wpis do pliku .plist iOS przez Cordova config.xml

80

Jestem nowy w Cordova CLI.

Muszę wykonać następujące kroki programowo za pośrednictwem Cordova.

  1. W projekcie .plist dodaj nowy wiersz
  2. Wprowadź następujące wartości w nowym wierszu:
  3. Klucz : GDLibraryMode Typ : String (domyślny) Wartość : GDEnterpriseSimulation

Myślę, że muszę to zrobić w pliku config.xml w katalogu głównym mojego projektu (lub może w folderze „platformy”).

Czy ktoś może mi wyjaśnić, jak dodać wpis poprzez config.xml, aby powyższy wpis był dodawany w czasie kompilacji?

Używam Cordova 3.3.1-0.42 (wiem, że nie jest najnowszy). Zrobiłem już swój projekt i wszystko jest w porządku, wystarczy dodać ten wpis do pList.

Czerwony 2678
źródło
4
Dla każdego, kto się spóźni, ustawianie wartości w pliku plist projektu jest teraz obsługiwane przez Cordova CLI 7 i nowsze .
decyduje

Odpowiedzi:

67

Myślę, że nie można tego zrobić za pomocą prostej config.xmlmodyfikacji. Przynajmniej nie widziałem żadnej wzmianki o tym w dokumentach: http://cordova.apache.org/docs/en/3.3.0/config_ref_index.md.html

Myślę, że musisz stworzyć wtyczkę, ponieważ mogą wstawiać wpisy plist: http://docs.phonegap.com/en/3.3.0/plugin_ref_spec.md.html#Plugin%20Specification

Zobacz sekcję „element pliku konfiguracyjnego”. Oto przypuszczenie, jak plugin.xmlbędzie wyglądać odpowiednia sekcja :

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

Następnie możesz zainstalować wtyczkę: cordova plugin add <your plugin name or file location>

zacumowane
źródło
1
@mooreds przepraszam, nie zrozumiałem twojej odpowiedzi ... Myślałem, że twoim rozwiązaniem jest użycie gap: config-file . Teraz zrozumiałem Twoje podejście (tworzenie dedykowanej wtyczki dla poszczególnych modyfikacji plist), spróbuję. Dzięki!
Fafaman
6
@mooreds, dokumentacja Cordova / PhoneGap jest myląca. Dowiedziałem się, że klucz powinien być określony w parent, a częścią wartości powinien być wewnętrzny XML. W tym konkretnym przypadku powinno wyglądać następująco: <config-file target = "* - Info.plist" parent = "GDLibraryMode"> <string> GDEnterpriseSimulation </string> </config-file>
Herman Kan
4
Ta wtyczka działa świetnie github.com/leecrossley/cordova-plugin-transport-security
rjhilgefort
1
Dzięki @rjhilgefort, o wiele łatwiejsze! :)
josebailo
2
Dla porównania, od Cordova CLI 7+, można to zrobić za config.xmlpośrednictwem <config-file>elementu - zobacz inne odpowiedzi, aby dowiedzieć się, jak to zrobić.
decyduje
43

Naprawdę podoba mi się rozwiązanie @ James z użyciem haczyka Cordova. Są jednak dwie kwestie. W docs stwierdzić:

  • „zdecydowanie zalecamy pisanie haków za pomocą Node.js
  • " /hookskatalog jest uważany za przestarzały na korzyść elementów zaczepienia w config.xml"

Oto implementacja Node.js przy użyciu pakietu NPM plist :

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' });

};

Ze wszystkich typów haków dostarczanych przez Cordova, odpowiednie dla Twojej sytuacji są:

  • after_prepare
  • before_compile

Wybierz typ haka, a następnie dodaj go do swojego config.xmlpliku:

<platform name="ios">
    <hook type="after_prepare" src="scripts/my-hook.js" />
</platform>
TachyonVortex
źródło
plistBiblioteka węzłów miała pewne problemy z analizowaniem mojego pliku plist, więc nie mogłem użyć tego rozwiązania i poszedłem z Jamesem, który używa pliku wykonywalnego PListBuddy, który jest dołączony do komputerów Mac. To było dobre rozwiązanie, gdyby tylko plistbiblioteka była bardziej niezawodna. Odwołałem się do mojego skryptu z config.xmlpliku, zgodnie z zaleceniami.
stephen.hanson
Miły! Nie ma potrzeby używania żadnych dodatkowych wtyczek i działa jak marzenie! Wszystkie inne rozwiązania wydają się nieaktualne lub zbyt skomplikowane w przypadku tak prostego problemu.
Arno van Oordt
Moduł plist npm jest poważnie uszkodzony. Stworzy nieprawidłowy plik .plist, gdy plik źródłowy zawiera puste wartości. Zamiast tego użyj simple-plist.
cleong,
Miałem duży problem z dodaniem lokalnej wtyczki z cordova @ 8, to rozwiązanie działa znacznie lepiej w moim przypadku i jest prostsze
Jean-Baptiste Martin
32

Możesz użyć narzędzia PlistBuddy wewnątrz skryptu przechwytującego Cordova, aby zmodyfikować plik * -Info.plist.

Na przykład mam następujący skrypt, pod <project-root>/hooks/after_prepare/010_modify_plist.shktórym dodaje właściwość słownika i dodaje wpis w tym słowniku:

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

Upewnij się, że skrypt jest wykonywalny ( chmod +x).

Na truekońcu skryptu występuje, ponieważ PlistBuddyzwraca kod zakończenia błędu, jeśli dodawany klucz już istnieje, i nie zapewnia sposobu na wykrycie, czy klucz już istnieje. Cordova zgłosi błąd kompilacji, jeśli skrypt przechwytujący zakończy działanie ze statusem błędu. Lepsza obsługa błędów jest możliwa, ale implementacja jest trudna.

James
źródło
To działa! Wypróbowałem rozwiązania zarówno twoje, jak i TachyonVortex. Biblioteka node.js, z której korzysta rozwiązanie TachyonVortex, nie przeanalizowała poprawnie mojego pliku PList, podczas gdy plik PListBuddy dołączony do komputera Mac użyty w Twojej odpowiedzi tak. config.xmlOdniosłem się do haka z zalecanego przez TachyonVortex.
stephen.hanson
1
Jeśli chcesz ZAWSZE aktualizować plist za każdym razem, nawet jeśli klucz już istnieje, dodaj Remove : NSAppTransportSecurity tuż przed instrukcją add, a najpierw usunie NSAppTransportSecurity, a następnie doda. To nie powinno niczego zawieść.
Samuel Thompson,
22

Oto kroki, które ostatecznie wykonałem, aby umożliwić mojej aplikacji udostępnianie plików za pośrednictwem iTunes między urządzeniami.

W aplikacji przejdź do pliku config.xml. Wpisz ten element do konfiguracji pod tagiem platformy <platform name="ios">.

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

2. Następnie przejdź do narzędzia wiersza poleceń i wpisz: przygotuj cordova

  1. Odinstaluj i ponownie zainstaluj aplikację na swoim urządzeniu, a zobaczysz, że aplikacja pojawi się w itunes, abyś mógł udostępniać dowolne pliki między urządzeniami.

Kilka rzeczy, upewnij się, że Cordova jest aktualna i że dodałeś platformę dla ios.

npm install -g cordova

To polecenie instaluje cordova.

cordova platform add ios

To polecenie dodaje platformę dla ios.

To, co się dzieje, to kiedy uruchamiasz polecenie przygotowania cordova, używasz zestawu Xcode SDK firmy Apple, który jest generowany w folderze platforma / ios. Tam możesz zobaczyć plik plist, który jest generowany dla Twojej aplikacji, oznaczony jako „yourApp-info.plist”. Tam możesz zobaczyć nowy klucz i ciąg utworzony w układzie xml, który wygląda następująco:

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

Również słowo ostrzeżenia, moja firma upuściła tę aplikację jonowego frameworka na moje kolana kilka tygodni temu (z naprawdę krótkim terminem). Wszystko, co ci mówię, opiera się na kilku tygodniach nauki. Może to nie jest najlepsza praktyka, ale mam nadzieję, że komuś pomoże.

Edytować

Link do dokumentów

Eric Weiss
źródło
4
Czy potrzebne jest coś jeszcze, aby to zadziałało? Używam Cordova 6.2 (najnowsza produkcja) i chociaż dodałem wpis do config.xml, nie widzę go w plist. Czy to możliwe, że masz wtyczkę Cordova Custom Config ( github.com/dpa99c/cordova-custom-config )?
Tomer Cagan
1
Działa jak marzenie. Dzięki.
Logus
<config-file>Element został dodany w Cordova CLI wersji 7, więc z ostatniej wersji Cordova CLI, to zadziała (zobacz tę kwestię na GitHub powtarzalny dowód od autora Cordova-custom-config ).
postanawia
To zadziałało dla mnie! Jednak określenie platformy jako atrybutu w tagu wydaje się zbędne, zwłaszcza, że ​​jest już umieszczona na platformie iOS. U mnie zadziałało bez tego.
Eric F.
14

Wydaje się, że jest to teraz możliwe przy użyciu pliku config.xml: przynajmniej niektórzy autorzy wtyczek tak twierdzą. Na przykład w dokumentach dotyczących wtyczki Cordova Camera Plugin omawiają nowy wymóg w systemie iOS 10, który polega na umieszczeniu ciągu komunikatu dotyczącego uprawnień w pliku plist. Aby to osiągnąć, sugerują wykonanie polecenia plugin add z argumentami, w ten sposób:

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

Powoduje to, że nie tylko dostajesz nowy <plugin>dodatek do config.xml, ale ma on <variable>potomka:

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

Co wydaje się być skorelowane z nowymi kluczami w mojej info.plist, być może w jakiś sposób przekazując wartości w czasie wykonywania?

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

Skłamałbym, gdybym powiedział, że wiem dokładnie, jak to działa, ale wydaje się, że wskazuje drogę.

XML
źródło
CAMERA_USAGE_DESCRIPTION zostaje przekazana do NSCameraUsageDescription. Jeśli chcesz dodać wartość dla NSPhotoLibraryUsageDescription, musisz również dodać<variable name="PHOTOLIBRARY_USAGE_DESCRIPTION" value="whatever" />
Nico Westerdale
1
Jeśli korzystasz z usługi PhoneGap Build, jest to zalecany sposób ustawiania tych wartości
Nico Westerdale,
Musiałem dodać <string>Random camera usage text</string>poniżej klucz, <key>NSCameraUsageDescription</key>aby moja kompilacja została zaakceptowana. Konfiguracja nie dodaje tekstu
Slartibartfast
9

AKTUALIZACJA: dla osób, które chcą używać aparatu z iOS> = 10. Oznacza to, że normalnie możesz skonfigurować wtyczkę jako:

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

Ale na razie nie możesz skonfigurować NSCameraUsageDescriptionani NSPhotoLibraryUsageDescriptionwtyczki. Musisz je skonfigurować na platformie -> projekt iOS przez Xcode lub w *-Info.plistpliku.

Od iOS 10 obowiązkowe jest dodanie NSCameraUsageDescription i NSPhotoLibraryUsageDescription w info.plist.

Dowiedz się więcej: https://www.npmjs.com/package/cordova-plugin-camera

Zawieszony
źródło
8

Używam następujących elementów w ionic 3 bez dodatkowej wtyczki lub importu i myślę, że może to być pomocne dla innych:

<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>
necixy
źródło
4

Możesz ustawić nazwę wyświetlaną w pliku plist aplikacji, bezpośrednio edytując plik ios.json w katalogu wtyczek.

Dodanie następujących elementów do sekcji config_munge.files w pliku ios.json załatwi sprawę i zostanie zachowane nawet podczas korzystania z interfejsu CLI.

"*-Info.plist": {

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

Oto pełny przykład

blakgeek
źródło
1
Uważaj, to nie działa podczas uruchamiania z Visual Sutdio Tools for Cordova, ponieważ ios.json jest nadpisywany przez narzędzia.
Herman Kan
2
Z tą odpowiedzią wiążą się dwa problemy. Po pierwsze, wszelkie ręczne zmiany w programie /plugins/ios.jsonzostaną utracone podczas uruchamiania, cordova platform remove iosa po nim cordova platform add ios. Po drugie, @ Red2678 poprosił o rozwiązanie polegające na „programowym wykonaniu edycji za pośrednictwem Cordova ... tak, aby nowy wpis został dodany w czasie kompilacji”.
TachyonVortex
3

Rozwiązanie @TachyonVortex wydaje się być najlepszą opcją, ale w moim przypadku uległo awarii. Problem został spowodowany przez puste pole NSMainNibFile, które nie zostało poprawnie przekonwertowane przez pakiet NPM plist. W pliku .plist

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

jest konwertowany na:

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

Naprawiłem to dodając do skryptu:

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

Skrypt w końcu wygląda następująco (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' });

};

i config.xml:

<platform name="ios">
    <hook type="before_build" src="scripts/my-hook.js" />
</platform>
Sebastien Horin
źródło
Napisałem patch_plist.jsw hooks/after_platform_addkatalogu z tym kodem. Ale nadal <key>NSMainNibFile</key><string>NSMainNibFile~ipad</string>mam plik plist. Masz jakiś pomysł, jak mogę rozwiązać ten problem?
Romain R.
2

Tak to mozliwe!

Używam Cordova 9.0.0 ([email protected]).

Na przykład jest to plik konfiguracyjny, którego użyłem do wstawienia nowej wartości ciągu do 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>

Następnie nie zapomnij odbudować pliku pomostowego, uruchamiając te dwa polecenia w terminalu:

cordova platform rm ios
cordova platform add ios

Aby potwierdzić zmianę, możesz sprawdzić nowo wygenerowany plik .plist, otwierając go za pomocą xCode.

-Info.plist znajdujący się pod adresem:

./platform/ios/[your app name]/[your app name]-Info.plist
Donovan P
źródło
edit-configzakłada, że ​​cel już istnieje na twoim plist. Dla jasności, jeśli chcesz dodać nową parę klucz / ciąg, powinieneś użyć config-filezamiast tego, co dodaje nowe dzieci do drzewa xml
Daniel Lizik
1

Jeśli próbujesz zmodyfikować a .plistw natywnej wtyczce iOS z <config-file>tagiem w swoim plugin.xml, oto co musisz zrobić:

  1. Upewnij się, że Twój .plistplik jest XML, a nie binarny! Możesz użyć, plutilaby przekonwertować plik binarny .plistna XML i zatwierdzić go do kontroli wersji.

    plutil -convert xml1 Info.plist

  2. Instrukcje dotyczące <config-file>wskazują, że target=jest to relatywne do wygenerowanego projektu xcode pod adresem platforms/ios/<project>/, ale stwierdziłem, że muszę dołączyć znak wieloznaczny do mojej ścieżki, aby działał:

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

  3. Jeśli chcesz dodać klucz na najwyższym poziomie .plist, musisz ustawić rodzica równy nazwie klucza, a następnie zagnieździć <string>tag z wartością. Użycie <array>lub, <dict>jak pokazują przykłady, spowoduje zagnieżdżenie tych kluczy w parent .

Oto kompletny przykład, który sprawdza się w przypadku dodawania wielu właściwości najwyższego poziomu:

<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>
Sky Kelsey
źródło
to nie działa dla mnie. Próbowałem dodać to, co masz powyżej, i nic się nie zmieniło w moim plista
Samuel Thompson
Spróbuj zawęzić przyczynę, umieszczając najpierw plik plist w katalogu głównym? Niestety, o ile wiem, ta funkcja nie działa cicho.
Sky Kelsey,
0

Wolę hook after_prepare dla większych projektów lub jeśli masz wiele wtyczek korzystających z tych samych uprawnień. Ale zawsze możesz iść prostą drogą:

po prostu: - usuń wtyczkę, która wymaga żądanych uprawnień - dodaj ją ponownie za pomocą --save - w config.xml, wtyczka ma teraz nową zmienną z pustym opisem, który możesz wypełnić - teraz buduj ios za pomocą - release i zostaną ustawione.

Emanuel
źródło
-4

potrzebujesz tylko następujących kroków 1.

Idź do nawigatora projektu Wybierz cel Kliknij informacje z zakładki opcja inna opcja to ustawienia budowania faza budowy zobaczysz wartość typu klucza Po wskazaniu dowolnej nazwy klucza znajdziesz znak + i - znak kliknij znak + wpisz Key: GDLibraryModew sekcji klucza Type:Stringw sekcja tyoe Value:GDEnterpriseSimulationw sekcji wartości

Nitin
źródło
1
Całkowicie chcę to zrobić, ale kiedy kompiluję aplikację Cordova z CLI, folder projektu jest w zasadzie usuwany i ponownie tworzony. Musiałbym wtedy robić powyższe za każdym razem, gdy kompiluję (nie jest to trudne), ale miałem nadzieję, że po prostu użyję pliku config.xml Cordova, aby zrobić to za mnie.
Red2678
czy możesz mi powiedzieć, dlaczego wymagane jest kompilowanie przez ciebie, uruchamiasz aplikację przez xcode, to rozwiązanie działa dla ciebie
Nitin
2
Cześć @Nitin, Cóż, to nie tyle „wymóg”, co standardowy sposób korzystania z CLI Cordova. Jeśli użyję „polecenia Cordova build”, folder projektu jest usuwany i ponownie tworzony po każdym uruchomieniu tego polecenia.
Red2678