Disable Screen Capture/ScreenShot in React Native App

后端 未结 4 1576
谎友^
谎友^ 2020-12-09 05:27

I have came across few solutions specific for ios and Android to prevent screen-capturing and taking screenshots. But how do i disable screen-capturing in react native?

4条回答
  •  感动是毒
    2020-12-09 06:07

    So there is little work for the iOS side build on React Native platform. So be patient with me to read the following approach.

    I am using the react-native-video package for playing media. My requirement was to show spinner if user has screen recording enabled.

    1. From https://developer.apple.com/documentation/uikit/uiscreen/2921651-captured?language=objc I understood that captured property is set to YES. I added observer in AppDelegate.m, under didFinishLaunchingWithOptions method.

      [[UIScreen mainScreen] addObserver:self forKeyPath:@"captured" options:NSKeyValueObservingOptionNew context:nil];

    2. Since RN allows communication with Native modules, I decided to add bridge so notify when capture flag is set to YES.

    I created two files ScreenRecordingNotification.h and .m

    .h

    #import 
    #import 
    #ifndef ScreenCaptureNotification_h
    #define ScreenCaptureNotification_h
    
    
    @interface ScreenCaptureNotification : RCTEventEmitter 
    -(void) isScreenCaptureEnabled:(BOOL)isCaptured;
    @end
    
    #endif /* ScreenCaptureNotification_h */
    

    and .m looks like

    #import 
    #import "ScreenCaptureNotification.h"
    #import 
    @implementation ScreenCaptureNotification
    
    + (id)allocWithZone:(NSZone *)zone {
      static ScreenCaptureNotification *sharedInstance = nil;
      static dispatch_once_t onceToken;
      dispatch_once(&onceToken, ^{
        sharedInstance = [super allocWithZone:zone];
      });
      return sharedInstance;
    }
    
    RCT_EXPORT_MODULE();
    
    - (NSArray *)supportedEvents {
      return @[           
               @"isScreenCaptureEnabled"];
    }
    
    -(void) isScreenCaptureEnabled:(BOOL)isCaptured {
      [self sendEventWithName:@"isScreenCaptureEnabled" body:@{@"value": @(isCaptured)}];
    }
    
    @end
    
    1. import #import "ScreenCaptureNotification.h" in AppDelegate and added the following method.

      - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
          if ([keyPath isEqualToString:@"captured"]){
            NSLog(@"Screen Capture is Enabled");
            RCTLog(@"Screen Capture is Enabled");
            if (@available(iOS 11.0, *)) {
              ScreenCaptureNotification *manager = [ScreenCaptureNotification allocWithZone: nil];
              [manager isScreenCaptureEnabled:UIScreen.mainScreen.isCaptured];
            }
          }
      }
      

    And also add [[UIScreen mainScreen] addObserver:self forKeyPath:@"captured" options:NSKeyValueObservingOptionNew context:nil]; in didFinishLaunchingWithOptions. This concludes changes at iOS side.

    1. Now you need to add Listener in .js files for notification which iOS sending. Once you get notification, it's up to you to decide what to do with it. Roughly it will look like below.
      addListener() {  
        let bridge = new NativeEventEmitter(NativeModules.ScreenCaptureNotification);
    
        this.screenCaptureEnabled = bridge.addListener("isScreenCaptureEnabled",res => { 
          this.setState({ screenCapture: true })
        })
      }
    

    and

    render() {
      if (this.state.screenCapture) {
         //Show spinner
         return 
      }
      return (
       
      )
    }
    

    I am open to suggestions to make changes to this post. Don't forget to upvote if this post helped you.

提交回复
热议问题