How do you cancel an HTTP request that has been sent before, if you encounter frequent HTTP requests in iOS development?

Source: Internet
Author: User

I have a textfield, whenever I enter a character, I appending this character to my URL, and then send a request to me now

A previous request needs to be canceled. For example, when I enter "shampoo", I will trigger 7 proxy methods, that is, I will trigger seven different networks please

Please, then there is a problem, these seven requests, the order of response is not the sequence you want to return, such as sending a 1234567, then return

The data is likely to be 1234576, which results in a "7" rather than a "6" result of the final need. So look how I solved it and met the pit ...


1. The first solution (failure)

[NSObject cancelpreviousperformrequestswithtarget:self]; I see this method, and the result of the final test is that it only cancels out the method that has not yet made the network request as follows

[Self performselector: @selector (Startsearchrefresh) Withobject:nil afterdelay:0.5];


Within 0.5 seconds of this delay, if I trigger the method again, the first method will cancel the method that was delay before and achieve the goal

But if in 0.5 seconds, the method has been HTTP request, already in the process of the request, this method is simply canceled.


Therefore, this method can be used for the user to quickly enter the time when the next operation overwrites the previous operation, for me or Failed method


2. The second solution (failure)

When I make a Web request,

[Manager.operationqueue cancelalloperations];

Get to the Afnetworking object, get its task queue, then cancel all previous tasks, I don't know if it's a version of the problem,

The latest AF (3.0) above seems to have no use, it may be my way of inserting a problem

Take a look at a foreigner's real Time search code snippet, did not cancel out

-(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=[[prod
                 UCT 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) {[Customtoastale
         RT ShowToastInParentView:self.view Withtext:no_data_avail withduaration:1.5];


    }];

return YES; }

3. The third solution, this is my final solution

The method was also found on the StackOverflow, it really killed me.

Take the code snippet above as an example, and that's how he does it.

The main essence is

1th: Do not initialize a new Afhttpsessionmanager object everytime must use the manager as a global

2nd: Throw the Task object returned by the request into the array, the next time the trigger is to iterate over the array, put all previous tasks [task Cancel]

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 it 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 are 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 Create}-(BOOL) TextField: (Uitextfield *) TextField Shouldchangecharactersinrange: (nsrange) Range replacementstring: (NSString *) string; {///Your code goes here///...///...///...///...///till we-if (stringlength>=3) {///Cancel all previous tasks [sel F.arrayoftasks enumerateobjectsusingblock:^ (nsurlsessiondatatask *taskobj, Nsuinteger idx, BOOL *stop) {[Task OBJ Cancel];

        When sending Cancel to the task Failure:block are going to be called}];

        Empty the Arraoftasks [Self.arrayoftasks removeallobjects]; Init new Task Nsurlsessiondatatask *task = [Self.manager get:urlstring parameters:nil success:^ (Nsurlsessionda 
           Tatask *task, id responseobject) {///Your code}failure:^ (nsurlsessiondatatask *task, Nserror *error) {

        Your code}];
    Add the task to our arrayoftasks [self.arrayoftasks addobject:task];
return YES; }

Note:

the task Cancel test here does cancel the network request, and you can look at the log below, and remember that this does not mean no callback after cancel .

, just will be back to the error of the block inside, you need information can be tested, in the error hit a breakpoint can be debugged out

View the status of a network task [Articleinterface.articlearraytask enumerateobjectsusingblock:^ (Nsurlsessiondatatask *taskObj, Nsuinteger idx, BOOL *stop) {ddlogverbose (@ "The status of the network task before deleting the current article is ==================>>>>>%ld",
    Taskobj.state); [Taskobj Cancel]; When sending Cancel to the task Failure:block are going to be called ddlogverbose (@ "The current article deleted after the network task status is ===============
===>>>>>%ld ", taskobj.state);
}]; typedef ns_enum (Nsinteger, nsurlsessiontaskstate) {nsurlsessiontaskstaterunning = 0,/* the task  is currently being serviced by the session * * nsurlsessiontaskstatesuspended = 1, nsurlsessiontaskstatecanceling =  2,/* The task has been told to cancel. The session would receive a URLSession:task:didCompleteWithError:message. * * nsurlsessiontaskstatecompleted = 3,/* The task has completed and the session'll receive no MOR e Delegate notifications */} ns_enum_available (Nsurlsession_available, 7_0); 


Print Log 2 Delegates here are nsurlsessiontaskstatecanceling




OK, perfect solution





Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.