Skip to content

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

Merged
merged 3 commits into from
Jan 4, 2023

Conversation

dianaafanador3
Copy link
Contributor

@dianaafanador3 dianaafanador3 commented Dec 14, 2022

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 @AsyncOpenonce 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.

@cla-bot cla-bot bot added the cla: yes label Dec 14, 2022
@dianaafanador3 dianaafanador3 force-pushed the dp/remove_warning_swiftui_property_wrappers branch 3 times, most recently from e8f218d to af344a6 Compare December 19, 2022 23:25
@dianaafanador3 dianaafanador3 changed the title WIP: Remove warnings @AutoOpen @AsyncOpen and @ObservedResults Remove warnings @AutoOpen @AsyncOpen and @ObservedResults Dec 19, 2022
@dianaafanador3 dianaafanador3 marked this pull request as ready for review December 20, 2022 15:21
@dianaafanador3 dianaafanador3 force-pushed the dp/remove_warning_swiftui_property_wrappers branch from af344a6 to 4380d99 Compare December 20, 2022 15:25
willSet {
objectWillChange.send()
DispatchQueue.main.async {
Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Member

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.

Comment on lines 1694 to 1696
- 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.
Copy link
Member

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.

Copy link
Contributor Author

@dianaafanador3 dianaafanador3 Dec 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tgoyne Related to some issue #7931), since v10.12.0, but now that I think about it, we should disable any use of a configuration which doesn't come from a user. And avoid this issues when users inject a local configuration so they can set options like encryptedKey or fileUrl.

@dianaafanador3 dianaafanador3 force-pushed the dp/remove_warning_swiftui_property_wrappers branch 3 times, most recently from 18d4e47 to 4e9d335 Compare December 22, 2022 22:44
… 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.
@dianaafanador3 dianaafanador3 force-pushed the dp/remove_warning_swiftui_property_wrappers branch from 4e9d335 to 0c63f6d Compare December 23, 2022 09:28
@dianaafanador3
Copy link
Contributor Author

@tgoyne I changed the approach for @AutOOpeN and @AsyncOpen after yesterday's chat. Now, the state is initialised for the first render, and we are publishing changes only if we are not coming from an update()

Comment on lines 1488 to 1509
// 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)
Copy link
Member

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.

Copy link
Contributor Author

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

@dianaafanador3 dianaafanador3 requested a review from tgoyne January 4, 2023 09:47
// 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 {
Copy link
Member

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.

@dianaafanador3 dianaafanador3 merged commit 6a1ec63 into master Jan 4, 2023
@dianaafanador3 dianaafanador3 deleted the dp/remove_warning_swiftui_property_wrappers branch January 4, 2023 17:59
dianaafanador3 added a commit that referenced this pull request Jan 23, 2023
… 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.
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants