pointfreeco / swift-composable-architecture

A library for building applications in a consistent and understandable way, with composition, testing, and ergonomics in mind.
https://www.pointfree.co/collections/composable-architecture
MIT License
11.91k stars 1.37k forks source link

Leverage UIKitNavigation #3180

Open stephencelis opened 3 weeks ago

stephencelis commented 3 weeks ago

This draft PR demonstrates how to use the new UIKitNavigation beta tools in a Composable Architecture application.

We can merge when the tools are finalized and released.

acosmicflamingo commented 3 weeks ago

Have you encountered any scoping issues when using UIBinding? The weirdest thing, I have two identical scopes but one works and the other gives me an error like below:

let binding = $store.scope(  // 1
  state: \.self,  // 2
  action: \.self // 3
)

// 1 error
Cannot call value of non-function type '_StoreUIBinding<AppMain.State, AppMain.Action, _>'
Value of type 'UIBinding<StoreOf<AppMain>>' (aka 'UIBinding<Store<AppMain.State, AppMain.Action>>') has
no dynamic member 'scope' using key path from root type 'AppMain.State'

// 2 error
Cannot infer key path type from context; consider explicitly specifying a root type

// 3 error
Cannot infer key path type from context; consider explicitly specifying a root type

If I get rid of $, then binding is of type Store<AppMain.State, AppMain.Action>

If I created a dummy function in UIBindable, then I get the following error:

extension UIBindable {
  public func scope2() {}
}

// Value of type 'UIBinding<StoreOf<AppMain>>' (aka 'UIBinding<Store<AppMain.State, AppMain.Action>>') has no
// dynamic member 'scopeMe2' using key path from root type 'AppMain.State'
let binding = $store.scope2() 

Edit: Whoops; there is a difference between @UIBindable and @UIBinding; that's what I was doing wrong. Hm, looks like I'm finally going to have to learn about the SwiftUI's rather similar terminology.