지난 번 포스트에 이어서 이번에는 PhotoKit에 변경 요청을 하는 법에 대해서 알아보도록 하겠습니다.
이 포스트는 다음 문서를 참고하여 작성되었습니다. Requesting Changes to the Photo Library
PHAsset, PHAssetCollection, PHCollectionList 객체는 모두 불변(immutable) 객체입니다. 따라서 이 객체들의 값을 변경해서 다시 돌려보내는 방법으로는 변경 요청을 할 수 없습니다. PhotoKit은 다음과 같이 변경 요청을 보내도록 하고 있습니다.
-
PHPhotoLibrary 타입의 싱글턴 변수를 받아옵니다. PHPhotoLibrary 타입은 Photos 앱에 의해 관리되는 모든 사진과 비디오의 집합을 나타냅니다.
let library = PHPhotoLibrary.shared()
-
performChange 계열의 함수를 호출해야 합니다. 인자로 줄 클로저 내용은 다음 단계에 작성할 예정입니다.
func performChanges(() -> Void, completionHandler: ((Bool, Error?) -> Void)?) // 변경 요청을 비동기적으로 한다. func performChangesAndWait(() -> Void) // 변경 요청을 동기적으로 한다.
-
변경하고자 하는 대상에 맞는 ChangeRequest를 선정합니다.
class PHAssetChangeRequest: PHChangeRequest // PHAsset에 대한 변경 요청 class PHAssetCollectionChangeRequest: PHChangeRequest // PHAssetCollection에 대한 변경 요청 class PHCollectionListChangeRequest: PHChangeRequest // PHCollectionList에 대한 변경 요청
-
3번에서 고른 ChangeRequest 타입은 각각의 타입에 맞는 생성,삭제 클래스 메소드, 업데이트 프로퍼티를 제공합니다.(CRUD중 C,U,D가 가능합니다. R은 지난 번 포스트에서 다루고 있습니다) 원하는 동작과 현재 가지고 있는 데이터에 맞는 동작을 선택합니다.
자세한 메소드와 프로퍼티 목록은 공식 문서를 참고해주세요.
PHAssetChangeRequest
PHAssetCollectionChangeRequest
PHCollectionListChangeRequest -
첫번째 클로저를 작성합니다. 생성, 삭제, 변경의 경우 모두 코드가 조금씩 다르므로 몇가지 예시로 보이도록 하겠습니다.
//UIImage를 받아 저장하는 함수 func save(image: UIImage) { PHPhotoLibrary.shared().performChanges({ let request = PHAssetChangeRequest.creationRequestForAsset(from: image) //일부 프로퍼티를 설정할 수 있다(생성 일자, 위치, 좋아요 여부, 숨김 여부) }, completionHandler: nil) } //사진을 삭제하는 함수 func delete(asset: PHAsset) { PHPhotoLibrary.shared().performChanges({ PHAssetChangeRequest.deleteAssets([asset] as NSArray) // 배열에 담아서 NSArray로 바꿔줘야 합니다. 정확히는 NSFastEnumerator를 상속받은 클래스면 됩니다. }, completionHandler: nil) } //좋아요를 껏다 키는 함수 func toggleFavoriteForAsset(asset: PHAsset) { PHPhotoLibrary.shared().performChanges({ let request = PHAssetChangeRequest(for: asset) request.isFavorite = !asset.isFavorite }, completionHandler: nil) }
첫번째 생성 예시에서 UIImage를 이용해서 사진첩에 사진을 생성합니다. 하지만 UIImage는 메타데이터를 가지고 있지 않기 때문에 이런 방식으로 생성하게 되면 메타데이터가 모두 날아갑니다. 이 메타데이터를 보존하기 위해서는, Image I/O를 이용해 임시 파일을 만든 뒤, 파일 URL을 이용한 생성 함수를 이용해 생성 요청을 보내야 합니다.
-
필요시 completionHandler를 작성하여 제공합니다. 클로저의 첫 인자은 성공,실패 여부를 나타내는 Bool 값이며, 두번째 인자는 실패시에만 받을 수 있는 error값입니다.
이상으로 PhotoKit에 사용법에 대해서 알아보았습니다. 앞선 포스트까지 해서 옵저버 등록, 권한 획득 등을 제외한 모든 기능을 돌아보았습니다. 처음에는 PhotoKit이 참 어렵다고 생각했는데, 막상 파고보니 아주 간단하게 끝났습니다. 다음에 더 좋은 내용으로 찾아오겠습니다:)