0

ブロックを使用して、あるクラスの応答からヘッダー フィールドを取得していますが、それを別のクラスで取得する必要があります。

このようなコードを実装しました

ファーストクラスで:

- (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;
}

ここで私の問題は、私がdictnullとして取得しているファーストクラスにあります。

クラスでもuserAuthentication私はnullになっています。

しかし、しばらくすると、コールバック メソッドが呼び出され、応答が正しく表示されcompletionHandlerます。

では、firstClass で応答を取得するにはどうすればよいでしょうか。

4

5 に答える 5

2

バックグラウンドスレッドで実行される非同期操作の基本原則を誤解しており、操作が完了すると完了ブロックにデータが表示されます。

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);

   }];
}
于 2016-10-18T09:46:17.360 に答える
2

これは慣れる必要があります。インターネット アクセスに関連するもの (およびそれに関連しないもの) はすべて、すぐに返すことはできません。それを待ち、ユーザー インターフェイスをブロックし、ユーザーを非常に、非常に不幸です。

アプリケーションが次の 4 つの状態になるようにアプリケーションを作成する必要があります。ユーザー構成を要求しない、ユーザー構成を要求する、ユーザー構成を要求して受信する、またはユーザー構成を要求して失敗する。この場合、ビューは 4 つの可能性すべてを処理し、状況が変化したときに処理する必要があります。

于 2016-10-18T09:49:04.247 に答える
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];
}

最初のクラスから上記のコードを呼び出すと、そこにブロックが作成され、必要な辞書がブロック パラメータで取得されます。

于 2016-10-18T09:42:57.427 に答える
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);

    }];

 }

Webサービスの応答で(サーバーから)データを取得するため、完了するまでに時間がかかるため、Webサービス呼び出しの完了ハンドラーからデータを返す必要があり、完了ハンドラーからデータを返すことができないため、独自の完了ハンドラーを作成する必要があります上記のように呼び出します。にアクセスresultDictionaryしてcompletionHandler、この から新しい VC を表示できますcompletionHandler

于 2016-10-18T09:43:14.357 に答える
0

completionHandler の最初のクラスでメソッドを呼び出す必要があります。

  1. UserAuthentication クラスにタイプ YOURFIRSTCLASS *myfirstclass のプロパティを作成します。

  2. 「self」を含むファーストクラスを UserAuthentication オブジェクトに渡します。

  3. 最初のクラス「-(void)responseCaller:(NSDictionary)dict」に可視メソッドを作成します

  4. 応答メソッドでメソッドを呼び出します

あなたのファーストクラス .h:

-(void)responseCaller:(NSDictionary)dict;

あなたのファーストクラス.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);
}

ユーザー認証 .h

#import "YOURFIRSTCLASS.h"
@property (nonatomic) *myfirstclass;

ユーザー認証 .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;
}

そんな感じ

于 2016-10-18T09:55:22.603 に答える