#1. PHPickerViewController 다루기
PHPickerViewController를 이용해서 여러 앨범 내부 이미지의 이미지 고유 ID를 가져오기
기본 구조
import Foundation
import Photos
import PhotosUI
import Combine
import UIKit
final class PhotoService{
static let shared = PhotoService()
var passthroughIdentifiers = PassthroughSubject<([String],UIViewController),Never>()
// RxSwift 사용 시...
// var passthroughIdentifiers:PublishSubject<([String],UIViewController)> = .init()
private weak var viewController: UIViewController?
static let limitedNumber = 10
private init(){}
...
✅ PHPicker 화면을 띄워주는 viewController를 약한 참조로 사용한다.
✅ passthroughIdentifiers 이미지 아이디와 화면을 띄우는 viewController의 값을 가져온다. ⇒ present한 컨트롤러만 이 Subject에 반응하기 위함..!
PHPicker Present 메서드
...
func presentPicker(vc: UIViewController,multipleSelection: Bool = false,prevIdentifiers:[String]? = nil) {
self.viewController = vc
let filter = PHPickerFilter.images
var configuration = PHPickerConfiguration(photoLibrary: .shared())
configuration.filter = filter
configuration.preferredAssetRepresentationMode = .automatic
configuration.selection = .ordered
configuration.selectionLimit = multipleSelection ? Self.limitedNumber : 1
if let prevIdentifiers{
configuration.preselectedAssetIdentifiers = prevIdentifiers
}
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
viewController?.present(picker, animated: true)
}
...
PHPicker 이미지 추가 메서드
extension PhotoService: PHPickerViewControllerDelegate{
// 델리게이트 구현 사항
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
viewController?.dismiss(animated: true)
let identifiers = results.map(\.assetIdentifier!) // 이미지에 존재하는 identifier만 가져온다.
guard let viewController else {return}
passthroughIdentifiers.send((identifiers,viewController))
// rxSwift를 사용하는 경우...
// passthroughIdentifiers.onNext((identifiers,viewController))
}
}
위 구현한 서비스 사용 예시
이미지 가져오는 영역
final class AddSetVM{
...
func bindPhPicker() {
photoService.passthroughIdentifiers.sink {[weak self] val,vc in
guard let self,self.vc == vc,let newAlbumID = val.first else {return}
let newFileName = newAlbumID.getLocalPathName(type: .photo)
let prevFileName = self.setItem?.imagePath
self.setItem?.imagePath = newFileName
Task{@MainActor [weak self] in
guard let self else {return}
if !self.ircSnapshot.existItem(id: newFileName){
await ImageService.shared.saveToDocumentBy(photoIDs:[newAlbumID])
}
if let setItem{ updatedSetItem.send((setItem,true)) }
Task.detached {
await self.ircSnapshotUpdate(new: newFileName, prev: prevFileName)
}
}
}.store(in: &subscription)
}
...
}
PHPicker 띄우기
final class AddSetVC{
...
func present(){
photoService.presentPicker(vc: self,multipleSelection: false)
}
}
전체 코드
'이모저모 > UIKit' 카테고리의 다른 글
커스텀 이미지 피커 뷰 만들기 #2 (0) | 2023.12.02 |
---|---|
커스텀 이미지 피커 뷰 만들기 #1 (0) | 2023.12.02 |
UIButton State 애니메이션용 모듈 만들고 적용하기 (0) | 2023.11.25 |
CustomDiffableDataSource와 MVVM으로 Cell 데이터 관리하기 #0 (0) | 2023.11.18 |
다양한 셀을 그리는 DiffableDataSource 데이터 구성하기 #2 (0) | 2023.11.10 |
댓글