applicationWillResignActive called by iOS alerts too. How to avoid this? - ios

I use applicationWillResignActive to display the splash image when my app is in background (see code-snippet). Reason: I don't want private data of the app be visible when my app is in background on iOS 7 and the user presses the Home button twice.
splashWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
splashWindow.windowLevel = UIWindowLevelAlert;
[splashWindow addSubview:splashViewController.view];
[splashWindow makeKeyAndVisible];
The problem is that applicationWillResignActive is also fired when iOS shows an alert because some certificate is about to expire. How can I fix this? Do I need to take another approach to display the splash image in background?
Thanks for any advice

You could also use the applicationWillEnterBackground to open a blank screen/your splash image and switch back to your normal screen with applicationWillEnterForeground.

Fixed: I could not change the iOS behaviour as described but I used:
[self.window addSubview:splashViewController.view];
instead of the code-snippet above. The iOS alert still makes the splash appear but I hide it again in applicationDidBecomeActive with [splashViewController.view removeFromSuperview];
The splash now disappears when the alert is answered with OK or Cancel.

Related

Take a picture after BTLE background notification fired

I'm developing an app that runs in background mode, so that my app receives BT notifications from a BTLE accessory.
When I get a specific notification, I want to take a picture whether the app is running in background or foreground.
First question: Would the app be rejected by Apple because of taking photos in background mode?
Second question:
What would be the best option to do this?
At first I thought about using UIImagePickerController, but finally I'm using AVFoundation AVCam example because I do not need to show preview.
But, Third and last question: could I show a preview?
I have tried to use the following code. It works ok if app is running in foreground mode, but not for background mode:
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"iPhone5Storyboard" bundle:nil];
AVCamViewController *camViewController = [mainStoryboard instantiateViewControllerWithIdentifier:#"ViewControllerCamera"];
UIViewController *rootVC = [[(AppDelegate *) [[UIApplication sharedApplication] delegate] window] rootViewController];
[rootVC presentViewController: camViewController animated:YES completion:nil];
Many doubts.
First off, you cannot take a picture when the app is not in the foreground. That's just a core iOS limitation. (You could do it with a jailbroken iphone though).
As for the second part of your question, you AVFoundation is a great way to work with camera functionality. It's flexible on the view presentation and any type of filters you'd like to apply to the video stream. The AVCam example is a great example.
And for the third, that goes back to the first point. No matter what you use, you can't take pictures in the background unless it's in the foreground and the user has given permission.
I suggest submitting a local notification and asking the user to bring the app to the foregound when you want to take a picture. Probably not the news you wanted to hear, but that's how Apple intended it to be used.

IOS Splash screen/popup display from closed library

We own proprietary library built for IOS, used by our customers in their application. Basically the library has no UI related functionality, but When they call our library init api, we want to add a splash screen or a popup(containing our company logo) to be displayed on top of their UI.
This splash screen might be called anytime, during or after the application launch time.
Also it is possible that proprietary library init API may not be called from main thread.
Would like to know if there is a reliable/feasible solution with some direction/examples?
Thanks,
Hari
Create UIImageView and add image and then
[self.window addSubview:uiimageview];
[self performSelector:#selector(dismissPopover) withObject:nil afterDelay:3];
and then remove the image
-(void)dismissPopover
{
[popover removeFromSuperview];
}
check this iPhone app: avoiding white screen after splash screen. Let splash screen linger, hide it after UIWebview loads? Splash screen not hiding properly

How to call a view controller from AppDelegate in iOS

I am creating an iOS app in which I have the following requeriment: the app should show the login screen when it starts the first time and also that screen must also be shown when the app comes from the background to the foreground, in case it has been sent to background during run time.
I have handled to show the screen in both cases. However, when I do it and the app comes from the background, and I click the texfield to type my password, the app gets frozen, and it fails in a thread that I don't know what it means.
I call the screen to be shown when the app comes from background like this, in the applicationWillEnterForeground, in AppDelegate:
self.window=[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
RoomRootViewController* room = [[RoomRootViewController alloc] init];
[[self window] setRootViewController:room];
[self.window makeKeyAndVisible];
Is this the correct way to do so?
Thanks a lot in advance ! I am completely lost with this as I am very new in iOS, so any help will be very appreciated.
Attached in an image you can see where the app fails.
The code you are currently using is completely deleting the root view controller of your app window, in other words, you are deleting all the views and view controllers in your app. If you are not using ARC, this is just one huge memory leak. If you are, it's still not a very good idea.
In your applicationWillEnterForeground: method, try using this code instead:
RoomRootViewController* room = [[RoomRootViewController alloc] init];
[self.window.rootViewController presentViewController:room
animated:NO
completion:nil];
This will display the RoomRootViewController over the top of all your app's current views, instead of deleting them. You can then dismiss it like this:
[self.window.rootViewController dismissViewControllerAnimated:YES
completion:nil];
and easily return to the rest of your app.
It will be very messy if you are using this line of code
self.window=[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
It means every time you are creating new instance of UIWindow which will contain UIViewController and all other component each time. Which means when you go to background and comes to foreground the old window instance has been flushed off and it will contain new components that's why when you click on the UITextField it has been deallocated, The reason you are getting error. Don't create new instance of window and use the code as #PartiallyFinite does.
Hope this helps.

Changing rootViewController in applicaitonWillEnterForeground

Long story short, I'm trying to change my iOS app's rootViewController on applicationWillEnterForeground:, like so:
- (void)applicationWillEnterForeground:(UIApplication *)application
{
MyViewController *controller = [[MyViewController alloc] init];
self.window.rootViewController = controller;
}
However, when iOS performs the "zoom in" animation that is performed when an app is moved from the background to the foreground, it still shows the previous rootViewController's view. Then, as soon as the animation is complete, the app blasts the new rootViewController's view onto the screen.
One way to solve this is to simply move that code to - (void)applicationDidEnterBackground:, but the problem with this solution is that, in my app, there is no way to tell if a new rootViewController will be assigned until - (void)applicationWillEnterForeground:(UIApplication *)application (it is based on time passed since leaving the app).
How can I force the app to redraw before iOS performs the animation taking the app from the background to the foreground?
I believe this is not possible. The screen that iOS shows of your app when it comes into the foreground is actually a screenshot the system took when the app went into the background. There is no way to manipulate or replace that image at the time the app comes back into the foreground.
This behavior is partly documented in the Moving to the Background section of the iOS Application Programming Guide:
Apps can use their applicationDidEnterBackground: method to prepare for moving to the background state. When moving to the background, all apps should do the following:
Prepare to have their picture taken. When the applicationDidEnterBackground: method returns, the system takes a picture of your app’s user interface and uses the resulting image for transition animations. If any views in your interface contain sensitive information, you should hide or modify those views before the applicationDidEnterBackground: method returns.
Apple does not explicitly document that you cannot modify or replace this screenshot at a later time but neither do they say the opposite anywhere I know of.

go to another page in applicationDidEnterBackground in iOS in device

In my application, When the application goes to background I am calling a Passcode page (Passcode Page which does authentication).
My requirement is when the user launch the app from the foreground he will see the passcode page. If he enters the correct passcode then only he can see the rest pages.
In delegate.m file
- (void)applicationDidEnterBackground:(UIApplication *)application
{
PasscodeViewController *passcodeController = [[PasscodeViewController alloc] initWithNibName:#"PasscodeViewController" bundle:nil];
[navController pushViewController:passcodeController animated:YES];
}
When I am launching the application from the background then It is showing me the previous page( from which page I came to background ) for a fraction of second and after that Passcode page comes.
But I want to hide my confidential information from others (who doesn't know the passcode) that are shown in the previous page.
It is correctly working in Simulator but in Device it is not working properly.
Can you please guide me in that ?
OR
Is it the normal behavior of the iOS device ? What ever the page transition it will do, it will perform while the application is running in foreground.
I am not sure about that. Please tell me where I went wrong.
Thank you.
Every app I've used with a similar feature has operated as you describe, with the fractional-second flash before the lock view appears.
I think it's a matter of when UIKit thinks it needs to re-render... We had a similar case with a splash screen, but using applicationDidEnterBackground for adding the splash helped.
My idea is to avoid the animating, using
[navController pushViewController:passcodeController animated:NO];
Whenever your app goes background add a UIView with white background.
Whenever your app comes up push your PasscodeViewController view on top
Please add observers for UIApplicationDidEnterBackgroundNotification and UIApplicationWillEnterForegroundNotification to do the above functionality
Also be sure to remove the Observers when your view disappears
When user enters correct passcode remove the UIView.
Try applicationWillResignActive:
- (void)applicationWillResignActive:(UIApplication *)application
{
PasscodeViewController* passcodeController = [[PasscodeViewController alloc] initWithNibName:#"PasscodeViewController" bundle:nil];
[navController pushViewController:passcodeController animated:YES];
}
When Application goes to background push the passcode viewcontroller to navigationcontroller in the delegate applicationDidEnterBackground because there will be that fractional flash almost all time u can have the passcodecontroller pushed before entering background.

Resources