我想从我的应用程序中的用户照片库访问照片,而我正在查看UIImagePickerController。但是,我想知道是否可以在不将照片实际存储在应用程序中的情况下访问和查看照片库中的照片?因此,基本上,该应用将存储对所选照片的引用,而不是存储照片本身。这是为了防止该应用占用大量空间来存储每张照片。
谢谢!
它不是那么简单,但是正如Rob所提到的,您可以保存照片资产url,然后使用Photos框架来获取它。您可以使用PHImageManager方法requestImageData获取它们。
import UIKit import Photos class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate { @IBOutlet weak var imageView: UIImageView! let galleryPicker = UIImagePickerController() // create a method to fetch your photo asset and return an UIImage on completion override func viewDidLoad() { super.viewDidLoad() // lets add a selector to when the user taps the image imageView.isUserInteractionEnabled = true imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(openPicker))) // request authorization switch PHPhotoLibrary.authorizationStatus() { case .authorized: print("The user has explicitly granted your app access to the photo library.") return case .denied: print("The user has explicitly denied your app access to the photo library.") case .notDetermined: PHPhotoLibrary.requestAuthorization { status in print("status", status) } case .restricted: print("Your app is not authorized to access the photo library, and the user cannot grant such permission.") default: break } } // opens the image picker for photo library @objc func openPicker(_ gesture: UITapGestureRecognizer) { galleryPicker.sourceType = .photoLibrary galleryPicker.delegate = self present(galleryPicker, animated: true) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) self.imageView.contentMode = .scaleAspectFit // check if there is an url saved in the user defaults // and fetch its first object (PHAsset) if let assetURL = UserDefaults.standard.url(forKey: "assetURL") { if let asset = PHAsset.fetchAssets(withALAssetURLs: [assetURL], options: nil).firstObject { asset.asyncImageData { data, _, _, _ in print("fetched") guard let data = data else { return } self.imageView.image = UIImage(data: data) } } else { print("assetURL:", assetURL) self.imageView.image = UIImage(contentsOfFile: assetURL.path) } } else { print("no assetURL found") } } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { dismiss(animated: true) print("canceled") } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { self.imageView.image = info[.originalImage] as? UIImage if let phAsset = info[.phAsset] as? PHAsset { phAsset.asyncURL { url in guard let url = url else { return } UserDefaults.standard.set(url, forKey: "assetURL") print("assetURL saved") } } dismiss(animated: true) } }
extension PHAsset { func asyncURL(_ completion: @escaping ((URL?) -> Void)) { switch mediaType { case .image: let options: PHContentEditingInputRequestOptions = .init() options.canHandleAdjustmentData = { _ in true } requestContentEditingInput(with: options) { editingInput, _ in completion(editingInput?.fullSizeImageURL) } case .video: let options: PHVideoRequestOptions = .init() options.version = .original PHImageManager.default() .requestAVAsset(forVideo: self, options: options) { asset, _, _ in completion((asset as? AVURLAsset)?.url) } default: completion(nil) } } func asyncImageData(version: PHImageRequestOptionsVersion = .original, completion: @escaping (Data?, String?, UIImage.Orientation, [AnyHashable : Any]?) -> ()) { let options = PHImageRequestOptions() options.version = version PHImageManager.default() .requestImageData(for: self, options: options, resultHandler: completion) } } extension URL { var phAsset: PHAsset? { PHAsset.fetchAssets(withALAssetURLs: [self], options: nil).firstObject } }
注意:不要忘记编辑您的信息列表并添加“隐私-照片库使用说明”
样品