Using 1 or more view model for register module (Sign in - Sign up - reset pass)? - mvvm

I'm working on an android project with MVVM + Data binding + Live data and I've some questions:
I have register module (Sign in - Sign up - reset pass) I'm asking is it better to use one view model for sign in & up or for every screen I should have view model?
If I take a user's info(mail- pass - name gender) should I use live string fields for them or use live user object?

After some researches, it's better to use one viewModel for every screen
It's better to user live user object.

Related

Best way to use BLoC as global state management

So I have a BLoC which I need to access globally through my app - CurrentUserBloc and its purpose is to hold data of currently logged in user. It can hold some states like CurrentUserWaiting, CurrentUserReady, CurrentUserError etc. Some of them hold user instance - like CurrentUserReady, and some don't - like CurrentUserWaiting. Now I need to access this user data in order to send an event to another BLoC. For example I want to post a photo and I need userId of currently logged in user to do this. But I can't just use BlocProvider.of<CurrentUserCubit>(context).state.user to get user data because some of this bloc's states - like CurrentUserWaiting - don't store user property and compiler won't take this.
I get around it by creating abstract state class CurrentUserWithUserInstance and extending it in states that hold user property. Then I just access state like this:
final currentState = BlocProvider.of<CurrentUserCubit>(context).state
as CurrentUserWithUserInstance;
Then I get user property from this and use it to add event in another BLoC.
I was wondering what would be a better way to do this. I need to access user data in multiple places in the app and I don't know if this is a good approach. I know I could use just one state class with all properties and then change it by copyWith method. By that doesn't really seem that good to me.
How do you store and access global state using BLoC?

Impersonation in MDriven?

I am trying to build an “impersonate” page in order to “log in” as another user . I am thus trying to assign the CurrenUser with a vCurrent_XXXX value but the result is that the CurrentUser is set to null ? How do I control this?
MDriven Turnkey checks for the model pattern above and sets the CurrentUser-transient-link on MVC gets based on the IdentityProvider mechanism from the web app.
The MDriven Turnkey app then use the value of this transient link to decide what SysUser to handle as logged in.
Consider changing the CurrentUser transient link to a a ReverseDerived (and derived) link.
Then Turnkey logic can set it - and you can override it.
Add a transient link called ImpersonatedUser - let the derivation of CurrentUser return self.ImpersonatedUser - that would give the effect you want.

Reinitialize ViewModel after coming back from another page

I use MvvmCross library for cross platform mobile development.
I've got the page with chat lists (ChatListPageViewModel). It loads chats from the container in the Init() method.
From this page you can navigate to the page which adds new chat to container (AddChatPageViewModel).
When the chat is added, I call Close(this) in AddChatPageViewModel. So, I automatically navigate to ChatListPageViewModel, but Init() method is not called at this moment and I cannot refresh my data. How can I handle this?
Init is reserved for initialising new viewmodels - it's not really designed for refreshing existing ones.
However, I think you can achieve the type of application flow you are looking for by:
sending a message from the AddChatViewModel when you add a chat
or writing custom OnNavigatedTo, ViewDidAppear, OnResume handlers and using these to call custom methods on your chat view model
One example of the first scheme is in the CollectABull N+1 sample - https://github.com/slodge/NPlus1DaysOfMvvmCross/tree/master/N-13-CollectABull-Part2 - when the collection service changes then it broadcasts a message allowing subscribed ViewModels to update - see http://mvvmcross.wordpress.com for walkthrough videos.

Web.api Get method to show only selected properties from entity

Let's say I have 3 entities: Advert, User and UserRole. And in Web.Api project GetAllAdverts method.
public IEnumerable<Advert> GetAllAdverts()
{
return repository.GetAll<Advert>();
}
When i enter url ../api/advert I get JSON with all Adverts and data about adverts, but I get all data about user and user role too.
How can I get for example all advert data and only UserName form entity User ?
Is this done by creating DTOs ?
Thanks in advance !
Using DTO's is usually a good idea. It is more work, but it gives you full control and it abstracts out peculiarities of a specific data layer.
In your case, if you really only want UserName you even have to use a DTO, because it is impossible to partly load the User as navigation property from Advert.
If it does not matter that you see all properties of User except its navigation properties (like role), you may also consider to (temporarily) turn off lazy loading for the context in the repository and eager load Advert.User by using Include.

