将完成处理程序添加到仅 returns 完成的异步请求方法
Adding a completion handler to an asynchronous request method that only returns completion
所以我已经就此发布了两次,但我仍然很困惑 (post 1, )。
我想在调用另一个请求时收到 401 质询时触发身份验证请求。我的请求有一个完成块,因此它接收数据,然后在收到数据后可以做一些事情。
问题是,如果我收到 401,我想调用身份验证,然后重试我的请求。我收到 的答复说我应该向我的 auth 方法添加一个完成处理程序,以便它可以调用原始请求。问题是我不知道如何只向我的方法添加一个完成块。我查找了块并尝试了 ray wenderlich 教程,但似乎一切都在 returning 某些东西或传递某些东西以及完成块。
+ (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];
}
如果我尝试使函数 return 成为布尔值,我实际上无法 return 它在我的 Web 请求完成块中,因为它认为我是 return为请求设置一个值,而不是总体方法。
我还尝试使用委托通过请求的完成块传递布尔值,但布尔值立即执行(因为异步请求)并且基本上没有用。
我如何获取 + (void)requestAuthToken
并向其添加一个完成块,这样我就可以执行 [self refreshAuth withCompletionHandler:weakself.requestDataForUser];
甚至
而不是调用 self requestAuthToken
[self requestAuthToken(^somethingblockyhere){
retry request
}];
谢谢
+animateWithDuration:animations:
of UIView
是关于如何声明 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];
}];
}
所以我已经就此发布了两次,但我仍然很困惑 (post 1,
我想在调用另一个请求时收到 401 质询时触发身份验证请求。我的请求有一个完成块,因此它接收数据,然后在收到数据后可以做一些事情。
问题是,如果我收到 401,我想调用身份验证,然后重试我的请求。我收到
+ (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];
}
如果我尝试使函数 return 成为布尔值,我实际上无法 return 它在我的 Web 请求完成块中,因为它认为我是 return为请求设置一个值,而不是总体方法。
我还尝试使用委托通过请求的完成块传递布尔值,但布尔值立即执行(因为异步请求)并且基本上没有用。
我如何获取 + (void)requestAuthToken
并向其添加一个完成块,这样我就可以执行 [self refreshAuth withCompletionHandler:weakself.requestDataForUser];
甚至
self requestAuthToken
[self requestAuthToken(^somethingblockyhere){
retry request
}];
谢谢
+animateWithDuration:animations:
of UIView
是关于如何声明 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];
}];
}