Migrate to NSData based parsing/serialization. Slim down RKObjectSerializer and rename to RKObjectParameters. refs #762

This commit is contained in:
Blake Watters
2012-09-03 16:23:22 -04:00
parent cb624080b2
commit e67848439c
17 changed files with 259 additions and 208 deletions

View File

@@ -184,7 +184,7 @@
[self resetPersistentStoreIfNecessary];
NSError *localError = nil;
NSString *payload = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&localError];
NSData *payload = [NSData dataWithContentsOfFile:path options:0 error:&localError];
if (! payload) {
RKLogError(@"Failed to read file at path '%@': %@", path, [localError localizedDescription]);
if (error) *error = localError;
@@ -192,10 +192,11 @@
}
NSString *MIMEType = [path MIMETypeForPathExtension];
id<RKParser> parser = [[RKParserRegistry sharedRegistry] parserForMIMEType:MIMEType];
// TODO: Return error RKParserNotRegisteredForMIMETypeError
NSAssert1(parser, @"Could not find a parser for the MIME Type '%@'", MIMEType);
id parsedData = [parser objectFromString:payload error:&localError];
id parsedData = [[RKParserRegistry sharedRegistry] parseData:payload withMIMEType:MIMEType error:&localError];
if (!parsedData) {
RKLogError(@"Failed to parse file at path '%@': %@", path, [localError localizedDescription]);
}
if (! parsedData) {
if (error) *error = localError;
return NSNotFound;

View File

@@ -22,5 +22,4 @@
#import "RKRoute.h"
#import "RKRouteSet.h"
#import "RKRouter.h"
#import "RKRequestSerializable.h"
#import "RKReachabilityObserver.h"

View File

@@ -22,7 +22,7 @@
#import "RKObjectMapping.h"
#import "RKAttributeMapping.h"
#import "RKRelationshipMapping.h"
#import "RKObjectSerializer.h"
#import "RKObjectParameters.h"
#import "RKMappingResult.h"
#import "RKObjectMapper.h"
#import "RKParserRegistry.h"

View File

@@ -19,7 +19,7 @@
//
#import "RKObjectManager.h"
#import "RKObjectSerializer.h"
#import "RKObjectParameters.h"
#import "RKManagedObjectStore.h"
#import "RKSupport.h"
#import "RKRequestDescriptor.h"
@@ -226,9 +226,8 @@ static NSOperationQueue *defaultMappingQueue = nil;
NSDictionary *requestParameters = nil;
RKRequestDescriptor *requestDescriptor = [self requestDescriptorForObject:object];
if (requestDescriptor) {
RKObjectSerializer *serializer = [[RKObjectSerializer alloc] initWithObject:object mapping:(RKObjectMapping *)requestDescriptor.mapping rootKeyPath:requestDescriptor.rootKeyPath];
NSError *error;
NSMutableDictionary *mergedParameters = [[serializer serializeObjectToDictionary:&error] mutableCopy];
NSError *error = nil;
NSMutableDictionary *mergedParameters = [[RKObjectParameters parametersWithObject:object requestDescriptor:requestDescriptor error:&error] mutableCopy];
if (parameters) [mergedParameters reverseMergeWith:parameters];
requestParameters = mergedParameters;
} else {
@@ -249,9 +248,8 @@ static NSOperationQueue *defaultMappingQueue = nil;
NSDictionary *requestParameters = nil;
RKRequestDescriptor *requestDescriptor = [self requestDescriptorForObject:object];
if (requestDescriptor) {
RKObjectSerializer *serializer = [[RKObjectSerializer alloc] initWithObject:object mapping:(RKObjectMapping *)requestDescriptor.mapping rootKeyPath:requestDescriptor.rootKeyPath];
NSError *error;
NSMutableDictionary *mergedParameters = [[serializer serializeObjectToDictionary:&error] mutableCopy];
NSError *error = nil;
NSMutableDictionary *mergedParameters = [[RKObjectParameters parametersWithObject:object requestDescriptor:requestDescriptor error:&error] mutableCopy];
if (parameters) [mergedParameters reverseMergeWith:parameters];
requestParameters = mergedParameters;
} else {

View File

@@ -0,0 +1,41 @@
//
// RKObjectParameters.h
// RestKit
//
// Created by Blake Watters on 5/2/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "RKRequestDescriptor.h"
/**
The RKObjectParameters class provides an interface for serializing a local domain
object into an NSDictionary representation suitable for use as the parameters of an
HTTP request.
*/
@interface RKObjectParameters : NSObject
/**
Returns a dictionary representation of the given object by performing object mapping using the mapping
from the given request descriptor. If the request descriptor specifies a root key path, the mapped parameters
will be nested within the dictionary under the specified root key path.
@param error If there is a problem mapping the parameters, upon return contains a
pointer to an instance of NSError that describes the problem.
@return A new dictionary containing the mapped parameters or nil if an error has occurred.
*/
+ (NSDictionary *)parametersWithObject:(id)object requestDescriptor:(RKRequestDescriptor *)requestDescriptor error:(NSError **)error;
@end

View File

@@ -1,5 +1,5 @@
//
// RKObjectSerializer.m
// RKObjectParameters.m
// RestKit
//
// Created by Blake Watters on 5/2/11.
@@ -18,39 +18,64 @@
// limitations under the License.
//
#import "RKRequestSerialization.h"
#import "RKMIMETypes.h"
#import "RKParser.h"
#import "RKObjectSerializer.h"
#import "NSDictionary+RKRequestSerialization.h"
#import "RKObjectParameters.h"
#import "RKParserRegistry.h"
#import "RKLog.h"
#import "RKObjectMappingOperationDataSource.h"
#import "RKObjectMapping.h"
#import "RKMappingOperation.h"
// Set Logging Component
#undef RKLogComponent
#define RKLogComponent lcl_cRestKitObjectMapping
@interface RKObjectSerializer ()
@property (nonatomic, readwrite, strong) id object;
@property (nonatomic, readwrite, strong) RKObjectMapping *mapping;
@property (nonatomic, readwrite, strong) NSString *rootKeyPath;
@interface RKObjectParameters () <RKMappingOperationDelegate>
@property (nonatomic, strong) id object;
@property (nonatomic, strong) RKRequestDescriptor *requestDescriptor;
- (id)initWithObject:(id)object requestDescriptor:(RKRequestDescriptor *)requestDescriptor;
- (NSDictionary *)mapObjectToParameters:(NSError **)error;
// Convenience methods
@property (nonatomic, readonly) RKObjectMapping *mapping;
@property (nonatomic, readonly) NSString *rootKeyPath;
@end
@implementation RKObjectSerializer
@implementation RKObjectParameters
- (id)initWithObject:(id)object mapping:(RKObjectMapping *)mapping rootKeyPath:(NSString *)rootKeyPath;
+ (NSDictionary *)parametersWithObject:(id)object requestDescriptor:(RKRequestDescriptor *)requestDescriptor error:(NSError **)error
{
RKObjectParameters *objectParameters = [[self alloc] initWithObject:object requestDescriptor:requestDescriptor];
return [objectParameters mapObjectToParameters:error];
}
- (id)initWithObject:(id)object requestDescriptor:(RKRequestDescriptor *)requestDescriptor
{
NSParameterAssert(object);
NSParameterAssert(requestDescriptor);
self = [super init];
if (self) {
self.object = object;
self.mapping = mapping;
self.rootKeyPath = rootKeyPath;
self.requestDescriptor = requestDescriptor;
}
return self;
}
- (id)serializeObjectToDictionary:(NSError **)error
- (RKMapping *)mapping
{
return self.requestDescriptor.mapping;
}
- (NSString *)rootKeyPath
{
return self.requestDescriptor.rootKeyPath;
}
- (NSDictionary *)mapObjectToParameters:(NSError **)error
{
RKObjectMappingOperationDataSource *dataSource = [RKObjectMappingOperationDataSource new];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
@@ -66,46 +91,11 @@
return self.rootKeyPath ? [NSMutableDictionary dictionaryWithObject:dictionary forKey:self.rootKeyPath] : dictionary;
}
- (id)serializeObjectToMIMEType:(NSString *)MIMEType error:(NSError **)error
{
// TODO: This will fail for form encoded...
id serializedObject = [self serializeObjectToDictionary:error];
if (serializedObject) {
id<RKParser> parser = [[RKParserRegistry sharedRegistry] parserForMIMEType:MIMEType];
NSString *string = [parser stringFromObject:serializedObject error:error];
if (string == nil) {
return nil;
}
return string;
}
return nil;
}
- (id<RKRequestSerializable>)serializationForMIMEType:(NSString *)MIMEType error:(NSError **)error
{
if ([MIMEType isEqualToString:RKMIMETypeFormURLEncoded]) {
// Dictionaries are natively RKRequestSerializable as Form Encoded
return [self serializeObjectToDictionary:error];
} else {
NSString *string = [self serializeObjectToMIMEType:MIMEType error:error];
if (string) {
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
return [RKRequestSerialization serializationWithData:data MIMEType:MIMEType];
}
}
return nil;
}
#pragma mark - RKObjectMappingOperationDelegate
- (void)mappingOperation:(RKMappingOperation *)operation didSetValue:(id)value forKeyPath:(NSString *)keyPath usingMapping:(RKAttributeMapping *)mapping
{
id transformedValue = nil;
Class orderedSetClass = NSClassFromString(@"NSOrderedSet");
if ([value isKindOfClass:[NSDate class]]) {
// Date's are not natively serializable, must be encoded as a string
@synchronized(self.mapping.preferredDateFormatter) {
@@ -114,7 +104,7 @@
} else if ([value isKindOfClass:[NSDecimalNumber class]]) {
// Precision numbers are serialized as strings to work around Javascript notation limits
transformedValue = [(NSDecimalNumber *)value stringValue];
} else if ([value isKindOfClass:orderedSetClass]) {
} else if ([value isKindOfClass:[NSOrderedSet class]]) {
// NSOrderedSets are not natively serializable, so let's just turn it into an NSArray
transformedValue = [value array];
}

View File

@@ -1,60 +0,0 @@
//
// RKObjectSerializer.h
// RestKit
//
// Created by Blake Watters on 5/2/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "RKObjectMapping.h"
#import "RKMappingOperation.h"
#import "RKRequestSerializable.h"
/**
Performs a serialization of an object and its relationships back into
a dictionary representation according to the mappings specified. The
transformed object is then enclosed in an RKRequestSerializable representation
that is suitable for inclusion in an RKRequest.
*/
@interface RKObjectSerializer : NSObject <RKMappingOperationDelegate>
@property (nonatomic, readonly, strong) id object;
@property (nonatomic, readonly, strong) RKObjectMapping *mapping;
@property (nonatomic, readonly, strong) NSString *rootKeyPath;
- (id)initWithObject:(id)object mapping:(RKObjectMapping *)mapping rootKeyPath:(NSString *)rootKeyPath;
/**
Return a serialized representation of the source object by applying an object mapping
with a target object type of NSMutableDictionary. The serialized object will contain attributes
and relationships composed of simple KVC compliant Cocoa types.
*/
- (NSMutableDictionary *)serializeObjectToDictionary:(NSError **)error;
/**
Return a serialized representation of the source object by mapping it into a NSMutableDictionary and
then encoding it into the destination MIME Type via an instance of RKParser that is registered
for the specified MIME Type
*/
- (NSString *)serializeObjectToMIMEType:(NSString *)MIMEType error:(NSError **)error;
/**
Return a request serialization for the source object by mapping it to an NSMutableDictionary, encoding
the data via a parser into the specified MIME Type, and wrapping it into a serializable format that can
be used as the params of an RKRequest or RKObjectLoader
*/
- (id<RKRequestSerializable>)serializationForMIMEType:(NSString *)mimeType error:(NSError **)error;
@end

View File

@@ -26,33 +26,76 @@
that handle parsing/serializing for content by MIME Type. Registration
is configured via exact string matches (i.e. application/json) or via regular
expression.
*/
*/
@interface RKParserRegistry : NSObject {
NSMutableDictionary *_MIMETypeToParserClasses;
NSMutableArray *_MIMETypeToParserClassesRegularExpressions;
NSData *_whitespaceData;
}
/**
Return the global shared singleton registry for MIME Type to Parsers
@return The global shared RKParserRegistry instance.
*/
+ (RKParserRegistry *)sharedRegistry;
/**
Sets the global shared registry singleton to a new instance of RKParserRegistry
@param registry A new parser registry object to configure as the shared instance.
*/
+ (void)setSharedRegistry:(RKParserRegistry *)registry;
/**
Returns the parsed data by delegating to a registered parser for the specified
MIME type.
If the data cannot be handled directly by the parser, it is first converted to
a string and subsequently passed to the parser.
@param data The data to be parsed.
@param MIMEType The MIME Type of the content to be parsed.
@param encoding The NSStringEncoding to use when converting the data to string.
@param error A pointer to an NSError object.
@return The parsed object or nil if an error occurred during parsing.
*/
- (id)parseData:(NSData *)data withMIMEType:(NSString *)MIMEType encoding:(NSStringEncoding)encoding error:(NSError **)error;
/**
Returns the parsed data by delegating to a registered parser for the specified
MIME type.
This simply invokes parseData:withMIMEType:encoding:error: with a NSUTF8StringEncoding.
@param data The data to be parsed.
@param MIMEType The MIME Type of the content to be parsed.
@param error A pointer to an NSError object.
@return The parsed object or nil if an error occurred during parsing.
*/
- (id)parseData:(NSData *)data withMIMEType:(NSString *)MIMEType error:(NSError **)error;
/**
Returns the serialized data by delegating to a registered parser for the specified
MIME type.
If the parser is only able to serialize to string, the serialized string will
be converted to NSData.
@param object The object to be serialized.
@param MIMEType The desired MIME Type for the serialized output.
@param error A pointer to an NSError object.
@return The serialized object or nil if an error occurred during serialization.
*/
- (NSData *)serializeObject:(id)object forMIMEType:(NSString *)MIMEType error:(NSError **)error;
/**
Returns an instance of the RKParser conformant class registered to handle content
with the given MIME Type.
MIME Types are searched in the order in which they are registered and exact
string matches are favored over regular expressions.
@param MIMEType The MIME Type of the content to be parsed/serialized.
@return An instance of the RKParser conformant class registered to handle the given MIME Type.
*/
@@ -61,10 +104,10 @@
/**
Returns an instance of the RKParser conformant class registered to handle content
with the given MIME Type.
MIME Types are searched in the order in which they are registered and exact
string matches are favored over regular expressions.
@param MIMEType The MIME Type of the content to be parsed/serialized.
@return The RKParser conformant class registered to handle the given MIME Type.
*/
@@ -73,7 +116,7 @@
/**
Registers an RKParser conformant class as the handler for MIME Types exactly matching the
specified MIME Type string.
@param parserClass The RKParser conformant class to instantiate when parsing/serializing MIME Types matching MIMETypeExpression.
@param MIMEType A MIME Type string for which instances of parserClass should be used for parsing/serialization.
*/
@@ -84,7 +127,7 @@
/**
Registers an RKParser conformant class as the handler for MIME Types matching the
specified regular expression.
@param parserClass The RKParser conformant class to instantiate when parsing/serializing MIME Types matching MIMETypeExpression.
@param MIMETypeRegex A regular expression that matches MIME Types that should be handled by instances of parserClass.
*/
@@ -92,6 +135,14 @@
#endif
/**
Returns wether the registry has a registered parser for that MIME type.
@param MIMEType The MIME type to test if it is parsable.
@return YES if a registered parser for that MIME type is registered, NO otherwise.
*/
- (BOOL)canParseMIMEType:(NSString*)MIMEType;
/**
Automatically configure the registry via run-time reflection of the RKParser classes
available that ship with RestKit. This happens automatically when the shared registry

View File

@@ -19,40 +19,80 @@
//
#import "RKParserRegistry.h"
#import "RKErrors.h"
RKParserRegistry *gSharedRegistry;
@implementation RKParserRegistry
+ (RKParserRegistry *)sharedRegistry
{
+ (RKParserRegistry *)sharedRegistry {
if (gSharedRegistry == nil) {
gSharedRegistry = [RKParserRegistry new];
[gSharedRegistry autoconfigure];
}
return gSharedRegistry;
}
+ (void)setSharedRegistry:(RKParserRegistry *)registry
{
+ (void)setSharedRegistry:(RKParserRegistry *)registry {
gSharedRegistry = registry;
}
- (id)init
{
- (id)init {
self = [super init];
if (self) {
_MIMETypeToParserClasses = [[NSMutableDictionary alloc] init];
_MIMETypeToParserClassesRegularExpressions = [[NSMutableArray alloc] init];
_whitespaceData = [[NSData alloc] initWithBytes:" " length:1];
}
return self;
}
- (id)parseData:(NSData *)data withMIMEType:(NSString *)MIMEType encoding:(NSStringEncoding)encoding error:(NSError **)error {
// Handle empty data and data containing a single whitespace character:
NSUInteger length = [data length];
if (length == 0 || (length == 1 && [data isEqualToData:_whitespaceData])) {
if (error) {
NSString* errorMessage = [NSString stringWithFormat:@"Attemped to parse empty data for MIME Type '%@'", MIMEType];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:errorMessage, NSLocalizedDescriptionKey, nil];
*error = [NSError errorWithDomain:RKErrorDomain code:RKParserRegistryEmptyDataError userInfo:userInfo];
}
return nil;
}
id<RKParser> parser = [self parserForMIMEType:MIMEType];
if (!parser) {
if (error) {
NSString* errorMessage = [NSString stringWithFormat:@"Cannot parse data without a parser for MIME Type '%@'", MIMEType];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:errorMessage, NSLocalizedDescriptionKey, nil];
*error = [NSError errorWithDomain:RKErrorDomain code:RKParserRegistryMissingParserError userInfo:userInfo];
}
return nil;
}
return [parser objectFromData:data error:error];
}
- (Class<RKParser>)parserClassForMIMEType:(NSString *)MIMEType
{
- (id)parseData:(NSData *)data withMIMEType:(NSString *)MIMEType error:(NSError **)error {
return [self parseData:data withMIMEType:MIMEType encoding:NSUTF8StringEncoding error:error];
}
- (NSData *)serializeObject:(id)object forMIMEType:(NSString *)MIMEType error:(NSError **)error {
id<RKParser> parser = [self parserForMIMEType:MIMEType];
if (!parser) {
if (error) {
NSString* errorMessage = [NSString stringWithFormat:@"Cannot serialize object without a parser for MIME Type '%@'", MIMEType];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:errorMessage, NSLocalizedDescriptionKey, nil];
*error = [NSError errorWithDomain:RKErrorDomain code:RKParserRegistryMissingParserError userInfo:userInfo];
}
return nil;
}
return [parser dataFromObject:object error:error];
}
- (Class<RKParser>)parserClassForMIMEType:(NSString *)MIMEType {
id parserClass = [_MIMETypeToParserClasses objectForKey:MIMEType];
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
if (!parserClass)
@@ -70,35 +110,35 @@ RKParserRegistry *gSharedRegistry;
return parserClass;
}
- (void)setParserClass:(Class<RKParser>)parserClass forMIMEType:(NSString *)MIMEType
{
- (void)setParserClass:(Class<RKParser>)parserClass forMIMEType:(NSString *)MIMEType {
[_MIMETypeToParserClasses setObject:parserClass forKey:MIMEType];
}
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
- (void)setParserClass:(Class<RKParser>)parserClass forMIMETypeRegularExpression:(NSRegularExpression *)MIMETypeRegex
{
- (void)setParserClass:(Class<RKParser>)parserClass forMIMETypeRegularExpression:(NSRegularExpression *)MIMETypeRegex {
NSArray *expressionAndClass = [NSArray arrayWithObjects:MIMETypeRegex, parserClass, nil];
[_MIMETypeToParserClassesRegularExpressions addObject:expressionAndClass];
}
#endif
- (id<RKParser>)parserForMIMEType:(NSString *)MIMEType
{
- (id<RKParser>)parserForMIMEType:(NSString *)MIMEType {
Class parserClass = [self parserClassForMIMEType:MIMEType];
if (parserClass) {
return [[parserClass alloc] init];
}
return nil;
}
- (void)autoconfigure
{
Class parserClass = nil;
- (BOOL)canParseMIMEType:(NSString*)MIMEType {
return [self parserClassForMIMEType:MIMEType] != nil;
}
- (void)autoconfigure {
Class parserClass = nil;
// JSON
NSSet *JSONParserClassNames = [NSSet setWithObjects:@"RKJSONParserJSONKit", @"RKJSONParserYAJL", @"RKJSONParserSBJSON", @"RKJSONParserNXJSON", nil];
for (NSString *parserClassName in JSONParserClassNames) {
@@ -108,7 +148,7 @@ RKParserRegistry *gSharedRegistry;
break;
}
}
// XML
parserClass = NSClassFromString(@"RKXMLParserXMLReader");
if (parserClass) {

View File

@@ -78,9 +78,7 @@ static NSString * RKUnsupportedMIMETypeErrorKey = @"MIME Type";
return nil;
}
// TODO: Pull in the NSData parser support...
NSString *string = [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding];
return [parser objectFromString:string error:error];
return [parser objectFromData:self.data error:error];
}
- (BOOL)responseMatchesMappingDescriptor:(RKResponseDescriptor *)mappingDescriptor

View File

@@ -67,15 +67,10 @@
- (id)parsedObjectWithContentsOfResource:(NSString *)name withExtension:(NSString *)extension
{
NSError *error = nil;
NSString *resourceContents = [self stringWithContentsOfResource:name withExtension:extension encoding:NSUTF8StringEncoding];
NSData* resourceContents = [self dataWithContentsOfResource:name withExtension:extension];
NSString *MIMEType = [self MIMETypeForResource:name withExtension:extension];
id<RKParser> parser = [[RKParserRegistry sharedRegistry] parserForMIMEType:MIMEType];
if (! parser) {
RKLogError(@"%@ Unable to parse Resource with name '%@' and extension '%@': failed to find parser registered to handle MIME Type '%@'", self, name, extension, MIMEType);
return nil;
}
id object = [parser objectFromString:resourceContents error:&error];
id object = [[RKParserRegistry sharedRegistry] parseData:resourceContents withMIMEType:MIMEType error:&error];
if (object == nil) {
RKLogCritical(@"%@ Failed to parse resource with name '%@' and extension '%@'. Error: %@", self, name, extension, [error localizedDescription]);
return nil;

View File

@@ -27,19 +27,16 @@
#define RKLogComponent lcl_cRestKitSupportParsers
// TODO: JSONKit serializer instance should be reused to enable leverage
// TODO: JSONKit serializer instance should be reused to leverage
// the internal caching capabilities from the JSONKit serializer
@implementation RKJSONParserJSONKit
- (NSDictionary *)objectFromString:(NSString *)string error:(NSError **)error
{
RKLogTrace(@"string='%@'", string);
return [string objectFromJSONStringWithParseOptions:JKParseOptionStrict error:error];
- (id)objectFromData:(NSData *)data error:(NSError **)error {
return [data objectFromJSONDataWithParseOptions:JKParseOptionStrict error:error];
}
- (NSString *)stringFromObject:(id)object error:(NSError **)error
{
return [object JSONStringWithOptions:JKSerializeOptionNone error:error];
- (NSData *)dataFromObject:(id)object error:(NSError **)error {
return [object JSONDataWithOptions:JKSerializeOptionNone error:error];
}
@end
@end

View File

@@ -30,7 +30,9 @@ typedef enum {
RKRequestBaseURLOfflineError = 2,
RKRequestUnexpectedResponseError = 3,
RKObjectLoaderUnexpectedResponseError = 4,
RKRequestConnectionTimeoutError = 5
RKRequestConnectionTimeoutError = 5,
RKParserRegistryMissingParserError = 6,
RKParserRegistryEmptyDataError = 7
} RKRestKitError;
/** @name Error Constants */

View File

@@ -20,31 +20,30 @@
/**
The RKParser protocol declares two methods that a class must implement
so that it can provide support for parsing and serializing object
representations to the RestKit framework. Parsers are required to transform
data to and from string representations and are configured via the
so that it can provide support for parsing and serializing objects
to and from data representations and are configured via the
RKParserRegistry shared instance.
*/
@protocol RKParser
@protocol RKParser <NSObject>
/**
Returns an object representation of the source string encoded in the
Returns an object representation of the source data encoded in the
format provided by the parser (i.e. JSON, XML, etc).
@param string The string representation of the object to be parsed.
@param data The data representation of the object to be parsed encoded in UTF-8.
@param error A pointer to an NSError object.
@return The parsed object or nil if an error occurred during parsing.
*/
- (id)objectFromString:(NSString *)string error:(NSError **)error;
- (id)objectFromData:(NSData *)data error:(NSError **)error;
/**
Returns a string representation encoded in the format
Returns a data representation encoded in the format
provided by the parser (i.e. JSON, XML, etc) for the given object.
@param object The object to be serialized.
@param A pointer to an NSError object.
@return A string representation of the serialized object or nil if an error occurred.
@return A data representation of the serialized object encoded in UTF-8 or nil if an error occurred.
*/
- (NSString *)stringFromObject:(id)object error:(NSError **)error;
- (NSData *)dataFromObject:(id)object error:(NSError **)error;
@end

View File

@@ -77,11 +77,7 @@ RestKit is broken into several modules that cleanly separate the mapping engine
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKObjectMappingOperation.html">RKObjectMappingOperation</a></td>
<td>An <tt>NSOperation</tt> that performs a mapping between object representations using an <tt>RKObjectMapping</tt>.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKObjectSerializer.html">RKObjectSerializer</a></td>
<td>Performs serialization of a given object into an <tt>NSDictionary</tt> represenation suitable for use as the parameters of an HTTP request.</td>
</tr>
</tr>
<tr><th colspan="2" style="text-align:center;"><a href="blob/development/Code/Network/README.md">Networking</a></th></tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKRequestDescriptor.html">RKRequestDescriptor</a></td>
@@ -91,6 +87,10 @@ RestKit is broken into several modules that cleanly separate the mapping engine
<td><a href="http://restkit.org/api/0.20.0/Classes/RKResponseDescriptor.html">RKResponseDescriptor</a></td>
<td>Describes an object mappable response that may be returned from a remote web application in terms of an object mapping, a key path, a <a href="">SOCKit pattern</a> for matching the URL, and a set of status codes that define the circumstances in which the mapping is appropriate for a given response.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKObjectParameters.html">RKObjectParameters</a></td>
<td>Performs serialization of a given object into an <tt>NSDictionary</tt> represenation suitable for use as the parameters of an HTTP request.</td>
</tr>
<tr>
<td><a href="http://restkit.org/api/0.20.0/Classes/RKObjectRequestOperation.html">RKObjectRequestOperation</a></td>
<td>An <tt>NSOperation</tt> that sends an HTTP request and performs object mapping on the parsed response body using the configurations expressed in a set of <tt>RKResponseDescriptor</tt> objects.</td>

View File

@@ -96,8 +96,8 @@
25160E24145650490060A5C5 /* RKPropertyInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D97145650490060A5C5 /* RKPropertyInspector.m */; };
25160E25145650490060A5C5 /* RKRelationshipMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D98145650490060A5C5 /* RKRelationshipMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E26145650490060A5C5 /* RKRelationshipMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D99145650490060A5C5 /* RKRelationshipMapping.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
25160E29145650490060A5C5 /* RKObjectSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D9C145650490060A5C5 /* RKObjectSerializer.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E2A145650490060A5C5 /* RKObjectSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D9D145650490060A5C5 /* RKObjectSerializer.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
25160E29145650490060A5C5 /* RKObjectParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D9C145650490060A5C5 /* RKObjectParameters.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E2A145650490060A5C5 /* RKObjectParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D9D145650490060A5C5 /* RKObjectParameters.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
25160E2B145650490060A5C5 /* RKParserRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D9E145650490060A5C5 /* RKParserRegistry.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160E2C145650490060A5C5 /* RKParserRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D9F145650490060A5C5 /* RKParserRegistry.m */; };
25160E2E145650490060A5C5 /* RestKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160DA1145650490060A5C5 /* RestKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -179,8 +179,8 @@
25160F5F145655C60060A5C5 /* RKPropertyInspector.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D97145650490060A5C5 /* RKPropertyInspector.m */; };
25160F60145655C60060A5C5 /* RKRelationshipMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D98145650490060A5C5 /* RKRelationshipMapping.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F61145655C60060A5C5 /* RKRelationshipMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D99145650490060A5C5 /* RKRelationshipMapping.m */; };
25160F64145655C60060A5C5 /* RKObjectSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D9C145650490060A5C5 /* RKObjectSerializer.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F65145655C60060A5C5 /* RKObjectSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D9D145650490060A5C5 /* RKObjectSerializer.m */; };
25160F64145655C60060A5C5 /* RKObjectParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D9C145650490060A5C5 /* RKObjectParameters.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F65145655C60060A5C5 /* RKObjectParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D9D145650490060A5C5 /* RKObjectParameters.m */; };
25160F66145655C60060A5C5 /* RKParserRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D9E145650490060A5C5 /* RKParserRegistry.h */; settings = {ATTRIBUTES = (Public, ); }; };
25160F67145655C60060A5C5 /* RKParserRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 25160D9F145650490060A5C5 /* RKParserRegistry.m */; };
25160F69145655D10060A5C5 /* RKCoreData.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160D46145650490060A5C5 /* RKCoreData.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -316,8 +316,8 @@
251610DF1456F2330060A5C5 /* RKObjectMappingOperationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610221456F2330060A5C5 /* RKObjectMappingOperationTest.m */; };
251610E21456F2330060A5C5 /* RKObjectMappingResultTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610241456F2330060A5C5 /* RKObjectMappingResultTest.m */; };
251610E31456F2330060A5C5 /* RKObjectMappingResultTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610241456F2330060A5C5 /* RKObjectMappingResultTest.m */; };
251610E61456F2330060A5C5 /* RKObjectSerializerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610261456F2330060A5C5 /* RKObjectSerializerTest.m */; };
251610E71456F2330060A5C5 /* RKObjectSerializerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610261456F2330060A5C5 /* RKObjectSerializerTest.m */; };
251610E61456F2330060A5C5 /* RKObjectParametersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610261456F2330060A5C5 /* RKObjectParametersTest.m */; };
251610E71456F2330060A5C5 /* RKObjectParametersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610261456F2330060A5C5 /* RKObjectParametersTest.m */; };
251610E81456F2330060A5C5 /* RKParserRegistryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610271456F2330060A5C5 /* RKParserRegistryTest.m */; };
251610E91456F2330060A5C5 /* RKParserRegistryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610271456F2330060A5C5 /* RKParserRegistryTest.m */; };
251610F01456F2340060A5C5 /* RKTestEnvironment.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610361456F2330060A5C5 /* RKTestEnvironment.m */; };
@@ -747,8 +747,8 @@
25160D97145650490060A5C5 /* RKPropertyInspector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKPropertyInspector.m; sourceTree = "<group>"; };
25160D98145650490060A5C5 /* RKRelationshipMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKRelationshipMapping.h; sourceTree = "<group>"; };
25160D99145650490060A5C5 /* RKRelationshipMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKRelationshipMapping.m; sourceTree = "<group>"; };
25160D9C145650490060A5C5 /* RKObjectSerializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectSerializer.h; sourceTree = "<group>"; };
25160D9D145650490060A5C5 /* RKObjectSerializer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectSerializer.m; sourceTree = "<group>"; };
25160D9C145650490060A5C5 /* RKObjectParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectParameters.h; sourceTree = "<group>"; };
25160D9D145650490060A5C5 /* RKObjectParameters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectParameters.m; sourceTree = "<group>"; };
25160D9E145650490060A5C5 /* RKParserRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKParserRegistry.h; sourceTree = "<group>"; };
25160D9F145650490060A5C5 /* RKParserRegistry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKParserRegistry.m; sourceTree = "<group>"; };
25160DA1145650490060A5C5 /* RestKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestKit.h; sourceTree = "<group>"; };
@@ -872,7 +872,7 @@
251610221456F2330060A5C5 /* RKObjectMappingOperationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMappingOperationTest.m; sourceTree = "<group>"; };
251610231456F2330060A5C5 /* RKObjectMappingProviderTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMappingProviderTest.m; sourceTree = "<group>"; };
251610241456F2330060A5C5 /* RKObjectMappingResultTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectMappingResultTest.m; sourceTree = "<group>"; };
251610261456F2330060A5C5 /* RKObjectSerializerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectSerializerTest.m; sourceTree = "<group>"; };
251610261456F2330060A5C5 /* RKObjectParametersTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectParametersTest.m; sourceTree = "<group>"; };
251610271456F2330060A5C5 /* RKParserRegistryTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKParserRegistryTest.m; sourceTree = "<group>"; };
251610351456F2330060A5C5 /* RKTestEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKTestEnvironment.h; sourceTree = "<group>"; };
251610361456F2330060A5C5 /* RKTestEnvironment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKTestEnvironment.m; sourceTree = "<group>"; };
@@ -1356,8 +1356,8 @@
25160D97145650490060A5C5 /* RKPropertyInspector.m */,
25160D98145650490060A5C5 /* RKRelationshipMapping.h */,
25160D99145650490060A5C5 /* RKRelationshipMapping.m */,
25160D9C145650490060A5C5 /* RKObjectSerializer.h */,
25160D9D145650490060A5C5 /* RKObjectSerializer.m */,
25160D9C145650490060A5C5 /* RKObjectParameters.h */,
25160D9D145650490060A5C5 /* RKObjectParameters.m */,
25160D9E145650490060A5C5 /* RKParserRegistry.h */,
25160D9F145650490060A5C5 /* RKParserRegistry.m */,
25CA7A8E14EC570100888FF8 /* RKMapping.m */,
@@ -1703,7 +1703,7 @@
251610221456F2330060A5C5 /* RKObjectMappingOperationTest.m */,
251610231456F2330060A5C5 /* RKObjectMappingProviderTest.m */,
251610241456F2330060A5C5 /* RKObjectMappingResultTest.m */,
251610261456F2330060A5C5 /* RKObjectSerializerTest.m */,
251610261456F2330060A5C5 /* RKObjectParametersTest.m */,
251610271456F2330060A5C5 /* RKParserRegistryTest.m */,
254A62BF14AD591C00939BEE /* RKObjectPaginatorTest.m */,
2519764215823BA1004FE9DD /* RKObjectAttributeMappingTest.m */,
@@ -1971,7 +1971,7 @@
25160E21145650490060A5C5 /* RKMappingResult.h in Headers */,
25160E23145650490060A5C5 /* RKPropertyInspector.h in Headers */,
25160E25145650490060A5C5 /* RKRelationshipMapping.h in Headers */,
25160E29145650490060A5C5 /* RKObjectSerializer.h in Headers */,
25160E29145650490060A5C5 /* RKObjectParameters.h in Headers */,
25160E2B145650490060A5C5 /* RKParserRegistry.h in Headers */,
25160E31145650490060A5C5 /* lcl_config_components.h in Headers */,
25160E32145650490060A5C5 /* lcl_config_extensions.h in Headers */,
@@ -2084,7 +2084,7 @@
25160F5C145655C60060A5C5 /* RKMappingResult.h in Headers */,
25160F5E145655C60060A5C5 /* RKPropertyInspector.h in Headers */,
25160F60145655C60060A5C5 /* RKRelationshipMapping.h in Headers */,
25160F64145655C60060A5C5 /* RKObjectSerializer.h in Headers */,
25160F64145655C60060A5C5 /* RKObjectParameters.h in Headers */,
25160F66145655C60060A5C5 /* RKParserRegistry.h in Headers */,
25160F69145655D10060A5C5 /* RKCoreData.h in Headers */,
25160F6F145655D10060A5C5 /* RKEntityMapping.h in Headers */,
@@ -2484,7 +2484,7 @@
25160E22145650490060A5C5 /* RKMappingResult.m in Sources */,
25160E24145650490060A5C5 /* RKPropertyInspector.m in Sources */,
25160E26145650490060A5C5 /* RKRelationshipMapping.m in Sources */,
25160E2A145650490060A5C5 /* RKObjectSerializer.m in Sources */,
25160E2A145650490060A5C5 /* RKObjectParameters.m in Sources */,
25160E2C145650490060A5C5 /* RKParserRegistry.m in Sources */,
25160E35145650490060A5C5 /* NSDictionary+RKAdditions.m in Sources */,
25160E37145650490060A5C5 /* NSString+RKAdditions.m in Sources */,
@@ -2577,7 +2577,7 @@
251610DC1456F2330060A5C5 /* RKObjectMappingNextGenTest.m in Sources */,
251610DE1456F2330060A5C5 /* RKObjectMappingOperationTest.m in Sources */,
251610E21456F2330060A5C5 /* RKObjectMappingResultTest.m in Sources */,
251610E61456F2330060A5C5 /* RKObjectSerializerTest.m in Sources */,
251610E61456F2330060A5C5 /* RKObjectParametersTest.m in Sources */,
251610E81456F2330060A5C5 /* RKParserRegistryTest.m in Sources */,
251610F01456F2340060A5C5 /* RKTestEnvironment.m in Sources */,
2516110E1456F2340060A5C5 /* NSDictionary+RKRequestSerializationTest.m in Sources */,
@@ -2651,7 +2651,7 @@
25160F5D145655C60060A5C5 /* RKMappingResult.m in Sources */,
25160F5F145655C60060A5C5 /* RKPropertyInspector.m in Sources */,
25160F61145655C60060A5C5 /* RKRelationshipMapping.m in Sources */,
25160F65145655C60060A5C5 /* RKObjectSerializer.m in Sources */,
25160F65145655C60060A5C5 /* RKObjectParameters.m in Sources */,
25160F67145655C60060A5C5 /* RKParserRegistry.m in Sources */,
25160F70145655D10060A5C5 /* RKEntityMapping.m in Sources */,
25160F74145655D10060A5C5 /* RKManagedObjectImporter.m in Sources */,
@@ -2746,7 +2746,7 @@
251610DD1456F2330060A5C5 /* RKObjectMappingNextGenTest.m in Sources */,
251610DF1456F2330060A5C5 /* RKObjectMappingOperationTest.m in Sources */,
251610E31456F2330060A5C5 /* RKObjectMappingResultTest.m in Sources */,
251610E71456F2330060A5C5 /* RKObjectSerializerTest.m in Sources */,
251610E71456F2330060A5C5 /* RKObjectParametersTest.m in Sources */,
251610E91456F2330060A5C5 /* RKParserRegistryTest.m in Sources */,
251610F11456F2340060A5C5 /* RKTestEnvironment.m in Sources */,
2516110F1456F2340060A5C5 /* NSDictionary+RKRequestSerializationTest.m in Sources */,