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

Question: Accessing Loadable state outside CountriesList #46

Open
Cobrijani opened this issue Jan 8, 2021 · 4 comments
Open

Question: Accessing Loadable state outside CountriesList #46

Cobrijani opened this issue Jan 8, 2021 · 4 comments

Comments

@Cobrijani
Copy link

Hi,

Thanks for the awesome repository! It is a great source for beginners in IOS development to learn the basics of Architecture in SwiftUI Programming!

I was wondering based on your current solution, how would you expose the current state of the loadable to the parent component? For example, you want to show something else in the parent as soon as the loadable in the child is finished loading.

Thanks!

@nalexn
Copy link
Owner

nalexn commented Jan 8, 2021

Hey @Cobrijani

Thank you for the feedback! Regarding your question, the state management in SwiftUI always complies with the "single source of truth" principle, so you'll need to choose the "owner" for this Loadable.

You have three options: parent component, child component, and AppState.

The AppState would make it accessible to the rest of the app - useful for some cases, but certainly not for all.

With regards to the parent - child parity, I'd bet that most of the time the parent should be the owner, and the child should consume the value through Binding. This way both parent and child will see the changes in the Loadable while either one can kick off the loading process by supplying the Binding to the Interactor (Service).

@Cobrijani
Copy link
Author

Cobrijani commented Jan 8, 2021

Hi @nalexn
Thanks for your answer! It completely makes sense to choose parent as owner in this case!

How would you implement parent ownership in case of view model approach?
Is LoadableSubject instead of Loadable needed in the view model in order to get the binding?

I tried creating Loadable Publisher in the parent and passing it to the child, but the updates in the parent are not being triggered when the data load is being triggered in the child view.

Pseudo Code Snippet:

struct CountriesList: View {

  @ObservedObject private(set) var viewModel: ViewModel
   var body: some View {
        // in this case child will trigger the loading of the countries in this loadable
        // parent will pass .notRequested
        Child(countries: self.viewModel.countries)
   }
}

extension CountriesList {
    class ViewModel: ObservableObject {
        
        // ... 
        @Published var countries: Loadable<LazyList<Country>>
 
       init(...){
          // inits ...

         // can something like this work? Do i need loadable subject store above and not just publisher?
         $countries.sink {
                // register when child loads the component to show something in the parent
            }.store(cancelBag)
       }
}

Thanks!

@nalexn
Copy link
Owner

nalexn commented Jan 8, 2021

Ok, the Child should consume the Binding in the init:

struct Child {
    @Binding var value: Int

    init(value: Binding<Int>) {
        self._value = value
    }
}

And you should pass the binding from the parent this way:

Child(countries: self.$viewModel.countries)

Note that self.viewModel.$countries will give you a Publisher, not a Binding.

I recommend reading my other post where I cover these topics.

@Cobrijani
Copy link
Author

Hi @nalexn,

Great, thanks!

Best regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants