Skip to content

Latest commit

 

History

History
79 lines (53 loc) · 3.72 KB

ReadMe.md

File metadata and controls

79 lines (53 loc) · 3.72 KB

FDSerialArchiver

Overview

FDSerialArchiver is a serial binary archiver in the style of NSArchiver. Concretely, FDSerialArchiver and FDSerialUnarchiver are concrete subclasses of NSCoder (thus allowing you to use the <NSCoding> protocol) implementing the features of NSArchiver. In opposition to NSKeyedArchiver, FDSerialArchiver does not support keyed archiving: data is serially appended/read from a stream of binary symbols for faster encoding/decoding.

Motivation

NSKeyedArchiver is a great piece of software: it gives view keyed (un)archiving, versioning, etc. In short: it gives you flexibility. I started experimenting with serial archiving because sometimes, this kind of flexibility is overkill. You might want to serialize very lightweight, straightforward pieces of data that will not be subject to change in the future. The flexibility of NSKeyedArchiver results in speed and space compromises, and unfortunately NSArchiver is deprecated on OS X since 10.2, and AFAIK never made it to iOS. I was curious to see what kind of performances you can get by using more basic archiving techniques. More importantly, I felt like it would be a good exercise and a nice way to get more acquainted with NSCoder.

Usage

Using FDSerialArchiver is as simple as using the NSCoding protocol, but without the keyed part. The classes you are used to using (NSArray, NSNumber, NSString, etc ) all support unkeyed archiving.

For your custom classes, you will need to implement the encodeWithCoder: method, for instance:

-(void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeValueOfObjCType:@encode(double) at:&_someDoubleMember];
    [aCoder encodeObject:_someCustomClassInstanceMember];
    [aCoder encodeObject:_someMutableArrayMember];
}

And simply call the archiving method on the root object to archive

data = [FDSerialArchiver archivedDataWithRootObject:objectToEncode];

Decoding is done by implementing initWithCoder: in the same classes as you implemented encodeWithCoder::

-(id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        // Serial archiving => order is important !
        [aDecoder decodeValueOfObjCType:@encode(double) at:& _someDoubleMember];
        _someCustomClassInstanceMember = [aDecoder decodeObject];
        _someMutableArrayMember = [aDecoder decodeObject]; 
    }
    return self;
}

And simply calling the unarchive method

decodedObject = [ISUBinaryUnarchiver unarchiveObjectWithData:data];

Performance

ToDo

  • Archive versionning
  • Performance chart
  • Endianness
  • Enable custom relation Class <-> ClassName (-(void)encodeClassName:(NSString *)trueName intoClassName:(NSString *)inArchiveName and - (NSString *)classNameEncodedForTrueClassName:(NSString *)trueName)

License

FDSerialArchiver is distributed using the MIT license. See the LICENSE file for detailed information

In short, you can use it, modify it and distribute it (including in binary form) as long as you include the following notice :

FDSerialArchiver
Copyright (c) 2013 Florian Denis

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.