realm / realm-swift

Realm is a mobile database: a replacement for Core Data & SQLite
https://realm.io
Apache License 2.0
16.32k stars 2.15k forks source link

SwiftUI: unmanaged objects and `@StateObject`/`@ObservedObject` #7810

Open flowbe opened 2 years ago

flowbe commented 2 years ago

How frequently does the bug occur?

All the time

Description

When annotating a Realm object as @StateObject or @ObservedObject, a crash happens if this object is unmanaged. If the object is not in any Realm, it would be great to still have the observation working like any other object in SwiftUI…

Stacktrace & log output

2022-05-24 10:54:02.383660+0200 Mail[77647:14805187] *** Terminating app due to uncaught exception 'RLMException', reason: 'Only objects which are managed by a Realm support change notifications'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010e5f1604 __exceptionPreprocess + 242
    1   libobjc.A.dylib                     0x000000010d1fca45 objc_exception_throw + 48
    2   MailCore                            0x000000011433aee4 RLMObjectBaseAddNotificationBlock + 196
    3   MailCore                            0x000000011456d467 $sSo13RLMObjectBaseC10RealmSwiftE8_observe8keyPaths2on_So20RLMNotificationTokenCSaySSGSg_So17OS_dispatch_queueCSgyAC12ObjectChangeOyxGctABRbzlF + 439
    4   MailCore                            0x00000001145874a0 $sSo13RLMObjectBaseC10RealmSwiftE8_observeySo20RLMNotificationTokenCSaySSGSg_xt7Combine10SubscriberRzs5NeverO7FailureRtzyt5InputRtzlF + 240
    5   MailCore                            0x0000000114587650 $sSo13RLMObjectBaseC10RealmSwift0C12SubscribableA2cDP8_observeySo20RLMNotificationTokenCSaySSGSg_qd__t7Combine10SubscriberRd__s5NeverO7FailureRtd__yt5InputRtd__lFTW + 16
    6   MailCore                            0x000000011458e0c0 $s10RealmSwift0A10PublishersO10WillChangeV7receive10subscriberyqd___t7Combine10SubscriberRd__s5NeverO7FailureRtd__yt5InputRtd__lF + 192
    7   MailCore                            0x000000011458e44b $s10RealmSwift0A10PublishersO10WillChangeVy_xG7Combine9PublisherAagHP7receive10subscriberyqd___tAG10SubscriberRd__7FailureQyd__AMRtz5InputQyd__6OutputRtzlFTW + 27
    8   SwiftUI                             0x00000001211c6e0a $s7SwiftUI20SubscriptionLifetimeC9subscribe10subscriber2toyqd___xt7Combine11CancellableRd__AG10SubscriberRd__7FailureAgIPQyd__AJRtz5InputAKQyd__6OutputRtzlF + 1095
    9   SwiftUI                             0x00000001210b2710 $s7SwiftUI25ObservedObjectPropertyBox33_0B8DF51E8EF5CE25E70FFDB20F490665LLV6update8property5phaseSbAA0cD0VyxGz_AA12_GraphInputsV5PhaseVtF + 247
    10  SwiftUI                             0x0000000121422a00 $s7SwiftUI9BoxVTable33_68550FF604D39F05971FE35A26EE75B0LLC6update3ptr8property5phaseSbSv_SvAA12_GraphInputsV5PhaseVtFZ + 207
    11  SwiftUI                             0x0000000121421e8c $s7SwiftUI22_DynamicPropertyBufferV6update9container5phaseSbSv_AA12_GraphInputsV5PhaseVtF + 68
    12  SwiftUI                             0x0000000120e57312 $s7SwiftUI11StateObjectV3Box33_26399901AD247149EF526863F9AAF7C4LLV6update8property5phaseSbACyxGz_AA12_GraphInputsV5PhaseVtF + 181
    13  SwiftUI                             0x0000000121422a00 $s7SwiftUI9BoxVTable33_68550FF604D39F05971FE35A26EE75B0LLC6update3ptr8property5phaseSbSv_SvAA12_GraphInputsV5PhaseVtFZ + 207
    14  SwiftUI                             0x0000000121421e8c $s7SwiftUI22_DynamicPropertyBufferV6update9container5phaseSbSv_AA12_GraphInputsV5PhaseVtF + 68
    15  SwiftUI                             0x00000001210fbfb6 $s7SwiftUI11DynamicBody33_49D2A32E637CD497C6DE29B8E060A506LLV11updateValueyyF + 336
    16  SwiftUI                             0x00000001212f623d $s14AttributeGraph0A0VyACyxGqd__c5ValueQyd__RszAA12StatefulRuleRd__lufcADSPyqd__GXEfU_ySv_So11AGAttributeatcyXEfU_ySv_AJtcqd__mcfu_ySv_AJtcfu0_TA + 26
    17  AttributeGraph                      0x0000000145bb57cd _ZN2AG5Graph11UpdateStack6updateEv + 559
    18  AttributeGraph                      0x0000000145bb5dc3 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 411
    19  AttributeGraph                      0x0000000145bbc193 _ZN2AG5Graph20input_value_ref_slowENS_4data3ptrINS_4NodeEEENS_11AttributeIDEjPK15AGSwiftMetadataRhl + 553
    20  AttributeGraph                      0x0000000145bd27f0 AGGraphGetValue + 213
    21  SwiftUI                             0x00000001210fbaf6 $s7SwiftUI10StaticBody33_49D2A32E637CD497C6DE29B8E060A506LLV9container9ContainerQzvg + 102
    22  SwiftUI                             0x00000001210fbbba $s7SwiftUI10StaticBody33_49D2A32E637CD497C6DE29B8E060A506LLV11updateValueyyF + 142
    23  SwiftUI                             0x00000001212f623d $s14AttributeGraph0A0VyACyxGqd__c5ValueQyd__RszAA12StatefulRuleRd__lufcADSPyqd__GXEfU_ySv_So11AGAttributeatcyXEfU_ySv_AJtcqd__mcfu_ySv_AJtcfu0_TA + 26
    24  AttributeGraph                      0x0000000145bb57cd _ZN2AG5Graph11UpdateStack6updateEv + 559
    25  AttributeGraph                      0x0000000145bb5dc3 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 411
    26  AttributeGraph                      0x0000000145bbc193 _ZN2AG5Graph20input_value_ref_slowENS_4data3ptrINS_4NodeEEENS_11AttributeIDEjPK15AGSwiftMetadataRhl + 553
    27  AttributeGraph                      0x0000000145bd27f0 AGGraphGetValue + 213
    28  SwiftUI                             0x000000012150c9b0 $s7SwiftUI19_ConditionalContentVA2A4ViewRzAaDR_rlE05ChildE033_1A625ACC143FD8524C590782FD8F4F8CLLV7contentACyxq_Gvg + 59
    29  SwiftUI                             0x000000012150cadd $s7SwiftUI19_ConditionalContentVA2A4ViewRzAaDR_rlE05ChildE033_1A625ACC143FD8524C590782FD8F4F8CLLV5valueAA03AnyE0Vvg + 274
    30  SwiftUI                             0x000000012150cbe1 $s7SwiftUI19_ConditionalContentVA2A4ViewRzAaDR_rlE05ChildE033_1A625ACC143FD8524C590782FD8F4F8CLLVyxq__G14AttributeGraph4RuleAaiJP5value5ValueQzvgTW + 48
    31  AttributeGraph                      0x0000000145bd5d67 $s14AttributeGraph4RuleP5value5ValueQzvgTj + 7
    32  SwiftUI                             0x0000000120b049de $s14AttributeGraph0A0VyACyxGqd__c5ValueQyd__RszAA4RuleRd__lufcADSPyqd__GXEfU_ySv_So11AGAttributeatcyXEfU_ySv_AJtcqd__mcfu_ySv_AJtcfu0_ + 111
    33  AttributeGraph                      0x0000000145bb57cd _ZN2AG5Graph11UpdateStack6updateEv + 559
    34  AttributeGraph                      0x0000000145bb5dc3 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 411
    35  AttributeGraph                      0x0000000145bbc193 _ZN2AG5Graph20input_value_ref_slowENS_4data3ptrINS_4NodeEEENS_11AttributeIDEjPK15AGSwiftMetadataRhl + 553
    36  AttributeGraph                      0x0000000145bd27f0 AGGraphGetValue + 213
    37  SwiftUI                             0x000000012110318c $s7SwiftUI11AnyViewList33_A96961F3546506F21D8995C6092F15B5LLV11updateValueyyF + 81
    38  SwiftUI                             0x0000000120ab8377 $s14AttributeGraph0A0VyACyxGqd__c5ValueQyd__RszAA12StatefulRuleRd__lufcADSPyqd__GXEfU_ySv_So11AGAttributeatcyXEfU_ySv_AJtcqd__mcfu_ySv_AJtcfu0_7SwiftUI8ViewList_p_AK03AnyiJ033_A96961F3546506F21D8995C6092F15B5LLVTg5TA + 15
    39  AttributeGraph                      0x0000000145bb57cd _ZN2AG5Graph11UpdateStack6updateEv + 559
    40  AttributeGraph                      0x0000000145bb5dc3 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 411
    41  AttributeGraph                      0x0000000145bbc193 _ZN2AG5Graph20input_value_ref_slowENS_4data3ptrINS_4NodeEEENS_11AttributeIDEjPK15AGSwiftMetadataRhl + 553
    42  AttributeGraph                      0x0000000145bd27f0 AGGraphGetValue + 213
    43  SwiftUI                             0x0000000120a60347 $s14AttributeGraph0A0VyACyxGqd__c5ValueQyd__RszAA4RuleRd__lufcADSPyqd__GXEfU_ySv_So11AGAttributeatcyXEfU_ySv_AJtcqd__mcfu_ySv_AJtcfu0_7SwiftUI8ViewList_p_AK01_hI7OutputsV14ApplyModifiers33_70E71091E926A1B09B75AAEB38F5AA3FLLVTg5 + 97
    44  AttributeGraph                      0x0000000145bb57cd _ZN2AG5Graph11UpdateStack6updateEv + 559
    45  AttributeGraph                      0x0000000145bb5dc3 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 411
    46  AttributeGraph                      0x0000000145bbc193 _ZN2AG5Graph20input_value_ref_slowENS_4data3ptrINS_4NodeEEENS_11AttributeIDEjPK15AGSwiftMetadataRhl + 553
    47  AttributeGraph                      0x0000000145bd27f0 AGGraphGetValue + 213
    48  SwiftUI                             0x0000000121103939 $s7SwiftUI11AnyViewList33_A96961F3546506F21D8995C6092F15B5LLV4ItemC4listAA0dE0_pvg + 99
    49  SwiftUI                             0x000000012110332d $s7SwiftUI11AnyViewList33_A96961F3546506F21D8995C6092F15B5LLV11updateValueyyF + 498
    50  SwiftUI                             0x0000000120ab8377 $s14AttributeGraph0A0VyACyxGqd__c5ValueQyd__RszAA12StatefulRuleRd__lufcADSPyqd__GXEfU_ySv_So11AGAttributeatcyXEfU_ySv_AJtcqd__mcfu_ySv_AJtcfu0_7SwiftUI8ViewList_p_AK03AnyiJ033_A96961F3546506F21D8995C6092F15B5LLVTg5TA + 15
    51  AttributeGraph                      0x0000000145bb57cd _ZN2AG5Graph11UpdateStack6updateEv + 559
    52  AttributeGraph                      0x0000000145bb5dc3 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 411
    53  AttributeGraph                      0x0000000145bbc193 _ZN2AG5Graph20input_value_ref_slowENS_4data3ptrINS_4NodeEEENS_11AttributeIDEjPK15AGSwiftMetadataRhl + 553
    54  AttributeGraph                      0x0000000145bd27f0 AGGraphGetValue + 213
    55  SwiftUI                             0x0000000121103939 $s7SwiftUI11AnyViewList33_A96961F3546506F21D8995C6092F15B5LLV4ItemC4listAA0dE0_pvg + 99
    56  SwiftUI                             0x000000012110332d $s7SwiftUI11AnyViewList33_A96961F3546506F21D8995C6092F15B5LLV11updateValueyyF + 498
    57  SwiftUI                             0x0000000120ab8377 $s14AttributeGraph0A0VyACyxGqd__c5ValueQyd__RszAA12StatefulRuleRd__lufcADSPyqd__GXEfU_ySv_So11AGAttributeatcyXEfU_ySv_AJtcqd__mcfu_ySv_AJtcfu0_7SwiftUI8ViewList_p_AK03AnyiJ033_A96961F3546506F21D8995C6092F15B5LLVTg5TA + 15
    58  AttributeGraph                      0x0000000145bb57cd _ZN2AG5Graph11UpdateStack6updateEv + 559
    59  AttributeGraph                      0x0000000145bb5dc3 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 411
    60  AttributeGraph                      0x0000000145bbc193 _ZN2AG5Graph20input_value_ref_slowENS_4data3ptrINS_4NodeEEENS_11AttributeIDEjPK15AGSwiftMetadataRhl + 553
    61  AttributeGraph                      0x0000000145bd27f0 AGGraphGetValue + 213
    62  SwiftUI                             0x0000000121103939 $s7SwiftUI11AnyViewList33_A96961F3546506F21D8995C6092F15B5LLV4ItemC4listAA0dE0_pvg + 99
    63  SwiftUI                             0x000000012110332d $s7SwiftUI11AnyViewList33_A96961F3546506F21D8995C6092F15B5LLV11updateValueyyF + 498
    64  SwiftUI                             0x0000000120ab8377 $s14AttributeGraph0A0VyACyxGqd__c5ValueQyd__RszAA12StatefulRuleRd__lufcADSPyqd__GXEfU_ySv_So11AGAttributeatcyXEfU_ySv_AJtcqd__mcfu_ySv_AJtcfu0_7SwiftUI8ViewList_p_AK03AnyiJ033_A96961F3546506F21D8995C6092F15B5LLVTg5TA + 15
    65  AttributeGraph                      0x0000000145bb57cd _ZN2AG5Graph11UpdateStack6updateEv + 559
    66  AttributeGraph                      0x0000000145bb5dc3 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 411
    67  AttributeGraph                      0x0000000145bbc193 _ZN2AG5Graph20input_value_ref_slowENS_4data3ptrINS_4NodeEEENS_11AttributeIDEjPK15AGSwiftMetadataRhl + 553
    68  AttributeGraph                      0x0000000145bd27f0 AGGraphGetValue + 213
    69  SwiftUI                             0x0000000120e23b72 $s7SwiftUI24DynamicLayoutViewAdaptor33_8B9C7F39264416187A895085215951BCLLV12updatedItemsAA0E4List_pSgyF + 81
    70  SwiftUI                             0x0000000120968af9 $s7SwiftUI20DynamicContainerInfoV11updateItems33_023AA827B8A8D39774F7A0C281455FEELL18disableTransitionsSb7changed_Sb8hasDepthtSb_tFAA0C17LayoutViewAdaptor33_8B9C7F39264416187A895085215951BCLLV_Tg5 + 53
    71  SwiftUI                             0x0000000120967142 $s7SwiftUI20DynamicContainerInfoV11updateValueyyFAA0C17LayoutViewAdaptor33_8B9C7F39264416187A895085215951BCLLV_Tg5 + 556
    72  SwiftUI                             0x0000000120a86b47 $s14AttributeGraph0A0VyACyxGqd__c5ValueQyd__RszAA12StatefulRuleRd__lufcADSPyqd__GXEfU_ySv_So11AGAttributeatcyXEfU_ySv_AJtcqd__mcfu_ySv_AJtcfu0_7SwiftUI16DynamicContainerV4InfoV_AK0ijK0VyAK0I17LayoutViewAdaptor33_8B9C7F39264416187A895085215951BCLLVGTg5TA + 15
    73  AttributeGraph                      0x0000000145bb57cd _ZN2AG5Graph11UpdateStack6updateEv + 559
    74  AttributeGraph                      0x0000000145bb5dc3 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 411
    75  AttributeGraph                      0x0000000145bbc193 _ZN2AG5Graph20input_value_ref_slowENS_4data3ptrINS_4NodeEEENS_11AttributeIDEjPK15AGSwiftMetadataRhl + 553
    76  AttributeGraph                      0x0000000145bd27f0 AGGraphGetValue + 213
    77  SwiftUI                             0x0000000120be3887 $s7SwiftUI25DynamicPreferenceCombiner33_023AA827B8A8D39774F7A0C281455FEELLV4infoAA0C9ContainerV4InfoVSgvg + 107
    78  SwiftUI                             0x0000000120be3a11 $s7SwiftUI25DynamicPreferenceCombiner33_023AA827B8A8D39774F7A0C281455FEELLV5value5ValueQzvg + 132
    79  SwiftUI                             0x0000000120be3ee4 $s7SwiftUI25DynamicPreferenceCombiner33_023AA827B8A8D39774F7A0C281455FEELLVyxG14AttributeGraph4RuleAafGP5value5ValueQzvgTW + 23
    80  AttributeGraph                      0x0000000145bd5d67 $s14AttributeGraph4RuleP5value5ValueQzvgTj + 7
    81  SwiftUI                             0x0000000120b049de $s14AttributeGraph0A0VyACyxGqd__c5ValueQyd__RszAA4RuleRd__lufcADSPyqd__GXEfU_ySv_So11AGAttributeatcyXEfU_ySv_AJtcqd__mcfu_ySv_AJtcfu0_ + 111
    82  AttributeGraph                      0x0000000145bb57cd _ZN2AG5Graph11UpdateStack6updateEv + 559
    83  AttributeGraph                      0x0000000145bb5dc3 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 411
    84  AttributeGraph                      0x0000000145bbbad8 _ZN2AG5Graph9value_refENS_11AttributeIDEPK15AGSwiftMetadataRh + 128
    85  AttributeGraph                      0x0000000145bd2841 AGGraphGetValue + 294
    86  SwiftUI                             0x0000000121417bba $s7SwiftUI9GraphHostC17updatePreferencesSbyF + 84
    87  SwiftUI                             0x0000000120d4e54e $s7SwiftUI9ViewGraphC13updateOutputs33_D63C4EB7F2B205694B6515509E76E98BLLyyF + 316
    88  SwiftUI                             0x000000012131fe6e $s7SwiftUI16ViewRendererHostPAAE6render8interval17updateDisplayListySd_SbtFyyXEfU_ + 2013
    89  SwiftUI                             0x0000000121316655 $s7SwiftUI16ViewRendererHostPAAE6render8interval17updateDisplayListySd_SbtF + 360
    90  SwiftUI                             0x000000012157a012 $s7SwiftUI14_UIHostingViewC14layoutSubviewsyyF + 286
    91  SwiftUI                             0x000000012157a06c $s7SwiftUI14_UIHostingViewC14layoutSubviewsyyFTo + 21
    92  UIKitCore                           0x000000011c929184 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2496
    93  QuartzCore                          0x000000011b3fc431 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 543
    94  UIKitCore                           0x000000011c9146ce -[UIView(Hierarchy) layoutBelowIfNeeded] + 1505
    95  UIKitCore                           0x000000011c64a878 -[UISheetPresentationController _sheetLayoutInfoLayout:] + 48
    96  UIKitCore                           0x000000011ba7ae80 -[_UISheetLayoutInfo _layout] + 371
    97  UIKitCore                           0x000000011c64c51d __54-[UISheetPresentationController _transitionWillBegin:]_block_invoke_2 + 52
    98  UIKitCore                           0x000000011c91b8af +[UIView(Animation) performWithoutAnimation:] + 84
    99  UIKitCore                           0x000000011c64c444 __54-[UISheetPresentationController _transitionWillBegin:]_block_invoke.523 + 132
    100 UIKitCore                           0x000000011bbc870e -[_UIViewControllerTransitionCoordinator _applyBlocks:releaseBlocks:] + 297
    101 UIKitCore                           0x000000011bbc4c6b -[_UIViewControllerTransitionContext __runAlongsideAnimations] + 278
    102 UIKitCore                           0x000000011c91b6d2 __63+[UIView(Animation) _setAlongsideAnimations:toRunByEndOfBlock:]_block_invoke + 16
    103 UIKitCore                           0x000000011c8ec731 -[UIViewAnimationState _runAlongsideAnimations] + 24
    104 UIKitCore                           0x000000011c8eb47e -[UIViewAnimationState pop] + 37
    105 UIKitCore                           0x000000011c8e8873 +[UIViewAnimationState popAnimationState] + 62
    106 UIKitCore                           0x000000011c91d408 +[UIView _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 887
    107 UIKitCore                           0x000000011c91d680 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:] + 25
    108 UIKitCore                           0x000000011c8e3e44 __50-[UITransitionView _startTransition:withDuration:]_block_invoke.170 + 148
    109 UIKitCore                           0x000000011c91da5d +[UIView(UIViewAnimationWithBlocks) conditionallyAnimate:withAnimation:layout:completion:] + 76
    110 UIKitCore                           0x000000011c8e386b -[UITransitionView _startTransition:withDuration:] + 737
    111 UIKitCore                           0x000000011c8e33a0 -[UITransitionView transition:fromView:toView:removeFromView:] + 3027
    112 UIKitCore                           0x000000011bbc0445 -[UIViewControllerBuiltinTransitionViewAnimator animateTransition:] + 1253
    113 UIKitCore                           0x000000011bbc9258 ___UIViewControllerTransitioningRunCustomTransition_block_invoke_2 + 59
    114 UIKitCore                           0x000000011bd0bab5 +[UIKeyboardSceneDelegate _pinInputViewsForKeyboardSceneDelegate:onBehalfOfResponder:duringBlock:] + 99
    115 UIKitCore                           0x000000011bbc91e7 ___UIViewControllerTransitioningRunCustomTransition_block_invoke.641 + 180
    116 UIKitCore                           0x000000011c91b5e5 +[UIView(Animation) _setAlongsideAnimations:toRunByEndOfBlock:] + 175
    117 UIKitCore                           0x000000011bbc907e _UIViewControllerTransitioningRunCustomTransition + 580
    118 UIKitCore                           0x000000011ba67901 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke.401 + 2422
    119 UIKitCore                           0x000000011c8bf1a9 -[_UIAfterCACommitBlock run] + 54
    120 UIKitCore                           0x000000011c8bf6a1 -[_UIAfterCACommitQueue flush] + 190
    121 UIKitCore                           0x000000011c36c809 _runAfterCACommitDeferredBlocks + 782
    122 UIKitCore                           0x000000011c35c0d9 _cleanUpAfterCAFlushAndRunDeferredBlocks + 135
    123 UIKitCore                           0x000000011c390612 _afterCACommitHandler + 72
    124 CoreFoundation                      0x000000010e55d2f1 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    125 CoreFoundation                      0x000000010e557ab5 __CFRunLoopDoObservers + 570
    126 CoreFoundation                      0x000000010e55804d __CFRunLoopRun + 1100
    127 CoreFoundation                      0x000000010e557704 CFRunLoopRunSpecific + 562
    128 GraphicsServices                    0x0000000113620c8e GSEventRunModal + 139
    129 UIKitCore                           0x000000011c35d65a -[UIApplication _run] + 928
    130 UIKitCore                           0x000000011c3622b5 UIApplicationMain + 101
    131 libswiftUIKit.dylib                 0x0000000110054cc2 $s5UIKit17UIApplicationMainys5Int32VAD_SpySpys4Int8VGGSgSSSgAJtF + 98
    132 Mail                                0x00000001040c92f8 $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 104
    133 Mail                                0x00000001040c9287 $s4Mail11AppDelegateC5$mainyyFZ + 39
    134 Mail                                0x00000001040c93d8 main + 24
    135 dyld                                0x000000010cd02f21 start_sim + 10
    136 ???                                 0x000000020493f51e 0x0 + 8666739998
    137 ???                                 0x0000000000000003 0x0 + 3
)
libc++abi: terminating with uncaught exception of type NSException

