iOS Photos庫的使用

說明

在iOS8以后正塌,AssetsLibrary被棄用当纱,蘋果要求用Photos呛每。查了一些資料,比較系統(tǒng)的使用Photos庫的文章不是很多坡氯,這里總結(jié)一下晨横。

一、<Photos/Photos.h>箫柳,對象說明

  • PHAsset:媒體資源對象手形,可能是圖片,或者視頻悯恍;
  • PHAssetCollection:相簙對象叁幢,包含一個相冊的所有信息;
  • PHImageManager:圖片管理坪稽,一個單例曼玩,可以通過asset獲取圖片;
  • PHImageRequestOptions:圖片請求選項窒百;
  • PHFetchResult:查找的結(jié)果黍判;
  • PHFetchOptions:查找請求的選項;

二篙梢、獲取系統(tǒng)相冊

__block BOOL showAlbums = YES;
WYPhotoLibraryController *library = (WYPhotoLibraryController *)self.navigationController;

//iOS8以后,使用PHAsset
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];

//獲取所有系統(tǒng)相冊
PHFetchResult *smartAlbumsFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:fetchOptions];
//遍歷相冊
[smartAlbumsFetchResult enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop) {
    showAlbums = NO;
    PHFetchOptions *fetchOptionsAlbums = [[PHFetchOptions alloc] init];
    
    //通過設(shè)置選擇器顷帖,獲取需要的資源
    switch (library.photoFilterType) {
        case WYPhotoFilterAllImage:
            fetchOptionsAlbums.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d", PHAssetMediaTypeImage];
            break;
        case WYPhotoFilterAllVideo:
            fetchOptionsAlbums.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d", PHAssetMediaTypeVideo];
            break;
        default:
            break;
    }
    
    //有可能是PHCollectionList,會造成crash渤滞,過濾掉
    if ([collection isKindOfClass:[PHAssetCollection class]]) {
        //從相冊中獲取數(shù)據(jù)
        PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptionsAlbums];
        //去掉視頻贬墩、最近刪除、最近添加
        if (![collection.localizedTitle isEqualToString:@"Recently Deleted"] &&
            ![collection.localizedTitle isEqualToString:@"Recently Added"] &&
            ![collection.localizedTitle isEqualToString:@"Videos"]) {
            if (fetchResult.count > 0) {
                WYPhotoGroup *group = [[WYPhotoGroup alloc] init];
                group.groupName = collection.localizedTitle;
                group.count = fetchResult.count;
                group.assetCollection = collection;
                group.fetchResult = fetchResult;
                [self.photoGroups addObject:group];
            }
        }
    }
}];

三妄呕、獲取自定義相冊

//獲取所有自定義相冊
PHFetchResult *userAlbumsFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:fetchOptions];
//遍歷相冊
[userAlbumsFetchResult enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop) {
    showAlbums = NO;
    PHFetchOptions *fetchOptionsAlbums = [[PHFetchOptions alloc] init];
    
    switch (library.photoFilterType) {
        case WYPhotoFilterAllImage:
            fetchOptionsAlbums.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d", PHAssetMediaTypeImage];
            break;
        case WYPhotoFilterAllVideo:
            fetchOptionsAlbums.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d", PHAssetMediaTypeVideo];
            break;
        default:
            break;
    }
    
    PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptionsAlbums];
    if (fetchResult.count > 0) {
        WYPhotoGroup *group = [[WYPhotoGroup alloc] init];
        group.groupName = collection.localizedTitle;
        group.count = fetchResult.count;
        group.assetCollection = collection;
        group.fetchResult = fetchResult;
        [self.photoGroups addObject:group];
    }
}];

四陶舞、獲取相冊的封面(相冊中的最后一張圖片)

