通過(guò)PHPhotoLibrary生百,將共享目錄中圖片批量導(dǎo)入相冊(cè)

一、基本配置

開(kāi)啟共享目錄功能午绳,在 Info.plist 文件中添加 UIFileSharingEnabled 這個(gè)Key, 并設(shè)置該值為 YES 即可置侍。在填寫(xiě)完 UIFileSharingEnabled 并回車(chē)后, 發(fā)現(xiàn)會(huì)自動(dòng)更正為Application supports iTunes file sharing , 將值設(shè)置為YES 即可。

開(kāi)啟相冊(cè)權(quán)限,info.plist 文件中添加 NSPhotoLibraryUsageDescription 這個(gè)Key, 并描述開(kāi)啟該功能理由蜡坊。調(diào)用PHPhotoLibrary時(shí)杠输,需要導(dǎo)入 <Photos/Photos.h> 框架。

點(diǎn)擊下載 Demo

二秕衙、檢測(cè)共享目錄中圖片

將圖片文件導(dǎo)入共享目錄中蠢甲。通過(guò) NSFileManager 檢測(cè)該文件夾及文件夾中的圖片是否合法。然后返回有效圖片數(shù)組据忘。例:

// 檢測(cè)圖片鹦牛,有圖片則返回圖片數(shù)組,無(wú)圖則返回nil
+ (NSArray *)checkImportPicture {
    // 判斷文件夾
    NSFileManager *fileMgr = [NSFileManager defaultManager];
    NSString *filePath = [self pictureFilePath];
    if (![fileMgr fileExistsAtPath:filePath]) {
        NSLog(@"請(qǐng)?jiān)诠蚕砟夸?Documents)中 創(chuàng)建文件夾 ZJHPicture");
        return nil;
    }
    
    // 判斷文件夾內(nèi)容
    NSArray *dirArray = [fileMgr contentsOfDirectoryAtPath:filePath error:nil];
    if (!dirArray || !dirArray.count) {
        NSLog(@"請(qǐng)?jiān)?ZJHPicture 文件夾內(nèi)添加圖片");
        return nil;
    }
    
    // 判斷文件是否有效
    NSMutableArray *pictureArr = [NSMutableArray arrayWithCapacity:dirArray.count];
    for (NSString *path in dirArray) {
        NSString *imagePath = [filePath stringByAppendingPathComponent:path];
        if ([self validExtentionWithPath:path]) {
            // 編碼文件名勇吊,以防含有中文曼追,導(dǎo)致存儲(chǔ)失敗
            NSCharacterSet *charSet = [NSCharacterSet URLQueryAllowedCharacterSet];
            NSString *encodeStr =
            [imagePath stringByAddingPercentEncodingWithAllowedCharacters:charSet];
            [pictureArr addObject:encodeStr];
        } else {
            // 刪除無(wú)效文件,以防占用多余空間
            [fileMgr removeItemAtPath:imagePath error:nil];
        }
    }
    if (!pictureArr.count) {
        NSLog(@"請(qǐng)?zhí)砑?jpg汉规、png礼殊、jpeg、heic针史、mov 類(lèi)型文件");
        return nil;
    }
    
    return pictureArr;
}

三晶伦、判斷相冊(cè)權(quán)限

通過(guò)該方法 + (PHAuthorizationStatus)authorizationStatus 獲取相冊(cè)的授權(quán)狀態(tài)。

// 相冊(cè)授權(quán)狀態(tài)
typedef NS_ENUM(NSInteger, PHAuthorizationStatus) {
    PHAuthorizationStatusNotDetermined = 0, // 用戶(hù)還沒(méi)有決定是否授權(quán)
    PHAuthorizationStatusRestricted,        // 訪問(wèn)權(quán)限受限制, 如家長(zhǎng)模式的限制才會(huì)有
    PHAuthorizationStatusDenied,            // 用戶(hù)拒絕App訪問(wèn)相冊(cè)
    PHAuthorizationStatusAuthorized         // 用戶(hù)已經(jīng)授權(quán)了訪問(wèn)
} PHOTOS_AVAILABLE_IOS_TVOS(8_0, 10_0);

