2

我有一个代码设计问题,我想不出最有效的方式来处理这个问题:

基本上,我想发送一个 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 值返回为真或假,以查看它是否有效。

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

-(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 等...

我希望能够让上面提到的每个请求方法返回它们的关联数据,但我不能(至少效率不高)。我必须为每个请求制作两种不同的方法吗?

IE

sendString
getSendStringResponse

我有点困惑如何处理这个问题。

如果我不清楚,我很抱歉,

我很感激我能得到的任何帮助。

4

1 回答 1

1

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

于 2012-08-20T03:05:45.157 回答