將圖片保存到系統(tǒng)相冊中, PHPhotoLibrary的簡單使用

一. 最簡單的保存函數(shù)

  1. UIImage的函數(shù)來保存圖片
    • 較為簡單, 只需要一個(gè)函數(shù)一個(gè)方法就可以保存

    • 但是不能創(chuàng)建相冊, 保存的圖片會直接保存到默認(rèn)的系統(tǒng)相冊中

        /** 該函數(shù)用于將圖片保存到系統(tǒng)相冊中
          UIImage * _Nonnull image : 要保存的圖片
          id  _Nullable completionTarget : 調(diào)用completionSelector方法的對象, 一般為self
          SEL  _Nullable completionSelector : 當(dāng)保存完成調(diào)用的方法, 是一個(gè)系統(tǒng)指定的方法
          void * _Nullable contextInfo : 上下文信息, 用于傳給完成后的回調(diào)方法, 一般為nil
        */
        UIImageWriteToSavedPhotosAlbum(_image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
        
        - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
            
            if (error) {
                NSLog(@"保存失敗");
            } else {
                NSLog(@"保存成功");
            }
        }
      
    • 注意點(diǎn)

      1. 第三個(gè)參數(shù)一定要使用系統(tǒng)的回調(diào)方法, 否則這個(gè)方法會報(bào)錯(cuò)
      2. 系統(tǒng)指定的image: didFinishSavingWithError: contextInfo:方法一定要實(shí)現(xiàn), 否則也會出現(xiàn)問題

