Skip to content

Commit

Permalink
Support non-JSON object decodable values in getMetadataValue (#4555)
Browse files Browse the repository at this point in the history
* support non-JSON decodable values in getMetadataValue

* remove method definition claiming to throw

* Update Offering.swift

* test for primitive decodable metadata values without a default

* simplify decoding
  • Loading branch information
codykerns authored Dec 6, 2024
1 parent f1e4ca5 commit 7c34072
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 12 deletions.
25 changes: 13 additions & 12 deletions Sources/Purchasing/Offering.swift
Original file line number Diff line number Diff line change
Expand Up @@ -310,20 +310,21 @@ extension Offering {
}

/// - Returns: The `metadata` value associated to `key` for the expected `Decodable` type,
/// or `nil` if not found.
/// - Throws: Error if the content couldn't be deserialized to the expected type.
/// or `nil` if not found or if the content couldn't be deserialized to the expected type.
/// - Note: This decodes JSON using `JSONDecoder.KeyDecodingStrategy.convertFromSnakeCase`.
public func getMetadataValue<T: Decodable>(for key: String) -> T? {
do {
guard let value = self.metadata[key] else { return nil }
let data = try JSONSerialization.data(withJSONObject: value)

return try JSONDecoder.default.decode(
T.self,
jsonData: data,
logErrors: true
)
} catch {
guard let value = self.metadata[key] else { return nil }

if JSONSerialization.isValidJSONObject(value),
let data = try? JSONSerialization.data(withJSONObject: value) {
return try? JSONDecoder.default.decode(
T.self,
jsonData: data,
logErrors: true
)
} else if let value = value as? T {
return value
} else {
return nil
}
}
Expand Down
12 changes: 12 additions & 0 deletions Tests/UnitTests/Purchasing/OfferingsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,18 @@ class OfferingsTests: TestCase {
let wrongMetadataType = offeringA.getMetadataValue(for: "string", default: 5.5)
expect(wrongMetadataType) == 5.5

let intWithoutDefault: Int? = offeringA.getMetadataValue(for: "int")
expect(intWithoutDefault) == 5

let doubleWithoutDefault: Double? = offeringA.getMetadataValue(for: "double")
expect(doubleWithoutDefault) == 5.5

let boolWithoutDefault: Bool? = offeringA.getMetadataValue(for: "boolean")
expect(boolWithoutDefault) == true

let stringWithoutDefault: String? = offeringA.getMetadataValue(for: "string")
expect(stringWithoutDefault) == "five"

struct Data: Decodable, Equatable {
var number: Int
}
Expand Down

0 comments on commit 7c34072

Please sign in to comment.