Reinitialize ViewModel after coming back from another page - mvvm

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.

Related

Best Practices For Handling Feed Subscription Events In getStream

Im having trouble finding documentation regarding best practices for handling activity data emitted from a realtime subscription to a getStream feed.
Our current set-up mimics what it seems react-activity-feed does: (1) subscribe to feed and listen for new activities (2) when a new activity is emitted display a button at the top of the feed announcing the new activity (3) when the announcement button is selected make a new feed.get() call to retrieve the most recent feed data.
The problem we are considering is how we could avoid making a new call to feed.get() every time a new activity is emitted (seems wasteful). We would rather store the original response data from feed.get() inside a state variable and insert new activities into that object.
This doesn't seem possible, however, as we get the following error whenever we try to append to the nested array inside the feed.get() response object: TypeError: Cannot assign to read only property 'activities'
I would greatly appreciate any advice on how others have handled new activities emitted from a feed.
I discovered that react-activity-feed does NOT make a call to feed.get() to retrieve the updated feed data after a new event is emitted to the feed.
feed.get() is only called when a feed is first visited or a pagination event occurs that makes a request to get more feed data. Otherwise, a copy of the feed activity object is created (using immutableJS.Map) and newly emitted events are pushed to this object which is used to display content in the feed (see object definition here). The same is done for managing reactions to activities as well as notifications.
So for anyone who is curious how to manage new events emitted from Streams real-time subscription try to managed feed state in your app by making a copy of the object that is initially returned by feed.get() and manipulate that object in your UI to limit the number of requests made to getStream and improves the performance of the feed as well.

MVC/JQM iPhone/Chrome - page posting back to different controller

I have an MVC4 application and I am seeing very odd behaviour on iPhone/Chrome only
Here is the happy path
go to /account/register
the register method of the account controller handles the request
fill out the form and click join
the register(signupModel) method of the account controller handles the event
here is what happens on iPhone/Chrome only
go to /account/register
the register method of the account controller handles the request
fill out the form and click join
the login(signupModel) method of the account controller handles the event
So I am baffled as to why the incorrect action is being called only on iPhone/iOS
This has been tested on numerous mobile and desktop devices (android, iphone/safari) without a problem
The site is MVC4/.Net4.0 and JQuery Mobile
the IIS logs are showing a POST to /account/login so I do not think its a route problem. It seems like the client really is posting to the wrong URL
Any insight would be greatly appreciated.

Where does related logic go on model creation when working with REST api with Django, Backbone, and Tastypie?

We are trying to move some of our app to use backbone and tastypie. I have the REST api set up and it is working on some basic examples. However, there are a few issues where currently we post an ajax request to a custom url, and in that view do a few things like
make related objects
call a few related functions
However, now that I've switched some of this functionality to using backbone and the REST api, I'm not sure where all of that should go!
For example, I had a view to make a Message, and when I made a Message, I also made a Notification and called a function to add some points to the user. Something like
def ajax_send_message(request):
## ... set up some variables ...
## Make the new message
message = Message(user=user, content=message)
message.save()
## Make the notification
notification = Notification(message=message)
notification.save()
## Give the user points
user.add_points_for_message();
return json_response({"status": "ok"})
Now--am I just supposed to do this all in JavaScript? I have a Message Backbone model as well.
// Create message backbone object
var msg = new Message({content:content, user: user});
// Post to server
msg.save();
// Add to backbone collection
messages.add(msg);
I've looked at different parts of tastypie, and it seems you can create custom URL endpoints, and also do validation, but that doesnt seem like the right spot to call related methods. It seems that calling related methods goes against the REST part of it---but then where are they supposed to go?
If I want to add some logic to backbone only when an object is created, where does that go?
The first thing I would suggest is to switch your mindset to an event-based model, where your code reacts to events. In your example above, you save the model to the server then immediately dd it to the collection. How do you even know that the model was saved correctly? That procedural style of programming works better in a synchronous, server-side style of programming.
In the asynchronous world of client-side programming, you make a request and then set up callbacks which determine what will happen next, depending on the events your are listening for. In your case, you want to react a certain way when the message is saved successfully, correct? You can define a success callback for your save operation like so:
msg.save({
success: function(model, response, options) {
messages.add(model);
// code to add notification
// code to add points
}
});
Basically, you are saying "I would like to save this model, and then listen for a success event. When the event comes in, execute the following code." Notice also that I am adding the model returned from the API to the collection, since this is the exact object that was persisted to the server so it's more appropriate to add than the model you created.

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.

ShareKit for iphone - SHKShareTypeText

I am using ShareKit for iphone to share some text in facebook. Can any one tell me which delegate is called after publishing the text successfully. I need this to inform the user that his action was successful.
The shareDelegate property in SHKSharer isn't the easiest to get to and change, but there are notifications sent from the delegate methods of SHKSharer, one for each of the methods: SHKSendDidStartNotification, SHKSendDidFinish, SHKSendDidCancel, SHKSendDidFailWithError. Observing these notifications turns out to be a simple way of listening for the outcome of sharing.
See shareDelegate property of SHKSharer . All the concrete sharers (e.g. SHKFacebook) extend this base class.
Having said that, I'm not sure where you set a class to be the delegate using ShareKit's public API (so I'm not claiming this to be a complete answer).