I'm building an app using ionic and angularfire and I didn't understand the logic behind the maintenance of sessions using the $onAuth. I know how the function works, but I do not know exactly where to use it..
Do I need to inject it the $onAuth in every controller and veirfy if the authData is null or not(to then use $unauth and redirect the user properly) OR there is a way to have this function($onAuth) centralized in an other file and let ir listining and only then do something if the authData is null?
Feel free to ask if the question it's not clear!
Thanks in advance to all who help! :)
There are many possible ways you can take to your goal. The worst one would be to take the way you described and have it in every controller, because you should keep your code DRY. Your goal clearly is to only write the method for $onAuth once.
One easy approach is to have either a MainController that is instanciated at the very top of your dom (like on of the outermost html elements, e.g. the body tag). You can then use your child controllers to access data from the parent controller like explained e.g. here. You would inject the $onAuth service in the main controller, and let it do your logic, and you could access the main controller's $scope with your authData from all its child controllers.
A more reusable part would be to write a service that you can access from all of your controllers. Find a great tutorial here.
The easiest way is to have the $onAuth in your module's run block and save it in your $rootScope that can also be accessed later from all controllers. Here is an auth example. You would write
angular.module('your-module').run(function($rootScope, Auth) {
$rootScope.auth = Auth;
$rootScope.auth.$onAuth(function(authData) {
$rootScope.authData = authData;
//do anything you want here, e.g. redirect
});
}
Related
I am using a custom AuthAttribute to determine whether a user can access a controller and/or actions. The problem is I have to duplicate information and EFx connections in the attribute that already exist on the class that is being adorned.
My question is whether there is a way to access the fields on the adorned class from the custom AuthAttribute? I am trying to avoid having to re-architect the software in a way that would provide a single point of access since that would open up a different can of worms.
I believe I have found an answer that works. I welcome all comments on this solution.
Rather than have the attribute gain access to the properties and fields on the controller it adorns you can share values between them in a thread-safe way through the common HttpContext object. So if you are being extreme like I am and are trying to cut down on duplicate calls to your database in both the authattribute and the adorned controller action then pass the results forward. What that means is the authattribute will be called first and you can stash the retrieved values in the "Items" collection off the HttpContext object passed into the AuthorizeCore(..) method. You can then retrieve the same value in a THREAD-SAFE way through the HttpContext object in the controller.
example to save value within the AuthorizeCore(..) override of the AuthAttribute:
httpContext.Items.Add("fester", "bester");
example to retrieve value inside the subsequent call to the Controller/Action:
this.HttpContext.ApplicationInstance.Context.Items["fester"];
I have to warn you this is only a possible implementation that appears to work in simple testing. Personally it feels like a hack and there has to be a better way. I would also state this is in pursuit of a dubious performance benefit. It should cut down on the number of database and/or network calls by cache'ing retrieved data in the HttpContext so you don't have to repeat the calls in both the authattribute and the adorned Controller/Action. If you don't have a web site that gets a huge volume of calls then I would warn you against this.
I hope someone recommends something better on this page. I will keep an eye on how this works on my web site and let y'all know if it behaves and is truly thread-safe.
I have noticed that with iPhone programming you kind of need to retrieve your data from within the ViewController because of the way the data is retrieved.
e.g.: ViewDidLoad is called. You start retrieving the data and then when its finished a message is sent to your viewcontroller e.g. requestFinished and this is where you configure/refresh your UI.
The problem that I have with this approach is that I have a bunch of web service code and XML building and parsing all in my view controller.
Does anyone know if this is the correct approach or is there a better way to do this.
In .NET I would have classes specifically for retrieving data from webservices and I would simply call the web service to fetch the data and I could use the same web service at various places inside my app.
There is no reason to do that different in Objective-C/Cocoa. You should create a class that handles the web service and notifies the view controller when data is available.
No, it absolutely isn't the correct approach. The key to this is the MVC paradigm, - model, view, controller - your data classes are perfectly suited to being the M = model so put all your data handling code inside a dedicated model class.
Because the url handling is hopefully asynchronous, your model will still need to inform your view controller when various events have taken place. You have a couple of choices here but the most appropriate is probably to use a delegate pattern so that the model can basically initiate a call back to the view controller when it has data that needs displaying etc.
(The other approach would be to use notifications which is less tightly coupled, and perfectly viable in this scenario, but delegates would be more appropriate).
Well you could create a parse that will parse your XML in a seprate class, and even your http request can be in a seprate class.
There is no need to do every thing in the the on viewcontroller.
Just be sure to create delegate or use the notification center if you are using threads. Set the delegate on either the request or parse to nil if the view controller get unloaded.
I have a UINavigation based application that gathers information on various screens and eventually makes a web service request using all the parameters collected.
So I have A,B,C,D view controllers. A gets the name & number, it then pushes B onto the screen with some basic info ETC ETC until it gets to D where I actually fire off the web service.
The poor method I have been using is to duplicate class fields from A onwards. Meaning if I collect name, and number, then I make those the fields of B, which then adds a few fields, and then C has class fields of both A & B which seems like a poor programing practice.
What can I do to get access to class A's fields in class D? I have gotten certain ideas but not sure how valid they are.
1). Use NSNotification (Is this overkill?) If so how do I pass fields?
2). DO I just retain all 5 view controllers and just get the info at the end? (seems very inefficient)
3). Should I just instantiate a NSObject class called Payload and just set its fields every time I bounce from one view controller to the next? (If so do I create it in class A? What if user navigates back to class A, will it then get reset ETC ETC)
As you can tell I have tried to find a solution and I am fairly new to it. Some detailed suggestions would be highly appreciated.
Depending on situation, there are several ways that seem appropriate.
Get to know MVC Design Pattern
Classes are not data storage. If class doesn't have interface to interact with represented object, excluding accessors, you're doing it wrong.
3.
I have a UINavigation based
application that gathers information
on various screens and eventually
makes a web service request using all
the parameters collected.
So, your web request is based on parameters gathered from various views. Why not create an
model of said request? MyRequest or something like that :) Or several more specific variants, sharing common parent class? This generator holds logic, gathers data and parameters as you advance trough views and provides NSUrlRequest at the end to WebView or maybe different kind of object which is NSURLRequest delegate and conforms to UITableViewDataSource/Delegate protocols to be used to display downloaded data.
I'd go for 3) and yes you should create it at the beginning (Class A).
But maybe user go back to Class A to change the value on purpose so resetting it doesn't seem to be a problem.
Why not use a singleton object and pass it around?
The advantages of this method are:
There's only one instance whose
reference is being passed around
between viewcontrollers
Changes you
make are reflected the next time you
access this object from another view
controller
And to answer one of your questions, NSNotification allows us to pass objects along....
Here's a good example on singleton objects in iOS by Matt Galloway. It's the one I always refer to:
http://www.galloway.me.uk/tutorials/singleton-classes/
I'm working on a new iPhone/iPod app that includes the need to do web services requests. I've found methods for doing these requests synchronously, or asynchronously by setting the controller as the delegate. What I'd really like to be able to do, though, is to create a single class that can handle all web requests for the whole application, and just create an instance of that class when I need to use it. That way, cookies and common pieces of code can be handled in one place, rather than all over the app.
So far the only thing I thought of that could accomplish what I'm trying to do is to create a new thread that handles the request synchronously within itself, then sends a message back to the calling controller once the request is complete. Is there a better way to accomplish what I'm trying to do?
Cookies are already a shared resource.
I would suggest reading the URL Loading System Overview to get an idea of how Apple set everything up. From what you describe, you want something very similar to how they have set up the system, maybe with a Singleton class for the connection. You can also look at ASIHTTPRequests which is a good wrapper around all of the connections stuff.
I would not suggest writing my own code here. Lots and lots of people have solved this problem for you.
I'm writing my first "real" MVVM application, and the first step the user will need to take is to provide login credentials. In the past, I would have shown the login dialog after the main window has been laid out and made visible for the first time.
What is the preferred way of doing this in the MVVM world, and why?
I see many options, one of which is to continue doing it the way I've done it before, as it's a one-time step and won't interfere with the rest of the "MVVM-ness" of the application. Once the user has logged in, I could initialize the MainWindow's ModelView with their credentials and then continue on my way. Another option is to let the ModelView cause the login dialog to be shown (somehow). Do MVVM gurus prefer either of these?
(There is one other option, which is showing the login dialog first, and then when it is dismissed, create the main window. This would technically solve my dilemma, but it wouldn't really educate me, nor do I like the aesthetics of having a "naked" login dialog.)
The Model-View-ViewModel Pattern doesn't tell us how to define the UI workflow. We are free to choose an appropriate workflow ourself. I would prefer your first approach because it is simple and straight forward to implement. The workflow:
Show empty Main Window
Show Login Dialog
Initialize Main Window with User Credentials
would be in the responsibility of a Controller (e.g. ApplicationController). How this might look like is shown in the ViewModel sample application of the WPF Application Framework (WAF).
I think the best(cleaner, testable...) option would be for the ViewModels to initiate the dialog show-up as the logic should belong to the VM and not the view...This 'show-up' is usually implemented by creating something like a DialogService that should take care of just that -
Create an abstraction for your modal window (for example by creating an interface that has a method like ShowDialog() and a property DialogResult and perhaps more - that depends on your concrete need) that your dialogs implement; then create your DialogService that has a dependency on your abstraction of the dialog and in this service you can call ShowDialog, check for the DialogResult's value etc; In your VM you'll only use this dialog service without having a reference on some view related stuff...I won't get into the details as there are some implementations out there on displaying/working with modal dialogs from your VM that are based on this (and more)...Choosing this approach also gets you UI framework platform independence.
HTH.