- (void)setGetThumbnail:(void (^)(UIImage *))getThumbnail {
    _getThumbnail = getThumbnail;

    //如果有相冊的封面緩存圖片,直接使用
    if (_cacheThumbImage) {
        _getThumbnail(_cacheThumbImage);
        return;
    }
    //獲取封面
    if ([_assetCollection isKindOfClass:[PHCollection class]]) {
        //定義一個查找結(jié)果
        if (!_fetchResult) {
            PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
            _fetchResult = [PHCollection fetchCollectionsInCollectionList:_assetCollection options:fetchOptions];
        }
    
        PHFetchResult *tmpFetchResult = _fetchResult;
        //獲取最后一個查找資源
        PHAsset *tmpAsset = [tmpFetchResult objectAtIndex:tmpFetchResult.count - 1];
    
        //獲取圖片绪励,并剪切
        PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
        requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
        requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
        [[PHImageManager defaultManager] requestImageForAsset:tmpAsset targetSize:CGSizeMake(200, 200) contentMode:PHImageContentModeAspectFill options:requestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
            BOOL download = ![info[PHImageCancelledKey] boolValue] && ![info[PHImageErrorKey] boolValue] && ![info[PHImageResultIsDegradedKey] boolValue];
        
            if (download) {
                float scale = result.size.height / kThumbImageHeight;
                _cacheThumbImage = [UIImage imageWithCGImage:result.CGImage scale:scale orientation:UIImageOrientationUp];
                _getThumbnail(_cacheThumbImage);
            }
        }];
    }
}

五肿孵、遍歷相冊中的所有資源唠粥,并封裝對象

 - (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block {
    if (_assetCollection) {
        if ([_assetCollection isKindOfClass:[PHCollection class]]) {
            if (!_fetchResult) {
                PHFetchOptions *tmpFetchOptions = [[PHFetchOptions alloc] init];
                _fetchResult = [PHCollection fetchCollectionsInCollectionList:_assetCollection options:tmpFetchOptions];
            }
            [(PHFetchResult *) _fetchResult enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                if (obj) {
                    WYPhoto *photo = [[WYPhoto alloc] init];
                    photo.asset = obj;
        
                    [weakSelf.photos addObject:photo];
                }
    
              if (weakSelf.group.count-1 ==idx) {
                  [weakSelf.collectionView reloadData];
              }
          }];
        }
    }
}

六、獲得一個資源(PHAsset)的文件大小

- (void)setGetFileSize:(void (^)(NSInteger))getFileSize {
     _getFileSize = getFileSize;

    if (_asset) {
        if (_cacheFileSize > 0) {
            _getFileSize(_cacheFileSize);
            return;
        }
    
        //視頻資源和圖片資源獲取文件大小的方式不同
        if (self.mediaType == WYPhotoMediaTypeVideo) {
            PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
            [[PHImageManager defaultManager] requestAVAssetForVideo:_asset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
                if ([asset isKindOfClass:[AVURLAsset class]]) {
                    AVURLAsset *urlAsset = (AVURLAsset *)asset;
                    NSNumber *size;
                
                    [urlAsset.URL getResourceValue:&size forKey:NSURLFileSizeKey error:nil];
                    _cacheFileSize = [size floatValue]; // _cacheFileSize / (1024 * 1024) 轉(zhuǎn)MB
                    _getFileSize(_cacheFileSize);
                }
            }];
        }else {
            [[PHImageManager defaultManager] requestImageDataForAsset:_asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
                _cacheFileSize = imageData.length; // _cacheFileSize / (1024 * 1024) 轉(zhuǎn)MB
                _getFileSize(_cacheFileSize);
            }];
        }
    }
}

七停做、獲得一個資源(PHAsset)的縮略圖

- (void)setGetThumbnail:(void (^)(UIImage *))getThumbnail {
    _getThumbnail = getThumbnail;

    if (_asset) {
        if (_cacheThumbImage) {
            _getThumbnail(_cacheThumbImage);
            return;
        }
    
        if ([_asset isKindOfClass:[PHAsset class]]) {
            PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
            requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
            requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
            [[PHImageManager defaultManager] requestImageForAsset:_asset targetSize:CGSizeMake(200, 200) contentMode:PHImageContentModeAspectFill options:requestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
                BOOL download = ![info[PHImageCancelledKey] boolValue] && ![info[PHImageErrorKey] boolValue] && ![info[PHImageResultIsDegradedKey] boolValue];
            
                if (download) {
                    _cacheThumbImage = result;
                    _getThumbnail(_cacheThumbImage);
                }
            }];
        }
    }
}

