在iOS 11.0中,NSMutableURLRequest的setTimeoutInterval属性无效。

8
我正在使用URL后台会话将pdf上传为数据流,使用iOS版本> 9.0。我设置了300秒的超时时间间隔,但根本不起作用。10秒后就会出现超时错误。
以下是代码片段。
  NSTimeInterval reqTimeInterval = 300.0f;

- (NSURLSession *)uploadSessionForMrNo:(NSString *)mrNo
                            userRoleId:(NSString *)userRoleId
                             timestamp:(NSString *)timestamp {

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    queue.maxConcurrentOperationCount = 4;

    NSString *backgroundSessionIdentifier = [NSString stringWithFormat:@"backgroundPdfUploadIdentifier_%@",mrNo];

    NSURLSessionConfiguration *backgroundSession = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:backgroundSessionIdentifier];
    backgroundSession.discretionary = true;

    NSURLSession *session = [NSURLSession sessionWithConfiguration:backgroundSession delegate:self delegateQueue:queue];

    [session setAccessibilityLabel:mrNo];
    [session setAccessibilityValue:userRoleId];
    [session setAccessibilityHint:timestamp];

    return session;
}


- (void)uploadPdfRequest:(NSURLRequest *)request
                 forMrNo:(NSString *)mrNo
              userRoleId:(NSString *)userRoleId
             andTimestamp:(NSString *)timestamp {

    NSURLSession *session = [self uploadSessionForMrNo:mrNo userRoleId:userRoleId timestamp:timestamp];
    NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request];
    NSLog(@"postDataTask %@ timeout %f",postDataTask,request.timeoutInterval);
    [postDataTask resume];
}

请求上传数据流。

NSMutableURLRequest *request = [[NSURLRequest requestForPDFStringUpload:uploadQueue.uploadData] mutableCopy];
[request setValue:[DataExchange authToken] forHTTPHeaderField:FBENCRYPT_TOKEN_KEY];
[request setCachePolicy:NSURLRequestUseProtocolCachePolicy];
[request setTimeoutInterval:reqTimeInterval];
[self uploadPdfRequest:request forMrNo:uploadQueue.mrNo userRoleId:uploadQueue.userRoleId andTimestamp:uploadQueue.timestamp];

委托

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error {

    if (error) {
        // Handle error
        NSLog(@"Error %@",error);
    }

    [session finishTasksAndInvalidate];
    self.receivedData = nil;
}

如果互联网正常工作,那就没问题,否则10秒后会出现错误。错误信息是Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSErrorFailingURLStringKey=http://test.mydomain.com/common.svc/json/FileUploadPDF, NSErrorFailingURLKey=http://test.mydomain.com/common.svc/json/FileUploadPDF, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2104, NSLocalizedDescription=The request timed out.}。
关于这个问题的更多细节:
我已经在ios 9.3模拟器中检查了我的代码,它等待连接出现,然后继续上传。我已经等待了4分钟,它可以正常工作。但是当我在ios 11.0.1上运行此代码时,10秒后就会超时。我需要额外做些什么才能解决呢?我也尝试过其他方法。
if ([backgroundSession respondsToSelector:@selector(setWaitsForConnectivity:)]) {
    [backgroundSession setWaitsForConnectivity:true];
}

但它没有任何效果。


您可以使用以下演示文件:

ViewController.h & .m


你可以直接将超时时间传递给会话配置,就像 session.timeoutIntervalForRequest = 30.0; session.timeoutIntervalForResource = 60.0; 这样。 - Prashant Tukadiya
根据我的想法,超时与互联网连接不可用没有任何关系。因为超时应该只在互联网工作时起作用,同时意味着请求无法完成! - Prashant Tukadiya
即使我没有提供超时时间,仍然会出现超时。 - Prince Kumar Sharma
根据 https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration/1408259-timeoutintervalforrequest ,默认值为60。 - Prashant Tukadiya
可能是一个蠢问题,但你尝试过重置你的模拟器(重置内容和设置),并/或者验证网络连接是否使用单一源吗?即严格使用WIFI。 - ChrisHaze
显示剩余9条评论
4个回答

3

@Warewolf我已经下载了你的.m文件并将其集成到我的演示项目中。

在Xcode 9.1和iOS 11.1上似乎都可以工作。

我能够在几秒钟内获得响应。

下面是你代码的输出。

response of background session --- {
    RestResponse =     {
        messages =         (
            "Total [249] records found."
        );
        result =         (
                        {
                "alpha2_code" = AF;
                "alpha3_code" = AFG;
                name = Afghanistan;
            },
                        {
                "alpha2_code" = AX;
                "alpha3_code" = ALA;
                name = "\Ufffd\Ufffdland Islands";
            },
                        {
                "alpha2_code" = AL;
                "alpha3_code" = ALB;
                name = Albania;
            },.....

@Warewolf 我已经设置了 NSTimeInterval reqTimeInterval = 10.0f;,它仍然可以正常工作并输出结果。 - Nirav Kotecha
我也能在几秒钟内得到响应,可能你还没有理解我的问题。关闭你的网络连接然后调用API。我的问题是为什么它不等待超过10秒。 - Prince Kumar Sharma
我已经关闭了网络连接,然后调用API。即使我设置了30秒,它默认需要60秒。 - Nirav Kotecha
你在尝试哪个iOS版本? - Prince Kumar Sharma
让我们在聊天中继续这个讨论 - Prince Kumar Sharma

0

我认为你应该将backgroundSession.timeoutIntervalForResource的值设置为大于reqTimeInterval。

NSURLSessionConfiguration *backgroundSession = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:backgroundSessionIdentifier];
backgroundSession.timeoutIntervalForRequest = reqTimeInterval;
backgroundSession.timeoutIntervalForResource = reqTimeInterval;

希望这能对你有所帮助。

我已经尽力尝试了一切,包括你的建议。如果你有iOS 11.0版本,请在关闭网络连接的情况下进行测试。 - Prince Kumar Sharma

0
情况1:我在调用本地服务器连接时遇到了这个错误。我在设备和手机上使用了不同的网络。当我将它们都连接到同一个WiFi时,它就可以工作了。
情况2:我遇到了Code=-1001“请求超时”的错误。我尝试了一些方法,但都没有起作用。最后我发现问题出在我发送到服务器的请求体参数中,格式有误(值是正确的,但类型有误)。这就是为什么请求超时,因为服务器无法处理它。如果其他方法都不起作用,您可以检查一下这个问题。
如果您还没有解决以上问题,请尝试使用GCD的抽象层,称为[NSURLConnection sendAsynchronousRequest:queue:completionHandler:

0

为后台会话设置timeoutIntervalForRequest属性。


请检查Agula Otgonbaatar的答案,它与之前的答案有何不同? - Prince Kumar Sharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接