web-dev-qa-db-ja.com

NSURLSessionが応答をキャッシュしないようにする

なぜ応答をキャッシュするのですか?以前に取得した応答を返します。ネットワーク接続をオフにしても機能します。 iOSシミュレーターのリセットも機能しないようです。リクエストを行ってから、インターネットをオフラインにすると機能します(キャッシュ).

public let urlSession: NSURLSession

public init()
{
    // ...

    var configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
    configuration.requestCachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
    urlSession = NSURLSession(configuration: configuration)
}

func makeRequest(path: String, httpMethod:String, body:String?, baseUrl: String?, headers:[String:String]=[:], callback: JsonRequestCallback)
{
    let urlString = (baseUrl ?? customOAuth2Manager.API_URL) + path
    let url = NSURL(string: urlString)
    let request = oauthInstance.request(forURL: url!)

    request.HTTPMethod = httpMethod
    self.customOAuth2Manager.setupRequest(request)

    for (key, value) in headers {
        request.setValue(value, forHTTPHeaderField:key)
    }

    if let body = body where body != "" {
        let postData = (body as NSString).dataUsingEncoding(NSUTF8StringEncoding)
        request.HTTPBody = postData
    }

    let task = urlSession.dataTaskWithRequest(request) { data, response, error in
        self.parseData(data, response:response, error:error, body:body, callback: callback)
    }
    task.resume()
}

更新

didFinishLaunchingAppDelegateから次のコードを呼び出すことで解決できました:

func removeUrlCache()
{
    NSURLCache.setSharedURLCache(NSURLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil))
}

ただし、元のコードが機能しない理由はまだ知りたいです。私の問題を解決するためにすべてのアプリのキャッシュを無効にするのも少し醜く感じます。

20
Sunkas

質問ありがとうございます。それは私を正しい道に導きました。

NSURLCache.sharedURLCache()にはさらに多くの可能性があり、このためにメモリ容量とディスク容量を変更する必要はありません。

キャッシュされたすべての応答を削除できます。 私のために働きます。

_URLCache.shared.removeAllCachedResponses()
_

または、単一の応答のキャッシュを削除できます。 iOS 9では機能しません

_let request = URLRequest(url: URL(string: url)!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 10)
    URLCache.shared.removeCachedResponse(for: request)

//Do your request here
_

私はそれが誰かを助けることを願っています!

編集:NSURLCache.sharedURLCache().removeCachedResponseForRequest(request)は残念ながら機能しません

私の代わりは:私はこれをプルして更新するために使用していて、私は最終更新日を追跡しています。だから私は次のコードを使用していました:

_ URLCache.shared.removeCachedResponses(since: lateUpdate)
_

しかし、何らかの理由でこれは機能していません。

IOS 8以降、単一のキャッシュ削除メソッドは壊れているようです: https://stackoverflow.com/a/26343653/2826164

2019-05-24、Swift 5.に更新。

18
Gerrit Post

これが実際にキャッシュを防ぐのか、毎回新しいリロードを強制するのかはわかりませんが、これは私にとってうまくいきました:

request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData

他のオプションが必要になる場合に備えて、次のスクリーンショットを示します。

enter image description here

11
Andrej

WillSessionデリゲートの実装では、URLSessionDelegateを実装し、nilを使用してcompletionBlockを呼び出します。これはあなたの要求が追いつかれることはありませんでした

1
Exception

オプション1sessionConfig.URLCache = nilを設定すると、キャッシュが無効になります。

/* The URL resource cache, or nil to indicate that no caching is to be performed */
@property (nullable, retain) NSURLCache *URLCache;

これはバックグラウンドセッションではデフォルトでnilなので、デフォルトではキャッシングは無効になっています。

参照: https://developer.Apple.com/documentation/foundation/urlsessionconfiguration/1410148-urlcache

オプション2

次のデリゲートメソッドを実装し、completementHandler(nil)を呼び出すと、キャッシュが防止されます。

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                                  willCacheResponse:(NSCachedURLResponse *)proposedResponse 
                                  completionHandler:(void (^)(NSCachedURLResponse * _Nullable cachedResponse))completionHandler

このデリゲートメソッドは、アップロードとデータタスクに対してのみ呼び出され、バックグラウンドまたは一時的な構成のセッションに対しては呼び出されないことに注意してください。

参照: https://developer.Apple.com/documentation/foundation/url_loading_system/accessing_cached_data

0
Abhijith