лучший способ добавить раздел лицензии в пакет настроек iOS

116

В моем приложении для iOS используется ряд сторонних компонентов, лицензированных под Apache 2.0 и аналогичными лицензиями, что требует от меня включения различных фрагментов текста, например:

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

Кажется, есть разумный прецедент для помещения этой информации в подстатью «Лицензия» в пакете настроек (на ipad facebook, страницы, основная заметка, числа и wikipanion, похоже, делают это).

Я немного борюсь, чтобы добиться того же самого; Мне кажется, что мне нужно разделить текст по строкам и ввести в xcode строку за раз (и у xcode4, похоже, возникает проблема сбоя при редактировании списков).

Это похоже на то, что почти наверняка есть где-то сценарий, который нужно сделать, или какой-то простой способ сделать это, который я пропустил.

JosephH
источник

Ответы:

192

Думаю, теперь мне удалось решить все проблемы, с которыми я столкнулся.

  • Кажется, лучше всего использовать заголовки элементов группы для хранения лицензий (это то, что Apple делает в приложениях iWork). Однако существует ограничение на их длину (и я еще не выяснил, какой именно предел), поэтому вам нужно разбить каждый файл лицензии на несколько строк.
  • Вы можете создать в них разрыв строки, включив буквальный возврат каретки (т. Е. Иначе известный как ^ M, \ r или 0x0A)
  • Убедитесь, что не добавили какой-либо литерал в середине текста. Если вы это сделаете, некоторые или все строки в файле будут игнорироваться.

У меня есть удобный сценарий, который я использую для создания файлов .plist и .strings, показанных ниже.

Чтобы использовать это:

  1. Создайте каталог лицензий в рамках вашего проекта
  2. Поместите скрипт в этот каталог
  3. Поместите каждую лицензию в этот каталог, по одной на файл, с именами файлов, заканчивающимися .license.
  4. Выполните необходимое переформатирование лицензий. (например, удалите лишние пробелы в начале строк, убедитесь, что в середине абзаца нет разрывов строк). Между каждым абзацем должна быть пустая строка.
  5. Перейдите в каталог лицензий и запустите скрипт
  6. Измените свой пакет настроек Root.plist, включив в него дочерний раздел под названием «Благодарности».

Вот сценарий:

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

Настройка вашего Settings.bundle

Если вы не создали файл Settings.bundle, перейдите в File -> New -> New File ...

В разделе "Ресурсы" найдите "Набор настроек". Используйте имя по умолчанию и сохраните его в корне вашего проекта.

Разверните Settings.bundleгруппу и выберите Root.plist. Вам нужно будет добавить новый раздел, в котором будет Preference Itemsтип ключа Array. Добавьте следующую информацию:

введите описание изображения здесь

В Filenameключевые моменты к PLIST , который был создан этот сценарий. Вы можете изменить его titleна то, что захотите.

Выполнить скрипт во время сборки

Кроме того, если вы хотите, чтобы этот сценарий запускался всякий раз, когда вы строите свой проект, вы можете добавить этап сборки к своей цели:

  1. Перейдите в файл вашего проекта
  2. Выберите цель
  3. Щелкните вкладку Build Phases.
  4. В правом нижнем углу этой панели нажмите «Добавить этап сборки».
  5. Выберите «Добавить сценарий запуска».
  6. Перетащите ваш Perl-скрипт в раздел для вашего скрипта. Измените, чтобы выглядеть примерно так:
  1. cd $SRCROOT/licenses( $SRCROOTуказывает на корень вашего проекта)
  2. ./yourScriptName.pl

После того, как вы закончите это, вы можете перетащить Run Scriptэтап сборки раньше в процессе сборки. Вы захотите переместить его раньше, Compile Sourcesчтобы обновления вашего пакета настроек были скомпилированы и скопированы.

