jamesmontemagno / MediaPlugin

Take & Pick Photos and Video Plugin for Xamarin and Windows
MIT License
712 stars 358 forks source link

[iOS] Limited Photos library access support for iOS 14 #890

Open AlexeyOvchynnikov opened 4 years ago

AlexeyOvchynnikov commented 4 years ago

Apple presented a new API for interaction with photos. PHPickerViewController is a new system photo picker, a replacement for the old UIImagePickerController.

The new API has backward compatibility, the old version gets authorized access even when a user provides limited access. But the user will see a system image picker that has no effect in access limitation.

Useful links: https://developer.apple.com/videos/play/wwdc2020/10641/ https://mackuba.eu/2020/07/07/photo-library-changes-ios-14/

Kingamattack commented 4 years ago

@AlexeyOvchynnikov do you have a workaround while the package is not updated? Cause on my side when i choose "limited access" there is no thumbnail for pictures but i can still select them

jmeyerworms commented 4 years ago

does MediaPlugin support IOS 14 ?

simonemarra commented 4 years ago

does MediaPlugin support IOS 14 ?

In my tests iOS14 is supported correctly, but pics will always be accessible by app, even if user choose the limited access. The great part is backward compatibility (at least at the moment), the bad part is user will select only some pics but app will access all anyway.

brentpbc commented 4 years ago

I have the same issue as @Kingamattack In IOS 14, when you are prompted by iOS to access the photo library for the first time if you select "Select Photos" the thumbnail images of the photos you have selected are not shown. You can still select the invisible images and they do seem to load fine. But the bigger issue is there is no other way to select more photos again unless you quit and reopen the app. Lastly you are unable to allow full access to the photo library ever again unless you delete the app if you previously selected "Select Photos" instead of "Allow full Access". See screenshot below for selected photo picker issue:

Image from iOS (90)

bradlak commented 4 years ago

I have the same problem. Selecting multiple photos is our main feature in application so it's urgent for me.

WorldOfBasti commented 3 years ago

