View

300x250

[iOS 앱 개발 - Swift] Photos Framework 사용하기

이 글은 edwith의 부스트코스 iOS 프로그래밍이라는 강좌를 들으며 혼자 공부한 내용을 글로 정리하며 작성한 포스팅입니다. 이번 강의는 챕터 4의 첫 번째 강의입니다. 갈수록 살짝씩 어려워지는 느낌이 들긴하지만 ㅋㅋㅋ 입문용 강의로는 그래도 정말 괜찮은 것 같아요. 어제 교보문고에 들러서 Swift 책을 하나 구입해서 옆에 두고 헷갈리는 내용을 참고하려고 몇개 살펴봤는데, Swift 교과서! 이런 느낌의 책을 펼쳤는데 거의 다 아는 내용이라 그냥 덮었거든요. 그만큼 이 강의가 괜찮은 것 같아요!

 

강의 전체랑 강의자료도 공짜로 제공되는데 네이버 아이디로도 수강할 수 있을만큼 접근성이 좋아서 프로그래밍을 기본적으로 할 줄 아시는 분이 아이폰 앱개발에 입문하고싶다! 하시는 분이 수강하기 딱 적절한 강의라고 생각됩니다. 프로젝트로 작은 앱을 계속 만들면서 공부를 하기 때문에 성취감도 있어요! ㅋㅋㅋ

 

관심이 있으신 분은 아래 링크를 눌러주세용!

https://www.edwith.org/boostcourse-ios/

 

[부스트코스] iOS 프로그래밍 강좌소개 : edwith

- 부스트코스

www.edwith.org

 


 

이전에 imagePicker로 사진을 선택하고, 가져오는 작업을 수행해준 적이 있었는데, 이번에 공부한 Photos 프레임워크는 좀 더 "사진!!" 이런 느낌이예요. ㅋㅋㅋㅋㅋ

 

Photos Framework는 뭘까?

iCloud에 올라가있는 사진 라이브러리나 사진 앱으로 관리하는 이미지 / 비디오에 접근해서 작업을 수행할 수 있게 해주는 프레임워크입니다. 사진을 가져와서 수정하고, 다른 여러 장치에 동기화 하는 작업을 수행할 수 있게 합니다.

 

특징

Photos framework medel 클래스에 여러 인스턴스가 있는데, ( PHAsset : 이미지, 비디오 등의 에셋 , PHAssetCollection : 그러한 에셋들의 collection , PHCollectionList : 그러한 collection 들의 리스트 ) 이들에게서 데이터를 가져와 수정같은 작업을 해준 뒤, PHPhotoLibrary 에게 변경사항을 알려 데이터를 교체할 수 있습니다.

 

PHImageManager 클래스는 섬네일이나 에셋등을 검색하거나 생성하는 기능을 제공합니다. 이를 이용하면, 포토s 프레임워크가 알아서 요청한 크기에 맞는 이미지를 쭉 로드해 캐싱해줍니다. 섬네일이나 작은 이미지를 만들 때 편-안 한 작업을 할 수 있게 도와줍니다. 유사품인 PHCachingImageManager 도 있습니다.

 

PHAsset, PHCollection, PHObject, PHFetchResult 등의 클래스들은 메타데이터를 가지고 있는 읽기 전용 데이터들입니다.

 

PHContentEditingInput, PHContentEditingOutput, PHAdjustmentData 등의 클래스를 이용해 사진 편집 및 반영을 수행할 수 있습니다. 만약 사진편집기능을 확장하고자 한다면, 이 클래스들을 바탕으로 다른 프레임워크등을 가져와 섞어 쌓아올리면 됩니다.

 

PHPhotoLibraryChangeObsserver, PHChange, PH~~Change 등의 클래스는 사진의 정보를 변경할 때(다른 앱에서 또는 다른 기기에서) 애플리케이션에게 이 사실을 알려 앱에 로드된 데이터를 업데이트하여 라이브러리를 일치시킬 수 있도록 하는 클래스입니다.

 


Photos 프레임워크를 사용해 사진을 가져오는 앱을 만들어보기

목표로 하는 앱은 아래 사진과 같은, 사진의 작은 섬네일을 담고있는 테이블 뷰를 만드는 것입니다.

 

 

StoryBoard

 

 

이렇게 간단하게 스토리보드를 구성했습니다. 그냥 TableView 하나 올리고, ReuseIdentifier가 "cell" 인 셀 하나를 올려줬어요.

 

에셋 가져오는 코드

