Combine Framework Update UI doesn't work properly

Viewed 367

I want to try Combine framework, very simple usage, press a UIButton, and update UILabel.

My idea is:

  1. Add a publisher

@Published var cacheText: String?

  1. Subscribe

$cacheText.assign(to: \.text, on: cacheLabel)

  1. assign a value when button pressed.

cacheText = "testString"

Then the label's text should be updated.

The problem is when the button pressed, the @Published value is updated, but the UILabel value doesn't change. e.g the cacheLabel1 was assigned 123 initially but not 789 when button pressed.

Here's the full code:

ViewModel.swift

import Foundation
import Combine

class ViewModel {
    @Published var cacheText: String?

    func setup(_ text: String) {
        cacheText = text
    }

    init() {
        setup("123")
    }
}

ViewController.swift

  class ViewController: UIViewController {
    @IBOutlet weak var cacheLabel: UILabel!

    var viewModel = ViewModel()

    @IBAction func buttonPressed(_ sender: Any) {
        viewModel.setup("789")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        viewModel.$cacheText.assign(to: \.text, on: cacheLabel)
    }
}

Not sure if I missed something, thanks for the help.

1 Answers

The pipeline is dying before you have a chance to tap the button. You have to preserve it, like this:

var storage = Set<AnyCancellable>()
override func viewDidLoad() {
    super.viewDidLoad()
    viewModel.$cacheText.assign(to: \.text, on: cacheLabel).store(in: &storage)
}
Related