For all those, who can't wait for an update, I found a workaround, I followed this tutorial from apple. I created an interface with a GetImage/GetImages Method. Then I added this code snippet to the iOS implementation:

    public class MediaPickerService : IMediaPickerService
    {
        void IMediaPickerService.GetImagesAsync()
        {
            var config = new PHPickerConfiguration();
            config.SelectionLimit = 0;
            config.Filter = PHPickerFilter.ImagesFilter;

            UIWindow window = UIApplication.SharedApplication.KeyWindow;
            var viewController = window.RootViewController;

            var picker = new PHPickerViewController(config);
            picker.Delegate = new PickerDelegate();
            viewController.PresentModalViewController(picker, true);
    }

    public class PickerDelegate : PHPickerViewControllerDelegate
    {
        public override void DidFinishPicking(PHPickerViewController picker, PHPickerResult[] results)
        {
            picker.DismissModalViewController(true);

            //Handle the selected images
        }
    }
hongyangsong commented 3 years ago

Exactly the same issue here. need a fix and it is urgent. Thanks

WorldOfBasti commented 3 years ago

For all those, who need an urgent fix: I implemented it for myself (as I said above) and it doesn't need this plugin. Here is the sample: TestApp - ImagePicker.zip

And here is a little video showing this Picker: https://youtu.be/Jv6v3Kjk0F0

For all those, who need a multiple image selection: iOS: You can easily set the limit with config.SelectionLimit = 0;. Then you only have to return more images and update the DidFinishPicking Method. Android: For Android you can use this tutorial.

Maybe I can help someone. Regards

jensbrobak commented 3 years ago

For all those, who need an urgent fix: I implemented it for myself (as I said above) and it doesn't need this plugin. Here is the sample: TestApp - ImagePicker.zip

And here is a little video showing this Picker: https://youtu.be/Jv6v3Kjk0F0

For all those, who need a multiple image selection: iOS: You can easily set the limit with config.SelectionLimit = 0;. Then you only have to return more images and update the DidFinishPicking Method. Android: For Android you can use this tutorial.

Maybe I can help someone. Regards

I implemented your solution for iOS (thanks btw!) but I also needed the possibility to also handle multi selection of images etc., so I struggled quite a bit to get in to work - mostly with race conditions.., but I got it sorted - so if anyone are experiencing the same issues as me, here is a code snippet:

                    var yourCollection = new System.Collections.Generic.List<Stream>();

                    foreach (var result in results)
                    {
                        var taskCompletionSource = new TaskCompletionSource<Stream>();

                        //Convert PHPickerResult to Stream
                        result.ItemProvider.LoadFileRepresentation(UTType.Image, (item, error) =>
                        {
                            if (error != null || item == null) return;

                            NSData data = NSData.FromUrl(item);
                            Stream stream = data.AsStream();

                            //Set Result
                            taskCompletionSource.SetResult(stream);
                        });

                        yourCollection.Add(taskCompletionSource.Task.Result);
                    }

                    yourCollectionTaskCompletionSource.SetResult(yourCollection);
MatthewKapteyn commented 3 years ago

I'm writing an updated MediaImplementation function to use PHPicker. Many thanks to the wonderful code snippets added here.

https://github.com/MatthewKapteyn/MediaPlugin/blob/5fcfb0080d0721e05a6b4d5dd7d03cdc26fd1abd/src/Media.Plugin/iOS/MediaPickerService.cs#L71

I've got a few questions and figured i'd throw them out here.

  1. Has anyone had success copying the tmp NSUrl directly without killing memory. Ideally i'd like to just read it with NSFileManager and copy it over to app storage. Instead I feel like i'm wasting a ton of memory loading into NSData first.

  2. Has anyone tried running this on earlier version of iOS? How 'backwards compatible' is the PHPicker?

p.s. might just be an oddity in my debug environment - but if I try limiting access to only a few photos, the PHPicker still lets me access everything? Watched the developer vid and at the 12min mark it's mentioned this is intentional? Why then lol. Answering my own question again, but apparently PHPicker is given carte-blanche because it's a read-only type control. Can't modify the original images. Totally not confusing for the end-user who might think this feature prevents access to private photos.

jensbrobak commented 3 years ago

I'm writing an updated MediaImplementation function to use PHPicker. Many thanks to the wonderful code snippets added here.

https://github.com/MatthewKapteyn/MediaPlugin/blob/5fcfb0080d0721e05a6b4d5dd7d03cdc26fd1abd/src/Media.Plugin/iOS/MediaPickerService.cs#L71

I've got a few questions and figured i'd throw them out here.

  1. Has anyone had success copying the tmp NSUrl directly without killing memory. Ideally i'd like to just read it with NSFileManager and copy it over to app storage. Instead I feel like i'm wasting a ton of memory loading into NSData first.
  2. Has anyone tried running this on earlier version of iOS? How 'backwards compatible' is the PHPicker?

~p.s. might just be an oddity in my debug environment - but if I try limiting access to only a few photos, the PHPicker still lets me access everything?~ ~Watched the developer vid and at the 12min mark it's mentioned this is intentional? Why then lol.~ Answering my own question again, but apparently PHPicker is given carte-blanche because it's a read-only type control. Can't modify the original images. Totally not confusing for the end-user who might think this feature prevents access to private photos.

To answer your second question - I only managed to get this to work on iOS14, when running on a earlier version of iOS it complains about missing a library etc.

MatthewKapteyn commented 3 years ago

@jensbrobak thanks for the reply! I'll need to wall off PHPicker to iOS 14 then. The ELC controller lives to see another decade lol.

MatthewKapteyn commented 3 years ago

I'll also answer my 1st question here. Turns out the destination directory that gets generated needs 'file:///' prepended to it. Oops.

https://github.com/MatthewKapteyn/MediaPlugin/commit/607580a8811b59eaa5a5ae6be9ccd76d9e1c0701

lazmeister commented 3 years ago

I'm writing an updated MediaImplementation function to use PHPicker. Many thanks to the wonderful code snippets added here. https://github.com/MatthewKapteyn/MediaPlugin/blob/5fcfb0080d0721e05a6b4d5dd7d03cdc26fd1abd/src/Media.Plugin/iOS/MediaPickerService.cs#L71 I've got a few questions and figured i'd throw them out here.

  1. Has anyone had success copying the tmp NSUrl directly without killing memory. Ideally i'd like to just read it with NSFileManager and copy it over to app storage. Instead I feel like i'm wasting a ton of memory loading into NSData first.
  2. Has anyone tried running this on earlier version of iOS? How 'backwards compatible' is the PHPicker?

~p.s. might just be an oddity in my debug environment - but if I try limiting access to only a few photos, the PHPicker still lets me access everything?~ ~Watched the developer vid and at the 12min mark it's mentioned this is intentional? Why then lol.~ Answering my own question again, but apparently PHPicker is given carte-blanche because it's a read-only type control. Can't modify the original images. Totally not confusing for the end-user who might think this feature prevents access to private photos.

To answer your second question - I only managed to get this to work on iOS14, when running on a earlier version of iOS it complains about missing a library etc.

I ran into the same issue on CrossMedia if I remember correctly. I was aware the PHPicker is backwards compatible