二. 使用PHPhotoLibrary來保存圖片

  1. 框架的簡單介紹:

    1. PHPhotoLibrary類, 專門用于管理系統(tǒng)的相片, 相簿等功能, 他可以獲取系統(tǒng)相冊中的相片信息, 也可以將App中獲取的圖片/相片存到手機(jī)相冊中, 以及iCloud Photos中.
    2. 對于手機(jī)相冊的各種操作, 幾乎都是通過PHPhotoLibrary的單例對象, 在ChangeBlock中, 以ChangeRequest來執(zhí)行的
      • 相片請求操作: PHAssetChangeRequest
      • 相冊請求操作: PHAssetCollectionChangeRequest
      • 相冊列表請求操作: PHCollectionListChangeRequest(小的暫時(shí)沒試過)
    3. PHObjectPlaceholder對象
      • 這個(gè)對象是用于存儲圖片時(shí)的占位對象
      • 如果你想保存一個(gè)圖片到一個(gè)相冊中, 需要先將這個(gè)占位對象添加到相冊中, 當(dāng)ChangeBlock調(diào)用結(jié)束之后, 會根據(jù)占位對象的標(biāo)識符搜索到占位對象的所在位置, 然后在保存圖片
    4. PHAuthorization: 用于查看當(dāng)前App的相冊授權(quán)狀態(tài)
      • 這個(gè)類用于獲取當(dāng)前你的App, 系統(tǒng)對其相冊訪問權(quán)限的授權(quán)狀態(tài)
      • 通過對四種不同的授權(quán)狀態(tài)的判斷, 我們可以做出對應(yīng)的操作
        • PHAuthorizationStatusNotDetermined : 用戶還沒有決定是否授權(quán)
        • PHAuthorizationStatusRestricted : 訪問權(quán)限受限制, 這個(gè)很少見, 如家長模式的限制才會有
        • PHAuthorizationStatusDenied : 用戶拒絕App訪問相冊
        • PHAuthorizationStatusAuthorized : 用戶已經(jīng)授權(quán)了訪問
    5. PHFetchResult: 檢索相簿中的相冊/相片
      • 這個(gè)類創(chuàng)建的對象, 是一個(gè)有序集合, 可以用于保存系統(tǒng)相簿中的相片/相冊的搜索結(jié)果列表
      • 該對象的每個(gè)元素, 都有一個(gè)localizedTitle, 即搜索得到的相片/相冊的名稱, 可以通過這個(gè)屬性來獲得指定的相冊/相片
      • 一般是通過遍歷的方式, 然后判斷l(xiāng)ocalizedTitle, 取得我們想要的相片/相冊
  2. 保存圖片的步驟

    1. 提供給外界調(diào)用的方法, 通過傳入要保存的圖片, 和指定的相冊名稱來保存一張圖片
      • 在這個(gè)方法中, 要獲取當(dāng)前App的相冊授權(quán)狀態(tài)

      • 如果用戶授權(quán)了, 就直接調(diào)用步驟2的方法, 保存圖片

      • 如果用戶沒有確定是否授權(quán), 要創(chuàng)建授權(quán)申請, 讓用戶選擇

      • 如果用戶已經(jīng)拒絕了授權(quán), 要顯示一個(gè)指示框, 讓用戶去打開授權(quán)

          + (void)saveImage:(UIImage *)image assetCollectionName:(NSString *)collectionName {
              
              // 1. 獲取當(dāng)前App的相冊授權(quán)狀態(tài)
              PHAuthorizationStatus authorizationStatus = [PHPhotoLibrary authorizationStatus];
              
              // 2. 判斷授權(quán)狀態(tài)
              if (authorizationStatus == PHAuthorizationStatusAuthorized) {
                  
                  // 2.1 如果已經(jīng)授權(quán), 保存圖片(調(diào)用步驟2的方法)
                  [self saveImage:image toCollectionWithName:collectionName];
                  
              } else if (authorizationStatus == PHAuthorizationStatusNotDetermined) { // 如果沒決定, 彈出指示框, 讓用戶選擇
                  
                  [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
                      
                      // 如果用戶選擇授權(quán), 則保存圖片
                      if (status == PHAuthorizationStatusAuthorized) {
                          [self saveImage:image toCollectionWithName:collectionName];
                      }
                  }];
                  
              } else {
                  
                  [SVProgressHUD showWithStatus:@"請?jiān)谠O(shè)置界面, 授權(quán)訪問相冊"];
              }
          }
        
    2. 用于保存圖片的方法, 通過外接接口獲取到的圖片, 相冊名稱來進(jìn)行保存
      • 將一個(gè)相片保存到一個(gè)自定義的相冊, 需要同時(shí)創(chuàng)建相片變動請求相冊變動請求

      • 根據(jù)傳入的相冊名, 要判斷一下當(dāng)前系統(tǒng)是否有這個(gè)相冊(這里需要步驟3的方法, 傳入相冊名稱, 來獲取相冊)

      • 在這個(gè)步驟, 需要用到的四個(gè)核心對象為PHPhotoLibrary, PHAssetCollectionChangeRequest, PHAssetChangeRequest, 以及PHObjectPlaceholder

          // 保存圖片
          + (void)saveImage:(UIImage *)image toCollectionWithName:(NSString *)collectionName {
              
              // 1. 獲取相片庫對象
              PHPhotoLibrary *library = [PHPhotoLibrary sharedPhotoLibrary];
              
              // 2. 調(diào)用changeBlock
              [library performChanges:^{
                  
                  // 2.1 創(chuàng)建一個(gè)相冊變動請求
                  PHAssetCollectionChangeRequest *collectionRequest;
                  
                  // 2.2 取出指定名稱的相冊
                  PHAssetCollection *assetCollection = [self getCurrentPhotoCollectionWithTitle:collectionName];
                  
                  // 2.3 判斷相冊是否存在
                  if (assetCollection) { // 如果存在就使用當(dāng)前的相冊創(chuàng)建相冊請求
                      collectionRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
                  } else { // 如果不存在, 就創(chuàng)建一個(gè)新的相冊請求
                      collectionRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:collectionName];
                  }
                  
                  // 2.4 根據(jù)傳入的相片, 創(chuàng)建相片變動請求
                  PHAssetChangeRequest *assetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
                  
                  // 2.4 創(chuàng)建一個(gè)占位對象
                  PHObjectPlaceholder *placeholder = [assetRequest placeholderForCreatedAsset];
                  
                  // 2.5 將占位對象添加到相冊請求中
                  [collectionRequest addAssets:@[placeholder]];
                  
              } completionHandler:^(BOOL success, NSError * _Nullable error) {
                  
                  // 3. 判斷是否出錯(cuò), 如果報(bào)錯(cuò), 聲明保存不成功
                  if (error) {
                      [SVProgressHUD showErrorWithStatus:@"保存失敗"];
                  } else {
                      [SVProgressHUD showSuccessWithStatus:@"保存成功"];
                  }
              }];
          }
        
    3. 步驟三用于獲取當(dāng)前系統(tǒng)中是否有指定的相冊
      • 如果有的話, 就返回已有相冊

      • 如果沒有的話, 就返回nil, 讓步驟二去創(chuàng)建一個(gè)新的系統(tǒng)相冊

      • 此處需要用到的關(guān)鍵類為: FHFetchResult, 用于搜索相冊/相片名稱的集合對象

      • 通過搜索結(jié)果的localizedTitle來找到對應(yīng)的相冊

          + (PHAssetCollection *)getCurrentPhotoCollectionWithTitle:(NSString *)collectionName {
              
              // 1. 創(chuàng)建搜索集合
              PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
              
              // 2. 遍歷搜索集合并取出對應(yīng)的相冊
              for (PHAssetCollection *assetCollection in result) {
                  
                  if ([assetCollection.localizedTitle containsString:collectionName]) {
                      return assetCollection;
                  }
              }
              
              return nil;
          }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鞭衩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子耀找,更是在濱河造成了極大的恐慌卤唉,老刑警劉巖很泊,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡咐刨,警方通過查閱死者的電腦和手機(jī)码俩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門度帮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事笨篷⊥啵” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵率翅,是天一觀的道長练俐。 經(jīng)常有香客問我,道長冕臭,這世上最難降的妖魔是什么腺晾? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮辜贵,結(jié)果婚禮上悯蝉,老公的妹妹穿的比我還像新娘。我一直安慰自己托慨,他們只是感情好鼻由,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著厚棵,像睡著了一般蕉世。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上窟感,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天讨彼,我揣著相機(jī)與錄音,去河邊找鬼柿祈。 笑死哈误,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的躏嚎。 我是一名探鬼主播蜜自,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼卢佣!你這毒婦竟也來了重荠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤虚茶,失蹤者是張志新(化名)和其女友劉穎戈鲁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嘹叫,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡婆殿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了罩扇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片婆芦。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡怕磨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出消约,到底是詐尸還是另有隱情肠鲫,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布或粮,位于F島的核電站导饲,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏被啼。R本人自食惡果不足惜帜消,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一棠枉、第九天 我趴在偏房一處隱蔽的房頂上張望浓体。 院中可真熱鬧,春花似錦辈讶、人聲如沸命浴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽生闲。三九已至,卻和暖如春月幌,著一層夾襖步出監(jiān)牢的瞬間碍讯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工扯躺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留捉兴,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓录语,卻偏偏與公主長得像倍啥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子澎埠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

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