Skip to content

Commit 888e104

Browse files
authored
Merge pull request #44 from RxSwiftCommunity/custom-caching
Allow to specify cached http methods
2 parents 6a05e3c + a620330 commit 888e104

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

RxHttpClient/HttpClientType+Extensions.swift

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@ public struct CacheMode {
99
public let returnCachedResponse: Bool
1010
/// If true, HttpClient will invoke request
1111
public let invokeRequest: Bool
12+
/// Specifies which HTTP methods should be cached
13+
public let cacheHttpMethods: Set<HttpMethod>
1214

13-
public init(cacheResponse: Bool = true, returnCachedResponse: Bool = true, invokeRequest: Bool = true) {
15+
public init(cacheResponse: Bool = true, returnCachedResponse: Bool = true, invokeRequest: Bool = true, cacheHttpMethods: [HttpMethod] = [.get]) {
1416
self.cacheResponse = cacheResponse
1517
self.returnCachedResponse = returnCachedResponse
1618
self.invokeRequest = invokeRequest
19+
self.cacheHttpMethods = Set(cacheHttpMethods)
1720
}
1821

1922
/// Only cached response will be returned
@@ -26,6 +29,14 @@ public struct CacheMode {
2629
public static let `default` = CacheMode(cacheResponse: true, returnCachedResponse: true, invokeRequest: true)
2730
}
2831

32+
extension CacheMode {
33+
func shouldCache(_ request: URLRequest) -> Bool {
34+
guard let raw = request.httpMethod else { return false }
35+
guard let method = HttpMethod(rawValue: raw) else { return false }
36+
return cacheHttpMethods.contains(method)
37+
}
38+
}
39+
2940
public extension HttpClientType {
3041
/**
3142
Creates StreamDataTask
@@ -165,9 +176,9 @@ public extension HttpClientType {
165176
let dataCacheProvider = MemoryDataCacheProvider(uid: UUID().uuidString)
166177
// variable for response with error
167178
var errorResponse: HTTPURLResponse? = nil
168-
179+
169180
let cachedRequest: Observable<Data> = {
170-
if urlRequest.httpMethod == HttpMethod.get.rawValue, requestCacheMode.returnCachedResponse, let url = urlRequest.url, let cached = urlRequestCacheProvider?.load(resourceUrl: url) {
181+
if requestCacheMode.shouldCache(urlRequest), requestCacheMode.returnCachedResponse, let url = urlRequest.url, let cached = urlRequestCacheProvider?.load(resourceUrl: url) {
171182
// return cached response
172183
return Observable.just(cached)
173184
}
@@ -199,7 +210,7 @@ public extension HttpClientType {
199210
guard let errorResponse = errorResponse else {
200211
let requestData = dataCacheProvider.getData()
201212

202-
if urlRequest.httpMethod == HttpMethod.get.rawValue, requestCacheMode.cacheResponse, let url = urlRequest.url {
213+
if requestCacheMode.shouldCache(urlRequest), requestCacheMode.cacheResponse, let url = urlRequest.url {
203214
// sache response
204215
self?.urlRequestCacheProvider?.save(resourceUrl: url, data: requestData)
205216
}

RxHttpClientTests/HttpClientCachingTests.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,23 @@ class HttpClientCachingTests: XCTestCase {
3232
XCTAssertTrue(cachedData.elementsEqual(data), "Should cache data")
3333
XCTAssertEqual(1, try! FileManager.default.contentsOfDirectory(atPath: cacheDirectory.path).count, "Should save data on disk")
3434
}
35+
36+
func testCacheCustomMethodResponse() {
37+
let data = "Some responded data".data(using: .utf8)!
38+
let requestUrl = URL(string: "https://test.com/json")!
39+
let _ = stub(condition: { $0.url == requestUrl && $0.httpMethod == HttpMethod.put.rawValue }) { _ in
40+
return OHHTTPStubsResponse(data: data, statusCode: 200, headers: nil)
41+
}
42+
43+
let cacheMode = CacheMode(cacheResponse: true, returnCachedResponse: true, invokeRequest: true, cacheHttpMethods: [.put])
44+
let exp = expectation(description: "Should complete request")
45+
_ = client.requestData(url: requestUrl, method: .put, requestCacheMode: cacheMode).subscribe(onCompleted: { exp.fulfill() })
46+
waitForExpectations(timeout: waitTimeout, handler: nil)
47+
48+
let cachedData = try! Data(contentsOf: cacheDirectory.appendingPathComponent(requestUrl.sha1()))
49+
XCTAssertTrue(cachedData.elementsEqual(data), "Should cache data")
50+
XCTAssertEqual(1, try! FileManager.default.contentsOfDirectory(atPath: cacheDirectory.path).count, "Should save data on disk")
51+
}
3552

3653
func testReturnCachedResponse() {
3754
let data = "Some responded data".data(using: .utf8)!

0 commit comments

Comments
 (0)