iOS 防截圖需求(偽)實現

需求: 防截圖,安卓可以通過系統級的禁止截圖來實現囱晴,但是iOS并不允許開發(fā)者這么做澳泵,另外实愚,這個功能本身就是一個雞肋,別人完全可以通過用別的手機拍照的形式獲取屏幕信息烹俗,更多是一種警告意味爆侣,本文實現的防截圖功能,依賴于Photos框架的performChanges方法幢妄,實現了 當用戶截圖時兔仰,提示用戶刪除,且必須刪除蕉鸳,可以多張圖片進行監(jiān)聽并刪除

  • 首先是權限問題乎赴,該功能需要相冊使用權限,且必須提前進行申請潮尝,否則榕吼,第一張圖片無法獲取并刪除。
[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;
        }
    }];
  • 初始化了一些屬性來配合整個業(yè)務流轉的順序的控制
@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);
  • 對系統的截屏時間進行監(jiān)聽,這里沒啥好說的
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(receiveScreenShotNotification:) name:UIApplicationUserDidTakeScreenshotNotification object:nil];

  • 收到截屏事件后勉失,維護一個本地的統計數字
- (void)receiveScreenShotNotification:(NSNotification *)notify {
    self.snapshotCount++;
}
  • 統計數字改變后羹蚣,根據統計數字狀態(tài),來決定是否需要激活刪除的事件
- (void)setSnapshotCount:(NSInteger)snapshotCount {
    BOOL needDelete = _snapshotCount < snapshotCount;
    _snapshotCount = snapshotCount;
    
    NSLog(@"setSnapshotCount changed: %ld",needDelete);
    if (needDelete) {
        [self deleteCounted];
    }
}
  • 激活刪除圖片, 這里乱凿,貼了兩個方法顽素,是因為,系統拍照需要處理事時間徒蟆,當我們收到拍照事件時胁出,系統相冊可能還沒有處理完成,此時獲取到的最后一張圖片是錯誤的段审,因此全蝶,我們需要盡可能的延遲代碼調用順序,這里通過彈窗來做延遲,也可以直接寫延遲執(zhí)行抑淫,但是時間不是很穩(wěn)定绷落,測試發(fā)現300毫秒可以稍微穩(wěn)定一點,1s更好始苇,但是流程上面就有了延遲嘱函。
-(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);
        }
    }];
}
  • 因為刪除事件是系統功能,因此存在用戶手動取消的情況埂蕊,這里采用在取消時,繼續(xù)彈出刪除來解決
- (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);
            }
        }];
    }
}
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末蓄氧,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子槐脏,更是在濱河造成了極大的恐慌喉童,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顿天,死亡現場離奇詭異堂氯,居然都是意外死亡,警方通過查閱死者的電腦和手機牌废,發(fā)現死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門咽白,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鸟缕,你說我怎么就攤上這事晶框。” “怎么了懂从?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵授段,是天一觀的道長。 經常有香客問我番甩,道長侵贵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任缘薛,我火速辦了婚禮窍育,結果婚禮上,老公的妹妹穿的比我還像新娘掩宜。我一直安慰自己蔫骂,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布牺汤。 她就那樣靜靜地躺著辽旋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上补胚,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天码耐,我揣著相機與錄音,去河邊找鬼溶其。 笑死骚腥,一個胖子當著我的面吹牛,可吹牛的內容都是我干的瓶逃。 我是一名探鬼主播束铭,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼厢绝!你這毒婦竟也來了契沫?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤昔汉,失蹤者是張志新(化名)和其女友劉穎懈万,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體靶病,經...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡会通,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了娄周。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涕侈。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖昆咽,靈堂內的尸體忽然破棺而出驾凶,到底是詐尸還是另有隱情,我是刑警寧澤掷酗,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布调违,位于F島的核電站,受9級特大地震影響泻轰,放射性物質發(fā)生泄漏技肩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一浮声、第九天 我趴在偏房一處隱蔽的房頂上張望虚婿。 院中可真熱鬧,春花似錦泳挥、人聲如沸然痊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽剧浸。三九已至锹引,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間唆香,已是汗流浹背嫌变。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留躬它,地道東北人腾啥。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像冯吓,于是被迫代替她去往敵國和親倘待。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內容

  • “你要成為什么樣的人组贺,必須有一整套的生活方式來匹配延柠。”M首席的話直指內心锣披。 拿讀書為例,當一年讀到100本書的時候...
    筆舒輕風閱讀 404評論 0 1
  • 窗外贿条,陽光明媚雹仿,打開它,一股清新的空氣撲面而來整以,早晨胧辽,好清爽! 這是自11月冷空氣襲開后公黑,第一次天氣晴朗邑商。心里思索...
    陌斑閱讀 281評論 5 6
  • 古之成大事業(yè),大學問者凡蚜,必經過三種之境界:“昨夜西風凋碧樹人断。獨上高樓,望盡天涯路朝蜘《衤酰”此第一境也∑状迹“衣帶漸寬終不悔暇仲,...
    背著因襲的重擔閱讀 467評論 1 5
  • 俗話說越努力也就越幸運奈附,但是近日有種感覺就是不管怎樣努力,還是看不到希望煮剧。堅持斥滤,還是放棄将鸵?蒼白無力感!正在經歷當中...
    薄荷的綠姑娘閱讀 1,838評論 0 2