###### tags: `第14屆IT邦鐵人賽文章` # 【在 iOS 開發路上的大小事2-Day12】PhotoKit 好像很好玩 (1) ## 前情提要 1 Apple 處理照片的 Framework 在 iOS 8 以前是使用 AssetsLibrary, 而在 iOS 8 推出後,Apple 推出了 PhotoKit 這個全新照片框架來取代 AssetsLibrary 所以今天要來介紹的就是 PhotoKit 這個照片框架! ![PhotoKit](https://docs-assets.developer.apple.com/published/b57f722288/rendered2x-1655840094.png) ▲ 圖取自 Apple ## 前情提要 2 會想要介紹 PhotoKit 是因為我的照片有點多 (大概也就 2xxxx 張而已啦), 前陣子在用內建的照片 App 時,有時候收藏照片 A,以前的照片 B 就會自己被改成未收藏, (雖然那時候,好像發現是 Google 相簿的 bug 造成的) 要尋找未收藏的照片會蠻辛苦的,加上內建的只有篩選已收藏的功能,沒有篩選未收藏的功能 所以就只好打開 App Store 看有沒有具有這種功能的 App 可以用 ## 前情提要 3 但身為 iOS App 開發者,遇到這個問題,當然是要自己寫可以解決問題的 App 來解決 (哈) 所以,就有了介紹 PhotoKit 的契機啦~ (這裡主要是會以 App 內有用到的來介紹, 其餘的可能就要自行查看 [Apple Developer Documentation](https://developer.apple.com/documentation/photokit)) ## 使用 PhotoKit 的前置動作 首先,因為我們會需要存取手機內的照片,所以要先在 info.plist 裡面新增存取照片的權限 ```Privacy - Photo Library Usage Description```,不然 App 一 Build 起來,就會炸給你看喔~ ![](https://i.imgur.com/2fXVSAh.png) ## 如何取得相簿內的影像 ### 首先,我們先宣告一些變數 ```swift // Photos 變數宣告 var allPhotos: PHFetchResult<PHAsset>! let allPhotosOptions = PHFetchOptions() // 創建 PHFetchOptions 實例 let photosImageRequestOptions = PHImageRequestOptions() let photoCacheImageManager = PHCachingImageManager() // 創建 PHCachingImageManager 實例 var thumbnailSize: CGSize! // 縮圖大小 ``` 上述有用到的 PhotoKit 型別說明 ↓ ```swift PHFetchResult // 發出影像抓取請求後取得的資源 PHAsset // 影像拍攝當下的資訊 PHFetchOptions // 影像抓取選項、篩選、排序等 PHImageRequestOptions // 影像抓取請求選項 PHCachingImageManager // 快取影像管理,提供縮圖、原圖等 ``` ### 確認照片存取權限 確認照片存取權限的方式有兩種 1. 單純查詢照片存取權限狀態 2. 查詢照片存取權限後,做出對應狀態的處理方式 這兩種查詢方式,分別對應到下面這幾個 Function ```swift // 取得照片存取權限狀態 @available(iOS 14, *) open class func authorizationStatus(for accessLevel: PHAccessLevel) -> PHAuthorizationStatus // 查詢照片存取權限後,做出對應狀態的處理方式 @available(iOS 14, *) open class func requestAuthorization(for accessLevel: PHAccessLevel, handler: @escaping (PHAuthorizationStatus) -> Void) // 查詢照片存取權限後,做出對應狀態的處理方式 (await/async) @available(iOS 14, *) open class func requestAuthorization(for accessLevel: PHAccessLevel) async -> PHAuthorizationStatus ``` 而照片存取權限也是有存取層級,像是可讀可寫、只能新增 ```swift @available(iOS 14, iOS 8, *) public enum PHAccessLevel : Int { @available(iOS 8, *) case addOnly = 1 // 只允許新增 @available(iOS 8, *) case readWrite = 2 // 允許讀寫 } ``` ### 取得照片存取權限 這邊是使用第二種方式來查詢照片存取權限,查詢的 Sample Code 如下 await/async 的 Sample Code 也是大同小異,這邊就不放了 ```swift PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in if (status == .authorized) { print("App can access User's Photos") } else { print("App can't access User's Photos") } } ``` 上面 Closure 內的變數 status,型別為 ```enum PHAuthorizationStatus : Int``` ```swift @available(iOS 8, iOS 8, *) public enum PHAuthorizationStatus : Int { @available(iOS 8, *) case notDetermined = 0 // 使用者尚未授權 App 是否可以存取照片 @available(iOS 8, *) case restricted = 1 // 此 App 沒有權限存取照片 @available(iOS 8, *) case denied = 2 // 使用者已拒絕 App 存取照片 @available(iOS 8, *) case authorized = 3 // 使用者已授權 App 可以完整存取照片 @available(iOS 14, *) case limited = 4 // 使用者授權 App 可以存取使用者在相簿內所選取到的照片 } ``` 下一篇,再來繼續介紹 PHFetchOptions、PHPhotoLibraryChangeObserver、PHImageManager~ ## 參考資料 > https://developer.apple.com/documentation/photokit > https://www.jianshu.com/p/3ac116ffffcc > https://www.jianshu.com/p/c5fe835bb0fb > https://juejin.cn/post/6985128108965756936 > https://www.jianshu.com/p/78960c4fd99d > https://www.jianshu.com/p/0ff787121ebc > https://www.jianshu.com/p/56ffe8583eaa