NSURLConnection块内的返回字符串 - 不兼容的块指针类型发送

时间:2014-04-06 08:59:49

标签: objective-c nsstring nsurlconnection

我正在尝试隔离负责身份验证的逻辑并在函数内部重新获取TOKEN。我有从NSURLConnetcion的BLOCK返回带有令牌的字符串的问题。

它导致semantic error:不兼容的块指针类型发送

'NSString *(^)(NSURLResponse *__strong, NSData *__strong, NSError *__strong)' 

类型的参数
'void (^)(NSURLResponse *__strong, NSData *__strong, NSError *__strong)'

我是Objective-C的新手,所以请原谅。以下是我的功能。

- (NSString*)getToken: (NSString *)username andPassword: (NSString *) password {

NSMutableURLRequest *request1 = [NSMutableURLRequest requestWithURL:
[NSURL URLWithString:@"http://127.0.0.1:8000/auth_ex"]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20];

__block NSString * tokens;
[request1 setHTTPMethod:@"POST"];

NSString * body1 = [NSString stringWithFormat:@"email=%@&password=%@",username,password];

[request1 setHTTPBody: [body1 dataUsingEncoding:NSUTF8StringEncoding]];

NSOperationQueue * queue1 = [[NSOperationQueue alloc]init];

[NSURLConnection
 sendAsynchronousRequest:request1 queue:queue1 completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
     if ([data length] >0 && connectionError == nil){
         NSDictionary* token = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
         tokens = [token objectForKeyedSubscript:@"token"];
         return tokens;
     }
     else{
         return @"NOT AUTHORIZEd";
     }
 }];


}

enter image description here

2 个答案:

答案 0 :(得分:3)

有几个问题。

  • Naming Conventions

  • 您的方法getToken:andPassword:应该是异步的。

  • NSOperationQueue使用不当(您不需要)

  • 未指定Content-Type标头

  • 在URI的查询组件中省略参数编码(x-www-form-urlencoded

  • NSURLConnection

    缺乏经验

    除非您确切知道您的请求与已实现的默认行为一起使用,否则不要使用类便捷方法(对于具有身份验证的请求,这几乎总是如此)。请阅读官方文档

因此,对于解决方案,我建议使用NSURLConnectionNSURLSession的委托方法。请参阅上面已经提到的官方文档中的示例和代码段。

您必须处理身份验证质询,并提供凭据。如果您将这些参数放入URL或正文中,这也可以使您免于容易出错且不方便对参数进行百分比编码。

您还应该使用https

答案 1 :(得分:1)

变量tokens在块外部声明,但可以从块内部访问。因此,if语句不需要return tokens,而else语句应该只是tokens = @"NOT AUTHORIZED";

请注意,您的块正在从某些框架代码中调用,并且该代码并不期望返回任何内容,因此completionHandler被声明为void,并且您不允许从void函数返回值。


我应该补充一点,sendAsynchronousRequest方法几乎会立即返回,但是在服务器响应请求之后的某个时间之后,完成处理程序将无法被调用。因此,通常使用完成处理程序来通知主线程操作已完成。通知主线程的一种方法是使用这样的代码

[self performSelectorOnMainThread:@selector(someMethod:) withObject:tokens waitUntilDone:NO];

someMethod方法声明为

- (void)someMethod:(NSString *tokens)
{
}

这样,您可以在网络请求完成后对结果执行某些操作。