I want the cancel button of my UIAlertView to launch the app store so that my app can be updated. I can get the app to launch the app store, but I want it to launch only when the cancel button of my UIAlertView is pressed. The way I have it now, I'm given this error when I press the cancel button:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType alertView:clickedButtonAtIndex:]: unrecognized selector sent to instance 0x1651bd90'
Here's the code where I initialize and display the UIAlertView:
NSString* updateString = #"Please update the app! Thank you!";
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Please Update" message:updateString delegate:self cancelButtonTitle:#"Update Now" otherButtonTitles:nil];
[alert show];
Here's the function that's supposed to handle the cancel button being pressed:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"itms://itunes.com/apps/appname"]];
}
I've written in the containing object's header file that it follows the UIAlertViewDelegate protocol.
What am I doing wrong here?
You might be released the object that was calling this piece of code. If you are using ARC please make it a property.
Related
I have created a password protected app. The app is allowed to run in background.
When it returns to foreground, I display an alert to prompt the user for password, by overriding the applicationWillEnterForeground: method in appdelegate like so-
- (void)applicationWillEnterForeground:(UIApplication *)application
{
if (/*password is enabled*/) {
alertview = [[UIAlertView alloc] initWithTitle:#"LOGIN"
message:#"Enter app password"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:nil];
alertview.alertViewStyle = UIAlertViewStyleSecureTextInput;
pwdTF = [alertview textFieldAtIndex:0];
[pwdTF setDelegate:self];
[alertview show];
}
}
However, the alert takes a little time to appear. During this time, the view remains vulnerable.
Is there a way to make uialertview show instantly?
dispatch_async(dispatch_get_main_queue(), ^{
<# Write UI related code to be executed on main queue #>
});
I'm aborting my iOS Application by below methods
-(void)cancelSelected
{
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:nil message:#"Are you sure you want to exit?" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alert show];
alert = nil;
}
Method 1 :
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex)
abort();
}
Method 2 :
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex)
[NSException raise:#"Disagree terms and conditions." format:#"Quit, Cancel"];
}
Shall I do this to quit my iOS Application programmatically?
Will this abort() method leads to reject my app?
Thanks!
See QA1561:
Q: How do I programmatically quit my iOS application?
A: There is no API provided for gracefully terminating an iOS
application.
In iOS, the user presses the Home button to close applications. Should
your application have conditions in which it cannot provide its
intended function, the recommended approach is to display an alert for
the user that indicates the nature of the problem and possible actions
the user could take — turning on WiFi, enabling Location Services,
etc. Allow the user to terminate the application at their own
discretion.
Yes the codes above will result in a reject. Use this code instead in your OK button of alert:
UIControl().sendAction(#selector(URLSessionTask.suspend), to: UIApplication.shared, for: nil)
Yes, generally you will get rejected for that.
Just present an alert to the user with a singe option, so they must approve to dismiss the alert. Then, if they dismiss (approve) they can use the app and if they don't they can't and must quit the app manually.
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Game Over" message:#"Your time is up" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *close = [UIAlertAction actionWithTitle:#"close" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
**exit(0);**
}];
UIAlertAction *playagain = [UIAlertAction actionWithTitle:#"Play again" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
[self viewDidLoad];
}];
[alert addAction:close];
[alert addAction:playagain];
[self presentViewController:alert animated:YES completion:nil];
Use exit(0) for close current application
You can use below code to Quit iOS Application Programmatically with UIAlertView :-
Step 1:
Delegate "UIAlertViewDelegate" to your viewcontroller.h
for example:
#interface User_mail_List : UIViewController< UIAlertViewDelegate >
Step 2:
//create your UIAlertView
UIAlertView *exit_alertView= [[UIAlertView alloc] initWithTitle:#"Bizbilla !" message:#"\nAre you sure you want to Exit ?" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes",nil];
[exit_alertView show];
Step 3:
-(void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex{
if(alertView==exit_alertView){//exit Alert Fns Start,,,,,
if(buttonIndex==1){
exit(0);
}
}//exit Alert Fns End,,,,,
}
thanks,
On your alertview button click
You can use: exit(0)?
Or,
[[NSThread mainThread] exit], using this you can quit ios app.
How about calling fatalError()
function? I've just used it, everything works as expected. (Hope this will not cause a rejection though.)
I would like when my app starts for it to show an Alert view for about 5 seconds, then depending on the outcome of a background process, it will show another Alert view.
The problem I am experiencing is that when I try to use Sleep to wait for a background process to occur. The first Alert does not show and wait the 5 seconds. The app shows the first view of the app, and then after 5 seconds the first Alert shows briefly.
What do I need to do to perform what I wish.
Here is my code.
- (void)viewDidAppear:(BOOL)animated
{
SSGlobalSettings *connSettings = [SSGlobalSettings sharedManager];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Connecting" message:#"Please wait, while your device connects" delegate:Nil cancelButtonTitle:nil otherButtonTitles: nil];
[alertView show];
[NSThread sleepForTimeInterval:5.0f];
[alertView dismissWithClickedButtonIndex: alertView.cancelButtonIndex animated: YES];
if ([connSettings.connectionStatus isEqual: #"Not Found"])
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Connection Failed" message:#"Cannot find your device on the network" delegate:Nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alertView show];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Connection Success" message:#"WYour device has been found on the network" delegate:#"OK" cancelButtonTitle:nil otherButtonTitles: nil];
[alertView show];
}
}
Don't use sleep on the main thread. Ever. Also don't update UI from a background thread.
What you want to do is to display your alert on the main thread and return.
Then, when your networking code completes, have it send a message to the main thread. In the main thread, when you receive a notice that it's done, remove the alert.
It's not working right because you are trying to tell the main thread of the app to sleep. If you are telling that thread to sleep, then you're most likely not going to allow any UI updating to occur during that time, because all UI updating happens on the main thread.
What you need to do is move the code for showing the second UIAlertView to a second method, and then call the method - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay, passing it that second method for the selector, and giving it a delay of 5 seconds. Make sure you remove the call to sleep the main thread.
However, this still seems like a bad practice, because this action should be occurring as a result of your background task completing. So if you can, you should be running the code to show the second alert view upon completion of that task, which most likely could finish in varying amounts of time.
you block the main thread in you way.
i think it seems that you just want the user not to do anything before the first 5 sec(to let you connection connect successfully?), if so, lots ways could do that, e.g. just show a view on the top of the window, until you want the user can do something, you can show the disappear button on that view or just disappear it immediately.
You can use performSelector:withObject:afterDelay: method instead.
I have created a tab in my app, where the user could call the client directly from within the app.
But I wont show his number, i want to display: "Do you want to call Client?" instead of "Do you want to call 000-000-000"
I've seen this solution in another app, but dont have a clue how to do this.
The openURL call does not automatically prompt the user for anything.
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:7205551212"]];
It's good practice to confirm with the user, but it's up to you to determine the message. To show the alert, do something like this:
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Confirmation" message:#"Do you want to call Client?" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alertView show];
[alertView release];
Then make the actual phone call in a UIAlertViewDelegate method:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:7205551212"]];
}
}
I've integrated push notifications in my app. Users will receive push notification to join a group. When the user clicks Join, I've to handle something in the code. And so I'm implementing:
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
This is working fine when the app is not running.
When the app is running, I don't see any UIAlertView. How can make my app show the push notification alert so that user can still decide whether to join or not?
I used code like this in my application delegate to mimic the notification alert when the app was active. You should implement the appropriate UIAlertViewDelegate protocol method(s) to handle what happen when the user taps either of the buttons.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
NSString *cancelTitle = #"Close";
NSString *showTitle = #"Show";
NSString *message = [[userInfo valueForKey:#"aps"] valueForKey:#"alert"];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Some title"
message:message
delegate:self
cancelButtonTitle:cancelTitle
otherButtonTitles:showTitle, nil];
[alertView show];
[alertView release];
} else {
//Do stuff that you would do if the application was not active
}
}
For anyone might be interested, I ended up creating a custom view that looks like the system push banner on the top but adds a close button (small blue X) and an option to tap the message for custom action. It also supports the case of more than one notification arrived before the user had time to read/dismiss the old ones (With no limit to how many can pile up...)
Link to GitHub: AGPushNote
The usage is basically on-liner:
[AGPushNoteView showWithNotificationMessage:#"John Doe sent you a message!"];
And it looks like this on iOS7 (iOS6 have an iOS6 look and feel...)
You have to show the alert yourself if you want to. This is intentional behavior as documented here http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/IPhoneOSClientImp/IPhoneOSClientImp.html below Listing 2-6
only this function will be invoked and you have to explicitly show the alert on that case no notification will come if app is running in which you have implement the notification.Put the break point there and handle the notification call when function called and show your customized alert there.
For showing alert view while running application you have to use
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
}
and by accessing the userInfo variable
The app will still receive the -application:didReceiveRemoteNotification message in your App Delegate, but you'll have to act on the message yourself (i.e. the alert isn't displayed by default).
The userInfo parameter contains an object with the key notificationType, which you can use to identify the push message.
Here is a version which support UIAlertController
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
UIApplicationState state = [application applicationState];
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
if (state == UIApplicationStateActive) {
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:notification.alertTitle
message:notification.alertBody
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* ok = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:ok];
[self.navigationController presentViewController:alert animated:YES completion:nil];
}
}
** Please note my app uses self.navigationController in App Delegate, just hook on to any ViewController to present ( show ) the Alert **