How to apply convertFromSnakeCase to decoder when using Combine?

I am using the Combine framework in my Swift project and I am struggling to convert from snake case.

I tried using this extension code

extension JSONDecoder {
    static let snakeCaseConverting: JSONDecoder = {
        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        return decoder
    }()
}

extension Publisher where Output == Data {
    func decode<T: Decodable>(
        as type: T.Type = T.self,
        using decoder: JSONDecoder = .snakeCaseConverting
    ) -> Publishers.Decode<Self, T, JSONDecoder> {
        decode(type: type, decoder: decoder)
    }
}

But it is not working as expected

urlSession.dataTaskPublisher(for: urlRequest)
    .tryMap() { element -> Data in
        guard let response = element.response as? HTTPURLResponse else {
            throw APIError.missingDataError
        }
        return element.data
    }
    .decode()
    .eraseToAnyPublisher()

Any Suggestions?

Thanks!

You need to provide your JSONDecoder instance to the decode call.

JSONDecoder instance is already there but I tried this also before and it didn't worked as expected.
.decode(type: T.self,
decoder: JSONDecoder()
)

I believe you need to do .decode(.snakeCaseConverting)

.decode(.snakeCaseConverting) is not syntactically correct. But I tried to get some way to include snakeCaseConverting, couldn't find out

1 Like

This would be

.decode(type: T.self, decoder: JSONDecoder.snakeCaseConverting)

You can also create your decoder inline if you wanted.

2 Likes

Awesome, it worked! Thank you so much @Jon_Shier