取消之前的 AFHTTPSessionManager 请求
Cancel previous request of AFHTTPSessionManager
我有一个文本字段,每当用户输入字符时,我都会将该字符附加到我的 url 并获得响应。 我需要取消之前的请求。
例如,如果我输入 "shampoo" 我将访问服务器 7 次,我需要取消最后 6 个请求。
目前我正在使用 [manager.operationQueue cancelAllOperations];
但是有些方法对我不起作用。可能是我没放对吧。
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
{
//[self.s_searchResultText setHidden:YES];
// [SVProgressHUD dismiss];
[self.s_tableView setHidden:true];
[searchProductArray removeAllObjects];
[self.s_tableView reloadData];
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:UNACCEPTABLE_CHARACTERS] invertedSet];
NSLog(@"%@",cs);
NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
NSLog(@"%@",filtered);
NSLog(@"%lu",(unsigned long)filtered.length);
if (filtered.length) {
[CustomToastAlert showToastInParentView:self.view withText:@"Please enter valid characters" withDuaration:1.5];
return NO;
}
searchTextString = [textField.text stringByAppendingString:string];
NSLog(@"%lu",(unsigned long)[searchTextString length]);
NSLog(@"%@",searchTextString);
int stringLength=[searchTextString length];
const char * _char = [string cStringUsingEncoding:NSUTF8StringEncoding];
int isBackSpace = strcmp(_char, "\b");
if (isBackSpace == -8) {
stringLength=[searchTextString length];
stringLength=[searchTextString length]-1;
searchTextString=[searchTextString substringToIndex:stringLength];
NSLog(@"Backspace was pressed");
NSLog(@"string is %@",searchTextString);
}
if(stringLength>=3)
{
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] init];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
NSString *urlString=[NSString stringWithFormat:kSearchProductUrl,kBaseUrl];
urlString = [urlString stringByAppendingString:searchTextString];
urlString = [urlString stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
NSLog(@"%@",searchTextString);
NSLog(@"%@",urlString);
[searchProductArray removeAllObjects];
// [manager invalidateSessionCancelingTasks:NO];
//[manager.operationQueue cancelAllOperations];
[manager GET:urlString parameters:nil success:^(NSURLSessionDataTask *task, id responseObject)
{
[searchProductArray removeAllObjects];
//[SVProgressHUD showWithStatus:LOADING_ITEMS maskType:SVProgressHUDMaskTypeGradient];
NSLog(@"JSON: %@", responseObject);
json= responseObject;
NSLog(@"%@",json);
NSLog(@"%lu",(unsigned long)[[json valueForKeyPath:@"data"] count ]);
for(int i=0;i<[[json valueForKeyPath:@"data"]count ];i++)
{
Product *s_productList=[[Product alloc]init];
s_productList.SKU_Name=[[json valueForKeyPath:@"data.sku_name"]objectAtIndex:i];
s_productList.SKU_Id=[[json valueForKeyPath:@"data.sku_id"]objectAtIndex:i];
s_productList.SKU_Price=[[json valueForKeyPath:@"data.sku_price"]objectAtIndex:i];
s_productList.SKU_OfferPrice=[[json valueForKeyPath:@"data.sku_offer_price"]objectAtIndex:i];
s_productList.SKU_Currency = RUPEE_SYMBOL;
s_productList.SKU_AvailableUnit=[[json valueForKeyPath:@"data.sku_available_unit"]objectAtIndex:i];
s_productList.SKU_OfferDescription= [[json valueForKeyPath:@"data.sku_offer_desc"]objectAtIndex:i];
s_productList.SKU_ImageUrls=[[json valueForKeyPath:@"data.sku_image_urls"]objectAtIndex:i];
[searchProductArray addObject:s_productList];
NSLog(@"%lu",(unsigned long)[searchProductArray count]);
}
[self.s_tableView setHidden:FALSE];
[self.s_tableView reloadData];
NSLog(@"%lu",(unsigned long)[searchProductArray count]);
if ([searchProductArray count]==0) {
[CustomToastAlert showToastInParentView:self.view withText:SEARCH_RESULT withDuaration:1.5];
}
}
failure:^(NSURLSessionDataTask *task, NSError *error)
{
[CustomToastAlert showToastInParentView:self.view withText:NO_DATA_AVAIL withDuaration:1.5];
}];
}
return YES;
}
我不确定您的 class 是如何工作的,但我注意到每次 textField 文本更改时您都在初始化一个新的 AFHTTPSessionManager 对象
所以这是我对这个问题的建议。
// somewhere in your class, let's say in ViewDidLoad you should init the AFHTTPSessionManager object
- (void)viewDidLoad {
[super viewDidLoad];
/// create the AFHTTPSessionManager object, we're gonna use it in every request
self.manager = [[AFHTTPSessionManager alloc] init];
self.manager.responseSerializer = [AFJSONResponseSerializer serializer];
/// create an array that is going to hold the requests task we've sent to the server. so we can get back to them later
self.arrayOfTasks = [NSMutableArray new];
/// discussion:
/// an array holds multiple objects. if you just want to hold a ref to the latest task object
/// then create a property of NSURLSessionDataTask instead of NSMutableArray, and let it point to the latest NSURLSessionDataTask object you create
}
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;{
/// your code goes here
/// .....
/// .....
/// .....
/// .....
/// till we reach
if(stringLength>=3){
/// cancel all previous tasks
[self.arrayOfTasks enumerateObjectsUsingBlock:^(NSURLSessionDataTask *taskObj, NSUInteger idx, BOOL *stop) {
[taskObj cancel]; /// when sending cancel to the task failure: block is going to be called
}];
/// empty the arraOfTasks
[self.arrayOfTasks removeAllObjects];
/// init new task
NSURLSessionDataTask *task = [self.manager GET:urlString parameters:nil success:^(NSURLSessionDataTask *task, id responseObject){
/// your code
}failure:^(NSURLSessionDataTask *task, NSError *error){
/// your code
}];
/// add the task to our arrayOfTasks
[self.arrayOfTasks addObject:task];
}
return YES;
}
我有一个文本字段,每当用户输入字符时,我都会将该字符附加到我的 url 并获得响应。 我需要取消之前的请求。 例如,如果我输入 "shampoo" 我将访问服务器 7 次,我需要取消最后 6 个请求。 目前我正在使用 [manager.operationQueue cancelAllOperations]; 但是有些方法对我不起作用。可能是我没放对吧。
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
{
//[self.s_searchResultText setHidden:YES];
// [SVProgressHUD dismiss];
[self.s_tableView setHidden:true];
[searchProductArray removeAllObjects];
[self.s_tableView reloadData];
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:UNACCEPTABLE_CHARACTERS] invertedSet];
NSLog(@"%@",cs);
NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
NSLog(@"%@",filtered);
NSLog(@"%lu",(unsigned long)filtered.length);
if (filtered.length) {
[CustomToastAlert showToastInParentView:self.view withText:@"Please enter valid characters" withDuaration:1.5];
return NO;
}
searchTextString = [textField.text stringByAppendingString:string];
NSLog(@"%lu",(unsigned long)[searchTextString length]);
NSLog(@"%@",searchTextString);
int stringLength=[searchTextString length];
const char * _char = [string cStringUsingEncoding:NSUTF8StringEncoding];
int isBackSpace = strcmp(_char, "\b");
if (isBackSpace == -8) {
stringLength=[searchTextString length];
stringLength=[searchTextString length]-1;
searchTextString=[searchTextString substringToIndex:stringLength];
NSLog(@"Backspace was pressed");
NSLog(@"string is %@",searchTextString);
}
if(stringLength>=3)
{
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] init];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
NSString *urlString=[NSString stringWithFormat:kSearchProductUrl,kBaseUrl];
urlString = [urlString stringByAppendingString:searchTextString];
urlString = [urlString stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
NSLog(@"%@",searchTextString);
NSLog(@"%@",urlString);
[searchProductArray removeAllObjects];
// [manager invalidateSessionCancelingTasks:NO];
//[manager.operationQueue cancelAllOperations];
[manager GET:urlString parameters:nil success:^(NSURLSessionDataTask *task, id responseObject)
{
[searchProductArray removeAllObjects];
//[SVProgressHUD showWithStatus:LOADING_ITEMS maskType:SVProgressHUDMaskTypeGradient];
NSLog(@"JSON: %@", responseObject);
json= responseObject;
NSLog(@"%@",json);
NSLog(@"%lu",(unsigned long)[[json valueForKeyPath:@"data"] count ]);
for(int i=0;i<[[json valueForKeyPath:@"data"]count ];i++)
{
Product *s_productList=[[Product alloc]init];
s_productList.SKU_Name=[[json valueForKeyPath:@"data.sku_name"]objectAtIndex:i];
s_productList.SKU_Id=[[json valueForKeyPath:@"data.sku_id"]objectAtIndex:i];
s_productList.SKU_Price=[[json valueForKeyPath:@"data.sku_price"]objectAtIndex:i];
s_productList.SKU_OfferPrice=[[json valueForKeyPath:@"data.sku_offer_price"]objectAtIndex:i];
s_productList.SKU_Currency = RUPEE_SYMBOL;
s_productList.SKU_AvailableUnit=[[json valueForKeyPath:@"data.sku_available_unit"]objectAtIndex:i];
s_productList.SKU_OfferDescription= [[json valueForKeyPath:@"data.sku_offer_desc"]objectAtIndex:i];
s_productList.SKU_ImageUrls=[[json valueForKeyPath:@"data.sku_image_urls"]objectAtIndex:i];
[searchProductArray addObject:s_productList];
NSLog(@"%lu",(unsigned long)[searchProductArray count]);
}
[self.s_tableView setHidden:FALSE];
[self.s_tableView reloadData];
NSLog(@"%lu",(unsigned long)[searchProductArray count]);
if ([searchProductArray count]==0) {
[CustomToastAlert showToastInParentView:self.view withText:SEARCH_RESULT withDuaration:1.5];
}
}
failure:^(NSURLSessionDataTask *task, NSError *error)
{
[CustomToastAlert showToastInParentView:self.view withText:NO_DATA_AVAIL withDuaration:1.5];
}];
}
return YES;
}
我不确定您的 class 是如何工作的,但我注意到每次 textField 文本更改时您都在初始化一个新的 AFHTTPSessionManager 对象
所以这是我对这个问题的建议。
// somewhere in your class, let's say in ViewDidLoad you should init the AFHTTPSessionManager object
- (void)viewDidLoad {
[super viewDidLoad];
/// create the AFHTTPSessionManager object, we're gonna use it in every request
self.manager = [[AFHTTPSessionManager alloc] init];
self.manager.responseSerializer = [AFJSONResponseSerializer serializer];
/// create an array that is going to hold the requests task we've sent to the server. so we can get back to them later
self.arrayOfTasks = [NSMutableArray new];
/// discussion:
/// an array holds multiple objects. if you just want to hold a ref to the latest task object
/// then create a property of NSURLSessionDataTask instead of NSMutableArray, and let it point to the latest NSURLSessionDataTask object you create
}
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;{
/// your code goes here
/// .....
/// .....
/// .....
/// .....
/// till we reach
if(stringLength>=3){
/// cancel all previous tasks
[self.arrayOfTasks enumerateObjectsUsingBlock:^(NSURLSessionDataTask *taskObj, NSUInteger idx, BOOL *stop) {
[taskObj cancel]; /// when sending cancel to the task failure: block is going to be called
}];
/// empty the arraOfTasks
[self.arrayOfTasks removeAllObjects];
/// init new task
NSURLSessionDataTask *task = [self.manager GET:urlString parameters:nil success:^(NSURLSessionDataTask *task, id responseObject){
/// your code
}failure:^(NSURLSessionDataTask *task, NSError *error){
/// your code
}];
/// add the task to our arrayOfTasks
[self.arrayOfTasks addObject:task];
}
return YES;
}