我正在构建一个 iOS 应用程序,需要经常检查服务器上 JSON 文件的更改。在这样做的过程中,我发现了缓存的一个怪癖。当我开始工作时,我的服务器目前正在运行一个非常基本的 http-server。
当我意识到缓存阻止我的客户编写时,我首先编写了代码:
let urlSession = URLSession(configuration: .ephemeral)
func updateModel() {
let (data, _) = try await urlSession.data(from: URL(string: myURLString)!)
// Do something with the data
}
这是在 Apple 开发者论坛中建议的。
这不起作用,所以我进一步尝试了这个
let urlSession = {
var session = URLSession(configuration: .ephemeral)
session.configuration.urlCache = nil
session.configuration.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData
return session
}()
func updateModel() {
let (data, _) = try await urlSession.data(from: URL(string: myURLString)!)
// Do something with the data
}
此方法是在 Stack Overflow 答案中建议的。值得注意的是,评论中的人们提到这对他们不起作用,或者他们需要打电话URLCache.shared.removeAllCachedResponses()
,这并不理想。我不想打这个电话,而且这段代码对我不起作用,所以我做了一些更重的事情。
let urlSession = {
var session = URLSession(configuration: .ephemeral)
session.configuration.urlCache = nil
session.configuration.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData
return session
}()
func updateModel() {
let request = URLRequest(url: URL(string: myURLString)!, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData)
let (data, _) = try await urlSession.data(for: request)
// Do something with the data
}
我不知道我到底从哪里得到尝试的想法。所以我来客。耶!有用。但同时……为什么这一切都是必要的?为什么我需要在 URLSession 和 URLRequest 级别取消缓存?这是否与我使用字符串 URL 有关,也许是我的服务器出售资源的方式,也许是 iOS 17,我出售的内容类型。我想了解更多。
extension URLSession {
public func data(for request: URLRequest, delegate: (URLSessionTaskDelegate)? = nil) async throws -> (Data, URLResponse)
public func data(from url: URL, delegate: (URLSessionTaskDelegate)? = nil) async throws -> (Data, URLResponse)
}
public struct URLRequest : ReferenceConvertible, Equatable, Hashable, Sendable {
public init(url: URL, cachePolicy: URLRequest.CachePolicy = .useProtocolCachePolicy, timeoutInterval: TimeInterval = 60.0)
}
对于URLSession
的第二个函数,它的实现可能是
public func data(from url: URL, delegate: (URLSessionTaskDelegate)? = nil) async throws -> (Data, URLResponse) {
let request = URLRequest(url: url)
return self.data(from: request)
}
你猜怎么着? URLRequest
的
cachePolicy
默认设置为 useProtocolCachePolicy。这就是你的问题所在。