【发布时间】:2020-06-11 02:25:27
【问题描述】:
我正在开发一个 SDK,并开发了一个简洁的组合管道方法,该方法接受一个用于解码 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 是从 assign(to:, on:) 调用中推断出泛型参数类型。
但是想要一个非组合版本的权力,我真的很难弄清楚如何帮助 Swift 推断类型。我尝试构建这样的直接模拟:
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)
}
导致一个非常神秘的错误无法推断通用参数“记录”
在这个非组合版本中,我如何指定通用 Record 'type' - 任何符合 Decodable 的东西?
Ps:这是 Wrapper 结构:
struct Wrapper<R: Decodable>: Decodable {
var totalSize: Int
var done: Bool
var records: [R]
}
【问题讨论】:
-
我的回答有帮助吗?请告诉我。
-
@jacobRelkin - 非常完美。谢谢!
标签: swift generics type-inference