Skip to content

Commit 28f1304

Browse files
committed
Merge pull request #3 from Telerik-Verified-Plugins/master
Don't wipe appstate & landscape iOS support
2 parents ea64cd3 + 11db044 commit 28f1304

File tree

4 files changed

+112
-50
lines changed

4 files changed

+112
-50
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ This is a lovely feature for most apps, but if your app displays sensitive infor
77

88
This plugin flags your app so that it doesn't show your users' sensitive data in the task switcher. It sets the [FLAG_SECURE](http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_SECURE) flag in Android (which also prevents manual screenshots from being taken) and hides the window in iOS.
99

10-
On iOS this plugin will show your splashscreen in the app switcher, but it requires your splashscreens basesname to be named `Default`. E.g. `Default~iphone.png` and `Default-568@2x~iphone.png`.
10+
On iOS this plugin will try to show your splashscreen in the app switcher. It will search for splashscreens prefixed by `Default` or the value of the key `UILaunchImageFile` in your .plist file.
11+
If it fails to find a splashscreen for a specific device or orientation (portrait or landscape), a black screen is shown instead.
1112

1213
Installation
1314
------------

plugin.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="org.devgeeks.privacyscreen" version="0.0.5">
2+
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="org.devgeeks.privacyscreen" version="0.0.7">
33

44
<name>PrivacyScreenPlugin</name>
55
<description>Secures your app from displaying a screenshot in task switchers under Android and iOS. Keeps sensitive information private.</description>

src/ios/AppDelegate+privacyscreen.h

+13-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,18 @@
66
*/
77
#import "AppDelegate.h"
88

9+
typedef struct {
10+
BOOL iPhone;
11+
BOOL iPad;
12+
BOOL iPhone5;
13+
BOOL iPhone6;
14+
BOOL iPhone6Plus;
15+
BOOL retina;
16+
17+
} CDV_iOSDevice;
18+
919
@interface AppDelegate (privacyscreen)
10-
- (void)applicationWillResignActive:(UIApplication *)application;
11-
- (void)applicationDidBecomeActive:(UIApplication *)application;
20+
- (void)applicationWillResignActive:(UIApplication *)application;
21+
- (void)applicationDidBecomeActive:(UIApplication *)application;
1222

13-
@end
23+
@end

src/ios/AppDelegate+privacyscreen.m

+96-45
Original file line numberDiff line numberDiff line change
@@ -11,63 +11,114 @@
1111

1212
@implementation AppDelegate (privacyscreen)
1313

14-
// Taken from https://github.com/phonegap-build/PushPlugin/blob/master/src/ios/AppDelegate%2Bnotification.m
15-
// its dangerous to override a method from within a category.
16-
// Instead we will use method swizzling. we set this up in the load call.
17-
+ (void)load
14+
- (void)applicationDidBecomeActive:(UIApplication *)application
1815
{
19-
Method original, swizzled;
20-
21-
original = class_getInstanceMethod(self, @selector(init));
22-
swizzled = class_getInstanceMethod(self, @selector(swizzled_init));
23-
method_exchangeImplementations(original, swizzled);
16+
if (imageView == NULL) {
17+
self.window.hidden = NO;
18+
} else {
19+
[imageView removeFromSuperview];
20+
}
2421
}
2522

26-
- (AppDelegate *)swizzled_init
23+
- (void)applicationWillResignActive:(UIApplication *)application
2724
{
28-
if ([UIApplication respondsToSelector:@selector(ignoreSnapshotOnNextApplicationLaunch:)]) {
29-
[[UIApplication sharedApplication] ignoreSnapshotOnNextApplicationLaunch];
30-
// Add any notification observers here...
31-
}
32-
// This actually calls the original init method over in AppDelegate. Equivilent to calling super
33-
// on an overrided method, this is not recursive, although it appears that way. neat huh?
34-
return [self swizzled_init];
25+
NSString *imgName = [self getImageName:self.viewController.interfaceOrientation delegate:(id<CDVScreenOrientationDelegate>)self.viewController device:[self getCurrentDevice]];
26+
UIImage *splash = [UIImage imageNamed:imgName];
27+
if (splash == NULL) {
28+
self.window.hidden = YES;
29+
} else {
30+
imageView = [[UIImageView alloc]initWithFrame:[self.viewController.view bounds]];
31+
[imageView setImage:splash];
32+
[self.viewController.view addSubview:imageView];
33+
}
3534
}
3635