如果這個(gè)方法返回PHAuthorizationStatusNotDetermined啄枕,則可以使用 + (void)requestAuthorization:(void (^)(PHAuthorizationStatus status))handler 方法提示用戶(hù)授權(quán)對(duì)照片庫(kù)的訪問(wèn)婚陪。例:

// 判斷相冊(cè)權(quán)限
- (void)judgePhotoAuthor {
   
    // 獲取當(dāng)前App的相冊(cè)授權(quán)狀態(tài)
    PHAuthorizationStatus authorizationStatus = [PHPhotoLibrary authorizationStatus];
    // 判斷授權(quán)狀態(tài)
    if (authorizationStatus == PHAuthorizationStatusAuthorized) {
        // 如果已經(jīng)授權(quán), 保存圖片
        [self saveImage];
    }
    // 如果沒(méi)決定, 彈出指示框, 讓用戶(hù)選擇
    else if (authorizationStatus == PHAuthorizationStatusNotDetermined) {
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
            // 如果用戶(hù)選擇授權(quán), 則保存圖片
            if (status == PHAuthorizationStatusAuthorized) {
                [self saveImage];
            }
        }];
    } else {
        // 前往設(shè)置
        NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        [[UIApplication sharedApplication] openURL:url];
    }
}

四、獲取相簿

根據(jù)相簿名獲取相簿频祝。通過(guò) PHAssetCollection 類(lèi)獲取相簿集泌参,遍歷搜索集合并取出對(duì)應(yīng)的相簿,然后創(chuàng)建相簿變動(dòng)請(qǐng)求智润,若無(wú)結(jié)果及舍,則通過(guò) PHAssetCollectionChangeRequest 新建相簿變動(dòng)請(qǐng)求。例:

// 創(chuàng)建一個(gè)相簿變動(dòng)請(qǐng)求
- (PHAssetCollectionChangeRequest *)getCurrentPhotoCollection{
    // 相簿名
    NSString *collName = self.title;
    // 獲取相簿集合
    PHFetchResult *result =
    [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
                                             subtype:PHAssetCollectionSubtypeAlbumRegular
                                             options:nil];

    // 遍歷選取已創(chuàng)建的相簿
    for (PHAssetCollection *assetCollection in result) {
        if ([assetCollection.localizedTitle containsString:collName]) {
            return [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];;
        }
    }
    
    // 創(chuàng)建新的相簿
    return [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:collName];
}

五窟绷、存儲(chǔ)圖片锯玛、視頻

+(PHPhotoLibrary *)sharedPhotoLibrary; 獲取共享照片庫(kù)對(duì)象妙色,即獲取 PHPhotoLibrary 的單例蛮寂。

-(void)performChanges:(dispatch_block_t)changeBlock completionHandler:(nullable void(^)(BOOL success, NSError *__nullable error))completionHandler; 異步運(yùn)行changeBlock回調(diào)胸完,來(lái)請(qǐng)求執(zhí)行對(duì)照片庫(kù)的修改缸逃。
Photos會(huì)在任意的串行隊(duì)列上調(diào)用你的changeBlock回調(diào)和handler回調(diào)呈础,如果你的回調(diào)中有需要與UI進(jìn)行交互的內(nèi)容量窘,請(qǐng)將此工作分配到主線程荐捻。

注意點(diǎn)1:創(chuàng)建圖片路徑 url 時(shí)潘明,需要對(duì)含中文的文件名進(jìn)行編碼辐棒,否則病曾,可能導(dǎo)致創(chuàng)建失敗
注意點(diǎn)2:iOS8系統(tǒng)需要在文件路徑添加協(xié)議頭 file:// 否則牍蜂,可能導(dǎo)致存儲(chǔ)失敗
注意點(diǎn)3:創(chuàng)建相片請(qǐng)求 PHAssetChangeRequest 時(shí),圖片和視頻要分開(kāi)創(chuàng)建泰涂,圖片使用: creationRequestForAssetFromImageAtFileURL鲫竞;視頻使用:creationRequestForAssetFromVideoAtFileURL。
例:

