简体   繁体   English

Swift - 未调用组合订阅

[英]Swift - Combine subscription not being called

Recently, I tried to use freshOS/Networking swift package.最近,我尝试使用freshOS/Networking swift package。

And I read the README file several times and I couldn't make it work with me.而且我多次阅读 README 文件,但我无法让它与我一起工作。 I'm trying to get a list of countries using public API services and here's what I did:我正在尝试获取使用公共 API 服务的国家/地区列表,这就是我所做的:

Model Model

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"
          }
     ]
}
*/

View Controller + print(data) in callAPI() function does not print查看 Controller + print(data) in callAPI() function 不打印

    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()国家API()

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)", params: ["name" : c.name, "Iso3" : c.Iso3])
    }
    
    // Delete
    func delete(country c: Country) -> AnyPublisher<Void, Error> {
        delete("/countries/\(c.Iso3)")
    }
    
    func countries() -> AnyPublisher<[CountryModel], Error> {
        get("/countries/iso")
    }
}

I hope someone can help with what I'm missing.我希望有人可以帮助我解决我所缺少的。

The problem lies in your callAPI() function, if you change your code to this:问题在于您的callAPI() function,如果您将代码更改为:

    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)
    }

Notice I just added the line print("debugging") .请注意,我刚刚添加了行print("debugging")

If you run that, you can see in your console that your subscription gets cancelled immediately.如果您运行它,您可以在控制台中看到您的订阅立即被取消。

debugging: receive cancel调试:接收取消

Why?为什么? Because your "cancellable" or "subscription" only lives in the scope of your function and it is deallocated immediately.因为您的“可取消”或“订阅”仅存在于您的 function 的 scope 中,并且会立即解除分配。

What you can do is add the cancellables set as a property in your ViewController, like this:您可以做的是在 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)
    }
    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM