I started writing a simple JSON RPC TCP library in Objective C. I have a method that invokes a RPC Method:
- (void)invokeMethod:(NSString *)method
withParameters:(id)parameters
requestId:(id)requestId
success:(void (^)(id responseObject))success
failure:(void (^)(NSError *error))failure
{
NSAssert(NSClassFromString(@"NSJSONSerialization"), @"NSJSONSerialization not found!");
NSDictionary *requestObject = @{@"jsonrpc": @"2.0",
@"method": method,
@"params": parameters,
@"id": requestId};
NSError *error = nil;
NSData *jsondData = [NSJSONSerialization dataWithJSONObject:requestObject options:0 error:&error];
if (error){
return failure(error);
}
[self->callbacks setObject:@{@"success": success ? [success copy] : [NSNull null],
@"failure": failure ? [failure copy] : [NSNull null]}
forKey:requestId];
NSString *str = [[NSString alloc] initWithData:jsondData encoding:NSUTF8StringEncoding];
NSLog(@"Sending: %@", str);
[self.socket writeData:jsondData withTimeout:-1 tag:1];
}
The class basically represents a TCP connection, when calling the above method, the JSON data is sent with an id over TCP to the server which either returns a success or a failure:
- (void) socket:(GCDAsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag
{
NSError *error = nil;
[self.socket readDataWithTimeout:-1 tag:2];
// … rpc response parsing code here, removed for simplicity …
// detect if error or success
NSDictionary *cbs = [self->callbacks objectForKey:JSONRPCObjectId];
void(^success)(id resultObject) = [cbs objectForKey:@"success"];
success ? success(JSONRPCObjectResult) : nil;
return;
}
Now, I am unsure how to keep track of the success
and failure
blocks, currently I am storing them in an NSMutableDict
, using the requestId as key. Is it fine to do this or is there a better approach that I should use?