How to validate login using UIAlertView in IOS application? - ios7

I have created login for my application. I have written alert view in iOS. Here the code:
alertView = [[UIAlertView alloc] initWithTitle:#"Login"
message:#"Enter username and password"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"Login", nil];
alertView.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
[alertView show];
I want to check the user name and password to allow to view next form. If the user name and password are wrong, the alert view need to pop up always.
How to pop up the alert always when the user name and password are wrong?
Any idea or reference should be appreciated.
Thanks in Advance.

In your view controller make sure you implement the UIAlertViewDelegate protocol
#interface MyCarsViewController () <UIAlertViewDelegate>
and then add this method:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
to the view controller. This is where you can get a reference to the text fields in the alert and do your db check etc. To get a reference to the text fields use
textFieldAtIndex:
https://developer.apple.com/library/ios/documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html#//apple_ref/occ/instm/UIAlertView/textFieldAtIndex:
After you check for the correct login you can present other view controllers or display another alert depending on the login results.
Hoep this helps

Related

Prevent access to UIViewControllers with tab bar controller (storyboard)

I currently encountering a problem with my iOS application.
I am attempting to incorporate a gradual login pattern, i.e.: the use can access some of the app without being required to login.
Required features are as follows:
At all times the user can view all navigation items that require login
When the user attempts to access an uiview(controller) that requires login, they will be prompted with a UIAlertView asking them to log in. (Preferably the UIAlertView will appear when the app recognised the initiated segue destination is restricted).
At first I used a subclass of UIViewController that, in the designated initialiser (initWithCoder), would check NSUserDefaults to see if the user was logged in. I then subclassed off of that. Limitations were as follows:
Couldn't use other subclasses of UIViewController, namely UITableViewController
The UIAlertView came up after the view had appeared, which i am assuming would cause errors if the subclassed UIViewController assumed the user was logged in.
Question summary:
I would like to know how to conditionally prevent users from accessing certain UIView(Controller)s and subclasses of UIViewController, and when that happens present a UIAlertView.
Update 1
Could categories and/or protocols be a viable solution?
Update 2
CodaFi pointed out singletons as a great solution to manage the user's state.
With that implemented I now need to figure out how to control the user's access.
As I am using storyboards I feel that the most versatile implementation would be subclassing UIStoryboardSegue, and on the perform method check if the user is attempting to access an restricted UIViewController (perhaps restricted controllers have a protocol property that specifies the required status: logged in/out). However the pitfall here is that you cannot choose the class/subclass of a UIStoryboardSegue in the storyboard graphic editor. I am aware that I could do it programatically, however that seems tedious as i would have to add IBActions and like that to methods that perform segues, furthermore I don't think that would work with the way elements such as navigationController and tabbarControllers behave.
Does anybody have a viable solution to restricting the user's navigation?
Update 3
I've added an answer to this question, however I still deem it as unanswered because the answer I've written doesn't take into account segues between navigation bar controllers. However it may help some people.
So, I've answered how to do this using custom segues.
Now I understand my real problem was the mental disconnect with the tabbarcontrollerdelegate protocol.
As a solution to preventing access to tabs I've made a class to handle said tab bar controller
#import <Foundation/Foundation.h>
#interface TabBarDelegate : NSObject<UITabBarControllerDelegate,UIAlertViewDelegate>{
UITabBarController *cachedTabBarController;
}
#end
#import "TabBarDelegate.h"
#implementation TabBarDelegate
-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
NSLog(#"%s",__FUNCTION__);
NSLog(#"Pretending the user isnt logged in");
if(true){
NSString *message = [NSString stringWithFormat:#"You require an account to access %#",viewController.tabBarItem.title];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Account Required" message:message delegate:self cancelButtonTitle:#"Okay" otherButtonTitles: #"Login",#"Create Account",nil];
[alert show];
//Hold tabbarcontroller property for alert callback
cachedTabBarController = tabBarController;
return false;
}
return true;
}
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
if(cachedTabBarController){
switch (buttonIndex) {
case 1:
//Login
[cachedTabBarController performSegueWithIdentifier:#"tabBarToLogin" sender:cachedTabBarController];
break;
case 2:
//Sign up
[cachedTabBarController performSegueWithIdentifier:#"tabBarToSignup" sender:cachedTabBarController];
break;
default:
break;
}
//Release tab bar controller from memory
cachedTabBarController = nil;
}
}
#end
Then i wired it up to my appDelegate in applicationDidFinishLaunching...
//Hook up tab bar delegate
mainTabController = (UITabBarController*)self.window.rootViewController;
mainTabBarDelegate = [[TabBarDelegate alloc] init];
mainTabController.delegate = mainTabBarDelegate;
And Voila
Okay, So I have part of a solution.
It only works in situations where you can choose a custom segue (and I've only written code for pushing, not modal).
Protocol "UIViewControllerAuthentication" for all controllers that require authentication, this protocol contains an method to retrieve the required authentication status.
enum authenticationStatus {
notLoggedIn = 0,
noPassword = 1,
loggedIn = 2
};
#protocol UIViewControllerAuthentication <NSObject>
-(enum authenticationStatus)authStatusRequired;
#end
Controllers that require authentication conform to this protocol:
-(enum authenticationStatus)authStatusRequired{
return loggedIn;
}
Then use this for the authenticated push segue
#interface SeguePushWithAuth : UIStoryboardSegue
#end
-(void)perform{
NSLog(#"custom segue destination : %#",self.destinationViewController);
NSLog(#"custom segue source : %#",self.sourceViewController);
NSLog(#"custom segue dest conforms to protocol : %i",[self.destinationViewController conformsToProtocol:#protocol(UIViewControllerAuthentication)]);
if([self.destinationViewController conformsToProtocol:#protocol(UIViewControllerAuthentication)]){
UIViewController <UIViewControllerAuthentication> *destination = (UIViewController <UIViewControllerAuthentication> *)self.destinationViewController;
if (!((int)[AccountModel userAuthStatus] >= (int)[destination authStatusRequired])) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Authentication" message:#"You need an account to access this area" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Login",#"Create Account", nil];
//alert
[alert show];
return;
}
}
[[self.sourceViewController navigationController] pushViewController:self.destinationViewController animated:true];
}
#end
Then use custom segues in uistoryboard
This is a good pattern to allow the destination controller to cancel the segue.
However its far from what I want as I want to be able to authenticate segues that link tab bar controllers to their children.

iOS Beginner: UIAlertView Window with 3 Buttons > Check what button was pressed

I have a working code from a tutorial but don't understand it completely.
Situation:
After a button was pressed in my iPhone App
an AlertView appears with three buttons.
Now I like to check what button the user pressed.
CODE FROM THE TUTORIAL:
- (IBAction)infoButtonPressed:(id)sender {
UIAlertView *myAlert1 = [[UIAlertView alloc]initWithTitle:#"My Alert View 1"
message:#"Here we go"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Option1", #"Option2", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSLog(#"Button: %i, was pressed.", buttonIndex);
}
Code works, I see the correct output in the console as a NSLog but how is it possible
that the method:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSLog(#"Button: %i, was pressed.", buttonIndex);
}
refers to the correct alert view. In this case: myAlert1.
What about with more than one alert view.
For example a second one calling myAlert2.
I know the following code is not correct but it would make more sense to me
if I'd write the method as follow:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSLog(#"Button: %i, was pressed.", buttonIndex_FROM_myAlert1);
}
Hope you can help, drives me nuts.
Regards,
Marc
how is it possible that the method refers to the correct alert view?
For exactly that reason, the delegate method alertView:didDismissWithButtonIndex: actually tells you which alert view it refers to. Note that the method has two arguments. The second one tells you the button index and the first one points to the alert view this button index refers to.
If you have more than one alert view that share the same delegate, you will have to check against the first argument which alert view this is about. To be able to do that, you would have to store the alert views in an ivar/property or other data structure in order to remember them in the delegate method. (Or, since UIAlertView is a subclass of UIView, you could use the tag property to distinguish between multiple views).

show alert xcode and go back after alert

i want to show the alert and when somebody click on OK they need to be send to the page before. How can i make this?
I use the following code:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"BOOYAH!"
message:#"Saved" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
Considering you have 1 option on the alert view and the delegate is self. Use this method in the same .m file as the code above
- (void)alertView:(UIAlertView *)alertV didDismissWithButtonIndex:(NSInteger)buttonIndex
{
//go back a page
[alertV autorelease];
}
Don't forget to release the alert view. I added it in the delegate method, but you can choose to release it right after showing it (only 1 release though)
Assign the UIAlertViewDelegate to self and then implement the following method is called
- (void) alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == buttonIndexForOK) { // Where buttonIndexForOK is the index for your ok button, in this case, that would be zero, but if you want an OK and a Cancel button this would be different.
// go back to the last page
}
}
UIAlertView follows the delegation design pattern that is extremely common in iOS development. You provide a delegate object, and when the object wants to tell you about something, it sends that delegate object a message.
In your code, you've provided self as the delegate. This means that this object needs to conform to the UIAlertViewDelegate protocol.
You will see that there are several methods you can implement to react to various events relating to the alert view. You should use the alertView:clickedButtonAtIndex: method, which provides an index parameter indicating which button was tapped.

How to open a dialog box in iphone?

I want to open the dialog box when the user clicks on a browse button in the nib. This would search for a picture he wants from his pc and upload it. How do I do this programmatically in iphone.
I'm not sure if I understand exactly what you want. But if you just want to show view on top of another view you should user the - (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated method of the UIViewController.
When pressing the button you init a new UIViewController subclass that does what you wan't to do in this 'popup'. Then you present it to your current view controller by calling the presentModal... method. When you're finished you can call - (void)dismissModalViewControllerAnimated:(BOOL)animated on your 'popup' view controller to dismiss it.
I think i understand ur problem,if u want to have something like dilogBox in iPhone, then i have something for U. the are two links for .h and .m file.
FileChooserAlert.h and FilechooserAlert.m.After clicking on these two links u'll get required files.Now to implement define ur class like this.
FileChooserAlert* fileChooserAlert = [[FileChooserAlert alloc] initWithTitle:#"Select" message:nil delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok",nil];
[fileChooserAlert show];
[fileChooserAlert release];
The two source file has something that u need to change before u can actually run it.Like there are three images named "File_icon.png","Folder_icon.png","Folder_up.png", which u need to include into ur project.
Now when user selects any file by selecting the tableView Cell and tapping OK button, U can get the file location by calling.
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == ALERT_TYPE_FILE_CHOOSER)
{
switch (buttonIndex)
{
case 0: //Cancel
break;
case 1:
{
myFileLocation = [(FileChooserAlert*)alertView getFileCompletePath]];
}break;
default:
break;
}
}
}
If U have any problem implementing this file email me.

iPhone keyboard popup problem in UIAlertView

I want to accept password using an alert view. Following is the code I am using. But I am unable to figure out why does the keyboard pop out two times instead of once? Any ideas?
UIAlertView *passwordAlert = [[UIAlertView alloc]
initWithTitle:#"Enter Password" message:#""
delegate:self cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Submit",nil];
[passwordAlert addTextFieldWithValue:#"" label:#"Password"];
UITextField *textfield = [passwordAlert textFieldAtIndex:0];
textfield.secureTextEntry = YES;
[passwordAlert setTag:10];
[passwordAlert show];
Not entirely sure where addTextFieldWithValue is defined but you may want to check your .xib file to make sure you didn't place double views on the "stage" as in this post:
http://www.iphonedevsdk.com/forum/iphone-sdk-development/1479-uialertview-popping-up-twice.html
Also, check out this post. Looks like you may have to "tell the text field to become first responder before showing the alert view, you'll wind up with two keyboards":
http://www.iphonedevsdk.com/forum/iphone-sdk-development/2753-new-info-adding-text-fields-alerts.html#post14701