Skip to content

Commit 8ee1e96

Browse files
authored
[Config] Add encoder and decoder param to public codable APIs (#14525)
1 parent 81ab6f9 commit 8ee1e96

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

FirebaseRemoteConfig/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# Unreleased
2+
- [fixed] Codable APIs now accept optional `FirebaseDataEncoder` and
3+
`FirebaseDataDecoder` parameters, allowing for customization of
4+
encoding/decoding behavior. (#14368)
5+
16
# 11.9.0
27
- [fixed] Mark internal `fetchSession` property as `atomic` to prevent a concurrency
38
related crash. (#14449)

FirebaseRemoteConfig/Swift/Codable.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,21 @@ public extension RemoteConfig {
4747
/// Decodes a struct from the respective Remote Config values.
4848
///
4949
/// - Parameter asType: The type to decode to.
50-
func decoded<Value: Decodable>(asType: Value.Type = Value.self) throws -> Value {
50+
func decoded<Value: Decodable>(asType: Value.Type = Value.self,
51+
decoder: FirebaseDataDecoder = .init()) throws -> Value {
5152
let keys = allKeys(from: RemoteConfigSource.default) + allKeys(from: RemoteConfigSource.remote)
5253
let config = keys.reduce(into: [String: FirebaseRemoteConfigValueDecoderHelper]()) {
5354
$0[$1] = FirebaseRemoteConfigValueDecoderHelper(value: configValue(forKey: $1))
5455
}
55-
return try FirebaseDataDecoder().decode(Value.self, from: config)
56+
return try decoder.decode(Value.self, from: config)
5657
}
5758

5859
/// Sets config defaults from an encodable struct.
5960
///
6061
/// - Parameter value: The object to use to set the defaults.
61-
func setDefaults<Value: Encodable>(from value: Value) throws {
62-
guard let encoded = try FirebaseDataEncoder().encode(value) as? [String: NSObject] else {
62+
func setDefaults<Value: Encodable>(from value: Value,
63+
encoder: FirebaseDataEncoder = .init()) throws {
64+
guard let encoded = try encoder.encode(value) as? [String: NSObject] else {
6365
throw RemoteConfigCodableError.invalidSetDefaultsInput(
6466
"The setDefaults input: \(value), must be a Struct that encodes to a Dictionary"
6567
)

FirebaseRemoteConfig/Tests/Swift/SwiftAPI/Codable.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
import FirebaseRemoteConfig
16+
import FirebaseSharedSwift
1617

1718
import XCTest
1819

@@ -206,4 +207,35 @@ class CodableTests: APITestBase {
206207
XCTAssertEqual(readDefaults.arrayValue, ["foo", "bar", "baz"])
207208
XCTAssertEqual(readDefaults.arrayIntValue, [1, 2, 0, 3])
208209
}
210+
211+
// MARK: - Test using injected encoder/decoder.
212+
213+
func testDateEncodingAndDecodingWithNonDefaultCoders() throws {
214+
// Given
215+
struct DateDefaults: Codable {
216+
let date: Date
217+
}
218+
219+
let defaults = DateDefaults(date: Date())
220+
221+
// When
222+
let encoder = FirebaseDataEncoder()
223+
encoder.dateEncodingStrategy = .iso8601
224+
try config.setDefaults(from: defaults, encoder: encoder)
225+
226+
// - Uses default decoder that won't decode ISO8601 format.
227+
let improperlyDecodedDefaults: DateDefaults = try config.decoded()
228+
XCTAssertNotEqual(improperlyDecodedDefaults.date, defaults.date)
229+
230+
// Then
231+
let decoder = FirebaseDataDecoder()
232+
decoder.dateDecodingStrategy = .iso8601
233+
234+
let decodedDefaults: DateDefaults = try config.decoded(decoder: decoder)
235+
XCTAssert(Calendar.current.isDate(
236+
decodedDefaults.date,
237+
equalTo: defaults.date,
238+
toGranularity: .second
239+
))
240+
}
209241
}

0 commit comments

Comments
 (0)