Can you reproduce the bug?

Yes, always

Reproduction Steps

  1. In a SwiftUI view, add a @StateObject or @ObservedObject variable with Realm Object type
  2. Assign an unmanaged object to this variable
  3. Observe the crash

Version

10.26.0

What SDK flavour are you using?

Local Database only

Are you using encryption?

No, not using encryption

Platform OS and version(s)

iOS 15.5

Build environment

Xcode version: 13.4 Dependency manager and version: SPM

pavel-ship-it commented 2 years ago

Hi @flowbe, Probably @StateRealmObject is what you want to try.

flowbe commented 2 years ago

@pavel-ship-it thanks for the answer, I didn't know about this and it fixes the crash. However, now I still get a crash when doing:

.onReceive(myObject.objectWillChange) { _ in
    print("Object changed")
}

Any other way to do this with Realm?

pavel-ship-it commented 2 years ago

What crash do you have? Can you show me the code?

flowbe commented 2 years ago

Same crash as above: Only objects which are managed by a Realm support change notifications

The code looks like this:

struct NewMessageView: View {
    @StateRealmObject var draft: Draft

    init(draft: Draft? = nil) {
        let draft = draft ?? Draft(messageUid: UUID().uuidString,
                                   body: "Default body")
        draft.identityId = "my_identity_id"

        _draft = StateRealmObject(wrappedValue: draft)
    }

