标签: urlsession

对于iOS 11中的任务,HTTP加载失败(错误代码:-999 [1:89])

我正在使用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)

有什么想法导致它,或如何解决它?

ios swift urlsession ios11

36
推荐指数
1
解决办法
2万
查看次数

如何使用新的 try wait URLSession.shared.download(...) 获取下载进度

苹果刚刚引入了 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 能够调用此函数,但它永远不会被调用,并且文件仍然可以愉快地下载。但我需要进度,请问如何获得?

progress async-await swift urlsession

22
推荐指数
2
解决办法
5615
查看次数

Swift从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返回语句.在这一点上,我很无能为力......

httprequest ios swift3 urlsession

10
推荐指数
2
解决办法
1万
查看次数

URLSession 缓存未按记录工作 - 我做错了什么?

根据文档,如果使用默认值,useProtocolCachePolicy逻辑如下:

  1. 如果该请求不存在缓存的响应,则 URL 加载系统将从原始源获取数据。
  2. 否则,如果缓存的响应没有指示每次都必须重新验证,并且缓存的响应不是过时的(超过其过期日期),则 URL 加载系统将返回缓存的响应。
  3. 如果缓存的响应已过时或需要重新验证,则 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

仅使用reloadRevalidatingCacheDataURLSessionConfiguration

如果我只 …

caching ios swift urlsession

10
推荐指数
1
解决办法
1151
查看次数

TIC TCP Conn失败

我用来获取.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)

ios swift urlsession urlsessiontask

9
推荐指数
0
解决办法
8931
查看次数

获得 401 响应代码并重试请求后,使用 URLSession 刷新访问令牌

我正在为使用 OAuth 2.0 授权技术 ( Access& Refresh Token) 的iOS 应用程序构建网络客户端。我一直在努力实现我的网络客户端的一项功能:

  • 当一个401错误出现时即表示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 swift urlsession

9
推荐指数
1
解决办法
1094
查看次数

如何为 WidgetKit 异步下载图像

我正在为 iOS 开发小部件,但我真的不知道如何为小部件下载图像。

小部件当前下载一组对象,每个对象都有一个图像的 URL。这个想法是每个对象都SimpleEntryTimeline.

实现这一目标的最佳方法是什么?我读到 Widgets 不应该使用ObservableObject. 我在时间线提供程序中获取了一组对象,这似乎是 Apple 推荐的。但是我是否也在那里下载图像并等待所有完成后发送时间线?

任何建议都会非常有帮助,

ios widgetkit urlsession swiftui

9
推荐指数
1
解决办法
2712
查看次数

尽管现代并发向后兼容,为什么我会看到有关“data(for:delegate:) is only available on iOS 15.0+”的错误

现代并发性Async / Await是通过 Swift 5.5 为 iOS 15 及更高版本引入的,但很快,随着 Xcode 13.2(以及随后的 13.2.1)的发布,它使我们能够使用AsyncAwait开发 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+ 有何意义?

concurrency xcode ios swift urlsession

9
推荐指数
1
解决办法
2853
查看次数

取消异步/等待网络请求

我有一个网络层,当前使用完成处理程序来传递操作完成的结果。

由于我支持多个 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)

ios async-await swift urlsession

8
推荐指数
1
解决办法
8032
查看次数

将 URLCache 子类与 URLSession 结合使用

我有一个应用程序,它使用URLSession基于网络的网络并将URLCache网络请求存储在磁盘上。我注意到,当 的存储大小URLCache达到 时diskCapacity,逐出策略似乎是删除所有条目,这在我的用例中是一个问题。因此,我决定编写一个URLCache子类,该子类将为缓存响应提供自定义存储,并通过更好的控制来实现 LRU 驱逐策略。

正如 URLCache 的文档所述,应该支持用于此目的的子类化:

URLCache 类应按原样使用,但当您有特定需要时,您可以对其进行子类化。例如,您可能想要筛选缓存了哪些响应,或者出于安全或其他原因重新实现存储机制。

URLCache然而,我在尝试将这个新子类与网络一起使用时遇到了问题URLSession

我有一个使用 获取的测试资源HTTP GET。响应标头包含:

  • Cache-Control: public, max-age=30
  • Etag: <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)

caching ios swift urlsession urlcache

8
推荐指数
1
解决办法
362
查看次数