From 5e83aaa9a1ed4aacdd70ffdb8e043ffd2c270293 Mon Sep 17 00:00:00 2001 From: wade Date: Wed, 22 Jul 2020 02:38:46 +0900 Subject: [PATCH 1/2] 2.0.12 --- TLPhotoPicker.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TLPhotoPicker.podspec b/TLPhotoPicker.podspec index 7a186b12..f7609580 100644 --- a/TLPhotoPicker.podspec +++ b/TLPhotoPicker.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'TLPhotoPicker' - s.version = '2.0.11' + s.version = '2.0.12' s.summary = 'multiple phassets picker for iOS lib. like facebook' # This description is used to generate tags and improve search results. From 7dfcbaa1b3a05dee962ade3dedcc6d7d69259ae2 Mon Sep 17 00:00:00 2001 From: wade Date: Sun, 20 Sep 2020 16:24:36 +0900 Subject: [PATCH 2/2] iOS 14 Privacy - Prevent Limit Access --- Example/TLPhotoPicker/Info.plist | 2 + README.md | 6 ++ TLPhotoPicker/Classes/TLPhotoLibrary.swift | 11 +-- .../TLPhotosPickerViewController.swift | 88 +++++++++++++------ .../Classes/TLPhotosPickerViewController.xib | 21 +++-- 5 files changed, 91 insertions(+), 37 deletions(-) diff --git a/Example/TLPhotoPicker/Info.plist b/Example/TLPhotoPicker/Info.plist index 8ab0bd05..23ad81e6 100644 --- a/Example/TLPhotoPicker/Info.plist +++ b/Example/TLPhotoPicker/Info.plist @@ -28,6 +28,8 @@ You need Usage Microphone Description NSPhotoLibraryUsageDescription You need Usage Photo Description + PHPhotoLibraryPreventAutomaticLimitedAccessAlert + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile diff --git a/README.md b/README.md index a3e01551..10625d2d 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,11 @@ github "tilltue/TLPhotoPicker" > Don't forget the Privacy Description in `info.plist`. +> iOS 14 +> You can suppress the automatic prompting from the system by setting this key to yes in your apps info plist. +> PHPhotoLibraryPreventAutomaticLimitedAccessAlert = YES +https://developer.apple.com/videos/play/wwdc2020/10641/ + ## Usage **use delegate** @@ -293,6 +298,7 @@ public struct TLPhotosPickerConfigure { public var maxVideoDuration:TimeInterval? = nil //for camera : max video recording duration public var autoPlay = true public var muteAudio = true + public var preventAutomaticLimitedAccessAlert = true // newest iOS 14 public var mediaType: PHAssetMediaType? = nil public var numberOfColumn = 3 public var singleSelectedMode = false diff --git a/TLPhotoPicker/Classes/TLPhotoLibrary.swift b/TLPhotoPicker/Classes/TLPhotoLibrary.swift index 2153deeb..192ca1dc 100644 --- a/TLPhotoPicker/Classes/TLPhotoLibrary.swift +++ b/TLPhotoPicker/Classes/TLPhotoLibrary.swift @@ -21,6 +21,7 @@ class TLPhotoLibrary { lazy var imageManager: PHCachingImageManager = { return PHCachingImageManager() }() + internal var limitMode: Bool = false internal var assetCollections: [PHFetchResult] = [] internal var albums: PHFetchResult? = nil @@ -240,11 +241,11 @@ extension TLPhotoLibrary { DispatchQueue.global(qos: .userInteractive).async { [weak self] in var assetCollections = [TLAssetsCollection]() - //Camera Roll - let camerarollCollection = getSmartAlbum(subType: .smartAlbumUserLibrary, - useCameraButton: useCameraButton, - result: &assetCollections) - if var cameraRoll = camerarollCollection { + //Recents + let recentsCollection = getSmartAlbum(subType: .smartAlbumUserLibrary, + useCameraButton: useCameraButton, + result: &assetCollections) + if var cameraRoll = recentsCollection { cameraRoll.title = configure.customLocalizedTitle[cameraRoll.title] ?? cameraRoll.title cameraRoll.useCameraButton = useCameraButton assetCollections[0] = cameraRoll diff --git a/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift b/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift index d580a363..076c2d71 100644 --- a/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift +++ b/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift @@ -73,6 +73,7 @@ public struct TLPhotosPickerConfigure { public var maxVideoDuration:TimeInterval? = nil public var autoPlay = true public var muteAudio = true + public var preventAutomaticLimitedAccessAlert = true public var mediaType: PHAssetMediaType? = nil public var numberOfColumn = 3 public var singleSelectedMode = false @@ -144,6 +145,7 @@ open class TLPhotosPickerViewController: UIViewController { @IBOutlet open var emptyView: UIView! @IBOutlet open var emptyImageView: UIImageView! @IBOutlet open var emptyMessageLabel: UILabel! + @IBOutlet open var photosButton: UIBarButtonItem! public weak var delegate: TLPhotosPickerViewControllerDelegate? = nil public weak var logDelegate: TLPhotosPickerLogDelegate? = nil @@ -253,27 +255,49 @@ open class TLPhotosPickerViewController: UIViewController { self.stopPlay() } - func checkAuthorization() { - switch PHPhotoLibrary.authorizationStatus() { + private func loadPhotos(limitMode: Bool) { + self.photoLibrary.limitMode = limitMode + self.photoLibrary.delegate = self + self.photoLibrary.fetchCollection(configure: self.configure) + } + + private func processAuthorization(status: PHAuthorizationStatus) { + switch status { case .notDetermined: - PHPhotoLibrary.requestAuthorization { [weak self] status in - switch status { - case .authorized: - self?.initPhotoLibrary() - default: - self?.handleDeniedAlbumsAuthorization() - } - } + requestAuthorization() + case .limited: + loadPhotos(limitMode: true) case .authorized: - self.initPhotoLibrary() - case .restricted: fallthrough - case .denied: + loadPhotos(limitMode: false) + case .restricted, .denied: handleDeniedAlbumsAuthorization() @unknown default: break } } + private func requestAuthorization() { + if #available(iOS 14.0, *) { + PHPhotoLibrary.requestAuthorization(for: .readWrite) { [weak self] status in + self?.processAuthorization(status: status) + } + } else { + PHPhotoLibrary.requestAuthorization { [weak self] status in + self?.processAuthorization(status: status) + } + } + } + + private func checkAuthorization() { + if #available(iOS 14.0, *) { + let status = PHPhotoLibrary.authorizationStatus(for: .readWrite) + processAuthorization(status: status) + } else { + let status = PHPhotoLibrary.authorizationStatus() + processAuthorization(status: status) + } + } + override open func viewDidLoad() { super.viewDidLoad() makeUI() @@ -294,7 +318,7 @@ open class TLPhotosPickerViewController: UIViewController { override open func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if self.photoLibrary.delegate == nil { - initPhotoLibrary() + checkAuthorization() } } @@ -404,9 +428,18 @@ extension TLPhotosPickerViewController { self.customDataSouces?.registerSupplementView(collectionView: self.collectionView) } + private func updatePresentLimitedLibraryButton() { + if #available(iOS 14.0, *), self.photoLibrary.limitMode && self.configure.preventAutomaticLimitedAccessAlert { + self.customNavItem.rightBarButtonItems = [self.doneButton, self.photosButton] + } else { + self.customNavItem.rightBarButtonItems = [self.doneButton] + } + } + private func updateTitle() { guard self.focusedCollection != nil else { return } self.titleLabel.text = self.focusedCollection?.title + updatePresentLimitedLibraryButton() } private func reloadCollectionView() { @@ -438,15 +471,6 @@ extension TLPhotosPickerViewController { self.albumPopView.setupPopupFrame() } - private func initPhotoLibrary() { - if PHPhotoLibrary.authorizationStatus() == .authorized { - self.photoLibrary.delegate = self - self.photoLibrary.fetchCollection(configure: self.configure) - }else{ - //self.dismiss(animated: true, completion: nil) - } - } - private func registerChangeObserver() { PHPhotoLibrary.shared().register(self) } @@ -503,6 +527,12 @@ extension TLPhotosPickerViewController { self.dismiss(done: true) } + @IBAction open func limitButtonTap() { + if #available(iOS 14.0, *) { + PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: self) + } + } + private func dismiss(done: Bool) { var shouldDismiss = true if done { @@ -620,13 +650,17 @@ extension TLPhotosPickerViewController: UIImagePickerControllerDelegate, UINavig } private func handleDeniedAlbumsAuthorization() { - self.delegate?.handleNoAlbumPermissions(picker: self) - self.handleNoAlbumPermissions?(self) + DispatchQueue.main.async { + self.delegate?.handleNoAlbumPermissions(picker: self) + self.handleNoAlbumPermissions?(self) + } } private func handleDeniedCameraAuthorization() { - self.delegate?.handleNoCameraPermissions(picker: self) - self.handleNoCameraPermissions?(self) + DispatchQueue.main.async { + self.delegate?.handleNoCameraPermissions(picker: self) + self.handleNoCameraPermissions?(self) + } } open func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { diff --git a/TLPhotoPicker/Classes/TLPhotosPickerViewController.xib b/TLPhotoPicker/Classes/TLPhotosPickerViewController.xib index 7e8ad0d5..57572f9a 100644 --- a/TLPhotoPicker/Classes/TLPhotosPickerViewController.xib +++ b/TLPhotoPicker/Classes/TLPhotosPickerViewController.xib @@ -1,9 +1,10 @@ - + - + + @@ -21,6 +22,7 @@ + @@ -30,6 +32,12 @@ + + + + + + @@ -46,7 +54,7 @@ - + @@ -123,7 +131,7 @@ + @@ -212,8 +221,10 @@ - + + +