Using this for UIAlertView
- (void) alertStatus:(NSString *)msg :(NSString *)title :(int) tag
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
message:msg
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
alertView.tag = tag;
[alertView show];
}
But now UIAlertView get deprecated. change my code
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* MyAlert = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:MyAlert];
[self presentViewController:alertController animated:YES completion:nil];
Here how can pass this tag value
alertView.tag = tag;
Help how to pass the tag value in UIAlertController. Thanks advance.
UIAlertController is the UIViewController , so we need to assign the tag for view, soe use alertController.view.tag.
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"sds" message:#"sdf" preferredStyle:UIAlertControllerStyleAlert];
alertController.view.tag = tag;
UIAlertAction* MyAlert = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:MyAlert];
[self presentViewController:alertController animated:YES completion:nil];
update
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"sds" message:#"sdf" preferredStyle:UIAlertControllerStyleAlert];
alertController.view.tag = 3;
UIAlertAction* MyAlert = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action)
{
// OK button tappped.
[self dismissViewControllerAnimated:YES completion:^{
}];
}];
[alertController addAction:MyAlert];
[self presentViewController:alertController animated:YES completion:nil];
create a property of UIAlertController *alertController;, then use this alertController where ever you want. set the tag like this
alertController.view.tag = <YOUR TAG VALUE>;
to get the tag of that alertController, when you click on YES on alertController
//OK button tapped.
[self dismissViewControllerAnimated:YES completion:^{
NSInteger *tag = alertController.view.tag;
}];
Have not any tag property in UIAlertController. You can use block for getting button action.
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Alert"
message:[NSString stringWithFormat:#"Your message"]
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
//NSLog(#"OK");
}]];
[self presentViewController:alert animated:YES completion:nil];
But you can use tag in this way-
alert.view.tag = 1;
I have a UIAlertController, which contains a textfield and 2 buttons: OK and Cancel. i want to retrieve the text that the user entered in the textfield when he presses OK, but because the textfield is in a block i cant access the textField.text field that is inside the block from the OK button block. how do i access it and use the text entered by the user? see my code below.
- (IBAction)saveItinerary:(id)sender
{
NSString *itineraryNameInput = [[NSString alloc] init];
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Save Itinerary"
message:#"Enter Name for the Itinerary"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
{
}];
UIAlertAction* cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:ok];
[alert addAction:cancel];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.placeholder = #"Name";
textField.text = itineraryNameInput;
}];
NSLog(#"name = %#", itineraryNameInput);
[self presentViewController:alert animated:YES completion:nil];
}
Use the textFields property of the UIAlertController.
UITextField *textField = alert.textFields.firstObject;
I am new on IOS. I have a sample project and trying to learn Obj-C on that.
Now I am on the stage that is about learning how to use UIAlertController.
And I have a code like that:
if (loanAmount == 0) {
UIAlertController *ErrorMessage =[UIAlertController alertControllerWithTitle:#"Invalid amount" message:#"Enter a valid number" preferredStyle:UIAlertControllerStyleAlert];
} else
{ // sets labels
self.interestLabel.text = [NSString stringWithFormat:#"%i%c",interestRate,percentage];
self.periodLabel.text = [NSString stringWithFormat:#"%i months",months];
self.totalLabel.text = [NSString stringWithFormat:#"$%i",(loanAmount + tinterest)];
========================================================================
But When I run the simulator. There should be pop up message on Simulator. Instead of that, there is an error that says:
015-10-11 13:56:39.985 iBank[8055:1231178] Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior (<UIAlertController: 0x7ca82400>)
Any help would be greatly appreciated
try this
if (loanAmount == 0) {
UIAlertController * ErrorMessage = [UIAlertController
alertControllerWithTitle:#"Invalid amount"
message:#"Enter a valid number"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"Cancel", #"Cancel action")
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
NSLog(#"Cancel action");
}];
UIAlertAction *okAction = [UIAlertAction
actionWithTitle:NSLocalizedString(#"OK", #"OK action")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
NSLog(#"OK action");
}];
[ErrorMessage addAction:cancelAction];
[ErrorMessage addAction:okAction];
[self presentViewController: ErrorMessage animated:YES completion:nil];
}
else
{
self.interestLabel.text = [NSString stringWithFormat:#"%i%c",interestRate,percentage];
self.periodLabel.text = [NSString stringWithFormat:#"%i months",months];
self.totalLabel.text = [NSString stringWithFormat:#"$%i",(loanAmount + tinterest)];
}
I have tried several ways to use UIAlertController,instead of UIAlertView. I tried several ways but I cannot make the alert action work.
Here is my code that works fine in IOS 8 and IOS 9 but is showing up with deprecated flags. I tried the elegant suggestion below but I can't make it function in this context. I need to submit my app and this is the last thing to address. Thank You for any further suggestions. I am a newbie.
#pragma mark - BUTTONS ================================
- (IBAction)showModesAction:(id)sender {
NSLog(#"iapMade: %d", iapMade3);
// IAP MADE ! ===========================================
if (!iapMade3) {
//start game here
gamePlaysCount++;
[[NSUserDefaults standardUserDefaults]setInteger:gamePlaysCount forKey:#"gamePlaysCount"];
NSLog(#"playsCount: %ld", (long)gamePlaysCount);
if (gamePlaysCount >= 4) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Basic"
message: THREE_PLAYS_LIMIT_MESSAGE
delegate:self
cancelButtonTitle:#"Yes, please"
otherButtonTitles:#"No, thanks", nil];
[alert show];
NSString *path = [[NSBundle mainBundle] pathForResource:#"cow" ofType:#"wav"];
_pop =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[_pop play];
[self dismissViewControllerAnimated:true completion:nil];
} else {
if (gamePlaysCount == 1) {
// Create & store the next 5 mins when player gets 3 more lives
nextDateToPlay = [[NSDate date] dateByAddingTimeInterval:60*60*0.1];
NSLog(#"CURRENT DATE: %#", [NSDate date]);
NSLog(#"NEXT DAY: %#", nextDateToPlay);
[[NSUserDefaults standardUserDefaults]setObject: nextDateToPlay forKey:#"nextDateToPlay"];
NSLog(#"nextDateToPlay: %#", nextDateToPlay);
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Basic"
message: THREE_PLAYS_LIMIT_MESSAGE2
delegate:self
cancelButtonTitle:#"Got it!"
otherButtonTitles:#"Start", nil];
[alert show];
} else {
if (gamePlaysCount == 3) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Basic"
message: THREE_PLAYS_LIMIT_MESSAGE3
delegate:self
cancelButtonTitle:#"Yep, I Know!"
otherButtonTitles:#"Start", nil];
[alert show];
}
}
}
}
}
// IAP NOT MADE =============================
#pragma mark - ALERTVIEW DELEGATE ============================
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if ([[alertView buttonTitleAtIndex:buttonIndex] isEqualToString:#"Yes, please"]) {
UIStoryboard *storyboard = self.storyboard;
MenuViewController *svc = [storyboard instantiateViewControllerWithIdentifier:#"Store"];
svc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:svc animated:YES completion:nil];
}
}
From iOS8 Apple provide new UIAlertController class which you can use instead of UIAlertView which is now deprecated, it is also stated in deprecation message:
UIAlertView is deprecated. Use UIAlertController with a preferredStyle
of UIAlertControllerStyleAlert instead
So you should use something like this
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:#"Title"
message:#"Message"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:#"Yes, please"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
//Handle your yes please button action here
}];
UIAlertAction* noButton = [UIAlertAction
actionWithTitle:#"No, thanks"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
//Handle no, thanks button
}];
[alert addAction:yesButton];
[alert addAction:noButton];
[self presentViewController:alert animated:YES completion:nil];
//Calling
[self showMessage:#"There is no internet connection for this device"
withTitle:#"Error"];
//Method
-(void)showMessage:(NSString*)message withTitle:(NSString *)title
{
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
//do something when click button
}];
[alert addAction:okAction];
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[vc presentViewController:alert animated:YES completion:nil];
}
If you want to use this alert in NSObject class you should use like:
-(void)showMessage:(NSString*)message withTitle:(NSString *)title{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}]];
[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:alertController animated:YES completion:^{
}];
});
}
Swift version of new implementation is :
let alert = UIAlertController(title: "Oops!", message:"your message", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Okay.", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
Xcode 8 + Swift
Assuming self is a UIViewController:
func displayAlert() {
let alert = UIAlertController(title: "Test",
message: "I am a modal alert",
preferredStyle: .alert)
let defaultButton = UIAlertAction(title: "OK",
style: .default) {(_) in
// your defaultButton action goes here
}
alert.addAction(defaultButton)
present(alert, animated: true) {
// completion goes here
}
}
Make UIAlertController+AlertController Category as:
UIAlertController+AlertController.h
typedef void (^UIAlertCompletionBlock) (UIAlertController *alertViewController, NSInteger buttonIndex);
#interface UIAlertController (AlertController)
+ (instancetype)showAlertIn:(UIViewController *)controller
WithTitle:(NSString *)title
message:(NSString *)message
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitle
tapBlock:(UIAlertCompletionBlock)tapBlock;
#end
UIAlertController+AlertController.m
#implementation UIAlertController (NTAlertController)
+ (instancetype)showAlertIn:(UIViewController *)controller
WithTitle:(NSString *)title
message:(NSString *)message
cancelButtonTitle:(NSString *)cancelButtonTitle
otherButtonTitles:(NSString *)otherButtonTitle
tapBlock:(UIAlertCompletionBlock)tapBlock {
UIAlertController *alertController = [self alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
if(cancelButtonTitle != nil) {
UIAlertAction *cancelButton = [UIAlertAction
actionWithTitle:cancelButtonTitle
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
tapBlock(alertController, ALERTACTION_CANCEL); // CANCEL BUTTON CALL BACK ACTION
}];
[alertController addAction:cancelButton];
}
if(otherButtonTitle != nil) {
UIAlertAction *otherButton = [UIAlertAction
actionWithTitle:otherButtonTitle
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
tapBlock(alertController, ALERTACTION_OTHER); // OTHER BUTTON CALL BACK ACTION
}];
[alertController addAction:otherButton];
}
[controller presentViewController:alertController animated:YES completion:nil];
return alertController;
}
#end
in your ViewController.m
[UIAlertController showAlertIn:self WithTitle:#"" message:#"" cancelButtonTitle:#"Cancel" otherButtonTitles:#"Other" tapBlock:^(UIAlertController *alertController, NSInteger index){
if(index == ALERTACTION_CANCEL){
// CANCEL BUTTON ACTION
}else
if(index == ALERTACTION_OTHER){
// OTHER BUTTON ACTION
}
[alertController dismissViewControllerAnimated:YES completion:nil];
}];
NOTE: If you want to add more than two buttons then add another
more UIAlertAction to the UIAlertController.
Use UIAlertController instead of UIAlertView
-(void)showMessage:(NSString*)message withTitle:(NSString *)title
{
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
//do something when click button
}];
[alert addAction:okAction];
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[vc presentViewController:alert animated:YES completion:nil];
}
I tried the above methods, and no one can show the alert view, only when I put the presentViewController: method in a dispatch_async sentence:
dispatch_async(dispatch_get_main_queue(), ^ {
[self presentViewController:alert animated:YES completion:nil];
});
Refer to Alternative to UIAlertView for iOS 9?.
-(void)showAlert{
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Title"
message:#"Message"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
}
[self showAlert]; // calling Method
Check this:
UIAlertController *alertctrl =[UIAlertController alertControllerWithTitle:#"choose Image" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *camera =[UIAlertAction actionWithTitle:#"camera" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self Action]; //call Action need to perform
}];
[alertctrl addAction:camera];
-(void)Action
{
}
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:#"Are you sure you want to logout?"
message:#""
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:#"Logout"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction * action)
{
}];
UIAlertAction* noButton = [UIAlertAction
actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
//Handle no, thanks button
}];
[alert addAction:noButton];
[alert addAction:yesButton];
[self presentViewController:alert animated:YES completion:nil];
Is there a supported way of launching Google Authenticator on iOS?
I want to make it easier for customers to open the app and copy out the time-based code, before pasting it back into my app.
I've empirically discovered that this (Swift) code will launch the app:
UIApplication.sharedApplication().openURL(NSURL(string: "otpauth://")!)
...but I want to know if there is a better, supported way.
Specifically, is the otpauth:// protocol supported without arguments to simply launch the app?
Looking at the Git repo for the app it does seem like they have registered the Custom URL Schemes for bot otpauth and totp
https://github.com/google/google-authenticator/blob/bd50d15c348a978c314d2b30e586fbc562096223/mobile/ios/OTPAuth-Info.plist#L42
And here
https://github.com/google/google-authenticator/blob/bd50d15c348a978c314d2b30e586fbc562096223/mobile/ios/Classes/OTPAuthURL.h#L23
And here is the documentation on how exactly to build the url:
https://github.com/google/google-authenticator/wiki/Key-Uri-Format
After you form them correctly and get your app and the Google Authenticator app on the same device you would just need to test.
Objective C
if ([[[notification realRequestResults] valueForKey:#"action"] isEqualToString:#"2FA"]) {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Two Factor Authentication"
message:#"Please, enter your Google Authenticator 2FA Token."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"Confirm Token"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
#try {
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:
[userName text], #"loginName",
[passwordField text], #"password",
#"false", #"rememberMe",
[[alert textFields][0] text], #"tfa",
nil];
[self callWebserviceForIdentifier:AuthRequestInternalLogin
withParameters:parameters
onSuccessSelector:#selector(loginSuccessfulAgain:)
onFailureSelector:#selector(loginFailedAgain:)];
} #catch (NSException *exception) {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"login"
message:[NSString stringWithFormat:#"%#", exception.description]
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
} #finally {
}
}];
[alert addAction:defaultAction];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.delegate = self;
textField.placeholder = [NSMutableString stringWithString:#"Enter your 2FA token"];
textField.keyboardType = UIKeyboardTypeNumberPad;
textField.font = [UIFont systemFontOfSize:16.0];
textField.textAlignment = NSTextAlignmentCenter;
textField.textColor = UIColor.blackColor;
UIButton *addButton = [UIButton buttonWithType:UIButtonTypeCustom];
[addButton setImage:[UIImage imageNamed:#"authenticator.png"] forState:UIControlStateNormal];
[addButton addTarget:self action:#selector(authenticatorBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
textField.rightViewMode = UITextFieldViewModeAlways;
textField.rightView = addButton;
}];
[self presentViewController:alert animated:YES completion:nil];
}
else {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Warning"
message:#"Invalid Credentials. Please try again."
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
[self stopAnimation];
}
}
-(IBAction)authenticatorBtnClicked:(id)sender{
NSString *AppStoreURL = #"https://apps.apple.com/in/app/google-authenticator/id388497605";
NSString *customAppURL = #"otpauth://";
BOOL canOpenURL = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:customAppURL]];
NSString *url = canOpenURL ? customAppURL : AppStoreURL;
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:URL]];
}
In Info.plist File