[英]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.