ra1028 / swiftui-atom-properties

⚛️ Atomic approach state management and dependency injection for SwiftUI

Home Page:https://ra1028.github.io/swiftui-atom-properties/documentation/atoms

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Doc Request]: use with Observable macro

joprice opened this issue · comments

Checklist

  • Reviewed the README and documentation.
  • Confirmed that this is uncovered by existing docs or examples.
  • Checked existing issues & PRs to ensure not duplicated.

Description

I see examples using ObservableObject, but not one using the newer Observable macro. Is it possible to define an Atom that would be reactive to fields on an @Observable annotated object?

Motivation & Context

No response

@joprice
I had an assumption that those who want to use Observable macro prefer the vanilla implementation and I had no plans to integrate it into this library, but yes, if you want to use it I can try to implement something like a new ObservableAtom.

Thanks for the response. I actually switched back to ObservableObject anyway to support more devices, so it's a non-issue for me personally. I just had some code I had already written using it and was curious how they overlap. I'll close.

@joprice I had an assumption that those who want to use Observable macro prefer the vanilla implementation and I had no plans to integrate it into this library, but yes, if you want to use it I can try to implement something like a new ObservableAtom.

Do you see the Observable Macro as a better replacement for this library? Because I think an Observable Object can still take advantage of this lib like dependency injection etc.

@smiLLe

I think you're right, the advantages of Observable macro over ObservableObject are also covered in this library, are rather more flexible.
But an official vanilla implementation is always appealing to anyone so it's a difficult question as to which is better.

@ra1028 Personally I would use an Observable(Macro)Atom since I target iOS17. But I am not into the details of the lib so I don't know if this would be even possible to create.

@smiLLe
I'd also use it if possible b/c I don't really like using Combine's @Published.
However, just recently I was wondering if it's possible, but seems that the Observable macro API (withObservationTracking) is too specialized to be integrated into this library generically.
I'd say it should work without problem if you wrap the Observable macro object with ValueAtom and use it in the view, but doesn't for testing or on selector atoms.

@ra1028 Using it in a ValueAtom is possible but it can lead to unexpected behaviour in subscribing Atoms if they rely on properties exposed by the Observable. But there shouldn't be any errors if the atom is only used in a View, I agree.

I did not try withObservationTracking yet, but it looks like a one time subscription to a property.
Maybe this naive implementation may work?

struct ObservableAtom: ValueAtom, Hashable {
    func defaultValue(context: Context) -> MyObservable {
        MyObservable()
    }
}

struct ChildAtom: ValueAtom, Hashable {
    func value(context: Context) -> Int {
        // will rebuild this ChildAtom whenever MyObservable changes
        let obsvAtom = context.watch(ObservableAtom())
        // immediately get the int and when the int changes somewhere in code, rebuild THIS ChildAtom and the Atom tree below
        let intProp = withObservationTracking { obsvAtom .someInt } onChange: { context.rebuild(ChildAtom()) } 
        return 1 + intProp
    }
}

@smiLLe
Yes, it would work.
rebuild > reset