Skip to content

Instantly share code, notes, and snippets.

@JimRoepcke
Created March 26, 2020 01:59
Show Gist options
  • Save JimRoepcke/9c21b8f438172dcdcafb4aaaef6bf846 to your computer and use it in GitHub Desktop.
Save JimRoepcke/9c21b8f438172dcdcafb4aaaef6bf846 to your computer and use it in GitHub Desktop.
Change in Swift behaviour with didSet property observer for @published property in Xcode 11.4
/*
In Xcode 11.3.1, the output is:
>>> setting n to -1
sending value through valueDidChange publisher
situation negative("hello")
<<< done
>>> setting n to 1
sending value through valueDidChange publisher
situation positive("hello")
<<< done
>>> setting n to 1
sending value through valueDidChange publisher
situation positive("hello")
<<< done
>>> setting n to 0
sending value through valueDidChange publisher
situation zero
<<< done
In Xcode 11.4, the output is:
>>> setting n to -1
<<< done
>>> setting n to 1
<<< done
>>> setting n to 1
<<< done
>>> setting n to 0
<<< done
*/
import Foundation
import Combine
enum Situation {
case positive(String)
case zero
case negative(String)
}
struct Thing {
var n: Int
var s: String
var situation: Situation {
if n > 0 {
return .positive(s)
} else if n < 0 {
return .negative(s)
}
return .zero
}
}
public typealias Reducer<Value, Action> = (Value, Action) -> Value
class Store<Value, Action>: ObservableObject {
public fileprivate(set) var reducer: Reducer<Value, Action>
@Published public fileprivate(set) var value: Value {
didSet {
print(" sending value through valueDidChange publisher")
valueDidChange.send(value)
}
}
let valueDidChange = PassthroughSubject<Value, Never>()
init(initialValue: Value, reducer: @escaping Reducer<Value, Action>) {
self.reducer = reducer
self.value = initialValue
}
func send(action: Action) {
self.value = self.reducer(self.value, action)
}
}
let reducer: Reducer<Thing, Int> = { value, action in
var copy = value
copy.n += action
copy.s += "\(action)"
return copy
}
let store = Store<Thing, Int>(
initialValue: Thing(n: 0, s: "hello"),
reducer: reducer
)
let situationCancellable = store.valueDidChange
.map(\.situation)
.sink { situation in print(" situation", situation) }
print(">>> setting n to -1")
store.value.n = -1
print("<<< done")
print(">>> setting n to 1")
store.value.n = 1
print("<<< done")
print(">>> setting n to 1")
store.value.n = 1
print("<<< done")
print(">>> setting n to 0")
store.value.n = 0
print("<<< done")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment