Swiftui 报告联合收割机中出版商名单的进展情况

Swiftui 报告联合收割机中出版商名单的进展情况,swiftui,combine,Swiftui,Combine,我正在使用SwiftUI/Combine编写一个黑客新闻iOS应用程序。他们有一个API调用来获取顶级帖子的ID,然后你应该自己请求每个故事。为此,我为这些调用创建了storyIds(:)->AnyPublisher和story(For:)->AnyPublisher 现在我想将它们组合成一个函数,getStories(),该函数首先下载标识符,然后遍历它们逐个获取故事。我想您可以使用MergeMany或API中的其他东西来实现这一点,但我不确定 我最不需要的是一个函数,它可以将这些内容组合成s

我正在使用SwiftUI/Combine编写一个黑客新闻iOS应用程序。他们有一个API调用来获取顶级帖子的ID,然后你应该自己请求每个故事。为此,我为这些调用创建了
storyIds(:)->AnyPublisher
story(For:)->AnyPublisher

现在我想将它们组合成一个函数,
getStories()
,该函数首先下载标识符,然后遍历它们逐个获取故事。我想您可以使用
MergeMany
或API中的其他东西来实现这一点,但我不确定

我最不需要的是一个函数,它可以将这些内容组合成
stories()->AnyPublisher
。我发现我几乎做到了。然而,我错过的是报告任务进度的方法。我想为每个获取的故事更新一个计数器,以向用户显示剩余下载量。我该怎么做

struct代理{
结构响应{
let值:T
let response:URLResponse
}
func run(request:URLRequest,decoder:JSONDecoder=JSONDecoder())->AnyPublisher{
返回URLSession.shared
.dataTaskPublisher(用于:请求)
.tryMap{result->中的响应
let value=try decoder.decode(T.self,from:result.data)
返回响应(值:value,响应:result.Response)
}
.receive(在:DispatchQueue.main上)
.删除任何发布者()
}
}
enum HackerNewsAPI{
静态let代理=代理()
静态let base=URL(字符串:https://hacker-news.firebaseio.com/v0/")!
}
扩展HackerNewAPI{
静态func storyIds()->AnyPublisher{
let request=URLRequest(url:base.appendingPathComponent(“topstories.json”))
返回代理。运行(请求)
.print()
.map(\.value)
.删除任何发布者()
}
}
扩展HackerNewAPI{
静态func故事(用于id:Int)->AnyPublisher{
let request=URLRequest(url:base.appendingPathComponent(“item/\(id.json”))
返回代理。运行(请求)
.map(\.value)
.删除任何发布者()
}
}
扩展HackerNewAPI{
静态func stories()->AnyPublisher{
HackerNewsAPI.storyIds()
.flatMap{storyIDs->AnyPublisher中的
let stories=storyIDs.map{story(for:$0)}
返回出版商。合并许多(故事)
.collect()
.删除任何发布者()
}
.删除任何发布者()
}
}

我希望下面的代码能起作用

最后是一个发布到目前为止已下载文章数量的
count
发布者,以及一个
array
发布者,该发布者在所有文章下载后发布整个
文章数组

func getStories() -> (count: AnyPublisher<Int, Error>, stories: AnyPublisher<[Post], Error>) {
    let posts = HackerNewsAPI.storyIds()
        .map { $0.map { HackerNewsAPI.story(for: $0) } }
        .flatMap { Publishers.Sequence(sequence: $0) }
        .flatMap { $0 }
        .share()

    let count = posts
        .scan(0) { count, _ in
            return count + 1
        }

    let array = posts
        .reduce([Post]()) { current, post in
            current + [post]
        }

    return (count.eraseToAnyPublisher(), array.eraseToAnyPublisher())
}
func getStories()->(计数:AnyPublisher,故事:AnyPublisher){
让posts=HackerNewsAPI.storyIds()
.map{$0.map{HackerNewsAPI.story(for:$0)}
.flatMap{publisher.Sequence(Sequence:$0)}
.flatMap{$0}
.share()
让计数=员额
.scan(0){count,{in
返回计数+1
}
让数组=posts
.reduce([Post]()){current,Post in
当前+[职位]
}
返回(count.eraseToAnyPublisher(),array.eraseToAnyPublisher())
}