-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Remove warnings @AutoOpen @AsyncOpen and @ObservedResults #8068
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove warnings @AutoOpen @AsyncOpen and @ObservedResults #8068
Conversation
e8f218d
to
af344a6
Compare
af344a6
to
4380d99
Compare
RealmSwift/SwiftUI.swift
Outdated
willSet { | ||
objectWillChange.send() | ||
DispatchQueue.main.async { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this dispatch to main here? Is this called from background threads?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tgoyne Because with @AutoOpen
and @AsyncOpen
we set the state directly from the view thread, (for example when there is no user logged when we change the state to waitingForUser), the warning is going to show even if we store it a different variable. We want to call objectWillChange.send()
from the main thread to update the view, but we don't want to do it directly from the UI element.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the set is happening from within a call to update() I think we just don't want to trigger objectWillChange. If it's not, then we want to do the set immediately. Doing an async set causes problems for sendability and is just sort of spooky in general as it means we're temporarily in a weird inconsistent state.
RealmSwift/SwiftUI.swift
Outdated
- note: It is recommend to use the configuration obtained from the user, using `user.configuration(partitionValue:)` | ||
or `user.flexibleSyncConfiguration()` when adding a configuration to this property wrapper, and modify any option from it | ||
if needed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What other configuration could they even use? This only works for sync realms and that's the only way to construct a sync config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
18d4e47
to
4e9d335
Compare
… this will cause undefined behavior` warnings for @AutOOpeN, @AsyncOpen, @ObservedResults and @ObservedSectionedResults. * Defer AutoOpen & AsyncOpen initialization, so it would not call `Realm.asyncOpen` more than once.
4e9d335
to
0c63f6d
Compare
RealmSwift/SwiftUI.swift
Outdated
// we observe the changes in the app state to check for user changes, | ||
// we store an internal state, so we could react to those changes (user login, user change, logout). | ||
app.objectWillChange.sink { app in | ||
switch self.appState { | ||
case .loggedIn(let user): | ||
if let newUser = app.currentUser, | ||
user != newUser { | ||
self.appState = .loggedIn(newUser) | ||
self.asyncOpenState = .connecting | ||
self.asyncOpenForUser(user) | ||
} else if app.currentUser == nil { | ||
self.asyncOpenState = .waitingForUser | ||
self.appState = .loggedOut | ||
} | ||
case .loggedOut: | ||
if let user = app.currentUser { | ||
self.appState = .loggedIn(user) | ||
self.asyncOpenState = .connecting | ||
self.asyncOpenForUser(user) | ||
} | ||
} | ||
}.store(in: &appCancellable) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a retain cycle. self
retains appCancellable
, appCancellable
retains the closure, and the closure retains self
. This probably needs a [weak self]
capture.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed this to avoid the retain cycle
RealmSwift/SwiftUI.swift
Outdated
// we observe the changes in the app state to check for user changes, | ||
// we store an internal state, so we could react to those changes (user login, user change, logout). | ||
app.objectWillChange.sink { [weak self] app in | ||
switch self?.appState { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should do guard let self = self else { return }
rather than checking for nil on every use.
… and @ObservedSectionedResults (#8068) * * Remove `Publishing changes from within view updates is not allowed, this will cause undefined behavior` warnings for @AutOOpeN, @AsyncOpen, @ObservedResults and @ObservedSectionedResults. * Defer AutoOpen & AsyncOpen initialization, so it would not call `Realm.asyncOpen` more than once.
Removed warning from @AutOOpeN @AsyncOpen and @ObservedResults and @ObservedSectionResults
While working on removing the warning, I fixed an issue, where Realm.asyncOpen was been called twice when used in
@AutoOpen
and@AsyncOpen
once when initialised and a second time if we injected a environment value, now this is done one when the wrapped value is called on the view, this is a similar approach to what we do in@ObservedResults
.Also, I added a note to
@AutoOpen
and@AsyncOpen
, which encourage users to inject configurations which comes from a user instead of creating a RealmConfiguration and inject it to the property wrapper.