How do notifications fit in iOS VIPER architecture? - ios

I was looking at VIPER architecures and I was wondering where notifications would go in the app. I use Realm local database which has the ability to send notifications when models are updated. Do notifications get broadcasted from the INTERACTOR --> PRESENTER --> VIEW or does it go somewhere else?

In this scenario Realm would be used as a data service, providing data. Accordingly, such as service is best placed in the interactor.
Then, as you say, events from the interactor can be passed to the presenter and them to the view, where you might want to reload a tableView or some such task.
I tend to pass the Realm results from the interactor to the presenter where I expose a variable for the view to use and update this in the callback from the interactor.

Related

VIPER architecture and proper place to save access token

So, lets say that this is a general definition in VIPER architecture:
The main parts of VIPER are:
View: displays what it is told to by the Presenter and relays user
input back to the Presenter.
Interactor: contains the business logic as specified by a use case.
Presenter: contains view logic for preparing content for display (as
received from the Interactor) and for reacting to user inputs (by
requesting new data from the Interactor).
Entity: contains basic model objects used by the Interactor.
Routing: contains navigation logic for describing which screens are
shown in which order.
Now in my interactor, I do a login network request, and I get the response that has access token (that I later save in keychain using my KeyChainManager).
Now, were would be a good and a proper place to save the token? Immediately in the interactor, or to pass it somewhere further maybe, eg. presenter... ?
This is a service so that's what the interactor is for. You should have a service for doing the request and a service for storing or retrieving the token, and only an interactor should be allowed to speak to them or even know of them.
That is, in fact, the whole point of the interactor — it's so that the presenter does not know anything about this. No one else should know anything about what's going on. A presenter should know nothing about the token — that it exists or where it is stored. That's all just behind-the-scenes implementation.

How to inform VIPER module about need of reloading, after another module perform task on shared service?

I'm trying to understand VIPER architecture with simple iOS tracks managing app.
I've got TracksListModule and NewTrackModule. Both with own's viewController, interactor, presenter and router. Both interactors have injected shared TracksService for fetching tracks. TracksListModule's router presents NewTrackModule's viewController which allows user to type in some track's properties. When user tap save button, NewTrackModule's interactor calls TracksService's add method then dismiss viewController to back to list.
The problem is list isn't updated after adding new track. How to inform TracksListModule's presenter (or interactor) that list needs update?

MVC in Swift 4 - Model's interactions with Controller

I'm developing a mobile application in Swift 4, that needs to interact with an external device using Bluetooth LE connection.
Currently i'm using the Model-View-Controller pattern to implement the structure of the app, but i need a clarification about.
When i receive data from the bluetooth adapter, i store it inside the model. The Model talks to the Controller "posting" the changes using the notification center.
On the other side, the Controller (the owner of the model) write the modification back to the Model simply setting the property of it.
The problem is that, sometimes, i do not have the Controller ready(instantiated), so i can loose Model's update (in that moment i'm not ready to "observe" the updates from the Model).
The only way that i found to workaround this issue is to:
In the Controller viewDidLoad read the status of the Model using "getters" of the Model properties.
Register the Controller to observe the future Model updates.
This now is working fine, but what i would like to understand is if this is the correct behaviour of communication between a Model and a Controller.
You can create a variable for that model in the view controller.
For the variable, implement didSet and perform the operations that you want to perform in the view controller. You do not need to post the changes using notification center.
In viewDidLoad, you can get the data first time from the bluetooth adapter.
After that whenever you receive the updated data from the bluetooth adapter, update the model only. It will do the rest of the things for you.

Should I call my API from my model or controller?

