Swift - 未调用组合订阅

问题描述

最近,我尝试使用 freshOS/Networking swift 包。

我多次阅读自述文件,但我无法让它与我一起工作。我正在尝试获取使用公共 API 服务的国家/地区列表,这是我所做的:

模型

import Foundation
import Networking

struct CountryModel: Codable {
    let error: Bool
    let msg: String
    let data: [Country]
}

struct Country: Codable {
    let name: String
    let Iso3: String
}

extension Country: NetworkingJSONDecodable {}
extension CountryModel: NetworkingJSONDecodable {}

/* 
Output
{
     "error":false,"msg":"countries and ISO codes retrieved","data":[
          {
               "name":"Afghanistan","Iso2":"AF","Iso3":"AFG"
          }
     ]
}
*/

视图控制器 + callAPI() 函数中的 print(data) 不打印

    override func viewDidLoad() {
        super.viewDidLoad()
        
        configureUI()
        callAPI()
        
    }

    fileprivate func configureUI() {
        title = "Choose Country"
        
        view.addSubview(tableView)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.frame = view.bounds
    }

    fileprivate func callAPI() {
        let countriesService = CountriesApi()
        var cancellable = Set<AnyCancellable>()
        
        countriesService.countries().sink(receiveCompletion: { completion in
            switch completion {
            case .finished:
                print("finished") // not printing
                break
            case .failure(let error):
                print(error.localizedDescription)
            }
        }) { data in
            print(data) // not printing
            self.countriesData = data
        }.store(in: &cancellable)
    }

CountriesAPI()

struct CountriesApi: NetworkingService {
    
    let network = NetworkingClient(baseURL: "https://countriesNow.space/api/v0.1")
    
    // Create
    func create(country c: Country) -> AnyPublisher<Country,Error> {
        post("/countries/create",params: ["name" : c.name,"Iso3" : c.Iso3])
    }
    
    // Read
    func fetch(country c: Country) -> AnyPublisher<Country,Error> {
        get("/countries/\(c.Iso3)")
    }
    
    // Update
    func update(country c: Country) -> AnyPublisher<Country,Error> {
        put("/countries/\(c.Iso3)","Iso3" : c.Iso3])
    }
    
    // Delete
    func delete(country c: Country) -> AnyPublisher<Void,Error> {
        delete("/countries/\(c.Iso3)")
    }
    
    func countries() -> AnyPublisher<[CountryModel],Error> {
        get("/countries/iso")
    }
}

我希望有人能帮助我解决我所缺少的。

解决方法

问题在于您的 callAPI() 函数,如果您将代码更改为:

    fileprivate func callAPI() {
        let countriesService = CountriesApi()
        var cancellable = Set<AnyCancellable>()
        
        countriesService.countries()
            .print("debugging")
            .sink(receiveCompletion: { completion in
                switch completion {
                case .finished:
                    print("finished") // not printing
                    break
                case .failure(let error):
                    print(error.localizedDescription)
                }
            }) { data in
                print(data) // not printing
                self.countriesData = data
            }.store(in: &cancellable)
    }

注意我刚刚添加了行 print("debugging")

如果您运行它,您可以在控制台中看到您的订阅立即被取消。

调试:接收取消

为什么?因为您的“可取消”或“订阅”仅存在于您的函数范围内,并且会立即解除分配。

您可以做的是在 ViewController 中添加可取消设置为属性,如下所示:

final class ViewController: UIViewController {
    
    private var cancellable = Set<AnyCancellable>()
    
    fileprivate func callAPI() {
        // the code you had without the set
        let countriesService = CountriesApi()
        
        countriesService.countries().sink(receiveCompletion: { completion in
            switch completion {
            case .finished:
                print("finished") // not printing
                break
            case .failure(let error):
                print(error.localizedDescription)
            }
        }) { data in
            print(data) // not printing
            self.countriesData = data
        }.store(in: &cancellable)
    }
    
}