我有一个奇怪的错误,从那里突然出现。我差不多完成了我的应用程序,我正在测试它,然后我注意到数据没有更新。数据库得到更新,我可以直接点击url并看到正确地从服务器返回数据,但是当我在Swift中打印数据时,它不会改变。
一旦我重新运行应用程序,它将会改变(大部分时间)
我正在使用Alamofire,但我还尝试了其他两种方法:
let url = NSURL(string: "http://www.stackoverflow.com")
let request = NSURLRequest(URL: url!)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
和
let url = NSURL(string: "http://www.stackoverflow.com")
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
task.resume()
所有3个都打印出相同的数据。
我猜测它是Swift中的一个缓存问题,但是我没有设置任何东西来告诉Swift缓存数据,并且它在过去的几周内一直运行良好。
我今天唯一做的就是为我的项目做一个Git回购。
有没有人知道造成这种情况的原因是什么?
*编辑:
使用Abhi Beckert的回答我试过了:
符合代表NSURLConnectionDelegate
添加:
func connection(connection: NSURLConnection, willCacheResponse cachedResponse: NSCachedURLResponse) -> NSCachedURLResponse?
{
return nil // never cache anything. ever.
}
然后拨打电话:
let url:NSURL! = NSURL(string: "http://coffee.datausadev.com/api/getCoffeeBrands")
let request = NSURLRequest(URL: url, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 60)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
此方法仍然无效。
答案 0 :(得分:1)
这不是Swift错误。
在幕后NSURLSession遵循某些策略,具体取决于支持它的配置对象。
默认配置(您通过sharedSession单例使用的配置)使用“当前设置的全局NSURLCache,NSHTTPCookieStorage和NSURLCredentialStorage对象,并基于默认配置”,通过NSUrlSession Reference
您的选择:
使用几乎无法缓存的“短暂”配置(想想隐私浏览模式),
自行设置配置并将缓存和其他策略设置为适合您需要的配置。
不要忘记考虑服务器的策略。请查阅文档,或者如果没有,请尝试根据您收到的http标头做出最佳决策,以响应您的请求。
编辑:我现在才注意到您最初使用的是Alamofire。所有这些(以及Objective-c中的AF)确实提供了一个方便的,更高级别的做法,与iOS7之前的NSURLSession和NSURLConnection相同。他们都必须让你自定义缓存,浏览他们的文档。
答案 1 :(得分:1)
您需要将控制器对象设置为NSURLConnection
:
let request = NSURLRequest(URL: requestURL, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 60)
self.currentConnection = NSURLConnection(request: request, delegate: self)
这还需要使自我符合数据源:
class MyController: NSURLConnectionDataDelegate {
使用相关的委托方法禁用缓存:
func connection(connection: NSURLConnection, willCacheResponse cachedResponse: NSCachedURLResponse) -> NSCachedURLResponse?
{
return nil // never cache anything. ever.
}
URL请求中的.ReloadIgnoringLocalCacheData
选项将禁用读取缓存,willCacheResponse
委托方法禁用写入缓存。你需要同时使用它们。
不幸的是,这意味着您无法使用sendAsynchronousRequest
便捷方法并阻止回调 - 相反,您必须使用NSURLConnectionDataDelegate
中的委托方法来处理响应。基本上你必须创建一个NSMutableData
对象,并在数据从连接进入时附加到它,直到连接告诉你请求完成或失败 - 然后你可以对数据做一些事情。
据我所知,使用sendAsynchronousRequest
时无法完全禁用缓存。您可能希望在NSURLConnection
周围创建一个包装类,以使您的代码更整洁。
答案 2 :(得分:1)
我厌倦了一切,没有帮助。这个解决方案适用于我( Swift 3)
我在每个HttpResponse之后调用了 destroyCache()函数。
public static func destroyCache() {
let fileManager = FileManager.default
let documentsUrl = fileManager.urls(for: FileManager.SearchPathDirectory.cachesDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).first! as NSURL
let documentsPath = documentsUrl.path
let bundleIdentifier = Bundle.main.bundleIdentifier! as String
do {
if let documentPath = documentsPath
{
let fileNames = try fileManager.contentsOfDirectory(atPath: "\(documentPath)/\(bundleIdentifier)")
for fileName in fileNames {
let filePathName = "\(documentPath)/\(bundleIdentifier)/\(fileName)"
try fileManager.removeItem(atPath: filePathName)
}
}
} catch {
print("Could not clear: \(error)")
}
}