Ios8 错误域=NSURLErrorDomain代码=-1005“;网络连接已断开。”;
我有一个应用程序,它在使用iOS7和iOS8的Xcode6-Beta1和Xcode6-Beta2上运行良好。但是对于Xcode6-Beta3、Beta4、Beta5,我面临iOS8的网络问题,但在iOS7上一切都正常。我收到错误信息“网络连接丢失。”。错误如下: 错误:Error Domain=NSURErrorDomain Code=-1005“网络连接已丢失。”UserInfo=0x7ba8e5b0{NSErrorFailingURLStringKey=,_kCFStreamErrorCodeKey=57,NSErrorFailingURLKey=,NSLocalizedDescription=网络连接已丢失。,_kCFStreamErrorDomainKey=1,NSUnderlyingError=0x7a6957e0“网络连接已丢失”。} 我使用AFNetworking 2.x和以下代码片段进行网络调用:Ios8 错误域=NSURLErrorDomain代码=-1005“;网络连接已断开。”;,ios8,ios-simulator,xcode6,xcode6-beta5,Ios8,Ios Simulator,Xcode6,Xcode6 Beta5,我有一个应用程序,它在使用iOS7和iOS8的Xcode6-Beta1和Xcode6-Beta2上运行良好。但是对于Xcode6-Beta3、Beta4、Beta5,我面临iOS8的网络问题,但在iOS7上一切都正常。我收到错误信息“网络连接丢失。”。错误如下: 错误:Error Domain=NSURErrorDomain Code=-1005“网络连接已丢失。”UserInfo=0x7ba8e5b0{NSErrorFailingURLStringKey=,_kCFStreamErrorCod
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);
}];
AFHTTPRequestOperationManager*manager=[AFHTTPRequestOperationManager];
[经理设置安全策略:策略];
manager.requestSerializer=[AFHTTPRequestSerializer序列化程序];
manager.responseSerializer=[AFHTTPResponseSerializer序列化程序];
[经理职位:
参数:
成功:^(AFHTTPRequestOperation*操作,id响应对象){
NSLog(@“成功:%@”,响应对象);
}失败:^(AFHTTPRequestOperation*操作,NSError*错误){
NSLog(@“错误:%@”,错误);
}];
我尝试了
NSURLSession
,但仍然收到相同的错误。在iOS 8模拟器上运行beta 5和AFNetworking 1.3时也出现问题,导致连接错误:
Domain=nsurErrorDomain Code=-1005“网络连接已断开。”
同样的代码在iOS 7和7.1模拟器上运行良好,我的调试代理显示故障发生在实际尝试连接之前(即没有记录任何请求)
我已经跟踪了NSURLConnection的失败,并向苹果公司报告了错误。请参见附图中的第5行:
更改为使用https
允许从iOS 8模拟器进行连接,尽管存在间歇性错误
Xcode 6.01(gm)中仍然存在问题。重新启动模拟器为我解决了问题。我必须退出Xcode,删除DerivedData文件夹内容(~/Library/Developer/Xcode/DerivedData或/Library/Developer/Xcode/DerivedData)然后退出模拟器以使其工作。我们遇到了这个确切的错误,结果证明它是
NSURLRequest的底层HTTP实现的一个问题:
据我们所知,当iOS 8/9/10/11接收到带有保持活动头的HTTP响应时,它会保持此连接以供以后重新使用(应该如此),但其保持时间超过保持活动头的timeout
参数(似乎总是保持连接活动30秒)
然后,当应用程序在不到30秒后发送第二个请求时,它会尝试重新使用可能已被服务器断开的连接(如果超过了真正的保持活动时间)
以下是我们迄今为止找到的解决方案:
- 将服务器的超时参数增加到30秒以上。看起来iOS总是表现得好像服务器将保持连接打开30秒,而不管keep Alive标头中提供的值如何。(这可以通过设置
KeepAliveTimeout
选项为Apache完成
- 您可以简单地根据应用程序的用户代理禁用iOS客户端的保持活动机制(例如,对于Apache:
BrowserMatch“iOS 8\”nokeepalive
,位于mod文件setenif.conf
)
- 如果您没有访问服务器的权限,可以尝试使用
连接:close
标头发送请求:这将告诉服务器立即断开连接并在没有任何保持活动标头的情况下响应。但目前,在发送请求时,NSURLSession似乎会覆盖连接
标头(我们没有对该解决方案进行广泛测试,因为我们可以调整Apache配置)
对我来说,开放解决了这个问题,这似乎很奇怪
Charles是HTTP proxy/HTTP monitor/Reverse proxy,允许开发人员查看其计算机与Internet之间的所有HTTP和SSL/HTTPS通信。这包括请求、响应和HTTP头(其中包含cookie和缓存信息)
iOS 8.0模拟器运行时存在一个错误,如果在启动模拟设备时网络配置发生变化,则会出现更高级别的API(例如:CFNetwork)在模拟运行时,您会认为它已失去网络连接。目前,建议的解决方法是在网络配置更改时简单地重新启动模拟设备
如果您受到此问题的影响,请在提交其他重复雷达,以提高优先级
如果您在没有更改网络配置的情况下看到此问题,则这不是已知的错误,您应该明确地提交雷达,表明此问题不是已知的网络配置更改错误。我也有此问题,在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
子类,但添加了您自己的请求代码
if (error.code == -1005)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
dispatch_group_t downloadGroup = dispatch_group_create();
dispatch_group_enter(downloadGroup);
dispatch_group_wait(downloadGroup, dispatch_time(DISPATCH_TIME_NOW, 5000000000)); // Wait 5 seconds before trying again.
dispatch_group_leave(downloadGroup);
dispatch_async(dispatch_get_main_queue(), ^{
//Main Queue stuff here
[self redoRequest]; //Redo the function that made the Request.
});
});
return;
}
-(id) connectionSitePost:(NSString *) postSender Url:(NSString *) URL {
// here set NSMutableURLRequest => Request
NSHTTPURLResponse *UrlResponse = nil;
NSData *ResponseData = [[NSData alloc] init];
ResponseData = [NSURLConnection sendSynchronousRequest:Request returningResponse:&UrlResponse error:&ErrorReturn];
if ([UrlResponse statusCode] != 200) {
if ([UrlResponse statusCode] == 0) {
/**** here re-use method ****/
return [self connectionSitePost: postSender Url: URL];
}
} else {
return ResponseData;
}
}
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlComponents.URL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlComponents.URL];
[request setHTTPMethod:@"PUT"];
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...
}
}];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
config.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
config.URLCache = nil;
self.session = [NSURLSession sessionWithConfiguration:config];