    var body: some View {
        NavigationView {
            // My view…
        }
        .onReceive(draft.objectWillChange) { _ in
            print("ON CHANGE")
        }
    }
}
pavel-ship-it commented 2 years ago

It looks we have a bug here, as StateRealmObject should work with unmanaged object.

Meanwhile, as a workaround, I can recommend to use managed object. If you want to separate a draft object from the saved objects you also can use a separate object type.

dianaafanador3 commented 2 years ago

Hi @flowbe the issue here is that our Combine API doesn't allow observation on unmanaged objects, so if you use StateRealmObject.objectWillChange this operation is not allowed unless StateRealmObject is managed by the realm. StateRealmObject is meant to be used in a way that any changes on the object properties (unmanaged or managed), will propagate to your SwiftUI view. So a better use of this will be to have something like this

class Draft: Object {
    @Persisted var messageUid: UUID
    @Persisted var body: String
    @Persisted var identityId: String?

    init(memessageUid: UUID, body: String) {
        self.messageUid = messageUid
        self.body = body
    }
}

struct NewMessageView: View {
    @StateRealmObject var draft: Draft

    init(draft: Draft? = nil) {
        let draft = draft ?? Draft(messageUid: UUID().uuidString,
                                   body: "Default body")
        draft.identityId = "my_identity_id"

        _draft = StateRealmObject(wrappedValue: draft)
    }

    var body: some View {
        NavigationView {
            Text("Identity: \(draft.identityId)")
            TextField("Body", text: $draft.body)
        }
    }
}

where your elements of the SwiftUI will change if for example there are some changes in identityId or body, and the other way in case of body

flowbe commented 2 years ago

Hi @dianaafanador3, thank you for the clarification. However, I needed to observe the changes using objectWillChange to perform non-UI actions…

Basically, my code looks like this:

var body: some View {
    NavigationView {
        TextField("", $draft.subject)
    }
    .onReceive(draft.objectWillChange) { _ in
        saveDraft()
    }
}
dianaafanador3 commented 2 years ago

If you are using iOS > 15.0, you can use .onSubmit which will be called every time you return over a SwiftUI element. If not you can use

.onChange(of: draft.body, perform: { _ in
})

to observe an specific property in the object.

For now objectWillChange works only with managed objects, like when our observe API. I'll take to the team if we want to extend this to unmanaged objects.

flowbe commented 2 years ago

Thank you for the suggestion. However, this doesn't match what I want to achieve. For now, I had to create a copy of my class that is not a Realm object only to make observation work and then convert it to a Realm managed object when I need to save it. This is clearly not ideal so it would be nice if you decide to improve this in the future.