2016-06-07 4 views
4

Я использую NSURLCache, и я бы хотел установить пользовательский ключ для NSURLRequest. Это возможно?NSURLCache, set custom key

Полное объяснение:

Я занимаюсь разработкой приложения отображения, который использует OpenStreetMap плитки. OpenStreetMap предоставляет несколько серверов для обслуживания фрагментов, чтобы уменьшить нагрузку на каждый сервер. Я использую эти серверы случайным образом. Так, например, следующие URL-адреса будут давать один и тот же плитки:

Очевидно, это вызывает некоторые проблемы для моего кэширования, потому что если я кэшировать плитки от сервера A, в следующий раз, если я попытаюсь загрузить с сервера B, NSURLCache не найдет плитку.

Итак, я хотел бы установить ключ кеша, чтобы обрабатывать этот случай. Это возможно?

+0

Другой подход заключается в использовании 'NSCache' для кэширования ваших ответов и перед началом запроса, посмотрите, есть ли у вас то, что вам нужно в вашем 'NSCache'. Вы можете использовать любой необходимый вам ключ. – Rob

ответ

5

Вы можете подклассифицировать NSURLCache и переопределить реализации cachedResponseForRequest: и storeCachedResponse:forRequest: - затем используйте setSharedURLCache:, чтобы установить его в свой подкласс.

Проще всего, наверное, назвать super для хранения (или не отменяет), а затем на поиске, если это запрос на плитку, проверьте все возможности (используя super) и возвращает ответ, если вы получите не- ниль один.

+0

Спасибо, подклассификация была решением. Я отправлю свой собственный ответ, хотя, поскольку ваш не касается пользовательской ключевой части. –

2

Итак, я, наконец, создал свой собственный NSURLCache, полностью изменив его поведение, в более «ручной» режим: теперь запросы не кэшируются по умолчанию, но я могу вручную добавлять/получать ответы с помощью настраиваемого ключа. Вот код:

import Foundation 

extension NSURLCache { 

    public func put(cachedResponse:NSCachedURLResponse, forKey key:String) {} 
    public func get(key:String) -> NSCachedURLResponse? { return nil; } 
} 

public class CustomNsUrlCache: NSURLCache { 

    // Prevent default caching: 
    public override func cachedResponseForRequest(request: NSURLRequest) -> NSCachedURLResponse? { return nil; } 
    public override func storeCachedResponse(cachedResponse: NSCachedURLResponse, forRequest request: NSURLRequest) {} 

    private func requestForKey(key:String) -> NSURLRequest { 

     let url:NSURL? = NSURL(string:"http://" + key); 
     return NSURLRequest(URL:url!); 
    } 

    public override func put(cachedResponse:NSCachedURLResponse, forKey key:String) { 

     super.storeCachedResponse(cachedResponse, forRequest:requestForKey(key)); 
    } 

    public override func get(key:String) -> NSCachedURLResponse? { 

     return super.cachedResponseForRequest(requestForKey(key)); 
    } 
} 

Не забудьте зарегистрировать пользовательский код делегата приложения:

let cache = CustomNsUrlCache(memoryCapacity: 4 * 1024 * 1024, diskCapacity: 100 * 1024 * 1024, diskPath: nil); 
NSURLCache.setSharedURLCache(cache); 

Использование:

if let cachedResponse = NSURLCache.sharedURLCache().get(cacheKey) { 

    // Use cached response 
} 
else { 

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { 

     data, response, error in 

     if let data = data, response = response { 

      // Cache the response: 
      NSURLCache.sharedURLCache().put(NSCachedURLResponse(response:response, data:data), forKey:cacheKey); 

      // Use the fresh response 
     } 
     else { 

      print(error); 
     } 
    }; 

    task.resume(); 
}