iOS 獲取系統(tǒng)相冊內(nèi)視頻與圖片(AssetsLibrary篇)

好些天沒寫點東西了象缀,最近公司要做新項目摩疑,有點小忙粤铭。不想我的堅持就此中斷吴侦,我把我前些天研究的東西拿出來給大家看看屋休。
這次整理的是AssetsLibrary和PhotoKit的使用。本人處女座备韧,有點強迫癥劫樟,之前寫的項目里用的是AssetsLibrary寫的調(diào)取相冊內(nèi)的媒體文件,但是Xcode總是報警告錯誤,雖然能夠編譯并展示效果叠艳,但是十幾個警告錯誤掛在那奶陈,心里總不是滋味,所以我就研究了一下AssetLibrary和PhotoKit附较。
在 iOS 8 出現(xiàn)之前尿瞭,開發(fā)者只能使用 AssetsLibrary 框架來訪問設(shè)備的照片庫,這是一個有點跟不上 iOS 應(yīng)用發(fā)展步伐以及代碼設(shè)計原則但確實強大的框架翅睛,考慮到 iOS7 仍占有不少的滲透率声搁,因此 AssetsLibrary 也是本文重點介紹的部分。而在 iOS8 出現(xiàn)之后捕发,蘋果提供了一個名為 PhotoKit 的框架疏旨,一個可以讓應(yīng)用更好地與設(shè)備照片庫對接的框架。

一扎酷、AssetsLibrary 組成##

AssetsLibrary 的組成比較符合照片庫本身的組成檐涝,照片庫中的完整照片庫對象、相冊法挨、相片都能在 AssetsLibrary 中找到一一對應(yīng)的組成谁榜,這使到 AssetsLibrary 的使用變得直觀而方便。想要了解AssetsLibrary得從它的類開始凡纳。

AssetsLibrary: 代表整個設(shè)備中的資源庫(照片庫)窃植,通過 AssetsLibrary 可以獲取和包括設(shè)備中的照片和視頻

  • ALAssetsGroup: 映射照片庫中的一個相冊,通過 ALAssetsGroup 可以獲取某個相冊的信息荐糜,相 冊下的資源巷怜,同時也可以對某個相冊添加資源。
  • ALAsset: 映射照片庫中的一個照片或視頻暴氏,通過 ALAsset 可以獲取某個照片或視頻的詳細(xì)信息延塑, 或者保存照片和視頻。
  • ALAssetRepresentation: ALAssetRepresentation 是對 ALAsset 的封裝(但不是其子類)答渔,可以更方便地獲取 ALAsset 中的資源信息关带,每個 ALAsset 都有至少有一個 ALAssetRepresentation 對象,可以通過 defaultRepresentation 獲取沼撕。而例如使用系統(tǒng)相機應(yīng)用拍攝的 RAW + JPEG 照片宋雏,則會有兩個 ALAssetRepresentation,一個封裝了照片的 RAW 信息端朵,另一個則封裝了照片的 JPEG 信息好芭。

二、AssetsLibrary 的基本使用##

AssetsLibrary 的功能很多冲呢,基本可以分為對資源的獲取/保存兩個部分,保存的部分相對簡單招狸,API 也比較少敬拓,因此這里不作詳細(xì)介紹邻薯。獲取資源的 API 則比較豐富了,一個常見的使用大量 AssetsLibrary API 的例子就是圖片選擇器(ALAsset Picker)乘凸。要制作一個圖片選擇器厕诡,思路應(yīng)該是獲取照片庫-列出所有相冊-展示相冊中的所有圖片-預(yù)覽圖片大圖。
首先是App 照片操作授權(quán):

NSString *tipTextWhenNoPhotosAuthorization; // 提示語
// 獲取當(dāng)前應(yīng)用對照片的訪問授權(quán)狀態(tài)
ALAuthorizationStatus authorizationStatus = [ALAssetsLibrary authorizationStatus];
// 如果沒有獲取訪問授權(quán)营勤,或者訪問授權(quán)狀態(tài)已經(jīng)被明確禁止灵嫌,則顯示提示語,引導(dǎo)用戶開啟授權(quán)
if (authorizationStatus == ALAuthorizationStatusRestricted || authorizationStatus == ALAuthorizationStatusDenied) {
    NSDictionary *mainInfoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString *appName = [mainInfoDictionary objectForKey:@"CFBundleDisplayName"];
    tipTextWhenNoPhotosAuthorization = [NSString stringWithFormat:@"請在設(shè)備的\"設(shè)置-隱私-照片\"選項中葛作,允許%@訪問你的手機相冊", appName];
    // 展示提示語
}

如果已經(jīng)獲取授權(quán)寿羞,則可以獲取相冊列表:

