20

在将基于 XML 的大型数据集读入 iPhone 应用程序时,Apple 强烈建议使用二进制 plist 格式。他们的理由之一是 XML 解析在 iPhone 上非常繁重。但是,这需要先转换位于远程 Web 服务器上的文件。

对于频繁更改的内容,手动执行此操作是不可接受的。如果可能的话,我想避免让基于 Web 的应用程序调用命令行来执行转换(即 plutil)。

是否有公开可用的算法来执行此转换?

4

9 回答 9

17

是的。所有 plist 代码都是 CoreFoundation 的一部分,它是开源的。CoreFoundation 可以直接在 Linux 和 Windows 上构建和运行,因此您可以使用在 Mac OS X 上使用的普通 API 编写 CF 工具,但在其他平台上构建和运行它。

您要查看的特定 API 是CFPropertyListWriteToStream()。CoreFoundation 的代码可从Apple ( tarball ) 等其他地方获得。

最后,取决于您更新文件的频率、服务器上必须保留多少处理器以及数据的重复次数,您可能还剩下一项重要的增强功能。默认情况下,二进制 plist 中的某些元素是唯一的(例如字符串)。其他元素不是(例如数组和字典)。二进制 plist 格式允许它们是唯一的,问题是实际遍历和唯一的数组和字典的成本很高。如果您的内容中有很多相同的数组或 dicts,您可能会看到通过使它们唯一化而显着减小了大小。您可以通过破解 CFBinaryPlist.c 中的 _flattenPlist() 来启用

如果您这样做,请确保对其进行非常彻底的测试,并且不要对无法通过网络更新的任何文件执行此操作,以防万一将来的版本进行任何优化会破坏它。此外,请确保您已准备好立即将其关闭。

于 2008-11-05T06:39:10.620 回答
14

有一个 PHP 和 ruby​​ 实现:

http://code.google.com/p/cfpropertylist/

于 2009-12-06T18:55:25.447 回答
7

链接的 Ruby 实现仅是 Ruby 1.9。我敲开了一个在 Ruby 1.8 中工作的快速二进制序列化程序。

http://gist.github.com/303378

于 2010-02-13T11:28:06.110 回答
6

目前尚不清楚您是要在 iPhone 上还是在服务器上进行转换。如果它在服务器上,并且您可以使用 Cocoa 框架,则NSPropertyListSerialization提供服务以在 OS X(自 10.2 起)上支持的 plist 类型(字符串、XML 和二进制)之间进行转换。如果您更愿意使用 Core Foundation 库中的类似方法,那么您也可以使用它。

要将 XML plist 转换为二进制 plist:

NSString *xmlPlistPath; // already set
NSString *outPath; // already set


NSData *plistData;
NSString *error;
NSPropertyListFormat format;
id plist;
plistData = [NSData dataWithContentsOfFile:xmlPlistPath];

plist = [NSPropertyListSerialization propertyListFromData:plistData
                                         mutabilityOption:NSPropertyListImmutable
                                                   format:&format
                                         errorDescription:&error];

if(plist == nil) { // unable to parse plist
    //deal with failure -- error gives description of the error
} else {
    binaryPlistData = [NSPropertyListSerialization dataFromPropertyList:plist
                                                                 format:NSPropertyListBinaryFormat_v1_0
                                                       errorDescription:&error];
    if(binaryPlistData == nil) {//unable to create serialized plist
         // deal with failure -- error gives description of the error
    }

    if(![binaryPlistData writeToFile:outPath atomically:YES]) {
        // unable to write file
    }
}

有关更多信息,请参阅developer.apple.com 上的Property List Pramming Guide页面。

于 2008-11-05T06:38:45.770 回答
3

还有一个 Perl 实现也称为 Data::Plist

于 2010-04-16T05:14:30.460 回答
3

命令行工具 plutil - 属性列表实用程序

Apple 有两个非常好的命令行工具来处理属性列表文件。

  • /usr/libexec/Plistbuddy- 用于编辑 plist
  • /usr/bin/plutil- 语法检查和类型转换

从 plutil 手册页:

plutil 可用于检查属性列表文件的语法,或将 plist 文件从一种格式转换为另一种格式。指定 - 作为从标准输入读取的输入文件。

将现有 plist 转换为 XML、二进制或 JSON 格式

plutil -convert xml1 stops2.plist
plutil -convert binary1 stops2.plist
plutil -convert json stops2.plist
于 2015-06-05T14:24:38.653 回答
1

将 plist 添加为 Rails 控制器的有效响应格式的binary_plist gem看起来很有希望。

于 2011-06-12T06:16:55.477 回答
1

几天前,我发现在 iOS 中与 plist 二进制数据联网时遇到了一些问题,而Gist我的这个是为了简单地解决问题:用 Swift 编写的 Plist Converter

于 2019-04-25T03:45:34.817 回答
-1

Java Spring框架解决方案

于 2012-11-15T05:42:22.827 回答