Property Wrappers
- Property wrappers are things like
@Publish
that are put beforevar
- A property wrapper actually creates a struct
@Published var emojiArt: EmojiArt = EmojiArt()
struct Published {
var wrappedValue: EmojiArt
var projectedValue: Publisher<EmojiArt, Never>
}
var _emojiArt: Published = Published(wrappedValue: EmojiArt())
var emojiArt: EmojiArt {
get { _emojiArt.wrappedValue }
set { _emojiArt.wrappedValue = newValue }
}
-
Publisher<EmojiArt, Never>
is a type that property wrapper decides- The point of wrappers is that it's possible to do something when the value is get/set
- For example when
Published
wrapperValue is changed, it's callingobjectWillChange.send()
-
$
is binding - Binding is used a lot and it's very important because it's all about having a single source of the truth
struct MyView: View {
@State var myString = "Hello"
var body: View {
OtherView(sharedText: $myString)
}
}
struct OtherView: View {
@Binding var sharedText: String
var body: View {
Text(sharedText)
}
}
-
@EnvironmentObject
is similar to.fill()
because when it's use in viewModel it's actually added to all of the views under neath the main View where it's called.
Publishers (18:17)
-
Publisher<Output, Failure>
-
Output
is the type of thing thisPublisher
publishes -
Failure
is the type of thing it communicates if it fails while trying to publish
-
Demo
import Combine
...
@Published private var emojiArt: EmojiArt
private var autosaveCancellable: AnyCancellable?
...
init() {
...
autosaveCancellable = $emojiArt.sink { emojiArt in
print("\(emojiArt.json?.utf8 ?? "nill")")
UserDefaults.standard.set(emojiArt.json, forKey: EmojiArtDocument.untitled)
}
...
- When sink is stored to a variable, it's going to work as long as this ViewModel exists
- This way it's auto saving all the changes as long as ViewModel is used
Top comments (0)