A ViewModel should only be created by another ViewModel. 
With this idea in mind, let's see it in practise[1:1]:
- User tries to login via Facebook. Has she registered herself into our backend with FB before?
- Yes. We are done. ✅
- No. Show a registration screen[1:2] , so she can complete the process. ❌
LoginViewController has a
LoginViewModel that allows the user to either login via the default way (username + password), or Facebook. This
LoginViewModel is composed by two inner objects:
Code wise, the consumer would call the
LoginViewModel like this for the Facebook authentication:
// `self` is a VC, since the FB API takes a VC has input // https://developers.facebook.com/docs/facebook-login/ios#custom-login-button loginViewModel.loginViaFacebook(self)
Eventually, inside the
FacebookLoginFetcher, we check if the user is already registered in our backend via another object (
As stated initially, the login can fail, if the user never registered. To inform the UI about this failure, I was initially using a
.SocialNotRegistered. With this approach, I was making the consumer (the VC) to be the one to decide what to do next. This decision, would then envolve creating a new ViewModel and push a
Instead, I am now passing a
SocialRegistrable is a protocol used to abstract the registration functionality. The protocol's concrete implementation (
SocialRegistrationViewModel) is setup with the information retrieved from the
- Authorization token.
- User's email.
This change, makes the API's semantics much more explicit about the information flow and takes the burden from the consumer.
You can now have your cake and eat it.