만들어준 화면의 ViewController에 코드를 작성해줍니다.

 

 

일단 TableView의 데이터소스와 델리게이트를 담당해야하기에 두 프로토콜을 준수해주고, 사진을 다루기 위해 Photos 프레임워크를 import 해줍니다!

 

PHAsset을 가져와 저장해줄 리스트인 fetchResult를 만들어줍니다. 그리고 다량의 섬네일을 빠르게 가져올 수 있는 PHCachingImageManager 를 만들고 imageManager라는 이름으로 선언해줍시다.

 

사진들을 앨범에서 가져와줄 함수인 requestCollection( )를 작성해줍시다. smartAlbum (동적으로 사진정보를 업데이트하는 앨범 - 그냥 앨범보다 좀 더 효율이 좋은 듯 하네요 ) 에서 사용자의 라이브러리에 있는 사진들을 받아오는 메서드를 작성해 사진의 콜렉션을 가져와 cameraRoll에 저장해줍니다. 이 데이터를 cameraRollCollection에 담아주는데, (collection의 리스트에서 첫 오브젝트를 가져와 이 collection에 담아요. 만약 가져오지 못해 빈 콜렉션이라면 nil 을 반환 -> guard에 의해 return 됩니다.)

 

그다음, PHFetchOption을 생성해 만들어줍니다. fetchOption중 정렬에 대한 설정으로 생성일에 대해 내림차순으로 정렬함을 넣어줍니다.

 

처음에 만들어준 fetchResult에 cameraRollCollection에 들어온 에셋들을 설정해준 fetchOptions 을 옵션으로 하여 fetch(로드)해줍니다.

흠.. 역시 코드에 대해서는 좀 더 연습해서 익숙해질 필요가 있을 것 같아요. 점점 복잡해지는 코드를 보니까 헷갈리네요 ㅋㅋㅋ

 

권한 설정하는 코드

사용자의 사진첩에 접근하는 앱이기 때문에, 사용자에게 접근해도 괜찮을지를 물어봐야합니다. 이게 없다면 애플의 앱 심사에서 결격사유가 될 수도 있으니, 신경써서 작성해줘야겠죠? 뷰가 메모리에 로드될 때 한 번 검사해주도록 합니다.

 

 

PHPhotoLibrary의 권한허가상태를 받아와서, 이 값에 따라 Switch 구문으로 분기해주도록 합시다. 허가를 받았다면 데이터를 요청하고 reload 해주면 되고, 거절을 받았다면 로드를 하면 안되겠죠? 만약에 아직 응답을 받지 않았다면 대답을 요청합니다. 이 대답에 대해서 switch 구문으로 분리해서 각 필요한 작업을 수행해줍니다. OperationQueue.main.addOperation은 동기/비동기와 관련된 내용으로, 뒤에서 다시 한번 포스팅으로 작성할 예정입니다!

 

그리고 'Info.plist' 파일에서 권한 허가를 요구할 때 전달할 메세지를 작성해줘야해요. 우클릭 후 Add Row로 'Privacy - Phto Library Usage Description'을 추가하고, Value에 전달할 메세지를 작성해줍니다.

 

tableView에 데이터 로드하는 코드

 

섹션당 행의 개수에 대해서는 fetchResult.count ?? 0 라는 코드로 값을 반환해줍시다. 이 문법은 fetchResult.count가 만약 값을 반환할 수 없다면 (nil 이라면) 0을 반환하게 하는 코드입니다. (Swift 재밌어... 문법 신기해... 후욱후욱)

 

셀을 설정하는 함수에서는, 메모리관리를 위해 dequeueReusableCell을 이용합시다. PHAsset 타입의 상수를 fetchResult.object(at: ) 으로 각 행에 맞는 사진 데이터를 가져와 지정해줍니다. 아까 만들어준 PHCachingImageManager가 드디어 나왔네요! 이 에셋에 대해 지정한 사이즈와 모드로, cell.imageView.image에 넣어줍니다. 그리고 설정한 cell을 반환해줍니다.

 

실행 결과

처음 앱을 실행하면, 아래 화면처럼 Photo 앨범에 접근해도 될지 허가를 요청하는 메세지가 팝업됩니다. 그리고 작은 글씨로 아까 Info.plist에서 작성해준 메세지가 떠있죠! (저의 경우는, Please allow to use Photo Library 였습니다)

여기서 OK를 눌러주면 맨 처음 사진처럼 테이블뷰에 사진이 올라간 모습을 볼 수 있습니다.


 

320x100
Share Link
reply
반응형
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30