将完成处理程序添加到仅返回完成的异步请求方法

时间:2017-11-22 17:34:11

标签: ios objective-c asynchronous nsurlsessiondatatask

所以我在此发布了两次,但我仍然陷入困境(post 1post 2)。

如果在调用另一个请求时遇到401质询,我想触发身份验证请求。我有一个完成块用于我的请求,因此它接收数据,然后可以在收到后执行某些操作。

问题是如果我得到我的401我想调用身份验证然后重试我的请求。我得到了second question的答案,说我应该为我的auth方法添加一个完成处理程序,以便它可以调用原始请求。问题是我不知道如何只为我的方法添加一个完成块。我查了一下块并尝试了一个光线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];
}

如果我尝试让函数返回一个bool,我实际上无法在我的完成块中为web请求返回它,因为它认为我正在向请求返回一个值,而不是总体方法。

我还尝试使用委托通过请求的完成块传递布尔值,但布尔值立即执行(因为异步请求)并且基本上没用。

如何点+ (void)requestAuthToken并为其添加完成块,以便调用self requestAuthToken而不是[self refreshAuth withCompletionHandler:weakself.requestDataForUser];我可以[self requestAuthToken(^somethingblockyhere){ retry request }]; 甚至

/*Mobile 480px*/
/*Desktop 992px*/
/*Huge 1280px*/

@media screen and (min-width: 480px) and (min-width: 768px), (min-width: 992px), (min-width: 1280px) {
.parralax {
   /* Full height */
   height: 100%; 

   /* Create the parallax scrolling effect */
   background-attachment: fixed;
   background-position: center;
   background-repeat: no-repeat;
   background-size: cover;
 }
} 

由于

1 个答案:

答案 0 :(得分:0)

+animateWithDuration:animations:的{​​p> UIView是一个关于如何声明空块的简单示例 它的声明如下:

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