terikon / cordova-plugin-photo-library

Maintainer needed. Please contact if you're using this library in your project
MIT License
149 stars 295 forks source link

iOS: Only request permission when necessary #8

Closed Menardi closed 7 years ago

Menardi commented 7 years ago

With this plugin, my app immediately requests access to Photos. The photos a user will save typically won't come up until they've used the app a bit more, so I'd rather only request the permission when they first try to save an image from the app.

I've looked through the code, but am not too familiar with Swift or iOS development, so I'm not sure what exactly triggers this first prompt - there don't appear to be any calls to requestAuthorization. I'm guessing that the instantiation of PHCachingImageManager or something like that automatically causes the system to bring up the prompt?

I'm happy to work on a PR for this, but am at a bit of a loss as to where to begin! Any guidance would be great. Thanks!

viskin commented 7 years ago

Do you have this issue on iOS only, or also on Android?

endoplasmic commented 7 years ago

You could always just use this permissions plugin if you are stuck on time: https://github.com/NeoLSN/cordova-plugin-android-permission

viskin commented 7 years ago

I could not reproduce this on iOS and Android. The plugin in my app never asks for permission by itself. Call to plugin just fails with error when no permission granted. As I catch the error, I show a dialog to user about the need to authorize access. The dialog calls requestAuthorization method, which opens app setting on iOS or shows system permission dialog on Android. There should be no request for permission when an app starts. Can it be other plugin that causes such an behavior in your case?

Menardi commented 7 years ago

I am only seeing this behaviour on iOS, not on Android.

I have looked into it a bit more, and have found that it only happens when cordova-plugin-file is installed. Interestingly, removing either cordova-plugin-file OR cordova-plugin-photo-library causes the prompt not to happen on start up.

In addition, I've found that PhotoLibraryService.requestAuthorization is not what is bringing up this prompt. I added a print statement to it and it wasn't logged on startup.

Funnily, I'm only using cordova-plugin-file so I can use this plugin! I need it to get the app's file:// url so I can save images from the www/ folder to Photos.

viskin commented 7 years ago

Weird. I use both cordova-plugin-file and cordova-plugin-photo-library, and there's no prompt on start up. What versions do you use

Menardi commented 7 years ago

I managed to reproduce this with just these plugins: cordova-plugin-add-swift-support 1.6.0 "AddSwiftSupport" cordova-plugin-photo-library 1.1.6 "Photo Library" cordova-plugin-file 4.3.0 "File"

I'm building with cordova@6.4.0 and cordova-ios@4.2.1. As far as I know, these are the most recent versions of everything as most were added this week.

One thing I am unsure about is, does the app explicitly have to show this dialog, or are there some calls that would automatically trigger it? I'm wondering where I should be looking for the possible cause of this dialog.

viskin commented 7 years ago

It would be great if you will isolate the problem to empty cordova project, that just opens permission prompt on start. Then please send me one on mail, and I'll have a look. Are we talking about iOS10 device? What device?

Menardi commented 7 years ago

It happens on both an iPod Touch running iOS 9 and iPad Pro running iOS 10.

I have reproduced it in a blank project:

If you cannot reproduce this way, I'll zip up that project and email it to the address on your profile.

viskin commented 7 years ago

Yep this reproduces the bug. I'll try to debug it...

viskin commented 7 years ago

You were right, it seems touching PHCachingImageManager at init caused prompt to appear. Please try 1.1.7. I postpone initialization of PhotoLibraryService from plugin load to first api call.

Menardi commented 7 years ago

Thanks for such a quick fix! This does indeed stop the permission prompt from appearing on startup.

However, now that the permission prompt happens when I call saveImage, I have somewhat unusual behaviour. On first calling saveImage, the permission prompt shows as expected. This immediately causes the error handler to be fired, where my JS sees that the user has not yet given permission. However, once they do give permission, the success handler is then fired. So, my app ends up in a bit of an unusual state, as one call caused both failure and success!

I tried wrapping the call in requestAuthorization, but it doesn't work quite as expected. Even if the user has already granted permission, it will take them to the permissions screen. I was expecting it to immediately call the success callback if it had already been granted. What do you think?

viskin commented 7 years ago

Hmmm, I will try to reproduce this tomorrow. It's more intuitive to not get either handler called until the user responses to the prompt.

Nuajan commented 7 years ago

I can also confirm this behaviour, been prompted for permission on app start, using file plugin as well, only on IOS, tested on an iPhone 6 10.1.1 I would be nice to be asked only when required but it think is not a critical thing.

viskin commented 7 years ago

I don't like current behavior when on iOS when prompt appears by itselft on API call, say on save. I think it will be a good approach to add a check for PHPhotoLibrary.authorizationStatus() on each API call, and if set to notDetermined, to throw Permission error. Then user will call to requestAuthorization, which will display an alert. I will add this ASAP.

viskin commented 7 years ago

Well, 1.1.10 now handles iOS permission with much more care. API call and requestAuthorization behave intuitively if permission not granted. API calls return Permission error, and requestAuthorization opens permission prompt (on first attempt) or redirects to app settings page (on subsequent calls).

Menardi commented 7 years ago

That sounds like the right behaviour. Thanks for being so responsive and fixing it so quickly. Definitely the best experience I've had reporting an issue on Github!

viskin commented 7 years ago

Thank you, it's good to hear.