Я работаю над SDK и разработал хороший лаконичный метод конвейера Combine, который принимает универсальный параметр c, который используется для декодирования json с помощью. По сути, это многоцелевой конвейер многократного использования для JSON -> Decodable
. Работает действительно хорошо. Вот как выглядит этот конвейер:
func records<Record: Decodable>(forRequest request:RestRequest ) -> AnyPublisher<[Record], Never> {
return NetworkService.publisher(for: request)
.tryMap({ (response) -> Data in
response.asData()
})
.decode(type: Wrapper<Record>.self, decoder: JSONDecoder())
.map({ (record) -> [Record] in
record.records
})
.catch({ _ in
Just([Record]())
})
.eraseToAnyPublisher()
}
Использование:
contactsCancellable = NetworkService.records(forRequest: request)
.receive(on: RunLoop.main)
.assign(to: \.contacts, on: self)
Насколько я понимаю, Swift + Combine выводит тип параметра generi c из вызова assign(to:, on:)
.
Но силам нужна не-Комбинатная версия, и я действительно изо всех сил пытаюсь понять, как помочь Свифту сделать вывод о типе. Я попытался создать прямой аналог, подобный этому:
func fetchRecords<Record: Decodable>(forRequest request: RestRequest,
_ completionBlock: @escaping (Result<[Record], RestClientError>) -> Void) {
RestClient.shared.send(request: request) { result in
switch result {
case .success(let response):
do {
let decoder = JSONDecoder()
let wrapper = try decoder.decode(Wrapper<Record>.self, from: response.asData())
completionBlock(.success(wrapper.records))
} catch {
completionBlock(.success([Record]()))
}
case .failure(let err):
completionBlock(.failure(err))
}
}
}
Этот компилирует , однако, выполнив этот метод следующим образом:
NetworkService.fetchRecords(forRequest: request) { records in
print(records)
}
Результат с любовью crypti c error Generi c параметр 'Запись' не может быть выведен
Как я могу указать этот тип c Запись 'type' - что-либо, что соответствует Decodable, в этой некомбинированной версии?
Ps: Вот та структура Wrapper:
struct Wrapper<R: Decodable>: Decodable {
var totalSize: Int
var done: Bool
var records: [R]
}