【问题标题】:SwiftUI Combine URLSession JSON Network CallSwiftUI 结合 URLSession JSON 网络调用
【发布时间】:2020-07-21 17:02:59
【问题描述】:

我正在尝试了解进行 JSON 网络调用的组合方法。我是 显然缺少一些基本的东西。

我得到的最接近失败,取消了 URLSession。

class NoteDataStore: ObservableObject {

    @Published var notes: [MyNote] = []

    init() {
        getWebserviceNotes()
    }

    func getWebserviceNotes() {

        let pub = Webservice().fetchNotes()
            .sink(receiveCompletion: {_ in}, receiveValue: { (notes) in
            self.notes = notes
            })
        }
    }
}//class

数据元素:

struct MyNote: Codable, Identifiable {
    let id = UUID()
    var title: String
    var url: String
    var thumbnailUrl: String

    static var placeholder: MyNote {
        return MyNote(title: "No Title", url: "", thumbnailUrl: "")
    }
}

网络设置:

class Webservice {
    func fetchNotes() -> AnyPublisher<[MyNote], Error> {
        let url = "https://jsonplaceholder.typicode.com/photos"
        guard let notesURL = URL(string: url) else { fatalError("The URL is broken")}

        return URLSession.shared.dataTaskPublisher(for: notesURL)
            .map { $0.data }
            .decode(type: [MyNote].self, decoder: JSONDecoder())
            .receive(on: RunLoop.main)
            .eraseToAnyPublisher()
    }
}

控制台输出为:

任务 . 以错误结束 [-999] 错误域=NSURLErrorDomain 代码=-999 “已取消” UserInfo={NSErrorFailingURLStringKey=https://jsonplaceholder.typicode.com/photos, NSLocalizedDescription=取消, NSErrorFailingURLKey=https://jsonplaceholder.typicode.com/photos}

任何指导将不胜感激。 Xcode 11.4

【问题讨论】:

    标签: ios json xcode swiftui combine


    【解决方案1】:
    let pub = Webservice().fetchNotes()
    

    这个发布者在退出范围时被释放,所以让它成为成员,就像

    private var publisher: AnyPublisher<[MyNote], Error>?
    
    func getWebserviceNotes() {
        self.publisher = Webservice().fetchNotes()
        ...
    

    【讨论】:

    • 太棒了。这行得通。对于其他人 - 我将添加更改后的代码。
    • 更准确地说,必须存储的是sink返回的AnyCancellable,因为当AnyCancellable被销毁时,它会取消订阅。
    【解决方案2】:

    根据 Asperi 的回答 - 您还需要添加:

    var cancellable: AnyCancellable?
    

    然后就可以sink获取数据了:

    func getWebserviceNotes() {
    
        self.publisher = Webservice().fetchNotes()
        guard let pub = self.publisher else { return }
    
        cancellable = pub
                .sink(receiveCompletion: {_ in },
                      receiveValue: { (notes) in
                        self.notes = notes
                })
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-03
      • 2019-02-04
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 2019-03-08
      • 2022-11-10
      相关资源
      最近更新 更多