swift 如何使用sink为数组赋值

ni65a41a  于 2022-11-28  发布在  Swift
关注(0)|答案(2)|浏览(192)

在一个演示中,我切换到使用合并,但似乎找不到一种方法来分配从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)
            
       
    }
    
}
byqmnocz

byqmnocz1#

您看到的是默认输出,因为您正在替换所有错误。在替换错误之前,请至少使用print查看错误。
原来这里的问题是日期的解码。应用正确的解码策略解决了这个问题。

func fetchData() async {
    //create custom decoder and apply dateDecodingStrategy
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .iso8601
    let url = URL(string: "https://www.hackingwithswift.com/samples/headlines.json")!
    
    URLSession.shared.dataTaskPublisher(for: url)
        .map(\.data)
        // use the custom decoder
        .decode(type: [NewsItem].self, decoder: decoder)
        // if an error occures at least print it
        .mapError({ error in
            print(error)
            return error
        })
        .replaceError(with: [NewsItem.shared])
        .sink(receiveValue: { item in
            news = item
        })
        .store(in: &request)
}
mbskvtky

mbskvtky2#

如果要使用合并,则需要一个ObservableObject和一个assign,管道的末端是一个@Published var。当对象被deinit时,它将自动取消管道。
async/await和.task的优点是我们不再需要对象,并且当UIView(由SwiftUI管理)消失时,任务被取消。

相关问题