121

我的 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 上似乎都这样做)。

不过,我正在努力实现同样的目标;我似乎需要逐行拆分文本并一次输入一行(并且 xcode4 在编辑 plist 时似乎有崩溃问题)。

似乎几乎可以肯定有一个脚本可以做,或者我错过了一些简单的方法来做这件事。

4

10 回答 10

196

我想我现在已经设法解决了我遇到的所有问题。

  • 似乎最好使用组元素标题来持有许可证(这是 Apple 在 iWork 应用程序中所做的)。但是,它们的长度是有限制的(我还没有确切地发现限制是什么),因此您需要将每个许可证文件分成多个字符串。
  • 您可以通过包含文字回车(即,也称为 ^M、\r 或 0x0A)在其中创建换行符
  • 确保不要包含任何文字 "s 中间文本。如果这样做,文件中的部分或全部字符串将被静默忽略。

我有一个方便的脚本用来帮助生成 .plist 和 .strings 文件,如下所示。

要使用它:

  1. 在您的项目下创建一个“许可证”目录
  2. 将脚本放入该目录
  3. 将每个许可证放入该目录,每个文件一个,文件名以 .license 结尾
  4. 对许可证执行任何必要的重新格式化。(例如,删除行首的多余空格,确保段落中间没有换行符)。每个段落之间应该有一个空行
  5. 切换到 licenses 目录并运行脚本
  6. 编辑您的设置包 Root.plist 以包含一个名为“Acknowledgements”的子部分

这是脚本:

#!/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. 单击构建阶段选项卡
  4. 在该窗格的右下角,单击“添加构建阶段”
  5. 选择“添加运行脚本”
  6. 将您的 perl 脚本拖放到您的脚本部分。修改为如下所示:
  1. cd $SRCROOT/licenses$SRCROOT指向项目的根目录)
  2. ./yourScriptName.pl

完成后,您可以Run Script在构建过程中更快地拖动构建阶段。您需要先将其向上移动,Compile Sources以便对 Settings Bundle 的更新进行编译和复制。

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);
}
于 2011-06-23T11:47:55.477 回答
37

这是@JosephH 提供的相同解决方案(没有翻译),但是对于喜欢 python 而不是 perl 的任何人来说,都是在 Python 中完成的

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"
)
于 2014-01-24T07:05:26.600 回答
16

作为替代方案,对于那些使用 CocoaPods 的人,它将为 Podfile 中指定的每个目标生成一个“确认”plist,其中包含该目标中使用的每个 Pod 的许可证详细信息(假设详细信息已在 Pod 规范中指定)。可以添加到 iOS 设置包的属性列表文件。

还有一些项目正在进行中,以允许在应用程序中转换和显示这些数据:

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

https://github.com/cocoapods/CPDAcknowledgements

于 2014-03-07T16:59:11.817 回答
15

我想我会把我的迭代放在 Sean 的很棒的 python 代码上。主要区别在于它需要一个输入目录,然后递归地在其中搜索 LICENSE 文件。它从 LICENSE 文件的父目录派生标题值,因此它可以很好地与 cocoapods 配合使用。

其动机是创建一个构建脚本,以便在我添加或删除 pod 时自动使我的应用程序的法律部分保持最新。它还执行其他一些操作,例如从许可证中删除强制换行符,以便段落在设备上看起来更好一些。

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

在此处输入图像描述

于 2014-09-15T16:20:40.373 回答
8

我在 @JosephH 脚本的启发下用 Ruby 编写了一个脚本。在我自己看来,这个版本将更好地代表各个开源项目。

访问iOS-AcknowledgementGenerator以下载脚本和示例项目。

这是您的应用程序中的确认信息:

设置.app Settings.bundle 致谢 在此处输入图像描述

于 2014-02-07T17:27:14.100 回答
2

这是 JosephH 答案的附录。(我没有代表发表评论)

我不得不向下移动 到Perl 脚本中<key>StringsTable</key> <string>Acknowledgements</string> 的最后一个。</dict>

在此修改之前,App 中的 Acknowledgements 部分为空,XCode 无法读取生成的 Acknowledgements.plist。(“无法读取数据,因为它的格式不正确。”)

(XCode 6.3.2 iOS 8.3)

于 2015-05-25T08:33:37.000 回答
2

这个线程中 Sean 的 Python 脚本有效。但是有一些基本的事情要知道。

  1. 在 Xcode 中,右键单击项目导航树顶部的项目名称,然后添加一个新组。这会在您的项目中放置一个新文件夹。
  2. 在此处添加 Sean 的脚本并确保将其保存为:Acknowledgements.py。
  3. 确保您的系统上安装了 Python。我正在使用 Mac。
  4. 将第一个许可证文件添加到您在 1 中创建的文件夹中。让它变得简单,就像在文件中只包含一个单词,比如:测试。将其保存在文件夹中作为 Test1.license。
  5. 按照上面的 JosephH 设置您的 Settings.bundle。
  6. 使用您的终端应用程序 CD 到您在 1 中创建的文件夹。
  7. 运行脚本。类型:python Acknowledgements.py。如果您没有收到错误,它将立即返回到终端提示符。在将任何运行脚本添加到构建之前执行所有这些操作。
  8. 构建并运行您的应用程序。
  9. 双击 iPhone 主页按钮并取消设置。在设置重新启动之前,它通常不会为您的应用获取设置更改。
  10. 重新启动设置后,转到您的应用程序并查看它是否有效。
  11. 如果一切正常,请慢慢添加更多许可证文件,但每次都运行脚本。由于文件中的某些字符,您可能会在运行脚本时出错,因此调试的简单方法是添加文件,运行脚本,查看它是否有效并继续。否则,编辑 .license 文件中的任何特殊字符。
  12. 按照上面的说明,我没有得到运行构建脚本的工作。但是,如果您不经常更改 .license 文件,则此过程可以正常工作。
于 2016-02-28T21:37:25.763 回答
1

Ack Ack: Acknowledgment Plist Generator 不久前
,我创建了一个 Python 脚本,用于扫描许可证文件并创建一个不错的 Acknowledgments plist,您可以在 Settings.plist 中使用它。它为你做了很多工作。

https://github.com/Building42/AckAck

特征

  • 检测 Carthage 和 CocoaPods 文件夹
  • 检测自定义许可证的现有 plist
  • 通过删除不必要的新行和换行符来清理许可证文本
  • 提供许多自定义选项(详见--help
  • 同时支持 Python v2 和 v3

安装

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

./ackack.py

截屏

致谢

如果您有改进建议,请随时在 GitHub 上发布问题或拉取请求!

于 2019-07-27T00:30:13.433 回答
0

Aknowlist是一个强大的 CocoaPod 候选者,在撰写本文时正在积极维护。如果您可以在应用程序而不是设置包中容纳许可证,它会自动执行此许可。它对我正在从事的项目非常有用。

于 2021-08-31T18:41:12.690 回答
0

我不得不为现代 python3 修改肖恩的脚本:

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"):
        with open(filename, 'r') as current_file:
            group = deepcopy(base_group)
            title = filename.split(".license")[0]
            group['Title'] = title
            group['FooterText'] = current_file.read()
            plist['PreferenceSpecifiers'].append(group)

with open("Acknowledgements.plist", "wb") as f:
    plistlib.dump(plist, f)
于 2022-01-13T00:22:01.473 回答