Search code examples
swiftalamofirensurlcache

Alamofire Cache not found


I have been trying to setup the cache for Alamofire 5.0 by doing the configuration below:

private func buildURLCache() -> URLCache {
  let capacity = 50 * 1024 * 1024 // MBs
  #if targetEnvironment(macCatalyst)
  return URLCache(memoryCapacity: capacity, diskCapacity: capacity)
  #else
  return URLCache(memoryCapacity: capacity, diskCapacity: capacity, diskPath: nil)
  #endif
}

private func defaultSessionManager(_ requestInterceptor: RequestInterceptor?) -> Alamofire.Session {

  let evaluators: [String: ServerTrustEvaluating] = [
    "google.com": PinnedCertificatesTrustEvaluator(certificates: pinnedCertificates())
  ]

  // Create custom manager
  let configuration = URLSessionConfiguration.af.default
  configuration.headers = HTTPHeaders.default
  configuration.requestCachePolicy = .useProtocolCachePolicy

  URLCache.shared = buildURLCache()
  configuration.urlCache = URLCache.shared

  return Alamofire.Session(
      configuration: configuration,
      interceptor: requestInterceptor,
      serverTrustManager: ServerTrustManager(evaluators: evaluators))
}

The function defaultSessionManager(_) returns a configured instance of Alamofire, I put it in as strong reference and do a request like this below (don't worry it's just an example):

let alamofireManager = defaultSessionManager(nil)

func getFoos(
  token: String,
  completion: @escaping (Result<[Foo], Error>) -> Void) {

  alamofireManager.request(
    "google.com",
    encoding: JSONEncoding.default,
    headers: headers(token))
    .validate()
    .responseJSON { (dataResponse: AFDataResponse<Any>) in

      if let cacheData = URLCache.shared.cachedResponse(for: dataResponse.request!) {
        print("URLCache.shared Data is from cache")
      } else {
        print("URLCache.shared Data is from Server")
      }

      if let cacheData = URLCache.shared.cachedResponse(for: (dataResponse.request?.urlRequest!)!) {
        print("URLCache.shared urlRequest Data is from cache")
      } else {
        print("URLCache.shared urlRequest Data is from Server")
      }

      //....
    }
}

Unfortunately the functions URLCache.shared.cachedResponse are returning nil, causing the function to only print ... Data is from Server. The app is never getting the data from the cache, any idea why this is happening?

Thank you!


Solution

  • There are a few issues here.

    First, currently response.request returns the last URLRequest that Alamofire saw, which is not necessarily the URLRequest that was performed and went out over the network. To see that value, you'll actually need to capture the Alamofire Request and check its task?.currentRequest property. That should give you the URLRequest that passed through Alamofire and the URLSession and was performed. We're looking into making these URLRequests available off the response as well.

    Second, if you just want to check whether you received a cached response, it's better to check the URLSessionTaskMetrics value, as that should provide a definitive answer without needing to check the URLCache.

    response.metrics?.transactionMetrics.last?.resourceFetchType
    

    If this value is .localCache, then you know your response came from the cache.