【问题标题】:Converting plist to binary plist将 plist 转换为二进制 plist
【发布时间】:2010-09-20 20:04:12
【问题描述】:

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

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

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

【问题讨论】:

    标签: objective-c iphone cocoa-touch plist core-foundation


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 谢谢,这很有帮助。我可能会构建它并将其中一些函数包装到 PHP 模块中。
    • 谢谢,但是 CFPropertyListWriteToStrean() 的任何 Java 实现? :S
    • 链接已失效。 CFPropertyListWriteToStream() 的新链接是 here;它说我们应该改用CFPropertyListWrite
    【解决方案2】:

    有一个 PHP 和 ruby​​ 实现:

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

    【讨论】:

      【解决方案3】:

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

      http://gist.github.com/303378

      【讨论】:

      • 这真是太棒了。正是我需要的。非常感谢!
      • 如果你的意思是github.com/ckruse/CFPropertyList“链接的Ruby实现”,那么我不得不说这不是真的。它向后兼容 Ruby 1.8。
      【解决方案4】:

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

      将 XML 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 页面。

      【讨论】:

      • 我肯定想在服务器上执行转换,因为我只需要执行一次,iPhone 必须尽可能少地读取数据;下载的数据也可能要少得多。感谢您的回答。
      • 我只是在寻找如何在本地缓存数据。谢谢!
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

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

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

        来自 plutil 手册页:

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

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

        plutil -convert xml1 stops2.plist
        plutil -convert binary1 stops2.plist
        plutil -convert json stops2.plist
        

        【讨论】:

          【解决方案7】:

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

          【讨论】:

            【解决方案8】:

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

            【讨论】:

              【解决方案9】:
              猜你喜欢
              • 1970-01-01
              • 2012-11-03
              • 1970-01-01
              • 1970-01-01
              • 2014-02-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多