Обновление для iOS 7: похоже, что iOS 7 по-другому обрабатывает ключ «Заголовок» и портит отображаемый текст. Чтобы исправить это, сгенерированный Acknowledgements.plist должен использовать ключ «FooterText» вместо «Title». Вот как изменить сценарий:

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
источник
1
Какая фантастическая идея! Я начал делать это вручную, прежде чем быстро понял, что мне нужно автоматическое решение, особенно из-за ограничения длины драконовских групповых заголовков.
Hilton Campbell
9
Одна вещь, на которую следует обратить внимание: «Имя файла» - это форма отображения ключа. Фактический ключ - «Файл». Если дочерняя панель не отображается, щелкните правой кнопкой мыши и выберите «Показать необработанные ключи / значения» и убедитесь, что имя ключа - «Файл».
atticus
10
Это здорово, спасибо. Я использовал 'cd "$ SRCROOT / Licenses /"' в блоке Run Script, который работает немного лучше, если над проектом работают несколько человек.
Крис
9
Прочтите devforums.apple.com/message/894791#894791, если вы используете это с iOS7. В частности, вам может потребоваться изменить <key> Title </key> на <key> FooterText </key>, чтобы он выглядел нормально.
esilver
2
Как сделать его дочерней панелью: Создайте элемент 0 внутри элементов предпочтений. Похоже, вы не можете выбрать дочернюю панель в качестве типа, но вы создаете элемент под элементом 0 (подпункт элемента 0), и этот первый элемент имеет ключ «Тип». Чтобы упростить задачу, щелкните по нему правой кнопкой мыши и выберите «Показать необработанные ключи / значения». Вы хотите установить для Type значение PSChildPaneSpecifier. После того, как вы отключите параметр «Показать необработанные ключи / значения», появится надпись «Дочерняя панель» даже в названии элемента 0, то есть «Его 0 (дочерняя панель -)». Это то, что вам нужно.
Марк
36

Вот то же решение, которое предоставил @JosephH (без переводов), но выполненное на Python для всех, кто предпочитает python 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"
)
Шон
источник
Этот ответ требует больше голосов. Синтаксис Python Синтаксис <3Perl. ;)
Ricardo Sanchez-Saez
5
current_file = codecs.open(filename, 'r', 'utf-8')для лицензий Unicode.
user2821144
Спасибо! Я создал новую версию на основе этой, которая отлично подходит для Карфагена. Он также удаляет некоторые ненужные символы новой строки из текста лицензии. Проверьте это: gist.github.com/Zyphrax/0d015c618d46093b4f815e62a6a33969
Zyphrax
1
Я немного поработал над этим, см .: github.com/Building42/AckAck
Zyphrax
15

В качестве альтернативы для тех, кто использует CocoaPods, он сгенерирует список «Подтверждений» для каждой цели, указанной в вашем Podfile, который содержит детали лицензии для каждого Pod, используемого в этой цели (при условии, что детали были указаны в спецификации Pod). Файл списка свойств, который можно добавить в пакет настроек iOS.

Также есть проекты, позволяющие преобразовывать эти данные и отображать их в приложении:

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

https://github.com/cocoapods/CPDAcknowledgements

JosephH
источник
3
Подробнее об этом: github.com/CocoaPods/CocoaPods/wiki/Acknowledgements
Орен,
Имейте в виду, что вики Cocoapods имеет имя входного файла как Pods-Acknowledgements.plist, но на самом деле файл создается как Pods -cknowledgements.plist (строчная буква «a»). Использование неправильного регистра приведет к остановке установки модуля, если ваша файловая система чувствительна к регистру.
Keller
14

Я подумал, что добавлю свою итерацию на потрясающий код Python Шона в микс. Основное отличие состоит в том, что он берет входной каталог и затем рекурсивно ищет в нем файлы LICENSE. Он получает значение заголовка из родительского каталога файла LICENSE, поэтому хорошо работает с cocoapods.

