This question already has answers here:
Prevent iOS from taking screen capture of app before going into background
(10 answers)
Closed 3 years ago.
I am new to IOS development
I want to remove my application from recent apps which is developed in Objective C.
I tried UIApplicationExitsOnSuspend in
info.plist
, but no luck still application is showing in info.plist.
Can anyone help me on this.
Thanks in Advance !!!
You could use concept of the cover window.
When app will resign active state you show your cover, and system will take snapshot of that cover instead of last visible UIViewController.
When app will become active you hide and deallocate your cover window.
Here is example
#import "AppDelegate.h"
#interface AppDelegate ()
#property (nonatomic) UIWindow *coverWindow;
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
self.coverWindow = UIWindow.new;
self.coverWindow.rootViewController = UIViewController.new;
[self.coverWindow makeKeyAndVisible];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self.coverWindow removeFromSuperview];
self.coverWindow = nil;
}
#end
UIApplicationExitsOnSuspend is deprecated. You shouldn't use it any more. There has been reports of apple rejecting apps with that key. As per apple:
Deprecated
The system now automatically suspends apps leaving the foreground when
they don’t require background execution. For more information, see
About the Background Execution Sequence.
So for now, you are stuck with letting apple handle the background state of apps. Forcefully trying to exit the app by any manner would lead to a rejection from App Store.
UPDATE
I just noticed your comment saying what you actually want. To prevent the Background Snapshot, you can add a custom view to the window. This is similar to the answer posted by Mark Agranal below, but the thing is you don't need to add a new Window or new ViewController. You can simply add a custom view to the window and remove the view when the app reenters active state. In your AppDelegate:
// The view to use as a mask
#property (nonatomic, weak) UIView* coverView;
// Add the view to window
-(void)applicationWillResignActive:(UIApplication *)application
{
coverView = [[UIView alloc]initWithFrame:[self.window frame]];
[self.window addSubview:coverView];
}
// Remove the view to window
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if(coverView != nil) {
[coverView removeFromSuperview];
coverView = nil;
}
}
Note that you can add any view to the window using the above method. The system will take screenshot of the added view and hence the sensitive user data will be protected.
Related
I am trying to change the screen shot that is automatically captured by iOS when the app enters the background.
However I am not entirely sure exactly when this screenshot is taken.
For example:
If you pull down the notification bar while in the app the following method is called:
- (void) applicationWillResignActive:(UIApplication *) application {
}
Also if you double tap the home button while in the app the same method is called. In addition if an alert view is show 'applicationWillResignActive' is called.
But in both of these cases
- (void) applicationDidEnterBackground:(UIApplication *) application {
}
is not called.
So my question is, is there a screenshot captured after the call to applicationWillResignActive even if the application does not enter the background? Or does iOS only capture a screenshot after applicationDidEnterBackground?
Look at official doc - "Preventing Sensitive Information From Appearing In The Task Switcher".
It says applicationDidEnterBackground: should be used for the said purpose.
you can look over here, in summary, change the view before return from applicationDidEnterBackground:
Yes.
- (void) applicationWillResignActive:(UIApplication *) application {
}
is called when you pull down the notification bar or even when you double click the home button. You have to do something here to prevent your sensitive information to be captured by the OS. One workaround might be:
Set a blurry screen overlay before the app goes in the background
Once the app becomes active remove this overlay
Something like this:
-(void)applicationWillResignActive:(UIApplication *)application
{
imageView = [[UIImageView alloc]initWithFrame:[self.window frame]];
[imageView setImage:[UIImage imageNamed:#"blurryImage.png"]];
[self.window addSubview:imageView];
}
And then remove this overlay before the application enters foreground:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if(imageView != nil) {
[imageView removeFromSuperview];
imageView = nil;
}
}
is called when you pull down the notification bar or even when you double click the home button. You have to do something here to prevent your sensitive information to be captured by the OS. One workaround might be:
Set a blurry screen overlay before the app goes in the background
Once the app becomes active remove this overlay
I’m new in iOS development. My question is, I’ve two view controllers.
viewController - A viewController - B
Now, if i killed the app from the viewController - A and than relaunch the app. than app must be open the viewController - A. and if i killed the app from the viewController - B and than relaunch the app. than app must be open the viewController - B.
Can anyone help me, I’ve done the RND but can not find the proper solution.
Thanks
Create a sharedDelegate in AppDelegate.m file
+(AppDelegate *)sharedDelegate {
return (AppDelegate *) [UIApplication sharedApplication].delegate;
}
in AppDelegate.h
+ (AppDelegate *)sharedDelegate;
#property (nonatomic, strong) NSString *currentViewContoller;
when push to any contoller then set AppDelegate's currentViewContoller to new VC
YourViewController *vc=[[YourViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
[AppDelegate sharedDelegate].currentViewContoller = NSStringFromClass([YourViewController class]);
now when app is terminated
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
[[NSUserDefaults standardUserDefaults]setObject:[AppDelegate sharedDelegate].currentViewContoller forKey:#"currentVC"];
}
now when app launched first time check previous controller when app terminated
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSString *string=[[NSUserDefaults standardUserDefaults] valueForKey:#"currentVC"];
and push this class
UIViewController *object = [[NSClassFromString(string) alloc] init...];
}
applicationWillTerminate you can use but it will only get called if user quit app from forground If your app is in background and then user quit app then applicationWillTerminate will not get called.
So, you have to take care of applicationDidEnterBackground.
So, when app enter in background (i.e call applicationDidEnterBackground ) or call applicationWillTerminate save state(your current VC) in your user defaults.
Now in your didFinishLaunchingWithOptions set that view controller as rootviewcontroller or whatever way that you want to manage it.
reference : Apple documentation for applicationWillTerminate
PS : You should not manage app like this. It is horrible way!! If possible then run your app as normal flow!
If you're using Storyboards you can use the Restoration Identifier to communicate the App which controller to launch as first
https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/PreservingandRestoringState.html
My case is the following: I have a Cordova application that has to run on iOS. I have to prevent sensitive information from being shown in the app switcher when the app is being in background.
Apple provides this solution for native applications which doesn't seem to solve my problem, because it doesn't manipulate the web view in any way.
I wonder if I can natively place some static image covering the webview. As I understand the system takes a screenshot of the view right after the applicationDidEnterBackground: method is invoked.
This way the system will take a screenshot of the image I put on top instead of the actual content of the webview.
I'm not an experienced iOS developer and I will appreciate any suggestion.
Thanks.
It turned out apple's solution could fix the problem with a small edit from me.
Instead of implementing
- (void)applicationDidEnterBackground:(UIApplication *)application
I implemented
-(void)applicationWillResignActive:(UIApplication *)application
Then no matter if you hit the home button once or twice, it will cover the viewcontroller with the blank one just created.
-(void)applicationWillResignActive:(UIApplication *)application {
UIViewController *blankViewController = [UIViewController new];
//this is how to attach image
UIImage *splashImage = [UIImage imageNamed:#"some image"];
blankViewController.view.backgroundColor = [UIColor colorWithPatternImage: splashImage];
// set some transition style
blankViewController.modalTransitionStyle = UIModalTransitionStylePartialCurl;
[self.window.rootViewController presentViewController:blankViewController animated:YES completion:NULL];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[self.window.rootViewController dismissViewControllerAnimated:YES completion:NULL];
}
This question already has answers here:
Controlling the screenshot in the iOS 7 multitasking switcher
(8 answers)
Closed 9 years ago.
I have an application that contains some sensitive information, I don't want others to snapshot the screen before app enter background, so I want to present a pattern lock viewController on the screen after user press home button. I tried this code
- (void)applicationWillResignActive:(UIApplication *)application
{
PatternLockViewController *pvc = [[SMICConfig sharedSMICConfig] patternLockVC];
if (!(pvc.isViewLoaded && pvc.view.window) && [SMICConfig sharedSMICConfig].isCookie) {
[self.window.rootViewController presentViewController:pvc animated:NO completion:nil];
}
}
But the PatternLockViewController only present after the app enter foreground. So, when the app stay in background, you can double-click home button to peek some information.
Tecent qq's pattern lock is very well. I just want to implement this effect.
Can any one help me? Thanks
You can tell iOS7 to avoid using the recent snapshot image during the next launch cycle by calling ignoreSnapshotOnNextApplicationLaunch Apple's documentation
The following is how I implemented for my App. Hope it helps.
- (void)applicationWillResignActive:(UIApplication *)application {
[application ignoreSnapshotOnNextApplicationLaunch];
self.imageView = [[UIImageView alloc]initWithFrame:[self.window frame]];
[self.imageView setImage:[UIImage imageNamed:#"Default-568h"]];
[self.window addSubview: self.imageView];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
if (self.imageView != nil) {
[self.imageView removeFromSuperview];
self.imageView = nil;
}
}
I am new to Objective-C and I'm making my first app, a single-view app. When I run my program ,the fullscreen ad that is supposed to appear (I'm using RevMob) appears. However, when I exit the ad I get a black screen with a blue status bar at the top.
I have tried many things, such as setting my main view controller as initial view controller, restarting my computer, changing/removing debugger, resetting the iOS simulator, etc.
My Xcode version is 4.6 and my OS is mac OSX 10.8.4
I don't want to delete Xcode and I also don't want to remove ads because that is my only source of income.
Here is my code:
Appdelegate.m
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
[RevMobAds startSessionWithAppID:#"myappid"];
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
RevMobFullscreen *ad = [[RevMobAds session] fullscreen];
[ad loadWithSuccessHandler:^(RevMobFullscreen *fs) {
[fs showAd];
NSLog(#"Ad loaded");
} andLoadFailHandler:^(RevMobFullscreen *fs, NSError *error) {
NSLog(#"Ad error: %#",error);
} onClickHandler:^{
NSLog(#"Ad clicked");
} onCloseHandler:^{
NSLog(#"Ad closed");
}];
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
- (void)dealloc
{
[_window release];
[super dealloc];
}
#end
Appdelegate.h:
#import <UIKit/UIKit.h>
#import "ViewController.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic)UIWindow *window;
#end
There is nothing wrong with the ad code. What seems to be (not) happening is that your app has no content. I suspect that you haven't set up the rootViewController (initial view controller) for the app correctly.
This is what you need to do:
Get rid of all of the app ad code and just make an app that works. All it has to do is correctly show an initial view controller. You could just make a new project in XCode using the Single View Application template.
Add your app code as per this example. You will invoke the code from your initial view controller via a button.
Once that is working, you can add the code into - (void)applicationDidBecomeActive:(UIApplication *)application as per your question. When you dismiss the advert, you should see your initial view controller.