Skip to content
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

SwiftUI warning - publishing changes within a view (Xcode b5) #7908

Closed
sonisan opened this issue Aug 11, 2022 · 36 comments
Closed

SwiftUI warning - publishing changes within a view (Xcode b5) #7908

sonisan opened this issue Aug 11, 2022 · 36 comments
Assignees

Comments

@sonisan
Copy link

sonisan commented Aug 11, 2022

How frequently does the bug occur?

All the time

Description

Using Xcode beta 5 triggers the following SwiftUI warnings:

[SwiftUI] Publishing changes from within view updates is not allowed, this will cause undefined behavior.

No warning was present in the previous beta 3.
My project uses Realm Sync with the @AutoOpen property wrapper. Besides the warning, the code is working as intended.

Stacktrace & log output

Warnings lead to the following block of code:

...
 @Published var asyncOpenState: AsyncOpenState = .connecting {
        willSet {
            objectWillChange.send() // <--- HERE
        }
    }

...
 private func asyncOpenForUser(_ user: User) {
        asyncOpenState = .connecting // <--- HERE

....

Can you reproduce the bug?

Yes, always

Reproduction Steps

Launch the complete code example from the SwiftUI quickstart on https://www.mongodb.com/docs/realm/sdk/swift/swiftui-tutorial/#complete-code

Version

10.28.5

What SDK flavour are you using?

MongoDB Realm (i.e. Sync, auth, functions)

Are you using encryption?

No, not using encryption

Platform OS and version(s)

macOS 12.5

Build environment

Xcode version: 14.0 beta 5

@QuietRocket
Copy link

I am experiencing the same warning when using @ObservedResults. Also seems to have no effect on the resulting program, but mentioning "undefined behavior" is slightly worrisome.

The code causing the warning is line 205 in ObservableStoragePublisher.

    func send() {
        subscribers.forEach {
            _ = $0.receive() // <- This one
        }
    }

It might be worth noting that I am not using any sync features, just a local database.

@drmarkpowell
Copy link

me too +1

@drmarkpowell
Copy link

Still happening Xcode 14 beta 6, RealmSwift 10.28.6 macOS Monterey 12.5

@sonisan
Copy link
Author

sonisan commented Aug 24, 2022

In my case, it seemed to be tied to @AutoOpen and @AsyncOpen property wrappers. I refactored my authentication flow without them (using let realm = try await Realm(configuration: configuration) and the warnings disappeared.

@robsontenorio
Copy link

Still happening Xcode 14 beta 6, RealmSwift 10.28.6 macOS Ventura 13

image

image

image

@QuietRocket
Copy link

QuietRocket commented Sep 13, 2022

Hello. This issue was opened over a month ago. Will it be addressed?

iOS 16 is out now, and developers want to upload/update their Realm apps. If we can at least have a statement that this warning is negligible (if that is that case) it would be very comforting. Thank you.

@BugMonkey
Copy link

this also affects navigationLink push in iOS16

@stremblayiOS
Copy link

+1

1 similar comment
@reinosutisno
Copy link

+1

@sonisan
Copy link
Author

sonisan commented Sep 17, 2022

@dianaafanador3 ?

@ejm01
Copy link
Contributor

ejm01 commented Sep 19, 2022

I've still been trying to figure out what's happening here. A couple of others have some interesting ideas. The issue seems to be affecting all developers, not just ones using Realm.
One interesting theory here (and elsewhere) says SwiftUI4 may intend for developers to not bind published variables...but I think that'd be odd for Apple to do?

If this warning is on purpose, and we're not supposed to bind published variables, I'm still thinking about what our team can do. But my first guess is this an Apple bug, especially given some reports say the warning can be suppressed by changing button styles.

@drmarkpowell
Copy link

@ericjordanmossman It looks like your intuition may be right on target regarding this issue.

Donny Wals tweet earlier today: "Heck yes! Xcode 14.1 Beta 3 (finally) fixed the "Publishing changes from within view updates is not allowed, this will cause undefined behavior" bug in SwiftUI https://www.donnywals.com/xcode-14-publishing-changes-from-within-view-updates-is-not-allowed-this-will-cause-undefined-behavior/ "

@drmarkpowell
Copy link

I'm still seeing a bunch of these warnings at runtime with Xcode 14.1 beta 3, so perhaps that means that only a certain type of modification within a view update was addressed.

@mattdornfeld
Copy link

I'm seeing this issue when defining a @GestureState variable in a class other than the view. The ui functions as expected but this warning appears.

@aehlke
Copy link

aehlke commented Oct 26, 2022

I'm getting this on 14.1 RC2 in Ventura, but I did not get it on RC1 on Monterey.

@drmarkpowell
Copy link

In our app we're seeing a high number of these purple warnings consistently at runtime using Xcode 14.1 (formerly RC2) on Monterey. Now that 14.1 is final, this is making me more nervous about it.

@dnlfrst
Copy link

dnlfrst commented Nov 13, 2022

I am experiencing the same warning when using @ObservedResults. Also seems to have no effect on the resulting program, but mentioning "undefined behavior" is slightly worrisome.

The code causing the warning is line 205 in ObservableStoragePublisher.

    func send() {
        subscribers.forEach {
            _ = $0.receive() // <- This one
        }
    }

I also observe the runtime warning during the development of gitlapp using realm-swift in version 10.32.0. More importantly, Sentry tracked crashes of the app in production for a marginal fraction of users where the stack trace points to this exact line of code causing a fatal error:

Exception Type: EXC_CRASH (SIGABRT)
Crashed Thread: 0

Application Specific Information:
AttributeGraph precondition failure: %s.
 > AttributeGraph precondition failure: setting value during update: 89784.
 >
Stack overflow in _Z23RLMAddNotificationBlockI10RLMResultsEP20RLMNotificationTokenPT_U13block_pointerFvP11objc_objectP19RLMCollectionChangeP7NSErrorEP7NSArrayIP8NSStringEPU28objcproto17OS_dispatch_queue8NSObject

Thread 0 Crashed:
0   libsystem_kernel.dylib          0x37656abbc         __pthread_kill
1   libsystem_pthread.dylib         0x3b7a67850         pthread_kill
2   libsystem_c.dylib               0x3162756a8         abort
3   AttributeGraph                  0x36c141510         AG::precondition_failure
4   AttributeGraph                  0x36c1256a4         AG::Graph::value_set
5   SwiftUI                         0x310a1f870         Attribute.setValue
6   SwiftUI                         0x3100b1290         GraphHost.flushTransactions
7   SwiftUI                         0x3100e0af8         GraphHost.asyncTransaction<T>
8   SwiftUI                         0x3100e618c         AttributeInvalidatingSubscriber.invalidateAttribute
9   SwiftUI                         0x3100b7f70         AttributeInvalidatingSubscriber.receive
10  SwiftUI                         0x31021df7c         AttributeInvalidatingSubscriber<T>
11  SwiftUI                         0x3100b8b80         SubscriptionLifetime.Connection.receive
12  Combine                         0x32ed98784         AnySubscriberBox.receive
13  Combine                         0x32ed87a64         AnySubscriber<T>
14  gitlapp                         0x20049cb04         [inlined] ObservableStoragePublisher.send (SwiftUI.swift:205)
15  gitlapp                         0x20049cb04         [inlined] Sequence.forEach
16  gitlapp                         0x20049cb04         ObservableStoragePublisher.send
17  gitlapp                         0x20049dac8         ObservableStorage.value.willset (SwiftUI.swift:241)
18  gitlapp                         0x2004ad448         ObservableStorage.value.setter
19  gitlapp                         0x20049ef0c         [inlined] ObservableStorage.value.setter
20  gitlapp                         0x20049ef0c         ObservedResults.Storage.setupValue (SwiftUI.swift:435)
21  gitlapp                         0x2004a0704         ObservedResults.wrappedValue.getter (SwiftUI.swift:519)
[...]

This crash occurred a dozen times, the stack trace is always the same but originates from different views, all of which use @ObservedResults to query Realm. Unfortunately, I am not even able to reproduce the fatal error on my physical device or the simulator running iOS 15 or iOS 16.

Is there any workaround for this?

@agaia
Copy link

agaia commented Nov 15, 2022

I am experiencing the same warning when using @ObservedResults. Also seems to have no effect on the resulting program, but mentioning "undefined behavior" is slightly worrisome.
The code causing the warning is line 205 in ObservableStoragePublisher.

    func send() {
        subscribers.forEach {
            _ = $0.receive() // <- This one
        }
    }

I also observe the runtime warning during the development of gitlapp using realm-swift in version 10.32.0. More importantly, Sentry tracked crashes of the app in production for a marginal fraction of users where the stack trace points to this exact line of code causing a fatal error:

Exception Type: EXC_CRASH (SIGABRT)
Crashed Thread: 0

Application Specific Information:
AttributeGraph precondition failure: %s.
 > AttributeGraph precondition failure: setting value during update: 89784.
 >
Stack overflow in _Z23RLMAddNotificationBlockI10RLMResultsEP20RLMNotificationTokenPT_U13block_pointerFvP11objc_objectP19RLMCollectionChangeP7NSErrorEP7NSArrayIP8NSStringEPU28objcproto17OS_dispatch_queue8NSObject

Thread 0 Crashed:
0   libsystem_kernel.dylib          0x37656abbc         __pthread_kill
1   libsystem_pthread.dylib         0x3b7a67850         pthread_kill
2   libsystem_c.dylib               0x3162756a8         abort
3   AttributeGraph                  0x36c141510         AG::precondition_failure
4   AttributeGraph                  0x36c1256a4         AG::Graph::value_set
5   SwiftUI                         0x310a1f870         Attribute.setValue
6   SwiftUI                         0x3100b1290         GraphHost.flushTransactions
7   SwiftUI                         0x3100e0af8         GraphHost.asyncTransaction<T>
8   SwiftUI                         0x3100e618c         AttributeInvalidatingSubscriber.invalidateAttribute
9   SwiftUI                         0x3100b7f70         AttributeInvalidatingSubscriber.receive
10  SwiftUI                         0x31021df7c         AttributeInvalidatingSubscriber<T>
11  SwiftUI                         0x3100b8b80         SubscriptionLifetime.Connection.receive
12  Combine                         0x32ed98784         AnySubscriberBox.receive
13  Combine                         0x32ed87a64         AnySubscriber<T>
14  gitlapp                         0x20049cb04         [inlined] ObservableStoragePublisher.send (SwiftUI.swift:205)
15  gitlapp                         0x20049cb04         [inlined] Sequence.forEach
16  gitlapp                         0x20049cb04         ObservableStoragePublisher.send
17  gitlapp                         0x20049dac8         ObservableStorage.value.willset (SwiftUI.swift:241)
18  gitlapp                         0x2004ad448         ObservableStorage.value.setter
19  gitlapp                         0x20049ef0c         [inlined] ObservableStorage.value.setter
20  gitlapp                         0x20049ef0c         ObservedResults.Storage.setupValue (SwiftUI.swift:435)
21  gitlapp                         0x2004a0704         ObservedResults.wrappedValue.getter (SwiftUI.swift:519)
[...]

This crash occurred a dozen times, the stack trace is always the same but originates from different views, all of which use @ObservedResults to query Realm. Unfortunately, I am not even able to reproduce the fatal error on my physical device or the simulator running iOS 15 or iOS 16.

Is there any workaround for this?

I have the exact same issue with @ObservedResults, also looking for a workaround

@JFERSD
Copy link

JFERSD commented Nov 16, 2022

I have the same issue with @ObservedResults too

@ThaC0derDre
Copy link

I am experiencing the same warning when using @ObservedResults. Also seems to have no effect on the resulting program, but mentioning "undefined behavior" is slightly worrisome.

The code causing the warning is line 205 in ObservableStoragePublisher.

    func send() {
        subscribers.forEach {
            _ = $0.receive() // <- This one
        }
    }

It might be worth noting that I am not using any sync features, just a local database.

Same issue.. Still not a peep regarding this from the team?

@ejm01
Copy link
Contributor

ejm01 commented Nov 16, 2022

One solution might be waiting for the observable storage to finish set up before calling objectWillChange.send(). Appears to resolve the warning for the apps I've been working on locally. Feel free to the try branch in testing. Still need to understand all the implications and if it covers all cases.

@ejm01
Copy link
Contributor

ejm01 commented Nov 17, 2022

I don't think this is the right solution. It causes a couple of legitimate testing failures. Needs to be looked into.

@santiagoSoft
Copy link

Same issue waiting for the fix.

@X901
Copy link

X901 commented Nov 26, 2022

This issue also happend to me
Screenshot 2022-11-26 at 9 11 00 PM

@esummers
Copy link

esummers commented Dec 7, 2022

This continues to be an issue in 10.33.0

@dianaafanador3
Copy link
Contributor

This is something we are working out at the moment. We want to remove all the SwiftUI warnings that appear because of our property wrappers. I'll have a branch to test out soon.

@dianaafanador3
Copy link
Contributor

I have this branch #8068 which removes the warnings in both AsyncOpen/AutoOpen and ObservedResults in my sample project, can someone test it on their projects and check if they still are seeing the warning?.

@drmarkpowell
Copy link

drmarkpowell commented Dec 14, 2022 via email

@PhilippeWeidmann
Copy link

I have this branch #8068 which removes the warnings in both AsyncOpen/AutoOpen and ObservedResults in my sample project, can someone test it on their projects and check if they still are seeing the warning?.

I can confirm that I don't see a warning with your branch 🎉

@dianaafanador3
Copy link
Contributor

@PhilippeWeidmann can you confirm which property wrappers are you using?

@PhilippeWeidmann
Copy link

I'm using @ObservedResults . However I'm not using AsyncOpen/AutoOpen so I cannot confirm if it's also working for them

@horatiu1921
Copy link

I can also confirm that the warnings are gone for @ObservedResults.

@reinosutisno
Copy link

I have this branch #8068 which removes the warnings in both AsyncOpen/AutoOpen and ObservedResults in my sample project, can someone test it on their projects and check if they still are seeing the warning?.

I can confirm that your branch removes the warnings for @ObservedResults

@drmarkpowell
Copy link

Hey mostly good news for you on this.

I tested our 2 apps that used @AsyncOpen @AutOOpeN and @ObservedResults using Xcode 14.2 (final) and your branch after running with latest production release of RealmSwift. Simulator was iOS 16.2.

Both apps showed this warning from @ObservedResults running release version:

**[SwiftUI] Publishing changes from within view updates is not allowed, this will cause undefined behavior.**

Running these apps rebuilt using the branch version made these warnings go away. Success!

The only potential issue I found was of a somewhat different type, maybe not one I've seen mentioned yet in the GitHub here yet that I can recall.

For one of my apps I was able to generate this warning:

**Thread Performance Checker: Thread running at QOS_CLASS_USER_INTERACTIVE waiting on a lower QoS thread running at QOS_CLASS_DEFAULT. Investigate ways to avoid priority inversions**

Here is the full console output from the run with a little context before and after to show you what is up.

**Login success: success(<RLMUser: 0x600000327040>)**

**2022-12-16 14:02:20.785797-0800 JPLMobile[3213:20238125] Sync: Connection[1]: Session[1]: client_reset_config = false, Realm exists = true, client reset = false**

**2022-12-16 14:02:20.890231-0800 JPLMobile[3213:20238125] Sync: Connected to endpoint '<ip_addr>:443' (from '<ip_addr>:<port>')**

**Thread Performance Checker: Thread running at QOS_CLASS_USER_INTERACTIVE waiting on a lower QoS thread running at QOS_CLASS_DEFAULT. Investigate ways to avoid priority inversions**

**PID: 3213, TID: 20237412**

**Backtrace**

**=================================================================**

**3   JPLMobile                           0x00000001060cbe14 _ZN5realm4util14SemaphoreMutex4lockEv + 32**

**4   JPLMobile                           0x00000001058ddd60 _ZNSt3__111unique_lockIN5realm4util14SemaphoreMutexEEC2ERS3_ + 60**

**5   JPLMobile                           0x00000001058ddce0 _ZNSt3__111unique_lockIN5realm4util14SemaphoreMutexEEC1ERS3_ + 36**

**6   JPLMobile                           0x00000001058d1a10 _ZN5realm4util17InterprocessMutex4lockEv + 48**

**7   JPLMobile                           0x00000001058d00e4 _ZN5realm2DB14do_begin_writeEv + 80**

**8   JPLMobile                           0x00000001058d42e0 _ZN5realm2DB17AsyncCommitHelper20blocking_begin_writeEv + 288**

**9   JPLMobile                           0x00000001058d41a4 _ZN5realm2DB29do_begin_possibly_async_writeEv + 56**

**10  JPLMobile                           0x000000010604b7c4 _ZN5realm11Transaction18acquire_write_lockEv + 116**

**11  JPLMobile                           0x0000000105bf8bcc _ZN5realm11Transaction16promote_to_writeINS_5_impl23NullInstructionObserverEEEbPT_b + 228**

**12  JPLMobile                           0x0000000105bf18d4 _ZN5realm11Transaction16promote_to_writeEb + 52**

**13  JPLMobile                           0x0000000105bf10c8 _ZN5realm5Realm13update_schemaENS_6SchemaEyNSt3__18functionIFvNS2_10shared_ptrIS0_EES5_RS1_EEENS3_IFvS5_EEEb + 584**

**14  JPLMobile                           0x0000000105637768 +[RLMRealm realmWithConfiguration:queue:error:] + 2304**

**15  JPLMobile                           0x0000000105640698 _ZZZ62+[RLMRealm asyncOpenWithConfiguration:callbackQueue:callback:]ENK3$_3clEN5realm19ThreadSafeReferenceESt13exception_ptrENUlvE_clEv + 80**

**16  JPLMobile                           0x000000010564063c ___ZZ62+[RLMRealm asyncOpenWithConfiguration:callbackQueue:callback:]ENK3$_3clEN5realm19ThreadSafeReferenceESt13exception_ptr_block_invoke_2 + 28**

**17  libdispatch.dylib                   0x000000010b830594 _dispatch_call_block_and_release + 24**

**18  libdispatch.dylib                   0x000000010b831d5c _dispatch_client_callout + 16**

**19  libdispatch.dylib                   0x000000010b842808 _dispatch_main_queue_drain + 1316**

**20  libdispatch.dylib                   0x000000010b8422d4 _dispatch_main_queue_callback_4CF + 40**

**21  CoreFoundation                      0x0000000180372ca4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12**

**22  CoreFoundation                      0x000000018036d360 __CFRunLoopRun + 1956**

**23  CoreFoundation                      0x000000018036c7a4 CFRunLoopRunSpecific + 584**

**24  GraphicsServices                    0x0000000188ff7c98 GSEventRunModal + 160**

**25  UIKitCore                           0x000000010cc2237c -[UIApplication _run] + 868**

**26  UIKitCore                           0x000000010cc26374 UIApplicationMain + 124**

**27  SwiftUI                             0x0000000110ef10d4 OUTLINED_FUNCTION_51 + 496**

**28  SwiftUI                             0x0000000110ef0f7c OUTLINED_FUNCTION_51 + 152**

**29  SwiftUI                             0x0000000110656b60 OUTLINED_FUNCTION_10 + 88**

**30  JPLMobile                           0x000000010501ab28 $s9JPLMobile0A3AppV5$mainyyFZ + 40**

**31  JPLMobile                           0x000000010501b9a8 main + 12**

**2022-12-16 14:02:21.678254-0800 JPLMobile[3213:20238125] Sync: Connection[2]: Session[2]: client_reset_config = false, Realm exists = true, client reset = false**

**2022-12-16 14:02:21.685395-0800 JPLMobile[3213:20238125] Sync: Connection[3]: Session[3]: client_reset_config = false, Realm exists = true, client reset = false**

Seems to have happened just after starting the Realm session as I'm setting up several configured realms (each with different partitions). After this warning, the app seems to run fine without any other issues, and just to be clear I was seeing the "Publishing changes from UI thread...unexpected results warning by the hundreds all the time before I tested the branch, so that does seem to do the trick on that warning.

@dianaafanador3
Copy link
Contributor

Thanks to everyone for testing this branch.
@drmarkpowell There is an issue which mentions this warning #8042, I'll attach your stack trace to the other issue.

@dianaafanador3
Copy link
Contributor

Fix merged, will be available on the next release

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests