design pattern, architecture for multi level viewcontroller containment - swift

Part of an iOS application I'm working on consists of multi level view controller containment. similar to this diagram
I'm trying to setup the interaction/ routing in a way that isolates each child controller to it's own scope and communication between is handled through a central router in "master vc". Only one single child in the diagram is visible to the user at a time. Each child belongs to a parent controller where those parents (orange color) are managed by master vc. Master doesn;t need to know all about each children as they're encapsulated within their respective parent controllers (orange).
As an example, if an event on child-A needs to present child-X with some data, it will inform master's router instead of talking directly to child-X.
Not really looking for a complete solution but rather an advice towards a suitable design pattern or communication mechanism that supports the isolation of child controllers to their scopes and tidy up the managing of controllers.
using swift 3 (no reactive programming)
Cheers

Two suggestions of how you could do this: (I would use protocols myself)
Protocols: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html
In short terms: your masterVC could implement a protocol in which all the children can use
NotificationCenter:
https://developer.apple.com/reference/foundation/notificationcenter
Your masterVC listens listens to several "notification-names", while all the children sends out notifications.

Related

Reading/writing to NSStream no matter what ViewController user is in

I am making a very basic iOS chat application, the app now has several different viewControllers so i now somehow want to always listen to the server no matter what viewController the user is on.
Before i had my NSStream code on the viewController that i wanted to update, however now since i have multiple views i want to make sure that the server is listening for updates no matter what viewController a user is on..
How can i do this? Where would i put my methods for listing / writing to the server (so that all viewControllers can read/write to it)?
You could make a global singleton that handles your chat connections and does all the reads and writes. All the view controllers that need to be able to send or receive chat messages would then use that singleton.
For how to communicate between the view controllers and your chat singleton, have a look at Apple's Notification Programming Topics and Key-Value Observing Programming Guide
Don't abuse the AppDelegate for things like that. Just because it is a globally available singleton, does not mean it should handle everything that is shared between view controllers.
Your views should not know anything about chat connections.
Create a singleton to manage the communication. Call it something like XXChatDataController. Be sure that none of the view controllers create their own instance.
If you have multiple view controllers you want to look at using notifications (instead of delegation) to distribute information about new chat data being received as this will allow your code to be simpler and to handle the situation where you have multiple view controllers observing updates at the same time (if you were using child view controllers say).

Implement a single class for View Transitions in iOS App?

I want to follow MVC for my current project, in which 7-8 UIViewController subclasses will be there.
There are more than 30 classes (NSObjectsubclasses) for maintaining data and server connections.
Most of the time server connection manager class will send local notifications to UIViewController subclassess to make view transitions. I want to make it happen in centralized manner. Meaning from a single class.
What I want to do is, Implement a single class which handles all my UIViewController Transitions.
Any idea on how I can implement this ???
Note: I don't know the pros and cons of following this kind of approach. Even I don't know this is feasible or not.
I think I know what you mean. My best bet, would be a singleton, that would receive two UIViewControllers references and then would apply the animations between the two. This way you would have a centralized place where you could your animations. Probably a more complete solution, would be receiving the two UIViewControllers and two blocks, one for the animation block and another one for the completion block.

single controller managing a model and multiple viewcontrollers?

I'm working on an app that has multiple view controllers for different screens and the whole app is about displaying data from an sqlite db.
My inicial design was to have a db object (the model), a main controller with exclusive access to this model and have all other view controllers merely manage visual aspects of windows,buttons,whathaveyou.
But I'm having a hard time realizing how to make the main controller be aware of all other view controllers throughout the app's life in the context of apple's ios app architecture.
I've thought of 3 approaches so far:
1 - NSNotificationCenter and have the main controller observe all other controllers?
2 - make the main controller delegate of all others? Though I'm still not clear on how to define a delegable (did I make this word up?) protocol in general. That is, even for objects that don't have a setDelegate method.
3 - passing an db object around to each view controller. Though this seems a bit like playing C passing state around..
Any thoughts?
Thanks!
Your approach should probably be one where the view controllers and models are as ignorant of each other as possible. This is a pretty common design pattern, I believe. You should have model objects that represent each logical "object" in your domain. Those objects may just be state. Next, you might want to create a controller (like you mentioned) that has access to your database and can make queries. The result of those queries should be used to construct instances of your logical model objects (e.g., XXPerson) and hand them off to whatever made the query. Given that, each view controller in your app should do the following:
Create its views and lay them out as appropriate
Instantiate your database controller object (and possibly hold on to it for further use)
Query the database for the data it needs via the database controller object
Use the resulting data (which should be returned as your logical model objects) to adjust the views or do whatever you need with them
Note that you could make use of a singleton for your database controller, but the singleton pattern is a loathsome one if you ask most good developers. :) Instead, there's really no reason why your application can't just create an instance of your database controller as needed, use it for some queries, then discard it afterwards.
Internally, of course, your database controller class should have singular, static access to the database and possibly synchronize access to write methods so that you don't run into issues with concurrency.
There are many possible design approaches, but one in which things are loosely coupled means that there isn't a bunch of interdependency going on, which is always a good thing. Let your model objects, database controller objects, and views all be independent of each other. The view controllers, of course, are the bridges that tie all those independent concepts together into a functional product.
That's my opinion, anyway. :)
It sounds like you're looking for a Data Access Object or service/store as part of your controller layer. I think that's a good idea and a common pattern in other languages that for some reason seems widely ignored in iOS apps.
Provide each of your view controllers with some object which manages access to your data store. You might want to only construct a single instance of that store but your controller's don't need to know that. As far as any individual controller is concerned it was given an object it can use to get and store model objects.
I don't think you should try to prevent your view controllers from accessing model objects at all. Rather introduce a service so that your view controllers don't need to know the details of how to load or persist those model objects. If necessary you can use that service to translate between one model and another if you find the need for a view-model or don't want your view controllers to work directly with whatever model objects you persist.
I think that a dependency like this should be a strong reference rather than a delegate and provided to each view controller when they are constructed via constructor-based or property-based dependency injection or some inversion of control container as appropriate for your app.

Controllers in MVVM, How to get info from viewmodel to it's controller?

We are building an app using the MVVM pattern, we have controllers that wire up all the views and viewmodels using DI. All examples of MVVM I've seen are really simplistic and have 1 view. How do/should viewmodels talk back to the controller? The controller knows about the models and views, should the viewmodel send events back to the controller? Where should a save happen? Model? Controller?
Could your ViewModel not take a dependency on an IController or some other interface, so they can talk back to it? I try to keep as much application logic out of the ViewModel as possible, as these classes can easily become bloated.
MyViewModel(IController controller)
{
this.controller = controller;
}
void Save()
{
this.controller.Save();
}
I do agree that the MVVM frameworks tend to be too simplistic with their samples. In particular, moving between views/screens in your application is something I would like to see more examples of. I create an IViewManager interface, to allow my ViewModels to request that we move to another view.
We use Controllers too but in our case they are responsible for the application workflow. The Controller knows the ViewModel and the Model but not the concrete View because this will be injected by the IoC Container.
If you are interested in an example that shows more than just one UI (modal dialog, wizard with conditional workflow) then you might have a look at:
WPF Application Framework (WAF) - http://waf.codeplex.com
In case of an application that has multiple modules and requires separation of concerns I would recommend using prism framework.
http://msdn.microsoft.com/en-us/library/gg406140.aspx
I use a similar setup to you. In my controller, where my DI and view injection goes down, I sometimes keep reference to the ViewModel (which hold the View). Some cases I may have an event on the VM which is handled by the controller. In other, extreme cases (like if the VM/V was created outside the controller, say in another VM), I may even use the EventAggregator (with a strong ref) to listen to events that may be fired on the VM. In that case, a stored ref to the VM is not needed.
How about using events wherein the controller subscribes to VM events or using a mediator pattern where in a mediator is injected in a VM.

Responsibilities of Delegates and Controllers in Cocoa Touch?

I'm new to development on the iPhone. Just about every sample project (as well as the default project templates) have one or more delegates and controllers. Can someone give me a breakdown of what the delegates are responsible for vs. what the controllers are supposed to do?
The simplest way I can think to differentiate the two are:
A delegate is a protocol (interface) that defines methods that an object implements in order to receive specific messages from other objects. Delegates objects are most often used to receive asynchronous callbacks such as user input, I/O.
A controller is an object that usually contains UI elements (views, controls, etc.) and data, and both receives and send messages to the various objects within it. In many cases, a controller is a delegate and can implement several delegate protocols to receive events from multiple objects.
Keep in mind that many UI elements and controls let you pass events back to the controller by linking them to an IBAction method in Interface Builder. This is very handy as it doesn't require extra code to implement delegates. However, some other APIs such as the ABPeoplePickerNavigationController or NSURLConnection have no visualization in Interface Builder and so must use delegates to handle their events.
A delegate is some object that implements a set of methods which either your application or the framework you link against depends on for functioning. It is a means of implementing a delegation based design pattern wherein the responsibility for performing an action is transferred from some root source to an interested third party. For instance, UIApplication has delegate methods that provide a third party with the ability to perform operations at certain times during the applications lifetime. It can be though of as a milestone in a timeline into which you can contribute to the story.
A controller is a totally different animal and is responsible for doing, well, the controlling. A ViewController is charged with managing views - for loading them into memory from disk when they are needed and unloading them when they are not. They transform content from some underlying model object into a form that is usable by your view objects, load content into your in-memory model from the disk or from the internet, and dump the contents back to disk when you save and/or quit.