37-
- (void)applicationDidBecomeActive:(UIApplication *)application
36+
// Code below borrowed from the CDV splashscreen plugin @ https://github.com/apache/cordova-plugin-splashscreen
37+
// Made some adjustments though, becuase landscape splashscreens are not available for iphone < 6 plus
38+
- (CDV_iOSDevice) getCurrentDevice
3839
{
39-
if (imageView == NULL && [[UIApplication sharedApplication] respondsToSelector:@selector(ignoreSnapshotOnNextApplicationLaunch:)]) {
40-
[[UIApplication sharedApplication] ignoreSnapshotOnNextApplicationLaunch];
41-
self.window.hidden = NO;
42-
} else {
43-
[imageView removeFromSuperview];
44-
}
40+
CDV_iOSDevice device;
41+
42+
UIScreen* mainScreen = [UIScreen mainScreen];
43+
CGFloat mainScreenHeight = mainScreen.bounds.size.height;
44+
CGFloat mainScreenWidth = mainScreen.bounds.size.width;
45+
46+
int limit = MAX(mainScreenHeight,mainScreenWidth);
47+
48+
device.iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
49+
device.iPhone = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone);
50+
device.retina = ([mainScreen scale] == 2.0);
51+
device.iPhone5 = (device.iPhone && limit == 568.0);
52+
// note these below is not a true device detect, for example if you are on an
53+
// iPhone 6/6+ but the app is scaled it will prob set iPhone5 as true, but
54+
// this is appropriate for detecting the runtime screen environment
55+
device.iPhone6 = (device.iPhone && limit == 667.0);
56+
device.iPhone6Plus = (device.iPhone && limit == 736.0);
57+
58+
return device;
4559
}
4660

47-
- (void)applicationWillResignActive:(UIApplication *)application
61+
- (NSString*)getImageName:(UIInterfaceOrientation)currentOrientation delegate:(id<CDVScreenOrientationDelegate>)orientationDelegate device:(CDV_iOSDevice)device
4862
{
49-
// for now, assuming 'Default' is the basename of the splashscreen, with a fallback to hiding the window
50-
UIImage *splash = [self imageNamedForDevice: @"Default"];
51-
if (splash == NULL && [[UIApplication sharedApplication] respondsToSelector:@selector(ignoreSnapshotOnNextApplicationLaunch:)]) {
52-
[[UIApplication sharedApplication] ignoreSnapshotOnNextApplicationLaunch];
53-
self.window.hidden = YES;
63+
// Use UILaunchImageFile if specified in plist. Otherwise, use Default.
64+
NSString* imageName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UILaunchImageFile"];
65+
66+
NSUInteger supportedOrientations = [orientationDelegate supportedInterfaceOrientations];
67+
68+
// Checks to see if the developer has locked the orientation to use only one of Portrait or Landscape
69+
BOOL supportsLandscape = (supportedOrientations & UIInterfaceOrientationMaskLandscape);
70+
BOOL supportsPortrait = (supportedOrientations & UIInterfaceOrientationMaskPortrait || supportedOrientations & UIInterfaceOrientationMaskPortraitUpsideDown);
71+
// this means there are no mixed orientations in there
72+
BOOL isOrientationLocked = !(supportsPortrait && supportsLandscape);
73+
74+
if (imageName) {
75+
imageName = [imageName stringByDeletingPathExtension];
76+
} else {
77+
imageName = @"Default";
78+
}
79+
80+
BOOL isLandscape = supportsLandscape &&
81+
(currentOrientation == UIInterfaceOrientationLandscapeLeft || currentOrientation == UIInterfaceOrientationLandscapeRight);
82+
83+
if (device.iPhone5) { // does not support landscape
84+
imageName = isLandscape ? nil : [imageName stringByAppendingString:@"-568h"];
85+
} else if (device.iPhone6) { // does not support landscape
86+
imageName = isLandscape ? nil : [imageName stringByAppendingString:@"-667h"];
87+
} else if (device.iPhone6Plus) { // supports landscape
88+
if (isOrientationLocked) {
89+
imageName = [imageName stringByAppendingString:(supportsLandscape ? @"-Landscape" : @"")];
5490
} else {
55-
imageView = [[UIImageView alloc]initWithFrame:[self.window frame]];
56-
[imageView setImage:splash];
57-
[UIApplication.sharedApplication.keyWindow.subviews.lastObject addSubview:imageView];
91+
switch (currentOrientation) {
92+
case UIInterfaceOrientationLandscapeLeft:
93+
case UIInterfaceOrientationLandscapeRight:
94+
imageName = [imageName stringByAppendingString:@"-Landscape"];
95+
break;
96+
default:
97+
break;
98+
}
5899
}
59-
}
60-
61-
- (UIImage*)imageNamedForDevice:(NSString*)name
62-
{
63-
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
64-
if (([UIScreen mainScreen].bounds.size.height * [UIScreen mainScreen].scale) >= 1136.0f) {
65-
name = [name stringByAppendingString:@"-568h@2x"];
66-
}
67-
} else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
68-
name = [name stringByAppendingString:@"-Portrait"];
100+
imageName = [imageName stringByAppendingString:@"-736h"];
101+
102+
} else if (device.iPad) { // supports landscape
103+
if (isOrientationLocked) {
104+
imageName = [imageName stringByAppendingString:(supportsLandscape ? @"-Landscape" : @"-Portrait")];
105+
} else {
106+
switch (currentOrientation) {
107+
case UIInterfaceOrientationLandscapeLeft:
108+
case UIInterfaceOrientationLandscapeRight:
109+
imageName = [imageName stringByAppendingString:@"-Landscape"];
110+
break;
111+
112+
case UIInterfaceOrientationPortrait:
113+
case UIInterfaceOrientationPortraitUpsideDown:
114+
default:
115+
imageName = [imageName stringByAppendingString:@"-Portrait"];
116+
break;
117+
}
69118
}
70-
return [UIImage imageNamed: name];
119+
}
120+
121+
return imageName;
71122
}
72123

73-
@end
124+
@end

0 commit comments

Comments
 (0)