将'[Publishers.Map <URLSession.DataTaskPublisher,[ProductRep]?>]'转换为[ProductRep]

时间:2019-11-18 15:18:52

标签: swift functional-programming combine

如何找出flatMap,reduce等将其转换为ProductRep数组?

我目前正在使用Cannot convert value of type 'Publishers.Map<URLSession.DataTaskPublisher, [StoreService.ProductRep]?>' to closure result type 'StoreService.ProductRep'-因为我不太了解如何将Publishers.Map变成实际的东西。 旨在成为使用map / flatMap的较大的发布者和订阅者网络的一部分。

let mapResult: [ProductRep] = parsePageURIs(firstPage, jsonDict)
            .map { pageUri in self.importProductsPublisher(pageUri, urlSession: urlSession, firstPage: false) }
            .map { publisher in publisher.map {(productsData, productsResponse) in
                    return self.handleImportProductsResponse(data: productsData, response: productsResponse, category: category, urlSession: urlSession)
                }
        }
func importProductsPublisher(_ uri: String, urlSession: URLSession, firstPage: Bool) -> URLSession.DataTaskPublisher { /* Start the network query */ }
func handleImportProductsResponse(data: Data, response: URLResponse, category: CategoryRep, urlSession: URLSession) -> [ProductRep]? { /* Handle the result of the network query and parse into an array of items (ProductRep) */ }

1 个答案:

答案 0 :(得分:1)

我认为这里正在发生两件事。首先,您缺少某种类型的接收器,通常您会看到一连串的发布商以.sink或.assign

结尾
whatever.map{ ... }.sink{ items in 
//Do something with items in this closure
}

其次,您似乎正在将页面uris映射到一个发布者集合,而不是一个发布者。然后,您将在地图内有一个嵌套地图,该地图目前还无法解决任何问题。

您可以使用合并的发布者之一,例如合并多个并收集以将一个发布者减少为多个: https://developer.apple.com/documentation/combine/publishers/mergemany/3209693-collect

一个基本的收集示例:


let arrayOfPublishers = (0...10).map{ int in
    return Just(int)
}

Publishers.MergeMany(arrayOfPublishers).collect().sink { allTheInts in
    //allTheInts is of type [Int]
    print(allTheInts)
}

认为,您需要这样的东西:


 let productPublishers = parsePageURIs(firstPage, jsonDict).map { pageUri in
    return self.importProductsPublisher(pageUri, urlSession: urlSession, firstPage: false).map {(productsData, productsResponse) in
        return self.handleImportProductsResponse(data: productsData, response: productsResponse, category: category, urlSession: urlSession)
    }
 }

 Publishers.MergeMany(productPublishers).collect().sink { products in
   //Do somethings with the array of products
 }

在映射数据请求发布者之后,将uris映射到模型中的发布者结果,然后合并所有发布者以将单个结果与MergeMany&collect合并到一个数组中,最后是实际触发所有事情发生的接收器。