将许可证部分添加到iOS设置包的最佳方法

时间:2011-06-21 15:57:44

标签: ios plist settings.bundle

我的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一行(编辑plist时xcode4似乎有一个崩溃的问题)。

看起来几乎可以肯定是某个地方要做的事情,或者是我错过了一些简单的方法。

8 个答案:

答案 0 :(得分:191)

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

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

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

使用它:

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

    #!/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,请转到文件 - &gt;新 - &gt;新文件......

    在“资源”部分下,找到“设置包”。使用默认名称并将其保存到项目的根目录。

    展开Settings.bundle群组,然后选择Root.plist。您需要添加一个新部分,其键的Preference Items类型为Array。添加以下信息:

    enter image description here

    Filename键指向此脚本创建的plist。您可以将title更改为您想要的内容。

    在构建时执行脚本

    此外,如果您希望在构建项目时运行此脚本,则可以向目标添加构建阶段:

    1. 转到您的项目文件
    2. 选择目标
    3. 单击“构建阶段”选项卡
    4. 在该窗格的右下角,点击“添加构建阶段”
    5. 选择“添加运行脚本”
    6. 将perl脚本拖放到脚本部分。修改为看起来像这样:
    7.   
          
      1. cd $SRCROOT/licenses$SRCROOT指向项目的根目录)
      2.   
      3. ./yourScriptName.pl
      4.   

      完成后,您可以在构建过程中更快地拖动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);
      }
      

答案 1 :(得分:36)

这是@JosephH提供的相同解决方案(没有翻译),但是在Python中为任何喜欢python over 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"
)

答案 2 :(得分:15)

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

还有正在进行的项目允许在应用程序中转换和显示此数据:

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

https://github.com/cocoapods/CPDAcknowledgements

答案 3 :(得分:13)

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

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

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

enter image description here

答案 4 :(得分:8)

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

Wisit iOS-AcknowledgementGenerator下载脚本和示例项目。

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

Settings.app Settings.bundle Acknowledgements enter image description here

答案 5 :(得分:2)

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

我不得不搬家 <key>StringsTable</key> <string>Acknowledgements</string> 低至Perl脚本中的最后一个</dict>

在此修改之前,应用程序中的Acknowledgements部分为空,XCode无法读取生成的Acknowledgements.plist。 (&#34;无法读取数据,因为格式不正确。&#34;)

(XCode 6.3.2 iOS 8.3)

答案 6 :(得分:2)

此线程中Sean的Python脚本可以正常工作。但有一些基本的事情要知道。

  1. 在Xcode中,右键单击Project Navigator树的顶部,在项目名称上,然后添加一个New Group。这会在您的项目中添加一个新文件夹。
  2. 在那里添加Sean的脚本,并确保将其保存为:Acknowledgements.py。
  3. 确保在系统上安装了Python。我正在使用Mac。
  4. 将第一个许可文件添加到您在1中创建的文件夹中。简单地说,只需在文件中包含一个单词,即:测试。将其作为Test1.license保存在文件夹中。
  5. 根据上述JosephH设置您的Settings.bundle。
  6. 使用您的终端应用程序将CD刻录到您在1中创建的文件夹。
  7. 运行脚本。键入:python Acknowledgements.py。如果没有错误,它将立即返回到终端提示符。在将任何运行脚本添加到Build之前执行所有这些操作。
  8. 构建并运行您的应用。
  9. 双击iPhone主页按钮并终止设置。在设置重新启动之前,它通常不会为您的应用选择设置更改。
  10. 重新启动设置后,转到您的应用并查看是否有效。
  11. 如果一切正常,请慢慢添加更多许可证文件,但每次都要运行脚本。由于文件中的某些字符,您可能会因运行脚本而出错,因此调试的简便方法是添加文件,运行脚本,查看是否有效并继续。否则,编辑.license文件中的任何特殊字符。
  12. 我没有按照上面的说明运行Run Build Script。但是,如果您不经常更改.license文件,则此过程可以正常工作。

答案 7 :(得分:0)

确认Ack:确认Plist生成器
不久前,我创建了一个Python脚本,该脚本扫描许可证文件并创建一个不错的Acknowledgments plist,您可以在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

屏幕截图

Acknowledgements

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