I have a logistics app which has a requirement to disable the screen recording, and I don't want people to use the new iOS-11 feature to record the screen with sensitive datas and make them public. Since disabling screen recording is not possible in iOS so i tried a work around by detecting the iOS11 screen recording feature On or Off. I used isCaptured and UIScreenCapturedDidChange Notification. The code is given below:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (@available(iOS 11.0, *)) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(screenCaptureChanged) name:UIScreenCapturedDidChangeNotification object:nil];
}
return YES;
}
So the logic is when the screen recording starts the notification is fired and the logic of placing the black color on video while recording is happening and when the recording stops the black color is removed. This works fine when the application is moved to background , active , inactive and foreground scenarios. But when the application is killed(terminated) while screen recording is still going on and when we launch the application again while screen recording is still going on the black color doesn't covers the screen. So how to call the notification selector again with the selector method working
Check the value of the screen's isCaptured
property in application:didFinishLaunchingWithOptions:
and show or hide the overlay view accordingly.
UIWindow+ScreenCapture.h:
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIWindow (ScreenCapture)
- (void)showOrHideContentDependingOnCapturedState;
- (void)hideContent;
- (void)showContent;
@end
NS_ASSUME_NONNULL_END
UIWindow+ScreenCapture.m:
#import "UIWindow+ScreenCapture.h"
@implementation UIWindow (ScreenCapture)
- (void)showOrHideContentDependingOnCapturedState {
if (self.screen.isCaptured) {
[self hideContent];
} else {
[self showContent];
}
}
- (void)hideContent {
UIView *blackView = [self viewWithTag:1234];
if (!blackView) {
blackView = [[UIView alloc] initWithFrame:self.bounds];
}
blackView.tag = 1234;
blackView.backgroundColor = UIColor.blackColor;
blackView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
// This is important! If this is not set, then any new view added to
// the window (like the root view controller's view) will be overtop of
// `blackView`, which we don't want.
blackView.layer.zPosition = 10000;
[self addSubview:blackView];
}
- (void)showContent {
[[self viewWithTag:1234] removeFromSuperview];
}
@end
AppDelegate.h:
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (nullable, strong, nonatomic) UIWindow *window;
@end
AppDelegate.m:
#import "AppDelegate.h"
#import "UIWindow+ScreenCapture.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(checkIsBeingRecorded)
name:UIScreenCapturedDidChangeNotification
object:nil];
[self.window showOrHideContentDependingOnCapturedState];
return YES;
}
- (void)checkIsBeingRecorded {
for (UIWindow *window in UIApplication.sharedApplication.windows) {
[window showOrHideContentDependingOnCapturedState];
}
}
@end