iOS-OC中级iOS-Developer-OCiOS基础·OC高级篇

iOS 防截图需求(伪)实现

2019-12-23  本文已影响0人  山已几孑

需求: 防截图,安卓可以通过系统级的禁止截图来实现,但是iOS并不允许开发者这么做,另外,这个功能本身就是一个鸡肋,别人完全可以通过用别的手机拍照的形式获取屏幕信息,更多是一种警告意味,本文实现的防截图功能,依赖于Photos框架的performChanges方法,实现了 当用户截图时,提示用户删除,且必须删除,可以多张图片进行监听并删除

[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        switch (status) {
            case PHAuthorizationStatusNotDetermined:
                // User has not yet made a choice with regards to this application
                break;
            case PHAuthorizationStatusRestricted:// This application is not authorized to access photo data.
                // The user cannot change this application’s status, possibly due to active restrictions
                //   such as parental controls being in place.
            case PHAuthorizationStatusDenied:           // User has explicitly denied this application access to photos data.
            {
                UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"权限异常" message:@"使用此APP需要相册使用权限,请前往设置-移动C3开启权限" preferredStyle:UIAlertControllerStyleAlert];
                [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
                    abort(); //强制退出
                }]];
                dispatch_async(dispatch_get_main_queue(), ^{
                    [UIApplication.sharedApplication.keyWindow.rootViewController presentViewController:alert animated:true completion:nil];
                });
                
            }
                break;
            case PHAuthorizationStatusAuthorized:
                break;
            default:
                break;
        }
    }];
@property(nonatomic, strong)NSOperationQueue * snapshotQueue;
@property(nonatomic, assign)NSInteger snapshotCount;
@property(nonatomic, retain)dispatch_semaphore_t semaphore;

    self.snapshotCount = 0;    
//当做串行的queue使用
    self.snapshotQueue = [[NSOperationQueue alloc]init];
    self.snapshotQueue.maxConcurrentOperationCount = 1;
    self.semaphore = dispatch_semaphore_create(0);
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(receiveScreenShotNotification:) name:UIApplicationUserDidTakeScreenshotNotification object:nil];

- (void)receiveScreenShotNotification:(NSNotification *)notify {
    self.snapshotCount++;
}
- (void)setSnapshotCount:(NSInteger)snapshotCount {
    BOOL needDelete = _snapshotCount < snapshotCount;
    _snapshotCount = snapshotCount;
    
    NSLog(@"setSnapshotCount changed: %ld",needDelete);
    if (needDelete) {
        [self deleteCounted];
    }
}
-(void)deleteCounted {
    
    [self.snapshotQueue cancelAllOperations];

    [self.snapshotQueue addOperationWithBlock:^{
        if (self.snapshotCount == 0) { //如果count==0,那么不用再删除了
            return ;
        }
        dispatch_async(dispatch_get_main_queue(), ^{

            UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"警告" message:@"我们的APP禁止截屏,请自觉删除!" preferredStyle:UIAlertControllerStyleAlert];
            
            [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                [self deleteAssets];
            }]];
            [UIApplication.sharedApplication.keyWindow.rootViewController presentViewController:alert animated:true completion:^{
                
            }];
        });
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    }];
    
}

-(void)deleteAssets {

    PHFetchOptions *options = [[PHFetchOptions alloc] init];
    options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
    
    PHFetchResult *assetsFetchResults = [PHAsset fetchAssetsWithOptions:options];
    
    NSMutableArray <PHAsset *>* assets = [NSMutableArray arrayWithCapacity:self.snapshotCount];
    if (self.snapshotCount >= 0) {
        for (int i = 0; i < self.snapshotCount; i ++) {
            PHAsset *asset = [assetsFetchResults objectAtIndex:i];
            [assets addObject:asset];
        }
    }
    __weak typeof(self) weakSelf = self;
    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        
        [PHAssetChangeRequest deleteAssets:assets];
    } completionHandler:^(BOOL success, NSError * _Nullable error) {
        if (!success) {
            
            [weakSelf deleteNewAssets:assets];
        } else {
            self.snapshotCount -= assets.count;
            dispatch_semaphore_signal(self.semaphore);
        }
    }];
}
- (void)deleteNewAssets:(NSArray<PHAsset *> *)assets {
    
    if (assets) {//增加一层判断,安全第一
        __weak typeof(self) weakSelf = self;
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
            
            [PHAssetChangeRequest deleteAssets:assets];
        } completionHandler:^(BOOL success, NSError * _Nullable error) {
            if (!success) {
                [weakSelf deleteNewAssets:assets];
            } else {
                self.snapshotCount -= assets.count;
                dispatch_semaphore_signal(self.semaphore);
            }
        }];
    }
}
上一篇下一篇

猜你喜欢

热点阅读