applicationDidEnterBackground method not getting called neither did applicationWillResignActive when My application goes in the background iOS 7 - ios7

I am developing a banking application and the client requirement is not to show/save the screen snapshot when app goes in the background (i.e., when home button is clicked).
I have added an overlay view in background method and removed that view when app again comes in the foreground. Its working perfectly fine when I click home button, wait for 1 or 2 secs and then again click home button twice.
My problem is: If I click home button once, wait for some milliseconds (just before the app icons visible)and then again click home button twice, then the screen snapshot is visible (in multitasker view).
When I analysed the issue, I came to know that my background delegate method doesn't get called in this scenario and hence, no overlay view is added in this case.
Steps to Reproduce:
Add An overlay view (with while color, lets say) in appDidEnterBackground Method of your application.
Add code for removing that overlay view in willEnterForeground Method.
Now, run your application.
Press Home button once.
Just after pressing home button once (and just before your application icon is visible), click home button twice so that you are able to see the Multitasker view.
Instead of your overlay view, you would be seeing the application screenshot there.
Expected Results:
The While overlay view should have been added, and you should have seen that instead of app snapshot.
Actual Results:
You are able to see the application screen shot in Multi tasker view
Version:
iOS 7 and above

I've created an app that does exactly what you want. I throw up the shield image view in applicationWillResignActive:
- (void)applicationWillResignActive:(UIApplication *)application {
// ...
self.shieldImageView = [[UIImageView alloc] initWithFrame:self.window.frame];
self.shieldImageView.image = [UIImage imageNamed:#"shieldimage"];
self.shieldImageView.contentMode = UIViewContentModeScaleAspectFit;
[self.window addSubview:self.shieldImageView];
// ...
}
and get rid of it in applicationDidBecomeActive:
- (void)applicationDidBecomeActive:(UIApplication *)application {
// ...
[self.shieldImageView removeFromSuperview];
self.shieldImageView = nil;
// ...
}

Related

React Native get notified just before app minimizes but still active

I need a way to hide sensitive information in a react native app so if you minimize the app and leave your phone unlocked the snapshot of the app in the multitasking view would be blurred and the navigation stack would be switched back to login screen when the app becomes active again.
Even just showing the Login screen just before the app becomes inactive->background would be sufficient but it seems that the AppState's change event is called after the state is already changed from active to inactive and at this point the snapshot is already made and the screen changing occurs after the app is restored. This way the screen with the sensitive data is visible in the multitasking.
I know how to make this with ease in native iOS environment but it seems it's not quite that trivial in React Native.
You can't avoid here from the native code.
in iOS:
In your AppDelegate.m file these 2:
1.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Your application can present a full screen modal view controller to
// cover its contents when it moves into the background. If your
// application requires a password unlock when it retuns to the
// foreground, present your lock screen or authentication view controller here.
UIViewController *blankViewController = [UIViewController new];
blankViewController.view.backgroundColor = [UIColor blackColor];
// Pass NO for the animated parameter. Any animation will not complete
// before the snapshot is taken.
[self.window.rootViewController presentViewController:blankViewController animated:NO completion:NULL];
}
And this
2.
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// This should be omitted if your application presented a lock screen
// in -applicationDidEnterBackground:
[self.window.rootViewController dismissViewControllerAnimated:NO completion:NO];
}
Source:
https://developer.apple.com/library/content/qa/qa1838/_index.html
Found this also:
https://github.com/kayla-tech/react-native-privacy-snapshot

IAD lifecycle - dismiss of ad sends app back to splash screen

I have a simple spritekit app, SKView on intialization shows a splash screen(scene), the user clicks on a button they are taken to the main game scene.
Everything works fine, but wanted to add iads to it, so I instantiated an adview in the main scene, and assign its delegate to the main scene.
The add appears fine, and I click on it, it properly shows the ad, but then I dismiss the ad, and when I do that the app goes back and looks like it reinitializes the entire SKVIEW which displays the Splash Scene, not the main scene which was paused in the delegate calls.
So, when the IAD is dismissed, what exactly are the callbacks back into the parent app, because its clear its not just the delegate methods, its going back and reinitializing the view etc. Basically where in my view do I need to trap its returning from a canceled ad and handle this case properly.
Sounds like you're running the scene in viewWillLayoutSubviews without checking whether a scene is already running. Make sure the launch code looks like this, or it will relaunch the starting scene whenever the viewWillLayoutSubviews method runs (it can and will be called multiple times, for example when rotating the device and apparently also when dismissing an ad):
-(void)viewWillLayoutSubviews
{
SKView* skView = (SKView*)self.view;
// only create/launch first scene when SKView has no running scene
if (skView.scene == nil)
{
// create and present scene here ...
}
[super viewWillLayoutSubviews];
}

On clicking a tab need to answer an alert before moving into the tab clicked - iPad programming

