Swift: Extending Combine operators

gmoraleda

I'm trying to wrap a tryMap operator along the lines of this article.

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

extension Publisher where Output == URLSession.DataTaskPublisher.Output {
    func processData(_: @escaping (Self.Output) throws -> Data) -> Publishers.TryMap<Self, Data> {
        tryMap { element -> Data in
            guard let httpResponse = element.response as? HTTPURLResponse,
                  httpResponse.statusCode == 200
            else {
                throw URLError(.badServerResponse)
            }
            return element.data
        }
    }
}

While using it I'm getting a compiler error which I'm struggling with:

return urlSession
    .dataTaskPublisher(for: request)
    .processData // <- Value of type '(@escaping (URLSession.DataTaskPublisher.Output) throws -> Data) -> Publishers.TryMap<URLSession.DataTaskPublisher, Data>' (aka '(@escaping ((data: Data, response: URLResponse)) throws -> Data) -> Publishers.TryMap<URLSession.DataTaskPublisher, Data>') has no member 'decode'
    .decode(as: InstantResponse.self)
    .eraseToAnyPublisher()

What would be the correct way of doing it? Thanks!

Dávid Pásztor

First of all, you aren't calling processData - you are missing the parentheses, which would actually execute the function. Second, your processData declaration is incorrect, it should not take a closure as its input argument, since you aren't using that closure anyways.

extension Publisher where Output == URLSession.DataTaskPublisher.Output {
    func processData() -> Publishers.TryMap<Self, Data> {
        tryMap { element -> Data in
            guard let httpResponse = element.response as? HTTPURLResponse,
                  httpResponse.statusCode == 200
            else {
                throw URLError(.badServerResponse)
            }
            return element.data
        }
    }
}

return urlSession
    .dataTaskPublisher(for: request)
    .processData() // parentheses necessary here
    .decode(as: InstantResponse.self)
    .eraseToAnyPublisher()

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related