PhotoKit
https://developer.apple.com/documentation/photokit
사용자가 앱이 접근할 수 있는 사진을 지정할 수 있게 되는 것이 포인트다
-> limited photo library라고 부른다
import PhotoKit
이렇게 해보려고 했더니 모듈이 없다고 나온다^^
UIKit는 되잖아요ㅠㅠ
프레임워크로 아래와 같은 것을 포함하고 있으니
- Photos
- PhotosUI
import Photos
이렇게 import 해줬다
Delivering an Enhanced Privacy Experience in Your Photos App
💡 iOS 14에서 PhotoKit을 사용하면 limited
Photos library는 모든 앱에 영향을 끼친다. 잘 작동하는지 확인해봐야 한다.
Determine Your App’s Access Needs
iOS14에서 Photos library에 read-only 목적으로 접근한다면 PHPickerViewController
를 사용하면 UX를 강화할 수 있다.
Session 10652: Meet the New Photos Picker
https://developer.apple.com/videos/play/wwdc2020/10652/
Describe Your Appʼs Photo Library Use
Info.plist파일에
앱에서 라이브러리를 추가만 하려면 NSPhotoLibraryAddUsageDescription를 추가해주고
read/write 하려면
NSPhotoLibraryUsageDescription를 추가해준다
Privacy - Photo Library Usage Description
Determine and Request Authorization
PHPhotoLibrary
를 사용해 사용자가 승인한 권한의 종류를 알 수 있다
// 앱 권한 상태 체크 (either read/write or add-only access).
let readWriteStatus = PHPhotoLibrary.authorizationStatus(for: .readWrite)
시스템에서 앱이 실행되면 자동으로 권한을 비동기적으로 물어보는데
plist에서 그렇지 않게 설정을 한 뒤
사용자의 액션에 따라서 권한을 요구하도록 할 수도 있다
Prevent limited photos access alert
1
// Request read-write access to the user's photo library.
PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in
switch status {
case .notDetermined:
// The user hasn't determined this app's access.
case .restricted:
// The system restricted this app's access.
case .denied:
// The user explicitly denied this app's access.
case .authorized:
// The user authorized this app to access Photos data.
case .limited:
// The user authorized this app for limited Photos access.
@unknown default:
fatalError()
}
}
💡 limited access only라면
authorizationStatus()
과 requestAuthorization(_:)
은 비교가 불가능하고(옛날에 만들어진 것이기도 하고, limited가 아직 없기 때문이다) PHAuthorizationStatus.authorized
를 리턴한다.
authorizationStatus(for:)
과 requestAuthorization(for:handler:)
를 사용해야한다.
💡 무슨 말이냐면 💡
PHPhotoLibrary.requestAuthorization(for: .readWrite)에서
addOnly나 readWrite를 사용할 수 있는데
기본적으로 사용자가 선택한 사진만을 추가할 수 있다는 것이 공통으로 깔려있다.
addOnly가 되면 앱이 사용자가 선택한 사진만 추가할 수 있다는 것이고,
readWrite가 되면 앱이 사용자가 선택한 사진을 사용할 수 있거나(limited) 모든 사진을 사용할 수 있게 되는거다(authorized)
Work with the Limited Library
iOS14가 되면서 사진을 선택적으로 공유를 할 수 있게 되었다
PHAuthorizationStatus.limited
상태라면 시스템은 PHAssetCreationRequest
로 에셋을 자동으로 추가한다
앨범을 생성하거나 가져오려면 PHAuthorizationStatus.limited
를 다른 상태로 바꿔야 한다.
Present the Limited-Library Selection Interface
권한 물어보는 피커 띄우기
// Present the limited-library selection user interface.
let viewController = // The UIViewController from which to present the picker.
PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: viewController)
iOS15부터는 limited권한을 사용 중인 사용자 행동을 observing하다가 권한을 콜백으로 실행시킬 수 있게 될거다
// Present the limited-library selection user interface with a callback.
let viewController = // The UIViewController from which to present the picker.
PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: viewController) { identifiers in
for newlySelectedAssetIdentifier in identifiers {
// Stage asset for app interaction.
}
}
PHPickerViewController
UIImagePickerController
가 PHPickerViewController
가 되었다!
Cannot inherit from non-open class 'PHPickerViewController' outside of its defining module
cocoa touch class를 사용해 ViewController 만들 듯이 만들었는데
오류가 난다
안쪽에 만들어서 사용하는건가부당🥲
💡 You can’t subclass PHPickerViewController because its view hierarchy is private and not accessible through the public API.
PHPickerViewController
를 subclass할 수 없습니다. 왜냐하면 뷰 계층이 private이거든요🥲
class PHPickerViewController : UIViewController
뷰컨트롤러를 상속받았구나
PhotosUI프레임워크 안에 들어있기 때문에 import 해줘야한다
PHPicker
필요한 경우
뭔가 사용자의 접근 권한이 없을 때 선택적으로 선택하게 만들어서 사진을 관리하는건감
아래는 예시코드
import UIKit
import PhotosUI
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
//라이브러리에서 가져온 사진 저장할 공간
var itemProviders: [NSItemProvider] = []
var iterator: IndexingIterator<[NSItemProvider]>?
override func viewDidLoad() {
super.viewDidLoad()
var configuration = PHPickerConfiguration()
configuration.selectionLimit = 0
configuration.filter = .images
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
present(picker, animated: true)
}
func displayNextImage() {
if let itemProvider = iterator?.next(), itemProvider.canLoadObject(ofClass: UIImage.self) {
let previousImage = imageView.image
itemProvider.loadObject(ofClass: UIImage.self) { [weak self] image, error in
DispatchQueue.main.async {
guard let self = self, let image = image as? UIImage, self.imageView.image == previousImage else { return }
self.imageView.image = image
}
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
displayNextImage()
}
}
extension ViewController: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true)
if let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self) {
itemProvider.loadObject(ofClass: UIImage.self) { image, error in
self.itemProviders = results.map(\.itemProvider)
self.iterator = self.itemProviders.makeIterator()
self.displayNextImage()
}
}
}
}
PhotoKit
let photoLibrary = PHPhotoLibrary.shared()
let configuration = PHPickerConfiguration(photoLibrary: photoLibrary)
let identifiers: [String] = results.compactMap(\.itemProvider)
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: identifiers, options: nil)
PhotoKit와 PHPickerViewController
를 사용하자
AssetLibrary는 deprecated되었고
UIImagePickerController는 deprecated되고 있당
🍎 사용자가 사진을 사용할때까지 권한을 요구하지 마라!!! 이게 핵심이다
Author And Source
이 문제에 관하여(PhotoKit), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@msi753/PHPicker저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)