_assetsLibrary = [[ALAssetsLibrary alloc] init];
_albumsArray = [[NSMutableArray alloc] init];
[_assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
    if (group) {
        [group setAssetsFilter:[ALAssetsFilter allPhotos]];
        if (group.numberOfAssets > 0) {
            // 把相冊儲存到數(shù)組中,方便后面展示相冊時使用
            [_albumsArray addObject:group];
        }
    } else {
        if ([_albumsArray count] > 0) {
            // 把所有的相冊儲存完畢赂蠢,可以展示相冊列表
        } else {
            // 沒有任何有資源的相冊绪穆,輸出提示
        }
    }
} failureBlock:^(NSError *error) {
    NSLog(@"Asset group not found!\n");
}];

上面的代碼中,遍歷出所有的相冊列表虱岂,并把相冊中資源數(shù)不為空的相冊 ALAssetGroup 對象的引用儲存到一個數(shù)組中玖院。這里需要強調(diào)幾點:

  • iOS 中允許相冊為空,即相冊中沒有任何資源第岖,如果不希望獲取空相冊难菌,則需要像上面的代碼中那樣手動過濾。
  • ALAssetsGroup 有一個 setAssetsFilter 的方法蔑滓,可以傳入一個過濾器扔傅,控制只獲取相冊中的照片或只獲取視頻。一旦設(shè)置過濾烫饼,ALAssetsGroup 中資源列表和資源數(shù)量的獲取也會被自動更新猎塞。
  • 整個 AssetsLibrary 中對相冊、資源的獲取和保存都是使用異步處理(Asynchronous)杠纵,這是考慮到資源文件體積相當(dāng)比較大(還可能很大)荠耽。例如上面的遍歷相冊操作,相冊的結(jié)果使用 block 輸出比藻,如果相冊遍歷完畢铝量,則最后一次輸出的 block 中的 group 參數(shù)值為 nil。而 stop 參數(shù)則是用于手工停止遍歷银亲,只要把 *stop 置 YES慢叨,則會停止下一次的遍歷。關(guān)于這一點常常會引起誤會务蝠,所以需要注意拍谐。

現(xiàn)在,已經(jīng)可以獲取相冊了,接下來是獲取相冊中的資源:

_imagesAssetArray = [[NSMutableArray alloc] init];
[assetsGroup enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
    if (result) {
        [_imagesAssetArray addObject:result];
    } else {
        // result 為 nil轩拨,即遍歷相片或視頻完畢践瓷,可以展示資源列表
    }
}];

跟遍歷相冊的過程類似,遍歷相片也是使用一系列的異步方法亡蓉,其中上面的方法所輸出的 block 中晕翠,除了 result 參數(shù)表示資源信息,stop 用于手工停止遍歷外砍濒,還提供了一個 index 參數(shù)淋肾,這個參數(shù)表示資源的索引。一般來說爸邢,展示資源列表都會使用縮略圖(result.thumbnail)樊卓,因此即使資源很多,遍歷資源的速度也會相當(dāng)快甲棍。但如果確實需要加載資源的高清圖或者其他耗時的處理简识,則可以利用上面的 index 參數(shù)和 stop 參數(shù)做一個分段拉取資源。例如:

NSUInteger _targetIndex; // index 目標(biāo)值感猛,拉取資源直到這個值就手工停止拉取
NSUInteger _currentIndex; // 當(dāng)前 index七扰,每次拉取資源時從這個值開始
 
_targetIndex = 50;
_currentIndex = 0;
 
- (void)loadAssetWithAssetsGroup:(assetsGroup *)assetsGroup {
    [assetsGroup enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:_currentIndex] options:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
        _currentIndex = index;
        if (index > _targetIndex) {
            // 拉取資源的索引如果比目標(biāo)值大,則停止拉取
            *stop = YES;
        } else {
            if (result) {
                [_imagesAssetArray addObject:result];
            } else {
                // result 為 nil陪白,即遍歷相片或視頻完畢
            }
        }
    }];
}// 之前拉取的數(shù)據(jù)已經(jīng)顯示完畢颈走,需要展示新數(shù)據(jù),重新調(diào)用 loadAssetWithAssetsGroup 方法咱士,并根據(jù)需要更新 _targetIndex 的值

最后一步是獲取圖片詳細(xì)信息立由,例如:

// 獲取資源圖片的詳細(xì)資源信息,其中 imageAsset 是某個資源的 ALAsset 對象
ALAssetRepresentation *representation = [imageAsset defaultRepresentation];
// 獲取資源圖片的 fullScreenImage
UIImage *contentImage = [UIImage imageWithCGImage:[representation fullScreenImage]];

