开发者

How to re-send/re-queue failed requests with ASIHTTP?

开发者 https://www.devze.com 2023-03-09 13:09 出处:网络
I\'m trying to implement a queuing system for sending stuff to a webservice in an iphone app. The code works, but if the connection fails due to network errors etc, the request is thrown away.

I'm trying to implement a queuing system for sending stuff to a webservice in an iphone app. The code works, but if the connection fails due to network errors etc, the request is thrown away.

I would like my app to re-queue that request, instead of just deleting it, but I cannot figure out a way to do it? I've tried doing this:

(void)requestWentWrong:(ASIHTTPRequest *)request
{
NSError *error = [request error];
NSLog(@"Error: %@",error);

//Re-queue the request
[[self queue] addOperation:request];
}

But that just gives me an error saying:

Terminating app due to uncaught exception 'NSInvalidArg开发者_运维知识库umentException', reason: '***      -[ASINetworkQueue addOperation:]: operation is finished and cannot be enqueued'

What am I doing wrong here?


I have a setup like this as well. I have a background thread that polls my server every 30 seconds or so. If it ever fails to connect, it sets "isOnline" to false. All my requests check if to make sure there is a network connection, and if any request fails to reach the server, the network connection is deemed to have been lost.

// Create operation...
[networkQueue addOperation:theOperation];
if( isOnline == YES )
    [networkQueue go];
else:
    [displayAlert message:@"The operation is waiting for a connection"];

When I determine the connection is back, my background thread does this:

-(void)setIsOnline:(BOOL)val {
    if( isOnline == NO && val == YES ) {
        [networkQueue go];
    }

    isOnline = val;
 }

The hard part was the requestDidFail method, where you do have to re-create the queue, or you lose the operation that first found the bad network connection. This is what my method looks like:

-(void)requestDidFail:(ASIHTTPRequest*)aRequest {
       // If we find that the network is down, recreate the queue and
       // add our operation to it in suspended mode.
       if( [aRequest.error code] == ASIConnectionFailureErrorType ) {
           isOnline = NO;
           [networkQueue setSuspended:YES];
           [networkQueue cancelAllOperations];
           self.networkQueue = nil;

           ASINetworkQueue *aQueue = [[ASINetworkQueue alloc] init];
           self.networkQueue = aQueue;
           [networkQueue setDelegate:self];
           [aQueue release];
       }

       // Don't add any cancelled requests back into the queue
       if( [aRequest.error code] != ASIRequestCancelledErrorType ) {
           [networkQueue addOperation:[aRequest copy]];
       }

    }

Now you will start queueing requests when the device is offline. Once that background thread sees a network connection, the queue starts processing and everything goes through.

There is more error checking that will be needed of course, but hopefully this will be a good starting point.


I encountered the same problem. You can simply copy the request:

[[self queue] addOperation:[request copy]];

Not sure what memory management says to what I'm doing here...


Just a guess: perhaps operations can't be queued multiple times, and have to be re-created?

0

精彩评论

暂无评论...
验证码 换一张
取 消