My question is mostly related to an architectural or design pattern for hierarchical models in Objective C. For background my app is relatively simple. In general it talks to a web service to retrieve and display things a user can follow. When someone follows something, the thing they are following is conceptually stored for access later by posting to the web service.
I would like advice on where the logic should go to manage the interaction between the web service and the group of things a user follows.
For example, is it appropriate to create a model object like MyStuffModel with an array property named followedThings that holds references to AThingModel objects? And if so, would the logic for refreshing from the web service, etc be written and executed in the model?
Potential code example
#interface MyStuffModel : NSObject
#property (nonatomic, strong) NSArray *followedThings;
- (void)refreshAllFollowedThingsFromWebService;
#end
#implementation MyStuffModel
- (void)refreshAllFollowedThingsFromWebService
{
//call my API client (built on AFNetworking), get back a response
//populate followedThings, notify a view controller, etc
}
#end
Or, should I not have a MyStuffModel object and manage the calls to my web service by calling my API client directly from a view controller?
In your experience, which approach is desired? Or is there another way?
I would do all of the networking from within the model. Here's an outline of how all the pieces fit together
the controller tells the model which items to follow
the model forwards that information to the server
when the server has new information, it uses APNS to notify the model
the model requests the new information from the server
after the data transfer is complete, the model uses NSNotificationCenter to inform the controller that new information is available
the controller reads the information from the model
the controller updates the view with the new information
Using Apple's Push Notification Service (APNS) allows your server to notify your app when new data is available. This helps reduce network traffic since your app doesn't have to constantly poll the server to determine when new data is available. If you aren't familiar with APNS, there's one very important feature of the service that you need to be aware of (since it seems to be a point of confusion for many new users). The service only guarantees delivery of the last message sent. So, for example, if the server gets 10 new items for a particular device, and sends 10 notifications to the device while the device is either off or in a tunnel, then the service is only guaranteed to deliver the 10th message. The point is that you can't use APNS to send any data from the server to the device, since some messages may be lost. You should only use APNS to notify the device that data is available.
I always create model classes (and interfaces, no idea if thats applicable in ObjectiveC).
The model is in many cases a view of the database backend.
Your model class should hide the database access and provide a simple interface, for example using a addNewFollower method. This method should then (optionally do sanity checks) and persist this to the database backend.
This approach allows you to easily replace your database integration without touching the service layer at all. For example using an in-memory mock database for testing.
I always create simple "dumb" objects for models, as they model the data, nothing more. If you're doing networking/api calls, I'd create a separate set of classes that deal strictly with API calls and utilize your models as the interchange data. Mixing data and functionality is always fishy to me.
Writing a clean, reusable, testable, and reliable API client, that can handle errors, parallel/serial calls, logging etc, requires quite a bit of code that really should be separated from your other application tiers. Data is just data, keep it clean, keep it simple.
The other thing is that some endpoints don't always return data exactly as it is defined in that 1 model where you are shoe-horning all of your code.
I wouldn't put it in the controllers either, I personally always create a different set of classes that can be used specifically for API calls, which also throw their own exceptions, handle serialization/de-serialization etc.

Making one view controller listen to another

So I have two view controllers. One has autocomplete for location search, and all it does is let the user use the google places api to get an address. The other lets the user do a keyword search and actually displays results in a table view(with a custom uitablecell).
I want to make it so that the I can take the address from one view controller, execute a search and use the code that draws the table in the other controller to draw my results.
In other words, I'm looking for a way for one view controller to trigger a message and the other view controller to listen.
Is there a way to do this?
When there are more than one receiver, use Notifications. We can set only one delegate.
When to use NSNotificationCenter Checklist:
You need a one-to-many relationships. You need few observers to react on a particular notification. Example: reachability notifications. When your network reachability changes, e.g. wi-fi becomes unavailable, all of the objects subscribed to this type of notifications will receive them and can process accordingly.
By design you encourage loose coupling. In the example above, producer that sends a ‘reachability changed’ notification doesn’t know anything about possible observers of this notifications. There could be few of them or none. Same true for observers, they don’t need to know anything about producers of this notification.
When to use Delegates Checklist:
Delegates should always be used only for one-to-one relationships.
Use delegates if you encourage tight coupling. Bear in mind, by using delegates you create more interdependency between objects and have more coordination with information flow.
A very good example of delegates would be UITableView. UITable ViewDelegate encourages more information flow and creates more interdependency between view controller and table view.
Here is what you need
Notification or Delegate
link 2

Resources