我正在尝试隔离负责身份验证的逻辑并在函数内部重新获取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";
}
}];
}
答案 0 :(得分:3)
有几个问题。
您的方法getToken:andPassword:
应该是异步的。
NSOperationQueue
使用不当(您不需要)
未指定Content-Type标头
在URI的查询组件中省略参数编码(x-www-form-urlencoded
)
NSURLConnection
:
除非您确切知道您的请求与已实现的默认行为一起使用,否则不要使用类便捷方法(对于具有身份验证的请求,这几乎总是如此)。请阅读官方文档
因此,对于解决方案,我建议使用NSURLConnection
或NSURLSession
的委托方法。请参阅上面已经提到的官方文档中的示例和代码段。
您必须处理身份验证质询,并提供凭据。如果您将这些参数放入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)
{
}
这样,您可以在网络请求完成后对结果执行某些操作。