diff --git a/ConfigCat.podspec b/ConfigCat.podspec index fae534e..b42268f 100755 --- a/ConfigCat.podspec +++ b/ConfigCat.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |spec| spec.name = "ConfigCat" - spec.version = "11.0.1" + spec.version = "11.0.2" spec.summary = "ConfigCat Swift SDK" spec.swift_version = "5.0" diff --git a/ConfigCat.xcconfig b/ConfigCat.xcconfig index b74f0c8..ffe01b6 100644 --- a/ConfigCat.xcconfig +++ b/ConfigCat.xcconfig @@ -38,4 +38,4 @@ SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator watchos watchsimulator app SWIFT_VERSION = 5.0 // ConfigCat SDK version -MARKETING_VERSION = 11.0.1 +MARKETING_VERSION = 11.0.2 diff --git a/README.md b/README.md index ef03158..4edd47b 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ The following device platform versions are supported: ``` swift dependencies: [ - .package(url: "https://github.com/configcat/swift-sdk", from: "11.0.1") + .package(url: "https://github.com/configcat/swift-sdk", from: "11.0.2") ] ``` diff --git a/Sources/ConfigCat/ConfigFetcher.swift b/Sources/ConfigCat/ConfigFetcher.swift index 3b688c5..406d53a 100755 --- a/Sources/ConfigCat/ConfigFetcher.swift +++ b/Sources/ConfigCat/ConfigFetcher.swift @@ -67,23 +67,17 @@ class ConfigFetcher: NSObject { } func fetch(eTag: String, completion: @escaping (FetchResponse) -> Void) { - let cachedUrl = baseUrl - executeFetch(url: cachedUrl, eTag: eTag, executionCount: 2) { response in - if let newUrl = response.entry?.config.preferences.preferencesUrl, !newUrl.isEmpty && newUrl != cachedUrl { - self._baseUrl.testAndSet(expect: cachedUrl, new: newUrl) - } - completion(response) - } + executeFetch(eTag: eTag, executionCount: 2, completion: completion) } - private func executeFetch(url: String, eTag: String, executionCount: Int, completion: @escaping (FetchResponse) -> Void) { - sendFetchRequest(url: url, eTag: eTag, completion: { response in + private func executeFetch(eTag: String, executionCount: Int, completion: @escaping (FetchResponse) -> Void) { + sendFetchRequest(url: baseUrl, eTag: eTag, completion: { response in guard case .fetched(let entry) = response else { completion(response) return } let newUrl = entry.config.preferences.preferencesUrl - if newUrl.isEmpty || newUrl == url { + if newUrl.isEmpty || newUrl == self.baseUrl { completion(response) return } @@ -92,6 +86,7 @@ class ConfigFetcher: NSObject { completion(response) return } + self.baseUrl = newUrl if redirect == .noRedirect { completion(response) return @@ -101,7 +96,7 @@ class ConfigFetcher: NSObject { + "Read more: https://configcat.com/docs/advanced/data-governance/") } if executionCount > 0 { - self.executeFetch(url: newUrl, eTag: eTag, executionCount: executionCount - 1, completion: completion) + self.executeFetch(eTag: eTag, executionCount: executionCount - 1, completion: completion) return } self.log.error(eventId: 1104, message: "Redirection loop encountered while trying to fetch config JSON. Please contact us at https://configcat.com/support/") diff --git a/Sources/ConfigCat/Utils.swift b/Sources/ConfigCat/Utils.swift index a61c002..f864701 100644 --- a/Sources/ConfigCat/Utils.swift +++ b/Sources/ConfigCat/Utils.swift @@ -47,7 +47,7 @@ extension Equatable { } class Constants { - static let version: String = "11.0.1" + static let version: String = "11.0.2" static let configJsonName: String = "config_v6.json" static let configJsonCacheVersion: String = "v2" static let globalBaseUrl: String = "https://cdn-global.configcat.com" diff --git a/Tests/ConfigCatTests/DataGovernanceTests.swift b/Tests/ConfigCatTests/DataGovernanceTests.swift index c2b0dbd..d850143 100644 --- a/Tests/ConfigCatTests/DataGovernanceTests.swift +++ b/Tests/ConfigCatTests/DataGovernanceTests.swift @@ -176,17 +176,30 @@ class DataGovernanceTests: XCTestCase { let fetcher = createFetcher(http: engine, url: customCdnUrl) // Act - let expectation = expectation(description: "wait for response") + let expectation1 = expectation(description: "wait for response") fetcher.fetch(eTag: "") { response in XCTAssertEqual(.fetched(.empty), response) XCTAssertNotNil(response.entry) - expectation.fulfill() + expectation1.fulfill() } - wait(for: [expectation], timeout: 5) + wait(for: [expectation1], timeout: 5) // Assert XCTAssertEqual(1, engine.requests.count) - XCTAssertTrue(engine.requests.last?.url?.absoluteString.starts(with: customCdnUrl) ?? false) + XCTAssertTrue(engine.requests[0].url?.absoluteString.starts(with: customCdnUrl) ?? false) + + // Act + let expectation2 = expectation(description: "wait for response") + fetcher.fetch(eTag: "") { response in + XCTAssertEqual(.fetched(.empty), response) + XCTAssertNotNil(response.entry) + expectation2.fulfill() + } + wait(for: [expectation2], timeout: 5) + + // Assert + XCTAssertEqual(2, engine.requests.count) + XCTAssertTrue(engine.requests[1].url?.absoluteString.starts(with: customCdnUrl) ?? false) } func testShouldNotRespectCustomUrlWhenForced() throws { @@ -199,18 +212,31 @@ class DataGovernanceTests: XCTestCase { let fetcher = createFetcher(http: engine, url: customCdnUrl) // Act - let expectation = expectation(description: "wait for response") + let expectation1 = expectation(description: "wait for response") fetcher.fetch(eTag: "") { response in XCTAssertEqual(.fetched(.empty), response) XCTAssertNotNil(response.entry) - expectation.fulfill() + expectation1.fulfill() } - wait(for: [expectation], timeout: 5) + wait(for: [expectation1], timeout: 5) // Assert XCTAssertEqual(2, engine.requests.count) XCTAssertTrue(engine.requests[0].url?.absoluteString.starts(with: customCdnUrl) ?? false) XCTAssertTrue(engine.requests[1].url?.absoluteString.starts(with: Constants.globalBaseUrl) ?? false) + + // Act + let expectation2 = expectation(description: "wait for response") + fetcher.fetch(eTag: "") { response in + XCTAssertEqual(.fetched(.empty), response) + XCTAssertNotNil(response.entry) + expectation2.fulfill() + } + wait(for: [expectation2], timeout: 5) + + // Assert + XCTAssertEqual(3, engine.requests.count) + XCTAssertTrue(engine.requests[2].url?.absoluteString.starts(with: Constants.globalBaseUrl) ?? false) } private func createFetcher(http: HttpEngine, url: String = "") -> ConfigFetcher {