我正在使用combine实现一个网络层,并且很难在一次滑动中提取内部数组作为发布者。我有它的工作,但作为两个独立的函数,在第二个函数中。水槽我拉我需要的东西,但我希望这一切都发生在第一个函数中。。。当前状态,以供下文参考。
json从api返回供参考:
{
"count": 1,
"entities": [
{facetids:[],
identifiers:[],
description:String},
{facetids:[],
identifiers:[],
description:String}
]
}
实体的样子:
struct Entities:Decodable
{
var count:Int?
var entities: [Entity]?
}
NetworkController.swift:
func get<T>(type: T.Type, url: URL, headers: Headers) -> AnyPublisher<T, Error> where T : Decodable
{
var urlRequest = URLRequest(url: url)
headers.forEach
{
key, value in
if let value = value as? String
{
urlRequest.setValue(value, forHTTPHeaderField: key)
}
}
return URLSession.shared.dataTaskPublisher(for: urlRequest)
return URLSession.shared.dataTaskPublisher(for: urlRequest)
.map(.data)
.decode(type: T.self, decoder: JSONDecoder())
.eraseToAnyPublisher()
}
EntitiesLogicController.swift:
func getEntities(named: String, count: Int) -> AnyPublisher<Entities, Error> {
let endpoint = Endpoint.companies(named: named, count: count)
return networkController.get(type: Entities.self, url: endpoint.url, headers: endpoint.headers)
}
ApiCaller.swift:
func getEntities(named: String)
{
entitiesLogicController?.getEntities(named: named, count: 20).sink{
[weak self] completion in
if case let .failure(error) = completion
{
print("Error retrieving Entity, ERROR: (error)")
} else if case .finished = completion
{
print("Data successfully downloaded")
}
} receiveValue:
{
requestedEntity in
do{
let entities:[Entity] = try requestedEntity.entities!.compactMap{
entity in
do
{
return try Entity(from: entity)
}
}
self.entities = entities
}catch
{
print("Error")
}
}.store(in: &subscriptions)
}
我想要/需要返回AnyPublisher<[T] ,错误>相反其中[T]==[Entity]可解码结构工作得非常好,其他一切也一样。
如果您想要the get to return AnyPublisher<[T], Error> instead where [T] == [Entity]
,那么您应该有一个通用LogicController,它将处理通用调用,而不是EntitiesLogicController.swift
GenericLogicController.swift
func getObjects<T>(parameters: [String: Any]) -> AnyPublisher<T, Error> where T : Decodable {
let endpoint = //create a genric endpoint - or use switch to differentiate
return networkController.get(type: T.self, url: endpoint.url, headers: endpoint.headers)
}