There are many tabs in my screen,I want to give an alert box which says "Do you want to save the changes?" if user changes anything in the page, without clicking on the save button provided in the page,he is clicking on diff tab.
I'm able to get the alert view but the tab click moves the screen to the tab which was clicked. The screen should not change until the alert view is answered.
Can anyone let me know how to suppress the screen change until the alert view is answered ?
This doesn't directly answer your question, but: what you're trying to do sounds like bad UI design. (In general, if it feels like you are fighting against UIKit, you're probably doing it the wrong.)
In this case: if you really want to ensure that a user taps a Save button before moving to a different screen, you should present that screen in a modal view, so that it is impossible to navigate to any other part of the app.
In other words, if you want to prevent a user from navigating away from a screen, don't show them buttons or tabs that would allow them to navigate away. Otherwise, you're just making more work for yourself and frustrating a user.
Implement UITabBarControllerDelegate in your app delegate's applicationDidFinishLaunching
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
self.tabBarController.delegate = self;
[window addSubview:self.tabBarController.view];
}
Then use the below delegate method,
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController;
This method is called before the tab switch and you can return no here to disable that and show an alert message instead. Once the user has performed the save either he can press on tab again or you can programmatically switch to the new tab as,
self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:0];
Add this inside your delegate,
How about this for switching to the tab programmatically,
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
if () {
//some code
} else {
//some other code
self.tabBarController.selectedViewController = viewController;
}
}

MKMapView not allowing user interaction on Ipod Touch OS 3.1.3, works correctly on simulator 3.2 / 4.0

I have been coding and testing an app which uses a navigation controller, tab bar and table views together as shown in this tutorial video:
I have also coded a MapView page which shows custom annotations. This seems to work fine in every version of the simulator I have tried it on. This morning I have finally got the app running on my Ipod Touch which runs OS 3.1.3 - everything works as expected except the map does not seem to allow user interaction at all. I cannot tap on annotations, the current location or move and zoom at all.
I have been through all the settings in the Interface Builder for the mapview, and made sure that all the 'User Interaction', 'Allow Multitouch' boxes have been ticked. This doesn't seem to change anything.
Any help greatly appreciated.
The Mapview is put into the view as follows:
// Grab the maps view controller ready for loading
MapView *childController = [[MapView alloc] initWithNibName:#"MapView" bundle:nil];
childController.title = #"View on Map";
// Push the new view controller onto the stack
[self.navigationController pushViewController:childController animated:YES];
[childController release];
childController = nil;
I've also tried running the view in a modal view controller just to see what would happen. The view was shown and any interaction didnt seem to work - with the exception of a small section at the bottom where I made the view itself slightly shorter so it would fit in above the tab bar. This section seems to have another map underneath my view which DOES respond to user interaction. So there is a 1cm or so block which does move - my view seems to stay static on top of it, though.
The view underneath does not appear to have any annotations or the current user location.
Ok I've solved this one:
In the mapview.m file where I set up the view and load the annotations, within the viewDidLoad function I had the following code:
- (void)viewDidLoad {
// More code before this..
[mapView addAnnotations: eventPoints];
// This is causing the problems on the ipod touch.
// The view is added ON TOP of the first map..
//[self.view addSubview:mapView];
self.view = mapView;
// More code after this..
}
Where mapView is
IBOutlet MKMapView *mapView;
Adding a subview on top of the current view didn't want to work. Actually setting the view to be the new updated view with annotations seems to work fine. It's still strange that the simulator would work and not the device in the first place though.
Hope this helps someone.

UINavigationBar not updating on 'back' in landscape

I'm working on a UINavigationController driven iPad app (testing in the simulator). There are only two UIViewControllers on the nav controllers stack. For demonstration, lets call them SetupController and ContentController. SetupController pushes a ContentController on the stack with
[self.navigationController pushViewController:contentController animated:YES];
While looking at the content, you can press the back button to go back to the setup controller. If the app is in portrait mode, things work correctly.
However, when the app is in landscape and I hit the back button, things go haywire. The view controller stack is updated properly (e.g. I see the SetupController's view), but the UINavigationBar is not updated properly. The UINavigation bar items associated with the ContentController are still displayed. To see the SetupCotroller's expected UINavigationBar items, I have to press the back button a second time, at which point the UINavigationBar animates to the correct state. Again, this only happens in landscape mode, portrait mode works perfectly.
As a test. In the [SetupController viewDidAppear:] method I have added the following debug output
if(self.navigationController.navigationBar.topItem != self.navigationItem) {
NSLog(#"wrong nav item!");
} else {
NSLog(#"correct nav item!");
}
I get the "wrong" message whenever the simulator is in landscape mode, and never when it is in portrait mode. I've tried removing all viewDidAppear: messages from both ViewControllers and any instances where I'm modifying their navigation items or the navigation bar itself.
Any thoughts? I'm assuming I'm doing something wrong here, but this sure feels like a bug to me.
I ran into the same problem. It's weird, but you need to make sure all of the view controllers in the stack have the following implemented (even if everything is displaying correctly rotated):
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}