八晤愧、獲得一個資源(PHAsset)的高清圖

- (void)setGetFullImage:(void (^)(UIImage *))getFullImage {
    _getFullImage = getFullImage;

    if (_asset) {
        if (_cacheFullImage) {
            _getFullImage(_cacheFullImage);
            return;
        }
    
        if ([_asset isKindOfClass:[PHAsset class]]) {
            PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
            requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
            requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
        
            //圖的寬度
            CGFloat photoWidth = [UIScreen mainScreen].bounds.size.width;
            //圖寬高比
            CGFloat aspectRatio = ((PHAsset*)_asset).pixelWidth / (CGFloat)((PHAsset*)_asset).pixelHeight;
            //屏幕分辨率 
            //[[UIScreen main] scale] == 1; //代表320 x 480 的分辨率
            //[[UIScreen main] scale] == 2; //代表640 x 960 的分辨率
            //[[UIScreen main] scale] == 3; //代表1242 x 2208 的分辨率
            CGFloat multiple = [UIScreen mainScreen].scale;
            //圖寬度,像素
            CGFloat pixelWidth = photoWidth * multiple;
            //圖高度蛉腌,像素
            CGFloat pixelHeight = pixelWidth / aspectRatio;
        
            //允許從iCloud上下載
            requestOptions.networkAccessAllowed = YES;
            requestOptions.progressHandler = ^(double progress, NSError * _Nullable error, BOOL * _Nonnull stop, NSDictionary * _Nullable info) {
                if (self.getNetworkProgressHandler) {
                    self.getNetworkProgressHandler(progress, error, stop, info);
                }
            };
        
            [[PHImageManager defaultManager] requestImageForAsset:_asset targetSize:CGSizeMake(pixelWidth, pixelHeight) contentMode:PHImageContentModeAspectFill options:requestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
                BOOL download = ![info[PHImageCancelledKey] boolValue] && ![info[PHImageErrorKey] boolValue] && ![info[PHImageResultIsDegradedKey] boolValue];
            
                if (download) {
                    _cacheFullImage = result;
                    _getFullImage(_cacheFullImage);
                }
            }];
        }
    }
}

九官份、完整代碼,請看:傳送門烙丛。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舅巷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蜀变,更是在濱河造成了極大的恐慌悄谐,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件库北,死亡現(xiàn)場離奇詭異爬舰,居然都是意外死亡,警方通過查閱死者的電腦和手機寒瓦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門情屹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人杂腰,你說我怎么就攤上這事垃你。” “怎么了喂很?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵惜颇,是天一觀的道長。 經(jīng)常有香客問我少辣,道長凌摄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任漓帅,我火速辦了婚禮锨亏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘忙干。我一直安慰自己器予,他們只是感情好,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布捐迫。 她就那樣靜靜地躺著乾翔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪弓乙。 梳的紋絲不亂的頭發(fā)上末融,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天钧惧,我揣著相機與錄音暇韧,去河邊找鬼勾习。 笑死,一個胖子當著我的面吹牛懈玻,可吹牛的內(nèi)容都是我干的巧婶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼涂乌,長吁一口氣:“原來是場噩夢啊……” “哼艺栈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起湾盒,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤湿右,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后罚勾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體毅人,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年尖殃,在試婚紗的時候發(fā)現(xiàn)自己被綠了丈莺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡送丰,死狀恐怖缔俄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情器躏,我是刑警寧澤俐载,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站登失,受9級特大地震影響遏佣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜壁畸,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一贼急、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捏萍,春花似錦太抓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至逗噩,卻和暖如春掉丽,著一層夾襖步出監(jiān)牢的瞬間跌榔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工捶障, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留僧须,地道東北人。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓项炼,卻偏偏與公主長得像担平,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子锭部,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354

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