글로벌 사용자를 타겟으로 하므로 한글/영어로 Localization을 진행
했습니다.Swift Concurrency를 이용하여 PHAsset 관련 요청을 처리할 수 있는 라이브러리
입니다.PHAsset 관련 기능은 프로젝트 내부에 종속되지 않는다고 판단
하여 별도 라이브러리로 구현하였습니다.AsyncThrowingStream
을 활용한 이미지 요청
ImageCacheManager
Request Option
을 편하게 작성할 수 있는 Option 기능PHPickerViewControllerDelegate의 호출 시점 딜레이를 최소화
하기 위해 커스텀 피커를 구현했습니다.startCachingImages
를 사용해 이미지를 미리 캐싱합니다.추가적으로
100장 이상의 사진을 한번에 추가할때 화면이 멈춤
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
dismiss(animated: true)
for result in results {
guard let assetIdentifier = result.assetIdentifier else { continue }
let assetResults = PHAsset.fetchAssets(withLocalIdentifiers: [assetIdentifier], options: nil)
guard let asset = assetResults.firstObject else { continue }
let photoAsset = coreDataManager.createPhotoAsset(
identifier: asset.localIdentifier,
creationDate: Date(),
mediaType: asset.mediaType
)
var snapshot = dataSource.snapshot()
snapshot.appendItems([.init(model: photoAsset)], toSection: .main)
dataSource.apply(snapshot, animatingDifferences: true)
}
}
func createPhotoAsset(identifier: String, creationDate: Date, mediaType: PHAssetMediaType) -> PhotoAsset {
let photoAsset = PhotoAsset(context: context)
photoAsset.identifier = identifier
photoAsset.creationDate = creationDate
photoAsset.mediaType = Int16(mediaType.rawValue)
saveContext()
return photoAsset
}
func fetchPhotoAssets() -> [PhotoAsset] {
let fetchRequest: NSFetchRequest<PhotoAsset> = PhotoAsset.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
do {
return try context.fetch(fetchRequest)
} catch {
print("Error fetching PhotoAssets: \\(error)")
return []
}
}