我有一个应用程序,可以在Xcode6-Beta1和Xcode6-Beta2与iOS7和iOS8上正常工作。但是对于Xcode6-Beta3, Beta4, Beta5,我在iOS8上面临网络问题,但在iOS7上一切都很好。我得到错误“网络连接丢失”。错误如下:

Error: ErrorDomain =NSURLErrorDomain Code=-1005 "The network connection was lost."UserInfo=0x7ba8e5b0 {NSErrorFailingURLStringKey=, _kCFStreamErrorCodeKey=57, NSErrorFailingURLKey=, NSLocalizedDescription=网络连接丢失。, _kCFStreamErrorDomainKey=1, NSUnderlyingError=0x7a6957e0 "The network connection was lost."}

我使用AFNetworking 2。X和下面的代码片段进行网络调用:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager setSecurityPolicy:policy];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];

[manager POST:<example-url>
   parameters:<parameteres>
      success:^(AFHTTPRequestOperation *operation, id responseObject) {
          NSLog(@“Success: %@", responseObject);
      } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
          NSLog(@"Error: %@", error);
      }];

我尝试了NSURLSession,但仍然收到相同的错误。


当前回答

2017年1月25日,苹果发布了一份关于此错误的技术问答:

Apple Technical Q&A QA1941 Handling “The network connection was lost” Errors A: NSURLErrorNetworkConnectionLost is error -1005 in the NSURLErrorDomain error domain, and is displayed to users as “The network connection was lost”. This error means that the underlying TCP connection that’s carrying the HTTP request disconnected while the HTTP request was in progress (see below for more information about this). In some circumstances NSURLSession may retry such requests automatically (specifically, if the request is idempotent) but in other circumstances that’s not allowed by the HTTP standards. https://developer.apple.com/library/archive/qa/qa1941/_index.html#//apple_ref/doc/uid/DTS40017602

其他回答

我也有同样的问题,问题是Alomofire和NSUrlSession的bug。当你从safari或电子邮件返回到应用程序时,你需要等待近2秒才能通过Alamofire进行网络响应

 DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
       Your network response
}

我在iOS 8设备上运行时也遇到了这个问题。 这里有更详细的说明,似乎是iOS试图使用已经超时的连接。 我的问题与那个链接中解释的Keep-Alive问题不一样,但它似乎是相同的最终结果。

我已经通过运行一个递归块纠正了我的问题,每当我收到一个错误-1005,这使得连接最终通过,即使有时递归可以在连接工作之前循环100+次,然而,它只增加了一秒钟的运行时间,我打赌这只是需要调试器为我打印NSLog的时间。

下面是我如何用AFNetworking运行递归块: 将此代码添加到连接类文件中

// 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); };
}

然后这样使用它:

+ (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);
}

您将看到我使用了一个AFHTTPRequestOperation子类,但添加了您自己的请求代码。重要的部分是调用递归(@offset.intValue+1));使该块再次被调用。

I was getting this error as well, but on actual devices rather than the simulator. We noticed the error when accessing our heroku backend on HTTPS (gunicorn server), and doing POSTS with large bodys (anything over 64Kb). We use HTTP Basic Auth for authentication, and noticed the error was resolved by NOT using the didReceiveChallenge: delegate method on NSURLSession, but rather baking in the Authentication into the original request header via adding Authentiation: Basic <Base64Encoded UserName:Password>. This prevents the necessary 401 to trigger the didReceiveChallenge: delegate message, and the subsequent network connection lost.

我的问题在服务器上。我正在使用Python的BaseHTTPRequestHandler类,我没有在响应中发送正文。当我像下面这样放一个空身体时,我的问题就解决了。

def do_POST(self):
    content_len = int(self.headers.get('Content-Length'))
    post_body = self.rfile.read(content_len)
    msg_string = post_body.decode("utf-8")
    msg_json = json.loads(msg_string)
    self.send_response(200)
    self.end_headers() #this and the following lines were missing
    self.wfile.write(b'') 

无论何时得到错误-1005,然后需要再次调用API。

AFHTTPRequestOperationManager *manager = 
[AFHTTPRequestOperationManager manager];
[manager setSecurityPolicy:policy];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];

[manager POST:<example-url>
   parameters:<parameteres>
    success:^(AFHTTPRequestOperation *operation, id responseObject) {
      NSLog(@“Success: %@", responseObject);
  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
      NSLog(@"Error: %@", error);
      if (error.code == -1005) {
          // Call method again... 
       }
  }];

您需要再次添加调用函数的代码。确保你是调用方法一次,否则它的调用循环递归。