Skip to content

Custom Serialization

Aleksey Garbarev edited this page Jun 30, 2015 · 1 revision

By Default, TyphoonRestClient allow you to send:

  • JSON
  • Plist
  • NSString
  • NSData or NSInputStream
  • HTTP query

and receive:

  • JSON
  • Plist
  • NSString
  • NSData (or write to file)
  • UIImage

If you not happy with that set, you can extend that by adding request or response serializations into TRC.

Request Serialization

Request serialization transforms result of requestBody method into NSData (or NSInputStream) which used later by NSURLRequest.

Request serialization has next protocol:

@protocol TRCRequestSerializer <NSObject>

@optional

- (NSData *)dataFromRequestObject:(id)requestObject error:(NSError **)error;

- (NSInputStream *)dataStreamFromRequestObject:(id)requestObject error:(NSError **)error;

- (NSString *)contentType;

@end

All methods are optional here.

  • dataFromRequestObject:error:
  • dataStreamFromRequestObject:error
  • You can implement one of them to return NSData/NSInputStream from requestBody object. If nothing implemented, or returned nil then request body is empty. For example JSON serializer converts NSDictionary requestObject into UTF8 String data.
  • contentType
  • This is string which would be used as Content-Type HTTP header value. If not implemented or returns nil, then Content-Type would be not specified.

After implementation of this protocol, you should register your implementation into TyphoonRestClient using next method:

- (void)registerRequestSerializer:(id<TRCRequestSerializer>)serializer forName:(TRCSerialization)serializerName;

serializerName is string which would be used to identify your serializer. You should point to that name in your TRCRequest implementations.

Response Serialization

Unlike request serailization, response serialization transforms NSData into responseObject, which can be used to 'compose' your model objects.

There is method list:

@protocol TRCResponseSerializer <NSObject>

- (id)objectFromResponseData:(NSData *)data error:(NSError **)error;

@optional
- (BOOL)isCorrectContentType:(NSString *)responseContentType;

@end
  • objectFromResponseData:error:
  • This method requered to implement. You have to parse input NSData into some object which would be used to compose model objects later. For example JSON serializer parses NSData as string into NSDictionary or NSArray (based on root object)
  • isCorrectContentType:
  • If implemented, provides response validation by Content-Type header. For example Image response serializer checks, that Content-Type prefixed with image, like image/png - this is usefull to handle text/html response (in case of 404 response) as error.

Similar to response serializer, you have to register your response serializer implementation.

- (void)registerResponseSerializer:(id<TRCResponseSerializer>)serializer forName:(TRCSerialization)serializerName;

Scheme Formats

While response and request serializers transforms binary data to objects and objects to binary data, there is no request/response validation and value transformation. To achieve automatic validation and value trasformation you need some schema. Schema is information that tells to the system correct data structure and knows value types. Information about data structure used to validate input data object. Information about value types used to convert input values into another type. Schema information must be stored as file and included into application bundle. Before response validation TRC loads schema from file, looks for file extension and use schema format (TRCSchemaFormat protocol) that match file format.

By default, TRC has two scheme formats: JSON and Plist. You register your own formats by protocol implementation:

@protocol TRCSchemaFormat <NSObject>

- (id<TRCSchemaData>)requestSchemaDataFromData:(NSData *)data dataProvider:(id<TRCSchemaDataProvider>)dataProvider error:(NSError **)error;
- (id<TRCSchemaData>)responseSchemaDataFromData:(NSData *)data dataProvider:(id<TRCSchemaDataProvider>)dataProvider error:(NSError **)error;

@end

These two methods creates TRCSchemaData implementation from file data. Your implementation of TRCSchemaData knows data structure of your schema format. Some scheme formats has same TRCSchemaData implementation, but at same, has different file serialization. For example JSON and Plist has same data structure: each item either array, dictionary or value, hence both of them uses TRCSchemaDictionaryData implementation of TRCSchemaData. If your schema format has same data structure as JSON or Plist, then your TRCSchemaFormat would be simple (Check TRCSerializerJson and TRCSerializerPlist implementations.

You have to register your TRCSchemaFormat implementation using that method of TRC:

- (void)registerSchemeFormat:(id<TRCSchemaFormat>)schemeFormat forFileExtension:(NSString *)extension

Like that:

TRCSerializerJson *json = [TRCSerializerJson new];
[self registerSchemeFormat:json forFileExtension:@"json"];

TRCSerializerPlist *plist = [TRCSerializerPlist new];
[self registerSchemeFormat:plist forFileExtension:@"plist"];

extension parameters specifies file extension of your schema file. For example, when TRC loads RequestToAuth.request.json, it found json extension and uses TRCSerializerJson to read file content. You can register one TRCSchemaFormat implementation for few file extension but you can't register two formats for one file extension, last one will override previous one.

Clone this wiki locally