我正在使用URLSession来执行数据任务,当我在iOS 11上运行它时,我收到一个控制台错误:
HTTP load failed (error code: -999 [1:89]) for Task <68809C58-C6A7-4F10-86A4-81396D8B18CF>.<2>
Run Code Online (Sandbox Code Playgroud)
有什么想法导致它,或如何解决它?
苹果刚刚引入了 async/await 和一堆Foundation使用它们的函数。我正在使用新的异步/等待模式下载文件,但我似乎无法获取下载进度。
(downloadedURL, response) = try await URLSession.shared.download(for: dataRequest, delegate: self) as (URL, URLResponse)
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,有一个委托,我尝试使我的类符合并URLSessionDownloadDelegate实现该urlSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:) 函数,但它从未被调用。
我还尝试创建一个新的 URLSession 并将其委托设置为同一个类,希望 URLSession 能够调用此函数,但它永远不会被调用,并且文件仍然可以愉快地下载。但我需要进度,请问如何获得?
我无法从HTTPrequest返回数据,也无法使完成处理程序工作.所以请帮助我解决这个问题:
public static func createRequest(qMes: message, location: String, method: String) -> String{
let requestURL = URL(string: location)
var request = URLRequest(url: requestURL!)
request.httpMethod = method
request.httpBody = qMes.toString().data(using: .utf8)
let requestTask = URLSession.shared.dataTask(with: request) {
(data: Data?, response: URLResponse?, error: Error?) in
if(error != nil) {
print("Error: \(error)")
}
return String(data: data!, encoding: String.Encoding.utf8) as String!
}
requestTask.resume()
}
Run Code Online (Sandbox Code Playgroud)
它在void函数中检测非void返回语句.在这一点上,我很无能为力......
根据文档,如果使用默认值,useProtocolCachePolicy逻辑如下:
- 如果该请求不存在缓存的响应,则 URL 加载系统将从原始源获取数据。
- 否则,如果缓存的响应没有指示每次都必须重新验证,并且缓存的响应不是过时的(超过其过期日期),则 URL 加载系统将返回缓存的响应。
- 如果缓存的响应已过时或需要重新验证,则 URL 加载系统会向原始源发出 HEAD 请求,以查看资源是否已更改。如果是,则 URL 加载系统从原始源获取数据。否则,它返回缓存的响应。
然而,我的实验(见下文)表明这是完全错误的。即使响应被缓存,它也永远不会被使用,也不会发出HEAD任何请求。
我正在向一个返回的 URL 发出请求,ETag并且Last-Modified标头永远不会改变。我至少发出过一次请求,因此响应已被缓存(我可以通过查看 iOS 模拟器上应用程序的缓存数据库来验证这一点)
useProtocolCachePolicy(默认)如果我将URLSessionwith设置为URLSessionConfiguration,则响应将被缓存(我可以在缓存数据库中看到它),但缓存的响应永远不会被使用。对同一 URL 的重复请求始终会发出不带或标头的新请求,因此服务器始终返回 HTTP 200 和完整响应。缓存的响应将被忽略。requestCachePolicyuseProtocolCachePolicyGET If-None-MatchIf-Modified-Since
reloadRevalidatingCacheData每个URLRequest如果我将每个cachePolicy设置为,那么我会看到缓存正在运行。每次发出请求时,都会发出请求,并将和标头分别设置为缓存响应的和标头的值。由于没有任何变化,服务器以 进行响应,并将本地缓存的响应返回给调用者。 URLRequestreloadRevalidatingCacheDataGETIf-None-MatchIf-Modified-SinceETagLast-Modified304 Not Modified
reloadRevalidatingCacheData在URLSessionConfiguration如果我只 …
我用来获取.mjpeg视频源的服务器中有些变化.
现在我收到这个错误:
TIC TCP Conn失败[5:0x1d4361380]:3:-9802 Err(-9802)
TIC TCP Conn失败[6:0x1c0177a00]:3:-9800 Err(-9800)
TIC TCP Conn失败[7:0x1d4361440]:3:-9800 Err(-9800)
NSURLSession/NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9800)
任务<2B8346B5-6BB2-4B92-B311-554410CBF92F>.<1> HTTP加载失败(错误代码:-1200 [3:-9800])
任务<2B8346B5-6BB2-4B92-B311-554410CBF92F>.<1>完成错误 - 代码:-1200
这是我收到错误的代码:
open func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
var credential: URLCredential?
var disposition: Foundation.URLSession.AuthChallengeDisposition = .useCredential
// Getting the authentication if stream asks it
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
if let trust = challenge.protectionSpace.serverTrust {
credential = URLCredential(trust: trust)
disposition = .useCredential
}
} else if let onAuthentication …Run Code Online (Sandbox Code Playgroud) 我正在为使用 OAuth 2.0 授权技术 ( Access& Refresh Token) 的iOS 应用程序构建网络客户端。我一直在努力实现我的网络客户端的一项功能:
Access Token已经过期,我需要发送Refresh Token到我的服务器,以获得新的Access Token。Access Token请求后,我需要重做之前出现 401 错误的请求。到目前为止,我已经为我的网络客户端编写了这段代码:
typealias NetworkCompletion = Result<(Data, URLResponse), FRNetworkingError>
/// I am using a custom result type to support just an Error and not a Type object for success
enum NetworkResponseResult<Error> {
case success
case failure(Error)
}
class FRNetworking: FRNetworkingProtocol {
fileprivate func handleNetworkResponse(_ response: HTTPURLResponse) -> NetworkResponseResult<Error> {
switch response.statusCode {
case 200...299: …Run Code Online (Sandbox Code Playgroud) 我正在为 iOS 开发小部件,但我真的不知道如何为小部件下载图像。
小部件当前下载一组对象,每个对象都有一个图像的 URL。这个想法是每个对象都SimpleEntry为Timeline.
实现这一目标的最佳方法是什么?我读到 Widgets 不应该使用ObservableObject. 我在时间线提供程序中获取了一组对象,这似乎是 Apple 推荐的。但是我是否也在那里下载图像并等待所有完成后发送时间线?
任何建议都会非常有帮助,
现代并发性Async / Await是通过 Swift 5.5 为 iOS 15 及更高版本引入的,但很快,随着 Xcode 13.2(以及随后的 13.2.1)的发布,它使我们能够使用Async和Await开发 iOS 13+、macOS 10.15+ 等。但是,当我尝试发出这样的异步请求时:
let (data, response) = try await URLSession.shared.data(for: request)
它不能在 iOS 13+ 上运行。相反,我收到一条错误消息:
data(for:delegate:)仅适用于 iOS 15.0 或更高版本
当我将最低部署目标设置为 iOS 15.0 时,该错误消失,但我希望该软件支持 iOS 13.0+。据我所知,data(for:delegate:)仅在 iOS 15.0+ 上受支持,但如果我无法发出异步网络获取请求,向后兼容 13.0+ 有何意义?
data(for:delegate:) 文档-> 其中规定最低 iOS 要求是 15.0
Xcode 发行说明-> 他们提到了在 15 之前将 Swift 并发功能部署到 iOS 的 clang bug 修复
我有一个网络层,当前使用完成处理程序来传递操作完成的结果。
由于我支持多个 iOS 版本,因此我在应用程序内扩展网络层以提供对合并的支持。我想将其扩展到现在也支持异步/等待,但我很难理解如何以允许我取消请求的方式实现这一点。
基本实现如下所示;
protocol HTTPClientTask {
func cancel()
}
protocol HTTPClient {
typealias Result = Swift.Result<(data: Data, response: HTTPURLResponse), Error>
@discardableResult
func dispatch(_ request: URLRequest, completion: @escaping (Result) -> Void) -> HTTPClientTask
}
final class URLSessionHTTPClient: HTTPClient {
private let session: URLSession
init(session: URLSession) {
self.session = session
}
func dispatch(_ request: URLRequest, completion: @escaping (HTTPClient.Result) -> Void) -> HTTPClientTask {
let task = session.dataTask(with: request) { data, response, error in
completion(Result {
if let error = error …Run Code Online (Sandbox Code Playgroud) 我有一个应用程序,它使用URLSession基于网络的网络并将URLCache网络请求存储在磁盘上。我注意到,当 的存储大小URLCache达到 时diskCapacity,逐出策略似乎是删除所有条目,这在我的用例中是一个问题。因此,我决定编写一个URLCache子类,该子类将为缓存响应提供自定义存储,并通过更好的控制来实现 LRU 驱逐策略。
正如 URLCache 的文档所述,应该支持用于此目的的子类化:
URLCache 类应按原样使用,但当您有特定需要时,您可以对其进行子类化。例如,您可能想要筛选缓存了哪些响应,或者出于安全或其他原因重新实现存储机制。
URLCache然而,我在尝试将这个新子类与网络一起使用时遇到了问题URLSession。
我有一个使用 获取的测试资源HTTP GET。响应标头包含:
Cache-Control: public, max-age=30Etag: <some-value>当使用标准的、非子类化的 时URLCache,第一个请求按预期从网络加载数据(使用 HTTP 代理验证)。如果按预期在前 30 秒内完成,第二个请求不会发送到网络。正如预期的那样,30 秒后的后续请求会导致GET带有 的条件Etag。
使用URLCache子类时,所有请求都会从网络加载数据 - max-age 似乎并不重要,并且不会进行任何条件 GET。
从内部存储加载实例后,似乎会对实例URLCache执行一些特殊操作,这会影响HTTP 缓存逻辑的处理方式。我在这里缺少什么?CachedURLResponseURLSession
我编写了一个非常小的URLCache子类实现来演示这个问题。此类使用/存储和加载CachedURLResponse实例,并且仅支持零个或一个响应。请注意,没有对 super 的调用 - 这是设计使然,因为我想使用自己的存储。NSKeyedArchiverNSKeyedUnarchiver
class CustomURLCache: URLCache {
let cachedResponseFileURL = URL(filePath: …Run Code Online (Sandbox Code Playgroud) urlsession ×10
ios ×9
swift ×8
async-await ×2
caching ×2
concurrency ×1
httprequest ×1
ios11 ×1
progress ×1
swift3 ×1
swiftui ×1
urlcache ×1
widgetkit ×1
xcode ×1