Мотивация заключалась в том, чтобы создать сценарий сборки, чтобы автоматически обновлять юридический раздел моего приложения при добавлении или удалении модулей. Он также выполняет некоторые другие действия, например, удаляет принудительные символы новой строки из лицензий, чтобы абзацы выглядели немного лучше на устройствах.

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

введите описание изображения здесь

carloe
источник
8

Я написал сценарий на Ruby, вдохновленный сценарием @JosephH. На мой взгляд, эта версия лучше представляет отдельные проекты с открытым исходным кодом.

Посетите iOS-AcknowledgementGenerator, чтобы загрузить сценарий и образец проекта.

Вот как будут выглядеть благодарности в вашем приложении:

Settings.app Settings.bundle Подтверждения введите описание изображения здесь

cvknage
источник
2

Это приложение к ответу Джозефа Х. (У меня нет представителя для комментариев)

Мне пришлось переместиться <key>StringsTable</key> <string>Acknowledgements</string> вниз к последнему </dict>в сценарии Perl.

Перед этой модификацией раздел благодарностей в приложении был пуст, и XCode не мог прочитать полученный список подтверждений. («Данные не могут быть прочитаны, потому что они не в правильном формате.»)

(XCode 6.3.2 iOS 8.3)

mattti
источник
2

Скрипт Python от Шона в этой ветке работает. Но есть пара основных вещей, которые нужно знать.

  1. в Xcode щелкните правой кнопкой мыши в верхней части дерева Project Navigator, на имени вашего проекта и добавьте новую группу. Это помещает новую папку в ваш проект.
  2. Добавьте туда сценарий Шона и обязательно сохраните его как: Acknowledgements.py.
  3. Убедитесь, что в вашей системе установлен Python. Я использую Mac.
  4. Добавьте первый файл лицензии в папку, созданную вами в 1. Сделайте это простым, как если бы в файле было всего одно слово, скажем: Тестирование. Сохраните его в папке как Test1.license.
  5. Настройте свой Settings.bundle, как описано выше для JosephH.
  6. Используйте приложение Terminal для компакт-диска в папку, созданную в 1.
  7. Запускаем скрипт. Тип: python Acknowledgements.py. Если вы не получите ошибок, он вернется обратно в окно терминала. Сделайте все это перед добавлением любого сценария запуска в сборку.
  8. Создайте и запустите свое приложение.
  9. Дважды нажмите кнопку «Домой» на iPhone и закройте «Настройки». Он не часто принимает изменения настроек для вашего приложения, пока настройки не будут перезагружены.
  10. После перезапуска настроек перейдите в свое приложение и посмотрите, работает ли оно.
  11. Если все это сработало, медленно добавляйте новые файлы лицензий, но каждый раз запускайте сценарий. Вы можете получить ошибки при запуске сценария из-за определенных символов в файле, поэтому простой способ отладки - это добавить файл, запустить сценарий, посмотреть, сработал ли он, и продолжить. В противном случае отредактируйте любые специальные символы из файла .license.
  12. Мне не удалось запустить сценарий сборки в соответствии с приведенными выше инструкциями. Но этот процесс работает нормально, если вы не часто меняете файлы .license.
Д. Ротшильд
источник
1

Ack Ack: Генератор списка подтверждений
Некоторое время назад я создал сценарий Python, который сканирует файлы лицензий и создает красивый список подтверждений, который вы можете использовать в своем Settings.plist. Он делает за вас большую часть работы.

https://github.com/Building42/AckAck

Характеристики

  • Обнаруживает папки Carthage и CocoaPods
  • Обнаруживает существующие списки для пользовательских лицензий
  • Очищает тексты лицензий, удаляя ненужные новые строки и разрывы строк
  • Предоставляет множество вариантов настройки ( --helpподробности см. )
  • Поддерживает Python v2 и v3

устанавливать

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

Бегать

./ackack.py

Скриншот

Подтверждения

Если у вас есть предложения по улучшению, не стесняйтесь размещать проблему или запрос на перенос на GitHub!

Zyphrax
источник