阅读复杂的套接字响应

时间:2012-08-19 08:30:00

标签: ios sockets cocoaasyncsocket gcdasyncsocket

我有一个代码设计问题,我无法想出最有效的方法来解决这个问题:

基本上,我想发送一个JSON请求并一次性从服务器读取响应。

我有一些方法,例如:

-(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;

我会解释一下

-(BOOL)sendString:(NSString *)sendString;

确实, 基本上将一个JSON字符串发送到服务器并得到一个响应,它是否失败。

我知道如何将此内容写入服务器并阅读此内容。 问题在于一起执行此操作,因此我可以将BOOL值作为true或false返回,以查看它是否有效。

现在写入套接字后,我得到一个响应,必须通过委托方法读取它:

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {

一旦服务器给出响应,就会调用它。问题是,所有这些对套接字的读/写都是异步发生的。

由于这种情况发生,我不能有这样做的方法:

-(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;
}

}

自从

之后调用的代码
[asyncSocket readDataWithTimeout:-1 tag:2];

在读取数据之前执行(因为它都是异步的)。

我意识到我必须在该委托方法中做点什么。哪个没问题,但我有不同类型的回复,每个回复必须以不同的方式处理。

我的想法是:标记每个写命令,然后使用一些

if(this_tag) {do this} ....else if(that_tag) {do this} ....
在didReadData委托方法中。

但是如何正确返回这些数据呢?有时我需要返回BOOL,有时我需要返回NSDictionary,NSString等...

我希望能够让我上面提到的每个请求方法都返回相关数据,但我不能(至少没有效率)。我是否必须为每个请求制作两种不同的方法?

sendString
getSendStringResponse

我对如何处理这个问题感到困惑。

如果我不清楚,我道歉,

感谢我能得到的任何帮助。

1 个答案:

答案 0 :(得分:1)

我要做的是为这个特定的应用程序创建某种类型的协议。例如,假设您有以下数据类型(与Obj-C无关)dat1,dat2,dat3等此应用需要发送并获得相应的响应,如res1,res2,res3等你会为发送部分和响应部分的每种数据类型提供一个签名。在发送每个数据之前,您需要在数据前加上签名。在接收器端使用readDataWithTimeout,在didReadData回调方法中,提取接收数据的标头,并根据您之前同意/设计的协议决定响应。在完成此设计之前还有其他额外步骤。例如,作为标题信息的一部分,它可能包含其他信息,例如数据长度等。希望这将有助于您开始使用。