es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

No recibiendo valor de PassthroughSubject en el segundo intento.

Estoy utilizando Combine para enviar valores desde una clase de modelo de vista a una vista. El código para la clase de modelo de vista es:

var subject = PassthroughSubject<user, error="">()

func validateLogin(username: String, password: String){
    let url = "someurl"
    let httpRequest = MerchantLogin(username: username, password: password)
    let httpBody = try! JSONEncoder().encode(httpRequest)
    cancellable = webservice.apiRequest(url: URL(string: url)!, resultType: User.self, httpMethodType: .post, requestBody: httpBody)
    receive(on: RunLoop.main)
        .sink { [weak self] completion in
            switch completion {
            case .failure(let error):
                 print(error)
                 self?.subject.send(completion: .failure(error))
            case .finished:
                 print("finished")
            }
        } receiveValue: { user in
            self.subject.send(user)
        }
}

El código para la clase de vista es:

private var binding = Set<anycancellable>()
var viewModel: LoginViewModel!

override func viewDidLoad() {
    super.viewDidLoad()
    setupBinding()
}

func setupBinding() {
    viewModel.subject
        .receive(on: RunLoop.main)
        .sink { [weak self] completion in
            switch completion {
            case .finished:
                print("")
            case .failure(let error):
                let message = "\(error)"
                self?.presentAlert(withTitle: "¡Oh, vaya!", message: message)
            }
        } receiveValue: { [weak self] user in
            print(user)
        }.store(in: &binding) 
}   

@IBAction func loginAction(_ sender: Any) {
    self.viewModel.validateLogin(username: self.usernameTextFiled.text!, password: self.passwordTextField.text!)
}

En el primer botón presionado, estoy recibiendo el valor y el evento en el controlador de vista, pero cuando intento presionar el botón nuevamente, la ejecución termina en el modelo de vista y no estoy recibiendo ningún evento en el controlador de vista.</user,>

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema podría estar relacionado con el hecho de que la propiedad cancellable en el modelo de vista no se reinicia correctamente después de que se complete la primera llamada a la API. Esto significa que las llamadas posteriores a validateLogin no crearán una nueva suscripción al flujo combinado y no generarán más eventos.

    Para solucionar este problema, podrías agregar una línea para cancelar la suscripción anterior antes de crear una nueva en el método validateLogin:

    func validateLogin(username: String, password: String) {
        cancellable?.cancel() // cancelar la suscripción anterior
        // ...
    }
    

    Esto asegurará que el modelo de vista siempre cree una nueva suscripción al flujo cuando se llame a validateLogin, lo que permitirá que el controlador de vista reciba valores y eventos cada vez que se presione el botón.

Comments are closed.