VIPER architecture and proper place to save access token - ios

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.

Related

How do notifications fit in iOS VIPER architecture?

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.

Store User Token, If Invalid token - present Login page,

Learning iOS Swift programming and like to know how to implement user login process ?
The backend-iOS mechanism is this :
User login with email and Password,
The Server returns user token and user id
In subsequent requests, user token and user id is sent to fetch data/work with the App.
I have doubt in iOS implementation.
Will be storing User token and User id in Core Data. Will there be
any slowness if I get the user token on every screen from Core
Data?
If the login token expires or is invalid on any screen, how to fall back to login page? Should I check the JSON output and have code "present login VC" on every screen? Any streamlined way to have abstract the code to a swift or cocoa touch file?
Actually, there are many approaches. It's all depends on you, how you will manage it. I can point you two examples, how I manage it by myself.
Using NSOperation.
There was an awesome session on WWDC 2015, about advanced NSOperations. Here it is.
Basically, you create a subclass of NSOperaton and make other operations depend on it. In your case, you will have operation of user login, and all other operations will depend on user login (of course only ones, who needs it). If it succeed, then operation will execute. In user login operation, you will check, if user already logged in, and you have a token, if not, present logging screen.
There is also awesome library called Operations, based on that WWDC talk. Here it is.
Using PromiseKit.
Here is another one, using PromiseKit. It is not really much difference from operations, but, in my opinion, a little simpler. You create Promise that ensures that you did login. It is very simple to make a chain of promises, so you promise a user login and chain anything else from it. If login succeed, chain of promises continues executing.
It's all based on another awesome library, PromiseKit. Here it is
It is very powerful and very simple to use, once you understand the thing. It is very well documented, and has a bunch of tutorials here.
There are many other approaches, so you can choose any of it, and combine one with other however you like.
Asking on your first question, you make it asynchronous, so it is not so much matter about slowness of CoreData as you make a web request.
1 - well, yes, a bit. But I doubt you will notice any lag or anything: CoreData is really fast and it won't take any significant amount of time to fetch just one object. Alternatively, your CoreData object that holds this data (let's call it User) can be a property of your subclass of UIApplicationDelegate (let's call it MyAppDelegate). You will fetch this User in
- application:didFinishLaunchingWithOptions:, and update it on login/logout/expire/etc. In such way you can access it from everywhere, and you don't need to fetch it from CoreData anytime you need it.
Also, instead of CoreData you can use iOS Keychain. (Here is tutorial that might help with this).
2 - again, you can use MyAppDelegate. For example you can add method to it, that will save current navigation state, and change root controller of UIWindow to your LoginViewController. Or it will present LoginViewController on top of current controller. After successful login you will return navigation stack to previous state.
Also you can move this code to some kind of NavigationController - class that will handle this situation. It will have something like
func checkToken(Dictionary response, UIViewController currentController) -> Bool. If token is valid, it just returns true, and if not, it returns false and handles navigation to LoginViewController, and after login - back to currentController. This NavigationController can be property of MyAppDelegate, it can be singleton, created every time you need it, or you can pass it along to every UIViewController that you show.

Sequence Diagram for Login MVC Webapp

i want to make a sequence diagram, which shows the login process in an .Net MVC Webapp (i.e. webshop).
I am quite new to UML modeling, so i am not sure, how to build the interaction between, Controller, model and view. I found different solution online.
Here are some question i have:
Does the client interact with the view, or directly with the Controller (in my test Trial the client interacts with the Controller)?
For the loginvalidation: In my test Trial the Controller ask the model, if the login_data (username and pw) are correct. Is it necessary, that the model interacts with an database, where the user data are stored?
If i would like to send data in an http Request, should i just add the variable in the brackets?
Here is my test Trial:
This is perfect. You just could shortcut the http-response and move it outside the alt fragment.
The controller is the one to "do the job" and the view just to present it. Actually there's a bit of intermix since views contain some basic I/O logic. But here the http-data travel from the client to the controller.
It depends. You "can" show that but you "must not". If the model reader needs to know the details you can show that directly or in a separate SD.
You would usually pass data as parameter of a method. You can also show concrete data (e.g. a quoted string or an integer value).

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.

ios App improve network performance by requesting data up front

I have an application that I'm writing that pulls data from a few network sources:
1) list of blog posts (UITableViewController)
2) list of videos (UIViewController with an embedded UIScrollView)
3) list of images (UIViewController with an embedded UIScrollView)
Right now, there is a home screen with a menu and when you push one of the buttons, a destinationViewController (described above) is what loads the data on demand. I've noticed this is quite slow, especially when on a cellular data connection as opposed to wifi.
I was thinking about creating a class that requests all the data up front and kick it off every time the app is reentered. Does anyone have suggestions that could help me answer the following?
1) are there any classes, frameworks, or existing i code i can use to kick off these requests in a single place?
2) how do my destination view controllers (mentioned above) get the data?
3) how do my destination view controllers get informed that the data is ready if they happen to be invoked before the data is available?
4) is there a better strategy i should employ?
I appreciate the help.
Thanks,
jas
Off the top of my head, I would make the request class you mentioned and start all the request methods in applicationDidFinishLaunching in AppDelegate. I would also probably make custom NSObjects for each type of object you would be fetching and in each of your request class methods, convert the fetched data into said object, then cache each object to disk as they are downloaded. Then in your viewcontrollers, fetch the cached objects as needed.
When you are cacheing, make sure you cache each object with a key that will 100% be unique, because you are going to want to run a check on the current local cache before you start a new download. I would probably string together the file type and file name, and set that string as the key for the cached object.
To run the check on current cache in your request class methods, something that says "if current cache contains object for key:
uniqueKey... do nothing. If else, start the download and cache the object when finished."
Also run a check in your view controllers, because you're also going to want to handle the case where your view controller is requesting a cached object, but it hasn't downloaded yet. So something along the lines of "if current cache has object for key:key, great! use it. If else, start the download... cache it... then give me a call back here so i can use it while I display a loading message to the end user."
Im sure there are other scenarios that you are going to have to deal with, but that's the theoretical direction I would head in.
EDIT:
check out this, it will probably help you a lot. I think it also uses Ego Cache (if you dont want to write your own cache methods): https://github.com/Infusion-apps/Download-Manager
EDIT 2:
I also agree with #RyanDignards point #4. If possible, avoid fetching data you don't need. However, only you really know your UI/UX and app functionality, and my suggestion is assuming there is a good chance your end user is going to be using your app for the sole purpose of consuming the content you provide. So they are most likely going to be wanting to read the blog posts, watch the videos etc... The call is up to you, if you think there is more of a chance that the user will be viewing all the content than not, I would go the preload route, because nothing pisses off a user like having to wait.
1) RestKit is generally regarded as one of the the standard web interaction frameworks http://restkit.org
2) RestKit provides methods such as -[getObjectsAtPath: parameters: success: failure:] or post, which will provide the response in success. Additionally, it can convert the response directly into the respective objects for you with mapping.
3) Generally I would post a notification which is unique to that request, and any controller interested would get notified, with the response located on notification.object within the listener. Additionally most network requests provide for a callback handler where you could update the UI directly.
4) I would advise against preemptive loading since you're using resources for something that you may not actually use. My advice would be to breakdown your calls to the smallest possible level, then as the notifications are posted, that data would be inserted into the UI.

Resources