iOS

[iOS/Swfit] PHAsset으로 날짜별 사진 가져오기: PHImageManager

ohlee52 2023. 9. 21. 23:16
반응형

PHAsset

기기의 사진첩에 접근하여 특정 날짜의 사진을 가져다 쓰는 법 입니다.

 

우선 특정 날짜의 사진에 대한 PHAsset을 가져옵니다.

사진 이미지를 전체 불러와서 처리하는게 아니라 PHAsset만 들고 있다가 최후에 이미지를 가져오는 것이기 때문에,

PHAsset을 처리하는건 이미지 불러오기처럼 오래 걸리진 않습니다.

import Photos

private func fetchPhotosForDate(date: Date)-> [PHAsset] {
        let options = PHFetchOptions()
        let calendar = Calendar.current
        let startOfDay = calendar.startOfDay(for: date)
        let endOfDay = calendar.date(byAdding: .day, value: 1, to: startOfDay)!
        options.predicate = NSPredicate(format: "creationDate >= %@ AND creationDate < %@", startOfDay as NSDate, endOfDay as NSDate)
        //원하는 로직 넣기
        let fetchResult = PHAsset.fetchAssets(with: .image, options: options)
        let res = fetchResult.objects(at: IndexSet(0..<fetchResult.count) )
        return res
    }

PHAsset은 Photos 프레임워크에 있기 때문에 임포트를 해줘야 하고요.

Calendar.current.strartOfDay를 이용하여 date의 00시를 잡아줍니다.

Date 처리는 UTC기준으로 처리되는 이유도 있지만, 해당 날짜에 찍은 사진 전체를 받아와야하기 때문에 누락이 안되려면 반드시 startOfDay를 해야겠죠.

FetchResult는 PHFetchResult<PHAsset>타입이기 때문에 저는 여기서 PHAsset으로 변환해서 리턴했습니다.

 

private let assets: [PHAsset]
private var images: [UIImage] = []

 private func getPhotoForCurrentPage22() throws {
        let options = PHImageRequestOptions()
        options.isSynchronous = true
        options.isNetworkAccessAllowed = true
        for asset in assets {
            PHImageManager.default().requestImage(for: asset, targetSize: CGSize(width: 400, height: 400), contentMode: .aspectFill, options: options) { image, info in
                if let image = image {
                    self.images.append(image)
                    print("이미지 가져오기 성공")
                } else {
                    print("이미지 가져오기 실패")
                }
            }
        }
    }

options.isNetworkAccessAllowed을 true로 하면 iCloud의 사진도 가져올 수 있습니다.

options.isSynchronous는 동기로 처리할것인가 비동기로 할것인가 옵션인데요,

requestImage를 한번에 쫙 처리하고 싶으면 동기(true)로 하면 편안합니다.

비동기로 하면 deliveryMode이  opportunistic로 되는데요,

이렇게 되면 저화질로 한번, 고화질로 한번 사진을 호출해서 로딩시간을 줄이게 됩니다.

이 때, 그냥 어펜드로 처리하면 사진이 두장씩 뜨겠지요?

클로져의  info 파라미터나 PHAsset정보를 이용하여 사진을 인덱싱 하셔도 좋을것 같습니다(전 안해봤어요 아직).

 

물론 비동기로 처리하면서 deliveryMode를 highQualityFormat(무조건 고화질)이나 fastFormat(고품질이 느리면 저화질)으로 변경하여 쓸 수도 있습니다.

PHImageRequestOptions에 관해서는 ZediOS 블로그에 잘 나와있더라고요. (언제나 감사합니다.)

https://zeddios.tistory.com/1151  

반응형