1

I'm trying to save data to a file in binary format so the file size is as small as possible. But it seems that NSPropertyListFormat.BinaryFormat_v1_0 does not actually create binary data but instead creates an XML-style format exactly the same as NSPropertyListFormat.XMLFormat_v1_0. Am I doing something wrong? Here is some test code:

@IBAction func archiveAction(sender: AnyObject) {
    let firstName = "Robert"
    let lastName = "Smith"

    var md: NSMutableData = NSMutableData()
    var archiver = NSKeyedArchiver(forWritingWithMutableData:md)
    archiver.outputFormat = NSPropertyListFormat.BinaryFormat_v1_0
    archiver.encodeObject(firstName, forKey: "first")
    archiver.encodeDouble(123.456, forKey: "double")
    archiver.encodeFloat(Float(M_PI), forKey: "pi")
    archiver.encodeObject(lastName, forKey: "last")
    archiver.finishEncoding()

    let filePath = NSTemporaryDirectory().stringByAppendingPathComponent("FileNameBinary")
    md.writeToFile(filePath, atomically: false)
    println("done")
}

When I examine the file this creates I see that it is an XML file. And it has exactly the same number of bytes as it has if I change the .BinaryFormat_v1_0 to .XMLFormat_v1_0.

So how can save data as binary?

EDIT: Here is the file contents:

<?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>$archiver</key>
    <string>NSKeyedArchiver</string>
    <key>$objects</key>
    <array>
        <string>$null</string>
        <string>Robert</string>
        <string>Smith</string>
    </array>
    <key>$top</key>
    <dict>
        <key>double</key>
        <real>123.456</real>
        <key>first</key>
        <dict>
            <key>CF$UID</key>
            <integer>1</integer>
        </dict>
        <key>last</key>
        <dict>
            <key>CF$UID</key>
            <integer>2</integer>
        </dict>
        <key>pi</key>
        <real>3.1415927410125732</real>
    </dict>
    <key>$version</key>
    <integer>100000</integer>
</dict>
</plist>
Matthias Bauch
  • 89,811
  • 20
  • 225
  • 247
RobertL
  • 14,214
  • 11
  • 38
  • 44
  • BinaryFormat_v1_0 is not XML. how do you examine the file? – Felix Jul 14 '15 at 22:14
  • I examine the file with the stand-alone Mac utility "iExplorer", which accesses the file system on an iPhone. So I use that to copy the file to the Mac desktop then open it with TextWrangler. I will edit the original question to show the file as it appears in TextWrangler. I carefully verified that it's not a file that's left over from a prior run, by deleting the app from the phone before running. – RobertL Jul 14 '15 at 22:38
  • What you had before was an archive. `$archiver NSKeyedArchiver $objects $null Robert Smith $top double 123.456 first CF$UID 1 last CF$UID 2 pi 3.1415927410125732 $version 100000` What's the problem? – matt Jul 14 '15 at 22:51
  • Hmmm. There's obviously something here I don't understand. iExplorer says the file on the iPhone is 196 bytes but when I look at it in TextWrangler (and as now shown in the post) it's 700 bytes so you're probably right. Somewhere along the line the file must get converted to its XML representation without my knowing it. I'll have to think about this some more. Thanks. – RobertL Jul 14 '15 at 23:18
  • 1
    I now see that TextWrangler displays the file as XML. I suppose that's a feature. If I look at the same file with TextEdit.app it looks like a binary file should look. Also, it's the right size to be binary (about 0.3 times the XML size). – RobertL Jul 14 '15 at 23:31

1 Answers1

1

TextWrangler probably know how to read plist files, whether in binary or in XML format. To actually see the difference, you have to use a utility that is agnostic to the plist file type. All information below uses the example code you posted.

File size:

> ls -l FileName*
-rw-r--r--  1 zd  staff  196 14 Jul 19:10 FileNameBinary
-rw-r--r--  1 zd  staff  700 14 Jul 19:10 FileNameXML

So binary format is much smaller than XML (196 vs. 700 bytes).

File content:

> cat FileNameBinary
bplist00?

X$versionX$objectsY$archiverT$top???    U$nullVRobertUSmith_NSKeyedArchiver?
VdoubleUfirstRpiTlast#@^?/??w?"@I#-27;AHN`ipvy~????

> cat FileNameXML
<?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">
(extra lines trimmed)

Again content is different.

There is a difference between the two formats. You just need to know how to look for them.

Community
  • 1
  • 1
Code Different
  • 90,614
  • 16
  • 144
  • 163