2017-11-22 19 views
-1

私はこれを2回投稿しましたが、まだまだかなりつまっています(post 1post 2)。補完だけを返す非同期リクエストメソッドに補完ハンドラを追加する

別の要求を呼び出すときに401のチャレンジを取得した場合、認証要求をトリガーしたいと思います。私は私の要求のための完了ブロックを持っているので、それはデータを受信し、それが受信されると何かをすることができます。

問題は、401を取得して認証を呼び出してから、リクエストをやり直したい場合です。 second questionに私の認証方法に補完ハンドラを追加して、元の要求を呼び出すことができるという答を得ました。問題は、どのように私のメソッドに補完ブロックだけを追加できるのか分かりません。私はブロックを探して、レイwenderlichチュートリアルを試しましたが、すべてが何かを返すか、何かを完了ブロックとして渡すようです。

+ (void)requestAuthToken { 

    NSLog(@"requestNewToken - Called: Requesting a new authorization bearer token."); 

    //Indicate Network Activity 
    [UIApplication sharedApplication].networkActivityIndicatorVisible = TRUE; 

    [[NSURLCache sharedURLCache] removeAllCachedResponses]; 

    //Build request URL String 
    NSString *requestString = [NSString stringWithFormat:@"%@%@",baseURL,authRequestURL]; 

    //Encode password so that it can be safely sent in request 
    NSString *encodedPassword = [kU1Password stringByAddingPercentEncodingForRFC3986]; 

    //Populate post request with user credentials 
    NSString *post = [NSString stringWithFormat:@"client_id=%@&password=%@&grant_type=%@", kU1ClientId, encodedPassword, kU1GrantType]; 

    //Encode post string & convert to type NSData 
    NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; 

    //Calculate the length of the post string 
    NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[postData length]]; 

    //Initialize url request 
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 

    //Set the url for which you will pass your request data 
    [request setURL:[NSURL URLWithString:requestString]]; 

    //Set HTTP method for request 
    [request setHTTPMethod:@"POST"]; 

    //Set HTTP header field with length of post data 
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 

    //Set the encoded value for HTTP Header field 
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 

    //Set the HTTP body of the urlrequest with our post data 
    [request setHTTPBody:postData]; 

    //Create full request 
    NSURLSession *session = [NSURLSession sharedSession]; 

    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request 
               completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){ 

                NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response; 
                NSLog(@"Status Code: %ld\n",(long)httpResponse.statusCode); 

                NSString *message = [NSHTTPURLResponse localizedStringForStatusCode:httpResponse.statusCode]; 
                NSLog(@"Message: %@", message); 

                //Check for an error, if there is no error we proceed. 
                if (!error) { 

                 NSLog(@"requestAuthToken - Successful responce from server"); 

                 //Populate the auth object with the parse json data (handled entirely in the builder) 
                 Token *auth = [TokenBuilder authFromJSON:data error:&error]; 
                 //Set the local tokens object equal to our responce object 
                 //self.tokens = auth; 

                 //Save the auth & refresh tokens in the keychain 
                 [SAMKeychain setPassword:downloadedAuthToken forService:kServer account:kKeyAccessToken]; 
                 [SAMKeychain setPassword:downloadedRefreshToken forService:kServer account:kKeyRefreshToken]; 

                 //Get que and perform any UI changes 
                 dispatch_async(dispatch_get_main_queue(), ^{ 
                  //_accessTokenLabel.text = _tokens.OOTAuthToken; 
                  [UIApplication sharedApplication].networkActivityIndicatorVisible = FALSE; 
                 }); 
                } 
                else { 
                 //Failed request 
                 NSLog(@"requestAuthToken - error : %@", error.description); 
                 dispatch_async(dispatch_get_main_queue(), ^{ 
                  [UIApplication sharedApplication].networkActivityIndicatorVisible = FALSE; 
                 }); 
                } 
               }]; 
    [dataTask resume]; 
} 

私は関数はブール値を返すようにしようと、それは私がリクエストではなく、包括的な方法に値を返すんだと考えているので、私は実際にWeb要求のための私の完了ブロック以内にそれを返すことはできません。 。

また、要求の完了ブロックでブール値を渡すためにデリゲートを使用しようとしましたが、ブール値は(非同期要求のため)すぐに実行され、基本的に役に立たないものです。

どのように私は​​を取ると私はUIView[self refreshAuth withCompletionHandler:weakself.requestDataForUser];あるいは

[self requestAuthToken(^somethingblockyhere){ 
retry request 
}]; 

おかげ

+1

は_not_ "この上の二回ポスト" を行います。あなたが望む答えが得られなかったら、その答えを受け入れないでください。あなたの質問が正しく提起されなかった場合は、それを編集してください。 – matt

答えて

0

+animateWithDuration:animations:を行うことができ、むしろself requestAuthTokenを呼び出すよりもよう、それに完了のブロックを追加することができますが宣言する方法についての簡単な例でありますvoidブロック。
は、それはこのように宣言です:

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations; 

は、私は個人的に、私はなかれそれらを宣言する方法を覚えておくのiOS SDK(私はいくつかの方法を知っている)を確認、それらを宣言する方法を覚えていることはありません。

だから、あなたの質問に適用する:あなたの他の呼(あなたの他のコードから取られたコード)で

+ (void)requestAuthToken:(void (^)(void))block 
{ 
    //do your thing 

    //When it's okay: 
    if (block) 
    { 
     block(); 
    } 
} 

-(void)requestDataForUser 
{ 
    //Do your things 

    //Need to refresh token: 
    [[CorrectClassName requestAuthToken:^{ 
     [weakSelf requestDataForUser]; 
    }]; 
} 
+0

こんにちは。私はあなたが言ったことを実装して、私の方法はついに動作します!助けてくれてありがとうございましたが、あなたが上に書いた完成ブロックについて質問があります。 'if(block){block();}'に関して、このコードは実際に何を言いますか?私たちはブロックの価値をどこにでも置いてはいません。私はこれがどのように動作し、説明が非常に高く評価されるだろうか、私はかなり確信していない! – Axemasta

+0

Cメソッド、Swiftメソッドのように見えますが、パラメータはありません。それは単にパラメータを持たない「メソッド」と呼ばれているだけです。そして、そのメソッドの '^ {}];' 'implementation"。何もしたくない場合は、単に[[CorrectClassName requestAuthToken:nil] 'を実行してください。 – Larme

+0

はい、意味があります、もう一度、助けてくれてありがとう! – Axemasta