對于一個 ALAssetRepresentation序厉,里面包含了圖片的多個版本锐膜。最常用的是 fullResolutionImage 和 fullScreenImage。fullResolutionImage 是圖片的原圖弛房,通過 fullResolutionImage 獲取的圖片沒有任何處理道盏,包括通過系統(tǒng)相冊中“編輯”功能處理后的信息也沒有被包含其中,因此需要展示“編輯”功能處理后的信息文捶,使用 fullResolutionImage 就比較不方便荷逞,另外 fullResolutionImage 的拉取也會比較慢,在多張 fullResolutionImage 中切換時能明顯感覺到圖片的加載過程粹排。因此這里建議獲取圖片的 fullScreenImage种远,它是圖片的全屏圖版本,這個版本包含了通過系統(tǒng)相冊中“編輯”功能處理后的信息顽耳,同時也是一張縮略圖坠敷,但圖片的失真很少妙同,缺點是圖片的尺寸是一個適應(yīng)屏幕大小的版本,因此展示圖片時需要作出額外處理常拓,但考慮到加載速度非辰ト埽快的原因(在多張圖片之間切換感受不到圖片加載耗時)辉浦,仍建議使用 fullScreenImage弄抬。

系統(tǒng)相冊的處理過程大概也是如上,可以看出宪郊,在整個過程中并沒有使用到圖片的 fullResolutionImage掂恕,從相冊列表展示到最終查看資源,都是使用縮略圖弛槐,這也是 iOS 相冊加載快的一個重要原因懊亡。

這里我整理一個demo,歡迎大家給予指正乎串。demo鏈接如下:https://github.com/Snoopy008/ChooseAlbumFile

結(jié)語##

由于時間有限店枣,我還是將PhotoKit的內(nèi)容放在下一篇。敬請期待叹誉。鸯两。。长豁。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钧唐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子匠襟,更是在濱河造成了極大的恐慌钝侠,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酸舍,死亡現(xiàn)場離奇詭異帅韧,居然都是意外死亡,警方通過查閱死者的電腦和手機啃勉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門忽舟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人璧亮,你說我怎么就攤上這事萧诫。” “怎么了枝嘶?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵帘饶,是天一觀的道長。 經(jīng)常有香客問我群扶,道長及刻,這世上最難降的妖魔是什么镀裤? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮缴饭,結(jié)果婚禮上暑劝,老公的妹妹穿的比我還像新娘。我一直安慰自己颗搂,他們只是感情好担猛,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著丢氢,像睡著了一般傅联。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上疚察,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天蒸走,我揣著相機與錄音,去河邊找鬼貌嫡。 笑死比驻,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的岛抄。 我是一名探鬼主播别惦,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼弦撩!你這毒婦竟也來了步咪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤益楼,失蹤者是張志新(化名)和其女友劉穎猾漫,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體感凤,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡悯周,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了陪竿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片禽翼。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖族跛,靈堂內(nèi)的尸體忽然破棺而出闰挡,到底是詐尸還是另有隱情,我是刑警寧澤礁哄,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布长酗,位于F島的核電站,受9級特大地震影響桐绒,放射性物質(zhì)發(fā)生泄漏夺脾。R本人自食惡果不足惜之拨,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咧叭。 院中可真熱鬧蚀乔,春花似錦、人聲如沸菲茬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽生均。三九已至听想,卻和暖如春腥刹,著一層夾襖步出監(jiān)牢的瞬間马胧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工衔峰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留佩脊,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓垫卤,卻偏偏與公主長得像威彰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子穴肘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

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

  • 寫在前面 在手機APP日益增加的前提下评抚,如何更好的提升用戶的交互體驗似乎成為衡量一個APP重要指標(biāo)豹缀。上述的感悟源于...
    Jack_lin閱讀 6,221評論 12 62
  • 圖片視頻管理 AssetsLibrary 在ios8之前 ,只能使用AssetsLibrary 來訪...
    蘇永茂閱讀 1,366評論 0 10
  • 由于前段時間慨代,需要完成一個跟相冊的需求邢笙,所以閱讀了一些與圖片有關(guān)的文章,和使用了一些相關(guān)的第三方庫侍匙。 在 iOS ...
    CoderLocus閱讀 57,091評論 76 55
  • AssetsLibrary的詳細(xì)使用 AssetsLibrary的組成 AssetsLibrary的組成和iPho...
    FlowerKanZhe閱讀 6,376評論 7 13
  • “助推”是一種深含價值觀和目標(biāo)氮惯,同時充分考慮到如何調(diào)動資源、制定有效流程想暗、使目標(biāo)得以實現(xiàn)妇汗、使價值觀得以堅守的“硬球...
    gyl58365閱讀 1,430評論 0 1