Is there a way to differ between mapping results which are empty due to there being no data do map att the key path and a mapping result which is empty due do skipping objects through KVC.
The problem I have is that I am working with a API which is not very well thought through, and I need to find a way to know when I am at the end of the page. The issue is that there is a possibility that the mapping result can be empty due to all the objects being returned are "deleted".
TLDR; Is there a way to see the amount of mapping errors through mapping result on a completed request.
EDIT
I solved my own problem by reading the documentation again. The solution was to create a subclass of RKObjectRequestOperation and then register it.
[[RKObjectManager sharedManager] registerRequestOperationClass:[CustomRequestOperation class]];
This mean that I could implement the following which would listen to mapping errors and increment a counter and add it to mappingMetaData when the mapping completed.
- (void)setCompletionBlockWithSuccess:(void ( ^ ) ( RKObjectRequestOperation *operation , RKMappingResult *mappingResult ))success failure:(void (^) ( RKObjectRequestOperation *operation , NSError *error ))failure {
__block typeof(skipCount) temp = skipCount;
[super setCompletionBlockWithSuccess:^void(RKObjectRequestOperation *operation , RKMappingResult *mappingResult) {
if (success) {
operation.mappingMetadata = #{#"skipCount" : #(temp)};
success(operation, mappingResult);
}
} failure:^void(RKObjectRequestOperation *operation , NSError *error) {
if (failure) {
failure(operation, error);
}
}];
}
- (void)mapper:(RKMapperOperation *)mapper didFailMappingOperation:(RKMappingOperation *)mappingOperation forKeyPath:(NSString *)keyPath withError:(NSError *)error {
skipCount++;
}
- (void)mapperWillStartMapping:(RKMapperOperation *)mapper {
skipCount = 0;
}
Related
I've been using AFNetworking 2.0 in my app.
I've noticed that if my web-service returns a 500 status code I do not get the body of the response.
Here is an example of my php code
try
{
$conn = new PDO( "sqlsrv:server=$serverName;Database = $database", $uid, $pwd);
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
return $conn;
}
catch( PDOException $e )
{
$response->status(500);
echo( "Connection Error: " . $e->getMessage() );
}
If I use a simple rest client this is an example of a response body.
Connection Error: SQLSTATE[08001]: [Microsoft][SQL Server Native Client 11.0]SQL Server Network Interfaces: Error Locating Server/Instance Specified [xFFFFFFFF].
However this seems to be the only response I can get from AFNetworking
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x15e58fa0 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
This is the part of my objective-c code that does this.
...} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"%#",error.description);
}];
Is there a way I can get the response body?
Edit: More code for clarification
Below is part of my subclass of AFHTTPSessionManager
#implementation MSMAMobileAPIClient
+ (MSMAMobileAPIClient *)sharedClient {
static MSMAMobileAPIClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[MSMAMobileAPIClient alloc] initWithDefaultURL];
});
return _sharedClient;
}
- (id)initWithDefaultURL {
return [self initWithBaseURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://%#/mamobile/index.php/" ,[[NSUserDefaults standardUserDefaults] stringForKey:#"serviceIPAddress"]]]];
}
- (id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (!self) {
return nil;
}
self.responseSerializer = [AFCompoundResponseSerializer compoundSerializerWithResponseSerializers:#[[AFJSONResponseSerializer serializer], [AFHTTPResponseSerializer serializer]]];
return self;
}
I tried setting the response serializer to a AFCompoundResponseSerializer but it didn't seem to make a difference
Below is an example of a subclass that I call the Librarian.
-(void)searchForItemWithString:(NSString *)searchString withCompletionBlock:(arrayBlock)block {
self.inventorySearchBlock = block;
NSDictionary *parameters = #{#"query": searchString};
[[MSMAMobileAPIClient sharedClient] GET:#"inventory/search" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
if (!responseObject) {
NSLog(#"Error parsing JSON");
} else {
//do stuff with the json dictionary that's returned..
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"Error: %#",error.description);
}];
}
UPDATE: I have created a github repository to contain the latest code I am using. All changes will be posted there. https://github.com/Hackmodford/HMFJSONResponseSerializerWithData
The answer comes from this issue on github.
https://github.com/AFNetworking/AFNetworking/issues/1397
gfiumara is the dev who came up with this. I have only slightly modified his subclass of AFJSONResponseSerializer to include an actual string instead of the NSData
//MSJSONResponseSerializerWithData.h
#import "AFURLResponseSerialization.h"
/// NSError userInfo key that will contain response data
static NSString * const JSONResponseSerializerWithDataKey = #"JSONResponseSerializerWithDataKey";
#interface MSJSONResponseSerializerWithData : AFJSONResponseSerializer
#end
// MSJSONResponseSerializerWithData.m
#import "MSJSONResponseSerializerWithData.h"
#implementation MSJSONResponseSerializerWithData
- (id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error
{
if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
if (*error != nil) {
NSMutableDictionary *userInfo = [(*error).userInfo mutableCopy];
userInfo[JSONResponseSerializerWithDataKey] = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError *newError = [NSError errorWithDomain:(*error).domain code:(*error).code userInfo:userInfo];
(*error) = newError;
}
return (nil);
}
return ([super responseObjectForResponse:response data:data error:error]);
}
#end
Here is an example of how I use it in the failure block.
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"%#",[error.userInfo objectForKey:#"JSONResponseSerializerWithDataKey"]);
}];
You need to use AFCompoundSerializer to tell the AFNetworking framework how to process all of the possible responses it could receive. By default it will only try to map JSON. A compound serializer will work through the serializers until it finds one that doesn't raise an error.
You want to use:
+ (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers
on AFCompoundResponseSerializer (in AFURLResponseSerialization.h).
You need to pass an array of serializers that can handle the response. One of the serializers in the array should be an instance of AFHTTPResponseSerializer to handle your error responses.
If you include my category in your project, it's as simple as the following:
[mySessionManager POST:#"some-api" parameters:params success:^(NSURLSessionDataTask *task, NSDictionary *responseObject) {
...
} failure:^(NSURLSessionDataTask *task, NSError *error) {
id responseObject = error.userInfo[kErrorResponseObjectKey];
... do something with the response ...
}];
Here's the code for my category. It swizzles AFURLSessionManager to inject a shim into the completion handler. The shim puts the response into the NSError's userInfo.
https://gist.github.com/chrishulbert/35ecbec4b37d36b0d608
I am doing a simple GET request with AFNetworking
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"http://someapi.com/hello.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
Once I have made the request I want to be able to access the responseObject from any other method in the class.
I want to be able to save the responseObject so I can do something like display the output in a tableview.
It's common to creat object models that will be represented by JSON. When you get the response you would then parse the data into the models. The approach we use is to return the response to the requester through a completion block. You don't have to parse the JSON into strongly typed objects, but it really is helpful long term. It's probably a good idea to farm out the network request operations into a separate class (called a service) as well. This way you can instantiate a new service and get notified through a completion block that it is finished. For example your service's request signature could look like this:
typedef void(^HelloWorldCompletionHandler)(NSString *helloWorld, NSError *error);
- (void)requestHelloWorldData:(HelloWorldCompletionHandler)completionHandler;
// implementation
- (void)requestHelloWorldData:(HelloWorldCompletionHandler)completionHandler {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"http://someapi.com/hello.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
id JSONResponse = [operation responseObject];
if (operation.error) {
completionHandler(nil, error);
} else {
// parse the response to something
id parserResult = [self parseJSONResponse:JSONResponse];
completionHandler(parserResult, nil);
}
}];
This way you'll know when the network request is complete, and you can set the data you want on a property within your class. Then you could call tableView.reloadData in order to use the data in your table.
All that code would go into a service type class. I like to organize my services by responsibility. I don't know how many different data calls you make, but we have several for our project. If for instance you were making a weather app you could potentially organize by Current Conditions, Daily Forecasts, and Hourly Forecasts. I would make a service for each one of these requests. Say I created a CurrentConditionsService. The header would look something like this:
typedef void(^CurrentConditionsCompletionHandler)(CurrentConditions *currentConditions, NSError *error);
#interface CurrentConditionsService : NSObject
// locationKey is some unique identifier for a city
+ (instancetype)serviceWithLocationKey:(NSString *)locationKey;
- (void)retrieveCurrentConditionsWithCompletionHandler:(CurrentConditionsCompletionHandler)completionHandler;
#end
Then in my implementation file I would make the request and invoke the given completion handler like I demonstrated above. This pattern can be followed by many different services to the point where all your services could inherit from a base class that handles the request/response portions. Then your subclasses could override specific methods and handle/parse the data appropriately based on type.
If you go the route of parsing the JSON responses into model objects, all your parsers will need to conform to a protocol. This way in your super class it doesn't matter what the concrete implementation of your parser is. You supply the super class with a concrete implementation and all it knows how to do is invoke the parser and return the response.
An example JSON parser protocol would look like this:
#protocol AWDataParser <NSObject>
#required
- (id)parseFromDictionary:(NSDictionary *)dictionary;
- (NSArray *)parseFromArray:(NSArray *)array;
#end
And invoking it in your services super class:
- (id)parseJSONResponse:(id)JSONResponse error:(NSError **)error {
NSAssert(self.expectedJSONResponseClass != nil, #"parseResponse: expectedJSONResponseClass cannot be nil");
NSAssert(self.parser != nil, #"parseResponse: parser cannot be nil");
id parserResult = nil;
if (![JSONResponse isKindOfClass:self.expectedJSONResponseClass]) {
//handle invalid JSON reponse object
if (error) {
*error = [NSError errorWithDomain:NetworkServiceErrorDomain code:kNetworkServiceErrorParsingFailure userInfo:#{#"Invalid JSON type": [NSString stringWithFormat:#"expected: %#, is: %#",self.expectedJSONResponseClass, [JSONResponse class]]}];
}
} else {
if (self.expectedJSONResponseClass == [NSArray class]) {
parserResult = [self.parser parseFromArray:JSONResponse];
}else {
parserResult = [self.parser parseFromDictionary:JSONResponse];
}
if (!parserResult) {
if (error) {
*error = [NSError errorWithDomain:NetworkServiceErrorDomain code:kNetworkServiceErrorParsingFailure userInfo:nil];
}
}
}
return parserResult;
}
Use this approach:
NSURL *COMBINAT = [[NSURL alloc] initWithString:#"http://someapi.com/hello.json"];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:
COMBINAT];
[self performSelectorOnMainThread:#selector(savedata:) withObject:data waitUntilDone:YES];
});
then simply call:
- (void)savedata:(NSData *)responseData {
NSError* error;
NSLog(#"Answer from server %#", responseData);
// ... your code to use responseData
}
Just create a property:
#property(nonatomic, strong) id savedResponseObject;
and set it in the success handler of the request:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"http://someapi.com/hello.json"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
self.savedResponseObject = responseObject;
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %#", error);
}];
Then you will be able to access it from other places in your class by referencing:
self.savedResponseObject
I've been using AFNetworking 2.0 in my app.
I've noticed that if my web-service returns a 500 status code I do not get the body of the response.
Here is an example of my php code
try
{
$conn = new PDO( "sqlsrv:server=$serverName;Database = $database", $uid, $pwd);
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
return $conn;
}
catch( PDOException $e )
{
$response->status(500);
echo( "Connection Error: " . $e->getMessage() );
}
If I use a simple rest client this is an example of a response body.
Connection Error: SQLSTATE[08001]: [Microsoft][SQL Server Native Client 11.0]SQL Server Network Interfaces: Error Locating Server/Instance Specified [xFFFFFFFF].
However this seems to be the only response I can get from AFNetworking
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x15e58fa0 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
This is the part of my objective-c code that does this.
...} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"%#",error.description);
}];
Is there a way I can get the response body?
Edit: More code for clarification
Below is part of my subclass of AFHTTPSessionManager
#implementation MSMAMobileAPIClient
+ (MSMAMobileAPIClient *)sharedClient {
static MSMAMobileAPIClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[MSMAMobileAPIClient alloc] initWithDefaultURL];
});
return _sharedClient;
}
- (id)initWithDefaultURL {
return [self initWithBaseURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://%#/mamobile/index.php/" ,[[NSUserDefaults standardUserDefaults] stringForKey:#"serviceIPAddress"]]]];
}
- (id)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if (!self) {
return nil;
}
self.responseSerializer = [AFCompoundResponseSerializer compoundSerializerWithResponseSerializers:#[[AFJSONResponseSerializer serializer], [AFHTTPResponseSerializer serializer]]];
return self;
}
I tried setting the response serializer to a AFCompoundResponseSerializer but it didn't seem to make a difference
Below is an example of a subclass that I call the Librarian.
-(void)searchForItemWithString:(NSString *)searchString withCompletionBlock:(arrayBlock)block {
self.inventorySearchBlock = block;
NSDictionary *parameters = #{#"query": searchString};
[[MSMAMobileAPIClient sharedClient] GET:#"inventory/search" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
if (!responseObject) {
NSLog(#"Error parsing JSON");
} else {
//do stuff with the json dictionary that's returned..
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"Error: %#",error.description);
}];
}
UPDATE: I have created a github repository to contain the latest code I am using. All changes will be posted there. https://github.com/Hackmodford/HMFJSONResponseSerializerWithData
The answer comes from this issue on github.
https://github.com/AFNetworking/AFNetworking/issues/1397
gfiumara is the dev who came up with this. I have only slightly modified his subclass of AFJSONResponseSerializer to include an actual string instead of the NSData
//MSJSONResponseSerializerWithData.h
#import "AFURLResponseSerialization.h"
/// NSError userInfo key that will contain response data
static NSString * const JSONResponseSerializerWithDataKey = #"JSONResponseSerializerWithDataKey";
#interface MSJSONResponseSerializerWithData : AFJSONResponseSerializer
#end
// MSJSONResponseSerializerWithData.m
#import "MSJSONResponseSerializerWithData.h"
#implementation MSJSONResponseSerializerWithData
- (id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error
{
if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
if (*error != nil) {
NSMutableDictionary *userInfo = [(*error).userInfo mutableCopy];
userInfo[JSONResponseSerializerWithDataKey] = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError *newError = [NSError errorWithDomain:(*error).domain code:(*error).code userInfo:userInfo];
(*error) = newError;
}
return (nil);
}
return ([super responseObjectForResponse:response data:data error:error]);
}
#end
Here is an example of how I use it in the failure block.
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(#"%#",[error.userInfo objectForKey:#"JSONResponseSerializerWithDataKey"]);
}];
You need to use AFCompoundSerializer to tell the AFNetworking framework how to process all of the possible responses it could receive. By default it will only try to map JSON. A compound serializer will work through the serializers until it finds one that doesn't raise an error.
You want to use:
+ (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers
on AFCompoundResponseSerializer (in AFURLResponseSerialization.h).
You need to pass an array of serializers that can handle the response. One of the serializers in the array should be an instance of AFHTTPResponseSerializer to handle your error responses.
If you include my category in your project, it's as simple as the following:
[mySessionManager POST:#"some-api" parameters:params success:^(NSURLSessionDataTask *task, NSDictionary *responseObject) {
...
} failure:^(NSURLSessionDataTask *task, NSError *error) {
id responseObject = error.userInfo[kErrorResponseObjectKey];
... do something with the response ...
}];
Here's the code for my category. It swizzles AFURLSessionManager to inject a shim into the completion handler. The shim puts the response into the NSError's userInfo.
https://gist.github.com/chrishulbert/35ecbec4b37d36b0d608
how to i set response mapping to manager with path pattern ..if the getobjects at path is different from path pattern that is used to map the response.
[manager addResponseDescriptorsFromArray:
#[[RKResponseDescriptor responseDescriptorWithMapping:categoryMapping
pathPattern:A
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]]];
[manager getObjectsAtPath:A/ID
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#" Category success");
[self.delegate didReceiveAssignedCategories];
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Category failure");
}];
response mapping path ie:A must be set to dynamic path used to getobject ie:A/ID .
ex:
Call 1)
A = /getAllCategories
A/ID = /getAllCategories/123
call 2)
A = /getAllCategories
A/ID = /getAllCategories/456
response mapping is same for 123, 456
only while getting the objects i am using different urls ie: with id's attached.
how to do that ?
If you have 2 path patters which both return the same type of data then you can use the same mapping with 2 different response descriptors.
If you have 1 path pattern which can return 2 different types of data then you need to use RKDynamicMapping to 'intercept' the incoming data and decide which mapping is actually required.
From your edited question, 'pattern' is the important thing that you have misunderstood. You need to use a path pattern, not a static path:
#"getAllCategories/:identity"
1) First create response mapping like
[manager addResponseDescriptorsFromArray:
#[[RKResponseDescriptor responseDescriptorWithMapping:categoryMapping
pathPattern:#"getAllCategories/:categoryID"
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]]];
2)Create Class with categoryID in it.
[CategoryRequest class]
3) create object of that class and set categoryID
CategoryRequest *categoryRequest = [CategoryRequest alloc] init];
categoryRequest.categoryID = #"123";
4)call getobject using that object
[manager getObject:categoryRequest
path:#"getAllCategories/123"
parameters:params
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Success");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Failure");
}];
if another call is required to be made for same mapping create object of of category request class set new category id and call get object using that categoryresquest and required path patter.
Using Restkit, I've setup the RKObjectManager in my AppDelegate and everything is working fine. I would like to know if there's some way to setup a default action for specific response codes.
For example, a user uses my iPhone app to login to my api and gets an auth_token back to use. If at any point, for any request, I get back I get a 403 response (like if the auth_token expires) I want to change the RootViewController to my login screen.
What would be the best way to set this up in my app?
In RestKit 0.20 you can register your RKObjectRequestOperation, so you can pass all requests/responses through your own success/failure blocks before anything else.
http://blog.higgsboson.tk/2013/09/03/global-request-management-with-restkit/
#import "RKObjectRequestOperation.h"
#interface CustomRKObjectRequestOperation : RKObjectRequestOperation
#end
#implementation CustomRKObjectRequestOperation
- (void)setCompletionBlockWithSuccess:(void ( ^ ) ( RKObjectRequestOperation *operation , RKMappingResult *mappingResult ))success failure:(void ( ^ ) ( RKObjectRequestOperation *operation , NSError *error ))failure
{
[super setCompletionBlockWithSuccess:^void(RKObjectRequestOperation *operation , RKMappingResult *mappingResult) {
if (success) {
success(operation, mappingResult);
}
}failure:^void(RKObjectRequestOperation *operation , NSError *error) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"connectionFailure" object:operation];
if (failure) {
failure(operation, error);
}
}];
}
#end
Then register your subclass:
[[RKObjectManager sharedManager] registerRequestOperationClass:[CustomRKObjectRequestOperation class]];
And listen for the "connectionFailure" you are sending above:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(connectionFailedWithOperation:) name:#"connectionFailure" object:nil];
In the listener (e.g. your AppDelegate or a login manager):
- (void)connectionFailedWithOperation:(NSNotification *)notification
{
RKObjectRequestOperation *operation = (RKObjectRequestOperation *)notification.object;
if (operation) {
NSInteger statusCode = operation.HTTPRequestOperation.response.statusCode;
switch (statusCode) {
case 0: // No internet connection
{
}
break;
case 401: // not authenticated
{
}
break;
default:
{
}
break;
}
}
}
When using RestKit 0.10 you can use the given delegate method objectLoaderDidLoadUnexpectedResponse.
- (void)objectLoaderDidLoadUnexpectedResponse:(RKObjectLoader *)objectLoader {
if ([[objectLoader response] statusCode] == 403) {
// Your action here
}
}
In RestKit 0.20 you can use a response descriptor for a single code or a set of codes.
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping
pathPattern:nil
keyPath:#"yourKeyPath"
statusCodes:[NSIndexSet indexSetWithIndex:403]];
More status code sets in the documentation.
Update
When using your BaseViewController for handling the errors of the request made in one of the other view controllers, you can set up notifications.
BaseViewController
- (void)viewDidLoad
{
// ...
// Set observer for notification e.g. "requestFailedWith403Error"
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handle403Error:) name:#"requestFailedWith403Error" object:self];
}
- (void)handle403Error:(NSNotification)notification
{
// Code for handling the error
}
SubViewController
- (void)loginToServer
{
// ...
// Set authorization header
[[RKObjectManager sharedManager].HTTPClient setAuthorizationHeaderWithUsername:#"username" password:#"password"];
// e.g. POST to server
[[RKObjectManager sharedManager] postObject:yourObject
path:#"path/toserver"
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
// Handling success
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
// Handling error with notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"requestFailedWith403Error" object:self];
}];
}
Too optimize your central configuration with the handling of errors you can have another look at the example code given in the RestKit Wiki (where the error mapping is added).