BendingSpoons / tempura-swift

A holistic approach to iOS development, inspired by Redux and MVVM

Home Page:http://bendingspoons.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Interface Builder

matthmart opened this issue · comments

Is it possible to initialize view controllers & views using Interface Builder?

hey @matthmart thanks for reaching out!

Interface Builder is communicating with your code using the ObjC runtime and the Foundation archiving/unarchiving capabilities to instantiate objects (UIViewControllers are instantiated using the init?(coder: NSCoder)).

first problem: ViewController class doesn't have the init?(coder: NSCoder) available as it needs the store to be provided using the init(store: Store<V.VM.S>).
this problem can be solved creating a subclass of ViewController that will implement the init?(coder: NSCoder) providing the store to the superclass initializer for instance accessing to a singleton wrapper of that store.

second problem: It is not possible (afaik) to use generic classes like the ViewController or ModellableView of Tempura inside IB, given that this feature is not exposed to the ObjC runtime enviroment "directly".
I do not see any workaround for this, as removing the generics for ViewController and ModellableView will remove all the automation that let the developer write way less code than usual.

Ok, I understand. So we will try to migrate to code for UI, to able to use your great library :)
Thank you for your work!

Let me know if you face any issue, or need any clarification!
The Demo project should be a good starting point.

I found a simple workaround by overriding loadView of ViewControllerWithLocalState,
just name xib's filename with the same as the view type's name.

class IBViewControllerWithLocalState<V: ViewControllerModellableView & UIView>: ViewControllerWithLocalState where V.VM: ViewModelWithLocalState {
override func loadView() {
let viewTypeName = String(describing: V.self)
guard let v =
UINib(nibName: viewTypeName, bundle: nil).instantiate(withOwner: nil, options: nil).first as? V else { return }
v.viewController = self
v.setup()
v.style()
self.view = v
}
}
class AddItemViewController2: IBViewControllerWithLocalState {
...
...
}