使用新的NSURLSession,现在在用于创建会话的NSURLSessionConfiguration对象上有一个timeoutIntervalForRequest。
但NSURLRequest对象上仍有一个timeoutInterval,可用于在会话中创建NSURLSessionTask。
我的问题是,如果配置的timeoutIntervalForRequest设置为30,但NSURLRequest用来创建任务的timeoutInterval是60,实际上会使用哪个超时间隔?
答案 0 :(得分:18)
根据我对iOS 7.0.3的调查,timeoutInterval
的{{1}}与NSURLRequest
一起使用时不会产生任何影响。
无论您是否为NSURLSession
设置timeoutIntervalForRequest
,都会忽略NSURLSessionConfiguration
。
您可以使用我的小样本应用程序NetworkTimeoutSample来检查此行为。
当您为'URLReq'字段设置1时,这会影响timeoutInterval
timeoutInterval
,然后点击'NSURLSession With URLRequest'按钮,您的会话将不会出现超时错误。
如果您希望对NSURLRequest
的{{1}}获得相同的超时效果,您也可能会认识到应该设置timeoutIntervalForResource
而不是timeoutIntervalForRequest
NSURLSession
}。
如果您为timeoutInterval
设置NSURLRequest
和timeoutIntervalForRequest
值,则会影响较小的值(我觉得此行为与当前的API文档不同)。
没有关于这些规范的文档,因此可能会在未来的iOS版本中进行更改。
答案 1 :(得分:5)
Since iOS8, the NSUrlSession in background mode does not call this delegate method if the server does not respond. -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
The download/upload remains idle indefinitely. This delegate is called on iOS7 with an error when the server does not respond.
In general, an NSURLSession background session does not fail a task if something goes wrong on the wire. Rather, it continues looking for a good time to run the request and retries at that time. This continues until the resource timeout expires (that is, the value of the timeoutIntervalForResource property in the NSURLSessionConfiguration object you use to create the session). The current default for that value is one week! In other words, the behaviour of failing for a timeout in iOS7 was incorrect. In the context of a background session, it is more interesting to not fail immediately because of network problems. So since iOS8, NSURLSession task continues even if it encounters timeouts and network loss. It continues however until timeoutIntervalForResource is reached.
So basically timeoutIntervalForRequest won't work in Background session but timeoutIntervalForResource will.
I got this answer from one of the members of Apple Staff at the developer forum. Also, I have verified this by implementing.
答案 2 :(得分:2)
自从n-miyo测试以来,事情发生了变化。
apple documentation表示NSURLRequest值将覆盖会话配置。
在某些情况下,此配置中定义的策略可能会被为任务提供的NSURLRequest对象指定的策略覆盖。除非会话的策略更具限制性,否则将遵守在请求对象上指定的任何策略。例如,如果会话配置指定不允许蜂窝网络,则NSURLRequest对象不能请求蜂窝网络。
答案 3 :(得分:0)
NSURLSession
提供两个超时,timeoutIntervalForRequest
和timeoutIntervalForResource
。
timeoutIntervalForRequest
由计时器强制执行,每次传输数据时都会重置该计时器。因此,如果将此超时设置为30秒,并且每30秒传输至少一个字节的数据,则永远不会发生超时。只有在30秒钟内绝对没有数据传输时,超时才会达到。您也可以说这是会话任务的最大空闲时间。默认值为60秒。
timeoutIntervalForResource
由永远不会重置的计时器强制执行。它在启动会话任务时启动,在会话任务停止或完成时停止。因此,这是会话任务最多可以花费的总时间,这就是大多数人在听到“超时”时所想到的。由于会话任务也可能是通过非常慢的Internet链接下载了100 GB的文件,因此此处的默认值为7天!
NSURLRequest
(及其可变子类)仅提供一个属性timeoutInterval
。正如timeoutIntervalForRequest
的文档所述,此超时值的行为类似于NSURLRequest
:
如果在尝试连接期间,请求保持空闲状态 超过超时间隔,则认为该请求 超时了。
来源:timeoutInterval - NSURLRequest | Apple Developer Documentation
NSURLSession
的文档中说:
注意
在某些情况下,此配置中定义的策略可能是 被提供的NSURLRequest对象指定的策略覆盖 完成一项任务。遵守在请求对象上指定的任何策略 除非会议的政策更具限制性。
来源:NSURLSessionConfiguration - Foundation | Apple Developer Documentation
因此,timeoutInterval
的{{1}}将覆盖NSURLRequest
的{{1}},但前提是系统认为它“更具限制性”,否则值timeoutIntervalForRequest
将获胜。