iOS: Decrease delay in UIAlertView show when app enters foreground - ios

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 #>
});

Related

How to dismiss UIAlertView in both iOS 7 & iOS 6?

How to dismiss uialertview(default) when click on out side. Here I have set the uialert with only one button (OK). Intend for implement this alert, if user seen free offer pack from this uialertview and he want to access his free pack offer by clicking the OK button in uialertview. Otherwise if he doesn't want to access his free offer pack at this time the user can tap the outside of uialert view and the alertview dismissed it.
Kindly give suggestion for how dismiss uialertview from out side clicking.
offeredAlert = [[UIAlertView alloc] initWithTitle:nil
message:strMessage
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil,nil];
[offeredAlert setTag:10002];
[offeredAlert show];
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *tempStr;
if(alertView.tag == 10001)
{
if(buttonIndex == 1)
{
tempStr = #"payable";
[self dietPackPurchaseAPI:id_Pack type:tempStr];
}
}
}

Quit iOS Application Programmatically with UIAlertView

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.)

Showing Waiting Alert View At Load

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.

iOS application asking the user two times to turn on location services when trying to access location with the location services turned off

I am trying to fetch user location at one button click in my iOS application. I am using below code to initiate the location manager.
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
locationManager.distanceFilter = 1000;
if ([CLLocationManager locationServicesEnabled]) {
[locationManager startUpdatingLocation];
}
else{
UIAlertView *alert= [[UIAlertView alloc]initWithTitle:#"Error" message:#"The location services seems to be disabled from the settings." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
alert= nil;
}
When the location services is turned on and the user is clicking the button, then it's working fine and the location is fetching correctly.
But when the location services is off and user tries to click the button, as per my code he alert should display as above. But before it reaches else loop, iOS displays a system level pop-up like below.
On top of this system level alert view, my own alert view is getting displayed. This is pretty frustrating. The problem is that if the user cancels the system level pop-up instead of going to settings and tries to click the button, second time also same thing (two alerts scenario) is happening. However, if the user continues the same step, then the system level alert is not displayed now. That means the system level pop-up as displayed above is coming for 2 times only and after that nothing is happening. How to handle this scenario. Please help.
Usually one would write:
if ([CLLocationManager locationServicesEnabled])
{
[locationManager startUpdatingLocation];
}
and let the iOS and the user sort it out. Merely calling [CLLocationManager locationServicesEnabled] will trigger the system dialog (for the first time). Following code is not tested but should work the way you want it to:
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized)
{
if ([CLLocationManager locationServicesEnabled])
{
[locationManager startUpdatingLocation];
}
}
else
{
UIAlertView *alert= [[UIAlertView alloc]initWithTitle:#"Error" message:#"The location services seems to be disabled from the settings." delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
alert= nil;
}
EDIT:
The result of my last code would be that user would not even get prompted to enable location updates for your app. You might do the following:
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"userWasAskedForLocationOnce"])
{
if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized)
{
UIAlertView *alert= [[UIAlertView alloc]initWithTitle:#"Error"
message:#"The location services seems to be disabled from the settings."
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
alert= nil;
}
}
else
{
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES]
forKey:#"userWasAskedForLocationOnce"];
if ([CLLocationManager locationServicesEnabled]) //this will trigger the system prompt
{
[locationManager startUpdatingLocation];
}
}
In this case user would get a system prompt to enable location updates for the first time. If they enable them, they would not get any prompts later on. If not, they would get your custom warning on subsequent launches - until they enable location updates in settings app.
Note 1: for testing this code you might want to delete your app from device from time to time (user-defaults are persistent until you delete your app)
Note 2: while this code should achieve the desired behavier it might be annoying to the user. Your UI should be arranged so that the user would know the locations services are disabled - alert is a bit overkill if this part of code is executed automatically at startup. If it is executed after a certain user's action (tapping a button) then it is ok to show alert.
I'm not sure about this. But whenever user accepts or denies the request to access their current location, a protocol callback locationManager:didChangeAuthorizationStatus: is called. Refer this for more details.

Dont show number on Call - iPhone App Development

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"]];
}
}

Resources