我使用块从一个类中的响应中获取头字段,我必须在另一个类中获取它。
我实现了像这样的代码
在头等舱:
- (void)viewDidLoad {
[super viewDidLoad];
UserAuthentication *auth = [[UserAuthentication alloc]init];
NSDictionary *dict = [auth getUserConfiguration];
NSLog(@"%@",dict);
}
在userAuthentication类中:
-(NSDictionary *)getUserConfiguration;
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
NSLog(@"%@",resultDictionary);
}
}] resume];
NSLog(@"%@",resultDictionary);
return resultDictionary;
}
我的问题出现在头等舱中,我将dict
视为空。
即使在userAuthentication
课程中,我也会变为空。
但是在一段时间后回调方法正在调用,然后我可以在completionHandler
中正确看到响应。
那么我如何在firstClass中获得响应?
答案 0 :(得分:2)
您误解了在后台线程中运行的异步操作的基本原理,当操作完成时,它会在完成块中为您提供数据。
要在viewDidLoad第二类方法中获取响应,您需要使用块。如下所示
-(void)getUserConfigurationOnCompletion:(void (^)(NSDictionary *))completion
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
// Call completion with parameter
completion(resultDictionary);
}
}] resume];
}
并在viewDidLoad
中使用它- (void)viewDidLoad {
[super viewDidLoad];
UserAuthentication *auth = [[UserAuthentication alloc]init];
[auth getUserConfigurationOnCompletion:^(NSDictionary *dict){
// do necessary work with response dictionary here
NSLog(@"%@",dict);
}];
}
答案 1 :(得分:2)
你需要习惯的东西:任何与互联网访问相关的东西(和一些与它无关的东西)都不能立即返回 - 除非你愿意等待它,阻止您的用户界面,让您的用户非常非常不开心。
您必须以这样一种方式编写应用程序:它可以处于以下四种状态:从未询问用户配置,询问用户配置,询问和接收用户配置,或者询问用户配置并失败了。在这种情况下,您的视图必须处理所有四种可能性,并且必须在情况发生变化时进
答案 2 :(得分:1)
您正在使用NSURLSession!它在后台线程上执行任务! 只有从服务器获得响应时才会调用完成块。当然,完成请求需要时间。您应该使用块来完成请求并在完成时返回结果。
-(void)getUserConfigurationAndOnCompletion:(void(ˆ)(NSDictionary *dict, NSError *error))completion;
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
NSLog(@"%@",resultDictionary);
//This will call the block in the first class with the result dictionary
dispatch_async(dispatch_get_main_queue(), ^{
if(!error){
completion(resultDictionary,nil);
}else{
completion(nil,error);
}
});
}] resume];
}
当您从第一个类调用上面的代码时,它将在那里创建一个块,您将在块参数中获得所需的字典!
答案 3 :(得分:1)
你的方法应该是,
-(void)getUserConfigurationwithCompletionHandler : (void (^)(NSDictionary* resultDictionary))completionHandler
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
NSLog(@"%@",resultDictionary);
completionHandler(resultDictionary);
}
}] resume];
NSLog(@"%@",resultDictionary);
}
你可以像
那样访问它 - (void)viewDidLoad {
[super viewDidLoad];
[self getUserConfigurationwithCompletionHandler:^(NSDictionary *resultDictionary) {
// you can acess result dictionary here
NSLog(@"%@",resultDictionary);
}];
}
因为您将在webservice(来自服务器)的响应中获取数据,因此需要一些时间才能完成,因此您必须从webservice调用的完成处理程序返回数据,并且您无法从完成处理程序返回数据,因此您必须创建如上所述,我自己的完成处理程序和调用。您可以访问resultDictionary
中的completionHandler
,然后您可以显示此completionHandler
中的新VC。
答案 4 :(得分:0)
你必须在completionHandler的第一堂课中调用一个方法。
在UserAuthentication类中创建YOURFIRSTCLASS * myfirstclass类型的属性。
通过" self"传递您的第一课程到UserAuthentication对象。
在你的第一类中创建可见方法"(void)responseCaller:(NSDictionary)dict"
在您的回复方法中调用该方法
YOURFIRSTCLASS .h:
-(void)responseCaller:(NSDictionary)dict;
YOURFIRSTCLASS .m
-(void)responseCaller:(NSDictionary)dict
{NSLog(@"%@",dict);}
- (void)viewDidLoad {
[super viewDidLoad];
UserAuthentication *auth = [[UserAuthentication alloc]init];
auth.myfirstclass = self;
NSDictionary *dict = [auth getUserConfiguration];
NSLog(@"%@",dict);
}
UserAuthentication .h
#import "YOURFIRSTCLASS.h"
@property (nonatomic) *myfirstclass;
UserAuthentication .m
-(NSDictionary *)getUserConfiguration;
{
__block NSDictionary *resultDictionary;
NSURLSession *session = [NSURLSession sharedSession];
__weak myfirstclassSave = myfirstclass;
[[session dataTaskWithURL:[NSURL URLWithString:@"http://72.52.65.142:8083/auth"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if ([response respondsToSelector:@selector(allHeaderFields)]) {
resultDictionary = [httpResponse allHeaderFields];
[myfirstclassSave responseCaller:resultDictionary ];
}
}] resume];
return resultDictionary;
}
像这样的东西