// 存儲(chǔ)圖片
- (void)saveImage {    
    // 獲取相片庫(kù)對(duì)象
    PHPhotoLibrary *library = [PHPhotoLibrary sharedPhotoLibrary];
    
    // 調(diào)用changeBlock
    [library performChanges:^{
        
        // 創(chuàng)建一個(gè)相冊(cè)變動(dòng)請(qǐng)求
        PHAssetCollectionChangeRequest *collectionRequest = [self getCurrentPhotoCollection];
        
        // 根據(jù)傳入的相片, 創(chuàng)建相片變動(dòng)請(qǐng)求
        NSString *imgStr = self.pictureArr[self.index];
        // iOS8系統(tǒng)需要添加 file:// 協(xié)議頭
        NSString *fileStr = [NSString stringWithFormat:@"file://%@", imgStr];
        NSURL *fileUrl = [NSURL URLWithString:fileStr];
        
        // 視頻逼蒙、圖片類(lèi)型分開(kāi)創(chuàng)建 Request
        NSString *ext = imgStr.pathExtension;
        NSString *extLower = ext.lowercaseString;
        PHAssetChangeRequest *assetRequest = nil;
        if ([extLower isEqualToString:@"mov"]) {
            assetRequest =
            [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:fileUrl];
        } else {
            assetRequest =
            [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:fileUrl];
        }
        
        // 創(chuàng)建一個(gè)占位對(duì)象
        PHObjectPlaceholder *placeholder = [assetRequest placeholderForCreatedAsset];
        // 將占位對(duì)象添加到相冊(cè)請(qǐng)求中
        [collectionRequest addAssets:@[placeholder]];
        
    } completionHandler:^(BOOL success, NSError * _Nullable error) {
        // 回調(diào)在子線程从绘,需要轉(zhuǎn)到主線程刷新界面
        dispatch_async(dispatch_get_main_queue(), ^{
            [self saveCompleteWithSuccess:success];
        });
    }];
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市是牢,隨后出現(xiàn)的幾起案子僵井,更是在濱河造成了極大的恐慌,老刑警劉巖驳棱,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件批什,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡社搅,警方通過(guò)查閱死者的電腦和手機(jī)渊季,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)罚渐,“玉大人,你說(shuō)我怎么就攤上這事驯妄『刹ⅲ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵青扔,是天一觀的道長(zhǎng)源织。 經(jīng)常有香客問(wèn)我,道長(zhǎng)微猖,這世上最難降的妖魔是什么谈息? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮凛剥,結(jié)果婚禮上侠仇,老公的妹妹穿的比我還像新娘。我一直安慰自己犁珠,他們只是感情好逻炊,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著犁享,像睡著了一般余素。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上炊昆,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天桨吊,我揣著相機(jī)與錄音威根,去河邊找鬼。 笑死视乐,一個(gè)胖子當(dāng)著我的面吹牛洛搀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播炊林,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼姥卢,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了渣聚?” 一聲冷哼從身側(cè)響起独榴,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎奕枝,沒(méi)想到半個(gè)月后棺榔,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡隘道,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年症歇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谭梗。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡忘晤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出激捏,到底是詐尸還是另有隱情设塔,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布远舅,位于F島的核電站闰蛔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏图柏。R本人自食惡果不足惜序六,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蚤吹。 院中可真熱鬧例诀,春花似錦、人聲如沸距辆。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)跨算。三九已至爆土,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間诸蚕,已是汗流浹背步势。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工氧猬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坏瘩。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓盅抚,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親倔矾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子妄均,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容