I have a code design question, I'm having trouble thinking of the most efficient manner to handle this:
Basically, I want to send a JSON request and read the response back from the server in one go.
I have a methods such as:
-(BOOL)sendString:(NSString *)sendString;
//This should return a NSString and a BOOL
-(NSDictionary *)loginRequestWithEmail:(NSString *)userEmail andPassword:(NSString *)userPassword;
//This should return a NSString and a BOOL
-(NSDictionary *)requestNewUserAccountWithDisplayName:(NSString *)displayName Email: (NSString *)userEmail andPassword:(NSString *)userPassword;
I'll explain what
-(BOOL)sendString:(NSString *)sendString;
does, Basically sends a JSON string to the server and gets a response of wether it failed or not.
I know how to write this to the server and read this. The issue is with doing this together, so I can return that BOOL value as a true or false to see if it worked.
Now after writing to a socket, I get a response and must read it through a delegate method:
-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
Which is called as soon as the server gives a response. The issue is, all this reading/writing to the socket happens asynchronously.
Since that happens, I can't have a method that does this:
-(BOOL)sendString:(NSString *)sendString{
NSError *error;
NSLog(@"Sending String: %@",sendString);
NSDictionary *blobData = [NSDictionary dictionaryWithObjectsAndKeys:
sendString,@"string",
nil];
NSString *blobString = [[NSString alloc]
initWithData:[NSJSONSerialization dataWithJSONObject:blobData options:kNilOptions error:&error]
encoding:NSUTF8StringEncoding];
NSLog(@"Blob Created: %@", blobString);
NSDictionary *requestData = [NSDictionary dictionaryWithObjectsAndKeys:
@"send_string",@"request_type",
[NSNumber numberWithInt:0],@"security_level",
@"ios",@"device_type",
//No Email Provided, This is just for testing
blobString,@"blob",
nil];
NSData *JSONRequestData = NULL;
JSONRequestData = [NSJSONSerialization dataWithJSONObject:requestData options:kNilOptions error:&error];
NSLog(@"Contents of JSONRequestData: %@",[[NSString alloc] initWithData:JSONRequestData encoding:NSUTF8StringEncoding]);
JSONRequestData = [[[[NSString alloc] initWithData:JSONRequestData encoding:NSUTF8StringEncoding] stringByAppendingString:@"\\n"] dataUsingEncoding:NSUTF8StringEncoding];
//Write the data
NSMutableData *JSONRequestDataWithLineEnding = [[NSMutableData alloc] initWithData:JSONRequestData];
[JSONRequestDataWithLineEnding appendData:[GCDAsyncSocket CRLFData]];
[asyncSocket writeData:JSONRequestDataWithLineEnding withTimeout:-1 tag:1];
//read a response
[asyncSocket readDataWithTimeout:-1 tag:2];
//This should be done in the didRead delegate
NSString *failure = [serverJSONResponseParsed objectForKey:@"failure"];
NSLog(@"Contents of string failure: %@", failure);
if ([failure isEqualToString:@"none"]) {
NSLog(@"Success Sending String");
return TRUE;
}
else {
NSLog(@"Failure: %@",failure);
return FALSE;
}
}
Since the code that is called after
[asyncSocket readDataWithTimeout:-1 tag:2];
executes before the data is read (because it's all async).
I realize I must do something in that delegate method. Which is fine, but I have different types of responses coming in, and each response must be handled differently.
My idea is: tag each of the write commands, and then use some
if(this_tag) {do this} ....else if(that_tag) {do this} ....
in the didReadData delegate method.
But how do I return this data correctly? Sometimes I need to return a BOOL, other times I need to return an NSDictionary, NSString, etc...
I would love to be able to have each of my request methods mentioned above return their associated data, but I can't (at least not efficiently). Do I have to make two different methods for each request?
i.e.
sendString
getSendStringResponse
I'm a little confused as to how to handle this.
I apologize if I'm not being clear,
I appreciate any help that I can get.