Skip to content

Latest commit

 

History

History
133 lines (102 loc) · 5.23 KB

ROADSerialization.md

File metadata and controls

133 lines (102 loc) · 5.23 KB

#Serialization

Attribute-based JSON and XML serializers.

#1. JSON

Component takes advantages of properties annotations to define serialization options with RFAttributes.

Encoding and decoding entry points are provided by correspondening classes:

  • RFAttributedCoder encodes serializable object into JSON stored in NSString, NSData or NSDictionary.

    + (id)encodeRootObject:(id const)rootObject;
  • RFAttributedDecoder acts in a reverse direction.

    + (id)decodeJSONString:(NSString *const)jsonString withRootClassNamed:(NSString * const)rootClassName;

Where rootClassName is a name of any NSObject subclass with serialization attributes defined.

##Defined Attributes

  • RFDerived. Annotates property to mark it as 'not serializable' in a serializable class.
  • RFSerializable. Marks class or property serializable. Sets all properties as serializable when annotates class declaration.
  • RFSerializableCollection. Marks a collection of serializable items.
  • RFSerializableDate. Defines format for serializable NSDate property or for all date properties on the class level.
  • RFSerializableBoolean. Defines custom serialization behaviour for boolean values.
  • RFSerializationCustomHandler. Defines custom serialization handler class. The handler class has to conform to RFJSONSerializationHandling protocol for JSON serialization.

##Sample Serializable Person object can look like:

RF_ATTRIBUTE(RFSerializable)
@interface Person : NSObject
	
@property (strong, nonatomic) NSString *firstName;
@property (strong, nonatomic) NSString *lastName;
	
// firstName + lastName. Not serialized
RF_ATTRIBUTE(RFDerived)
@property (copy, nonatomic) NSString *fullName;
	
RF_ATTRIBUTE(RFSerializableDate, format = @"dd/MM/yyyy HH:mm:ss Z", encodingFormat = @"MM.dd.yyyy HH:mm:ss.AAA Z")
@property (strong, nonatomic) NSDate *birthday;
	
RF_ATTRIBUTE(RFSerializableCollection, collectionClass = [Car class])
@property (copy, nonatomic) NSArray *cars;

RF_ATTRIBUTE(RFSerializationCustomHandler, decodingPreprocessor = ^(NSString *string) {
                                               return [NSURL URLWithString:string];
                                           },
                                           encodingPreprocessor = ^(NSURL *website) {
                                               return [website absoluteString];
                                           })
@property (strong, nonatomic) NSURL *website;
	
@end

where RF_ATTRIBUTE(RFSerializable) defines that class with all it's properties should be serialized. fullName is annotated as RFDerived which means that it should be omitted for encoding. birthday is annotated with encoding date type and encoding format. cars property marked as a serializable collection containing Car objects.

#2. XML Serializer implements SAX-based XML deserialization into attributed object tree on top of NSXMLParser and XML serialization with libxml2.

API is similar to JSON serializer:

  • RFAttributedXMLCoder encodes serializable object into XML stored in NSString, NSData or NSDictionary.

    - (id)encodeRootObject:(id const)rootObject;
  • RFAttributedXMLDecoder acts in a reverse direction.

    - (id)decodeData:(NSData *)xmlData withRootObjectClass:(Class)rootObjectClass;

Where rootClassName is a name of any NSObject subclass with serialization attributes defined.

##Defined Attributes

JSON parsing attributes are derived and extended with:

  • RFXMLSerializable.
    • isTagAttribute Applied to object property and defines whether it is stored in parent tag as attribute or as a child.
  • RFXMLSerializableCollection. Applied to object property of NSArray or NSDictionary type when it should be serialized directly into parent's tag.
    • itemTag sets tag name for collection items.

##Sample

<person age="54" name="John Doe" city="Boyarka">
  <children>
    <person age="25" name="Mary Doe" city="Boyarka"/>
    <person age="13" name="Chris Doe" city="Boyarka"/>
  </children>
</person>	

XML above can be annotated in code in the following way:

RF_ATTRIBUTE(RFSerializable)
@interface Person : NSObject
	
RF_ATTRIBUTE(RFXMLSerializable, isTagAttribute = YES);
@property (copy, nonatomic) NSString *name;
RF_ATTRIBUTE(RFXMLSerializable, isTagAttribute = YES);
@property (copy, nonatomic) NSString *city;
RF_ATTRIBUTE(RFXMLSerializable, isTagAttribute = YES);
@property (assign, nonatomic) int age;
	
RF_ATTRIBUTE(RFSerializableCollection, collectionClass = [Person class])
@property (copy, nonatomic) NSArray *children;

If children of John are stored without container tag:

<person age="54" name="John Doe" city="Boyarka">
  <person age="25" name="Mary Doe" city="Boyarka"/>
  <person age="13" name="Chris Doe" city="Boyarka"/>
</person>	

children property can be annotated that content of it's subtags with 'person' key is associated with the children array:

RF_ATTRIBUTE(RFXMLSerializableCollection, collectionClass = [Person class], itemTag = @"person")
@property (copy, nonatomic) NSArray *children;

Serialization works in the same way.