Swift Photo Library Access

后端 未结 1 974
终归单人心
终归单人心 2020-12-06 22:35

I would like to access photos from the user\'s photo library in my app and I was looking at the UIImagePickerController to do so. However, I was wondering if it is possible

相关标签:
1条回答
  • 2020-12-06 22:48

    It is not so simple but as mentioned by Rob you can save the photo asset url and later fetch it using the Photos framework. You can fetch them using PHImageManager method 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
        }
    }
    

    Note: Don't forget to edit your info plist and add "Privacy - Photo Library Usage Description"

    Sample

    0 讨论(0)
提交回复
热议问题