在一个演示中,我切换到使用合并,但似乎找不到一种方法来分配从sink中的json解码获得的值,以指向一个数组,下面是我的代码,正如您可以在注解掉的代码中看到的,使用URLSession要容易得多...谢谢
目前只看到默认记录
struct NewsItem: Decodable {
let id: Int
let title: String
let strap: String
let url: URL
let main_image: URL
let published_date: Date
static let shared = NewsItem(id: 0, title: "", strap: "", url: URL(string: "https://www.hackingwithswift.com/articles/239/wwdc21-wrap-up-and-recommended-talks")!, main_image: URL(string: "https://www.hackingwithswift.com/resize/300/uploads/wwdc-21@2x.jpg")!, published_date: Date())
}
struct CardView: View {
@State private var news = [NewsItem]()
@State private var request = Set<AnyCancellable>()
var body: some View {
List {
ForEach(news, id:\.id) { news in
Text(news.title)
Text("\(news.published_date)")
Link("Goto Link", destination: news.url)
AsyncImage(url: news.main_image)
.frame(width: 50, height: 50)
}
}
.onAppear {
Task {
await fetchData()
}
}
}
func fetchData() async {
let url = URL(string: "https://www.hackingwithswift.com/samples/headlines.json")!
// URLSession.shared.dataTask(with: url) { data, response, error in
// if let error = error {
// print(error.localizedDescription)
// } else if let data = data {
// let json = JSONDecoder()
//
// json.dateDecodingStrategy = .iso8601
// do {
// let user = try json.decode([NewsItem].self, from: data)
// news = user
// } catch {
// print(error.localizedDescription)
// }
// }
// }.resume()
URLSession.shared.dataTaskPublisher(for: url)
.map(\.data)
.decode(type: [NewsItem].self, decoder: JSONDecoder())
.replaceError(with: [NewsItem.shared])
.sink(receiveValue: { item in
news = item
})
.store(in: &request)
}
}
2条答案
按热度按时间byqmnocz1#
您看到的是默认输出,因为您正在替换所有错误。在替换错误之前,请至少使用print查看错误。
原来这里的问题是日期的解码。应用正确的解码策略解决了这个问题。
mbskvtky2#
如果要使用合并,则需要一个
ObservableObject
和一个assign
,管道的末端是一个@Published var
。当对象被deinit时,它将自动取消管道。async/await和
.task
的优点是我们不再需要对象,并且当UIView(由SwiftUI管理)消失时,任务被取消。