'Swift combine: assign value in .sink, but can't use .assign
$overallSecondsLeft
.map
{ ti -> String? in
let seconds = (ti.rounded(.up))
if seconds > 0
{
return { String(format: "%02d:%02d", $0.0, $0.1) }(seconds.minutesAndSecondsOverHours)
}
return nil
}
.assign(to: \.timerText, on: bv)
.store(in: &cancellables)
does not work. I mean - nothing happens. map returns string, but this string do not come in timerText.
Variant
$overallSecondsLeft
.map
{ ti -> String? in
let seconds = (ti.rounded(.up))
if seconds > 0
{
return { String(format: "%02d:%02d", $0.0, $0.1) }(seconds.minutesAndSecondsOverHours)
}
return nil
}
.sink{ bv.timerText = $0 }
.store(in: &cancellables)
works correctly.
Environment:
class BView: UIView {
...
var timerText: String? {
get { ... }
set { ... }
}
...
}
guard let bv = view as? BView else { return }
Obviously, the question is: w..?
I found an advice to add .receive(on: RunLoop.main) before .assign, but it did not help.
Solution 1:[1]
The problem is that timerText variable is a computed property. The assign(to:on:) works on a KVO-compliant property of an object, and a computed property is not KVO compliant, if you remove the get/set it will work.
Also please note that assign(to:on:) maintains a strong reference to object so you do not have to store the result to the cancellables.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Christos Koninis |
