如何立即获得结果?

时间:2016-10-18 09:34:09

标签: ios objective-c objective-c-blocks nsurlsession nshttpurlresponse

我使用块从一个类中的响应中获取头字段,我必须在另一个类中获取它。

我实现了像这样的代码

在头等舱:

- (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中获得响应?

5 个答案:

答案 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的第一堂课中调用一个方法。

  1. 在UserAuthentication类中创建YOURFIRSTCLASS * myfirstclass类型的属性。

  2. 通过" self"传递您的第一课程到UserAuthentication对象。

  3. 在你的第一类中创建可见方法"(void)responseCaller:(NSDictionary)dict"

  4. 在您的回复方法中调用该方法

  5. 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;
    }
    

    像这样的东西