Cocoa Design Patterns for Authentication

After developing for iOS for some time now, I have gotten comfortable with the language and am trying to get better at designing well-structured applications. Initially my focus was on seeing something functional, so I ended up with gigantic view controllers which were horribly architected. Now, I'm learning to separate my model classes and trying to keep my architecture more modular. I would greatly appreciate any advice on the following sample situation:
I am developing an app which (among other things) pulls a list of articles from a server and displays them. However, the user has to be authenticated to be able to retrieve this list. Because other aspects of the application utilize the same authentication, I want a single class to manage the authentication. The goal is that when any controller requests data from the model which requires authentication, if the user is not authenticated, the authentication prompt will automatically be presented.
I expect to create the following:
VIEW
- ArticlesView
- AuthenticationView
CONTROLLER
- ArticlesViewController
- AuthenticationViewController
- ArticleManager (singleton)
- AuthenticationProvider (singleton)
MODEL
- Article
When the application first loads, execution will reach the ArticlesViewController's viewDidLoad method. In this method, I get a shared instance of the ArticleManager, specify the authentication class to be the authentication provider, and ask it for a list of recent articles.
// ArticlesViewController.m
-(void) viewDidLoad {
...
AuthenticationProvider *authProvider = [AuthenticationProvider sharedInstance];
[[ArticleManager sharedInstance] setAuthenticationProvider:authProvider];
[[ArticleManager sharedInstance] fetchNewArticles];
}
If no authentication was necessary, the ArticleManager would successfully retrieve the list from the server and post a notification letting anyone interested know that the articles have been retrieved. The ArticlesViewController would handle this notification:
// ArticlesViewController.m
- (void) handleNewArticlesNotification:(NSNotification *)note {
[self updateUI];
}
However, if authentication is required, the user needs to be presented with a login screen before the articles can be fetched and displayed. So I imagine the ArticleManager doing something like this:
// ArticleManager.m
- (void) fetchNewArticles {
if( [self.authenticationProvider isAuthenticated] ){
// go fetch list from the web
}
else {
[self.authenticationProvider presentAuthenticationRequest];
}
}
Now, at this point I run into some difficulty fleshing out the remainder of the details. The AuthenticationProvider could present the AuthenticationViewController as a modal view controller from the AppDelegate's window's rootViewController and AuthenticationProvider would be the delegate of AuthenticationViewController. The AuthenticationViewController would probably be dumb to the actual actions that it is taking, and would have it's delegate (AuthenticationProvider) do the work to authenticate the user. Once the user is authenticated, AuthenticationProvider would dismiss the modal view controller (AuthenticationViewController).
But how does ArticleManager get notified that the authentication that it requested has completed? It would need to be able to handle both successful and failed authentication attempts separately. A successful authentication would eventually result in fetchNewArticles being called again.
One thought is for ArticleManager to be a delegate of AuthenticationProvider. This seems to work in this case, but there are other Model Managers which could also rely on AuthenticationProvider. Presumably this would be resolved if AuthenticationProvider is not a singleton. Would that be a decent design approach?
Thanks for taking the time to help me understand a good design approach. I have coded this a couple of times, but always get stuck/confused toward the end. Also, if the entire approach needs to be re-architected, please feel free to point me in another direction.
Many thanks!
I have always used Global NSNotifications to post when a user has logged in or logged out. Every view controller that presents data differently can subscribe to those notifications and update themselves accordingly when an event happens.
This is nice, because you may already have other views (perhaps in other tabs) that have already loaded and will need to refresh when a user has logged in or out.
One thought is for ArticleManager to be a delegate of
AuthenticationProvider. This seems to work in this case, but there are
other Model Managers which could also rely on AuthenticationProvider.
Presumably this would be resolved if AuthenticationProvider is not a
singleton. Would that be a decent design approach?
Perhaps instead you could have the AuthenticationProvider singleton provide AuthenticationSession objects, set the caller as the delegate of the AuthenticationSession, and ask the AuthenticationSession to perform the authentication.