Error Domain=NSURLErrorDomain Code=-1005 “The network connection was lost.”

前端 未结 30 3632
悲哀的现实
悲哀的现实 2020-11-22 05:51

I have an application which works fine on Xcode6-Beta1 and Xcode6-Beta2 with both iOS7 and iOS8. But with Xcode6-Beta3, Beta4, Beta5 I\'m facing network issues with iOS8 but

30条回答
  •  闹比i
    闹比i (楼主)
    2020-11-22 06:47

    I have this issue also, running on an iOS 8 device. It is detailed some more here and seems to be a case of iOS trying to use connections that have already timed out. My issue isn't the same as the Keep-Alive problem explained in that link, however it seems to be the same end result.

    I have corrected my problem by running a recursive block whenever I receive an error -1005 and this makes the connection eventually get through even though sometimes the recursion can loop for 100+ times before the connection works, however it only adds a mere second onto run times and I bet that is just the time it takes the debugger to print the NSLog's for me.

    Here's how I run a recursive block with AFNetworking: Add this code to your connection class file

    // From Mike Ash's recursive block fixed-point-combinator strategy https://gist.github.com/1254684
    dispatch_block_t recursiveBlockVehicle(void (^block)(dispatch_block_t recurse))
    {
        // assuming ARC, so no explicit copy
        return ^{ block(recursiveBlockVehicle(block)); };
    }
    typedef void (^OneParameterBlock)(id parameter);
    OneParameterBlock recursiveOneParameterBlockVehicle(void (^block)(OneParameterBlock recurse, id parameter))
    {
        return ^(id parameter){ block(recursiveOneParameterBlockVehicle(block), parameter); };
    }
    

    Then use it likes this:

    + (void)runOperationWithURLPath:(NSString *)urlPath
                andStringDataToSend:(NSString *)stringData
                        withTimeOut:(NSString *)timeOut
         completionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                            failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
    {
        OneParameterBlock run = recursiveOneParameterBlockVehicle(^(OneParameterBlock recurse, id parameter) {
            // Put the request operation here that you want to keep trying
            NSNumber *offset = parameter;
            NSLog(@"--------------- Attempt number: %@ ---------------", offset);
    
            MyAFHTTPRequestOperation *operation =
                [[MyAFHTTPRequestOperation alloc] initWithURLPath:urlPath
                andStringDataToSend:stringData
                withTimeOut:timeOut];
    
            [operation setCompletionBlockWithSuccess:
                ^(AFHTTPRequestOperation *operation, id responseObject) {
                    success(operation, responseObject);
                }
                failure:^(AFHTTPRequestOperation *operation2, NSError *error) {
                    if (error.code == -1005) {
                        if (offset.intValue >= numberOfRetryAttempts) {
                            // Tried too many times, so fail
                            NSLog(@"Error during connection: %@",error.description);
                            failure(operation2, error);
                        } else {
                            // Failed because of an iOS bug using timed out connections, so try again
                            recurse(@(offset.intValue+1));
                        }
                    } else {
                        NSLog(@"Error during connection: %@",error.description);
                        failure(operation2, error);
                    }
                }];
            [[NSOperationQueue mainQueue] addOperation:operation];
        });
        run(@0);
    }
    

    You'll see that I use a AFHTTPRequestOperation subclass but add your own request code. The important part is calling recurse(@offset.intValue+1)); to make the block be called again.

提交回复
热议问题