I am trying to write a wrapper for RestKit, so that all requests call one function which in turn would trigger a request via RestKit.
Here’s what I have so far:
A function would call my wrapper as follows:
NSDictionary *response = [Wrappers sendRequestWithURLString:url method:@”GET”];
And my wrapper methods:
+ (NSDictionary *)sendRequestWithURLString:(NSString *)request method:(NSString *)method
{
RKRequestDidFailLoadWithErrorBlock failBlock;
if ([method isEqualToString:@"GET"])
return [self sendGETRequestWithURLString:request withFailBlock:failBlock];
else if ([method isEqualToString:@"POST"])
return [self sendPOSTRequestWithURLString:request withFailBlock:failBlock];
return nil;
}
+ (NSDictionary *)sendGETRequestWithURLString:(NSString *)request withFailBlock:(RKRequestDidFailLoadWithErrorBlock)failBlock {
RKObjectManager *manager = [RKObjectManager sharedManager];
__block NSDictionary *responseDictionary;
[manager loadObjectsAtResourcePath:request usingBlock:^(RKObjectLoader *loader) {
loader.onDidLoadResponse = ^(RKResponse *response) {
[self fireErrorBlock:failBlock onErrorInResponse:response];
RKJSONParserJSONKit *parser = [RKJSONParserJSONKit new];
responseDictionary = [[NSDictionary alloc] initWithDictionary:[parser objectFromString:[response bodyAsString] error:nil]];
};
}];
return responseDictionary;
}
+ (void)fireErrorBlock:(RKRequestDidFailLoadWithErrorBlock)failBlock onErrorInResponse:(RKResponse *)response {
if (![response isOK]) {
id parsedResponse = [response parsedBody:NULL];
NSString *errorText = nil;
if ([parsedResponse isKindOfClass:[NSDictionary class]]) {
errorText = [parsedResponse objectForKey:@"error"];
}
if (errorText)
failBlock([self errorWithMessage:errorText code:[response statusCode]]);
}
}
+ (NSError *)errorWithMessage:(NSString *)errorText code:(NSUInteger)statusCode {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"Please make sure you are connected to WiFi or 3G."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
return nil;
}
The problem here is when responseDictionary returns, the value is nil since onDidLoadResponse would not have processed yet as it runs concurrently.
In this case, what would be the best approach in setting responseDictionary? I’m trying to avoid calling a setter method of another class. In this case, is my only option using delegates, which defeats the whole purpose of creating a wrapper class since RestKit calls require usage of delegate methods to return the response?
Would I be able to pass my wrapper a success block which would update some local ivar? How would I do that?
You pass a success block as you have said. Here is an example of how to do that:
.h
.m
However, let me warn you of a potential design flaw. You should design your app so that the UI is driven by your data and not your web service. This means your UI should automatically update when your data model is updated and not when your web service returns. Be careful how you use this response dictionary. If it is to update UI then you are running down a dangerous road.