I have some confusion about permission with using PHPickerViewController & UIImagePickerController.
Do I have to request permission for using it ? (Currently, I open it without request permission but It's working.)
Is it acceptable for upload to app store ? and if it acceptable when I have to request permission for photo?
Ps.
I use PHPickerViewController for iOS14+ and UIImagePickerController for <iOS13.
Thank you for every reply or answer.
First you need to know is, according to Apple's docs
The PHPickerViewController class is an alternative to UIImagePickerController. PHPickerViewController improves stability and reliability, and includes several benefits to developers and users
So both PHPickerViewController and UIImagePickerController are just the same with new upgrade.
As default, it runs in a separate process and on read-only access you don't need any special permissions for that.
And of course if you need some advance features, like retrieving assets and collections, or updating the library from your apps you must have permission for it.
You can read more from this link for permission to access some feature if need.
PHPicker provides a better privacy and does not require to ask for user consent so it can be used. Even though an app can trigger its presentation, the picker runs in a separate process where users can select only type of media necessary for their tasks, and do nothing beyond that; not even to get a snapshot of the picker. So, with PHPicker, simply forget about usage descriptions and rely on the built-in iOS privacy.
And if you want to explicitly allow user to select limited photos then you can implement it using the same.
Yes there is no problem to upload it to the app store.
Related
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: { })
}
Even if I set access to Photos in Settings to "Never" with above code I can still present image picker and show photos. I'll check for PHPhotoLibrary.authorizationStatus() before showing it, but I would like to know is this expected behaviour?
Okay, you can sort of piece this together from answers and comments already, but to try to tell a more complete story...
In iOS 11, UIImagePickerController runs as a separate process from your app. That means:
Your app can't see the user's whole Photos library — it gets read-only access just for whichever asset(s) the user chooses in the image picker.
Because of (1), your app doesn't need the standard privacy authorization for Photos library access. The user explicitly chooses a specific asset (or multiple) for use in your app, which means the user is granting your app permission to read the asset(s) in question.
You can see more about this in the WWDC17 talk on PhotoKit.
(By the way, this model matches what you've seen in the Contacts framework since iOS 9; if you show contact picker, your app only gets a one-time drop of contact information for the contact(s) the user picked, not ongoing read/write access to the Contacts database, so the contact picker doesn't require special privacy permission.)
PHPhotoLibrary and its authorization status reflect the global read/write permission for Photos access that users can control from Settings > Privacy. (That's the one where your Info.plist needs NSPhotoLibraryUsageDescription.) Any use of the PHPhotoLibrary API requires this permission, regardless of whether your app's use of that API is only for writing or only for reading. This has been true since PhotoKit was introduced in iOS 8.
If you're not using PHPhotoLibrary, PHAsset, etc, there are narrower permission options that are new in iOS 11 (and not part of the Photos.framework API):
As noted above, UIImagePickerController doesn't need blanket Privacy Settings permission because each use grants one-time read access for the specific assets chosen.
If you need only to add new assets to the Photos library, use UIImageWriteToSavedPhotosAlbum or UISaveVideoAtPathToSavedPhotosAlbum. With those you can put NSPhotoLibraryAddUsageDescription in your Info.plist — then the system's Privacy Settings will make clear to the user that they're not giving your permission to see or modify existing assets, only to add new ones.
If the user grants add-only permission, it applies only to those UIKit functions — attempting to use PHPhotoLibrary will still prompt for (and require the Info.plist key for) read/write access.
See this part of the WWDC17 talk for more on the add-only privacy setting.
Is this expected behaviour? - YES.
From the docs - https://developer.apple.com/documentation/uikit/uiimagepickercontroller/1619144-issourcetypeavailable
true if the device supports the specified source type; false if the specified source type is not available.
It tells you if the device supports the source type and not if the app has the permission to access it.
As you already mentioned in the question, PHPhotoLibrary.authorizationStatus() would be correct way to check this.
This (new) behaviour does sound logical to me, here's why. When using UIImagePickerController your app doesn't actually get access to any photos. It only sees the one your user has picked, when that happens; and if the user taps Cancel in the picker none of those become available to the app.
PHPhotoLibrary is part of a separate framework, Photos, where you can do a lot of stuff with the user's photo library, and therefore need permission.
So if you are only using UIImagePickerController I'd suggest not mixing Photos stuff in.
Disclaimer: haven't heard of any official statement from Apple folks. This forum thread looks relevant, maybe we get a reply there. UPD: there it is, same idea.
Also, if you're evil enough you can theoretically fiddle with UIImagePickerController view hierarchy at runtime and examine whatever the user sees there. But that's again for Apple to deal with, we should just be nice :-)
UIImagePickerController and PHPhotoLibrary responsible for different areas.
You should check both: auth status and source availability.
PHAuthorizationStatus
Information about your app’s authorization to access the user’s Photos
library.
isSourceTypeAvailable
Discussion
Because a media source may not be present or may be unavailable,
devices may not always support all source types.
For example, if you
attempt to pick an image from the user’s library and the library is
empty, this method returns false. Similarly, if the camera is already
in use, this method returns false.
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: { })
}
Even if I set access to Photos in Settings to "Never" with above code I can still present image picker and show photos. I'll check for PHPhotoLibrary.authorizationStatus() before showing it, but I would like to know is this expected behaviour?
Okay, you can sort of piece this together from answers and comments already, but to try to tell a more complete story...
In iOS 11, UIImagePickerController runs as a separate process from your app. That means:
Your app can't see the user's whole Photos library — it gets read-only access just for whichever asset(s) the user chooses in the image picker.
Because of (1), your app doesn't need the standard privacy authorization for Photos library access. The user explicitly chooses a specific asset (or multiple) for use in your app, which means the user is granting your app permission to read the asset(s) in question.
You can see more about this in the WWDC17 talk on PhotoKit.
(By the way, this model matches what you've seen in the Contacts framework since iOS 9; if you show contact picker, your app only gets a one-time drop of contact information for the contact(s) the user picked, not ongoing read/write access to the Contacts database, so the contact picker doesn't require special privacy permission.)
PHPhotoLibrary and its authorization status reflect the global read/write permission for Photos access that users can control from Settings > Privacy. (That's the one where your Info.plist needs NSPhotoLibraryUsageDescription.) Any use of the PHPhotoLibrary API requires this permission, regardless of whether your app's use of that API is only for writing or only for reading. This has been true since PhotoKit was introduced in iOS 8.
If you're not using PHPhotoLibrary, PHAsset, etc, there are narrower permission options that are new in iOS 11 (and not part of the Photos.framework API):
As noted above, UIImagePickerController doesn't need blanket Privacy Settings permission because each use grants one-time read access for the specific assets chosen.
If you need only to add new assets to the Photos library, use UIImageWriteToSavedPhotosAlbum or UISaveVideoAtPathToSavedPhotosAlbum. With those you can put NSPhotoLibraryAddUsageDescription in your Info.plist — then the system's Privacy Settings will make clear to the user that they're not giving your permission to see or modify existing assets, only to add new ones.
If the user grants add-only permission, it applies only to those UIKit functions — attempting to use PHPhotoLibrary will still prompt for (and require the Info.plist key for) read/write access.
See this part of the WWDC17 talk for more on the add-only privacy setting.
Is this expected behaviour? - YES.
From the docs - https://developer.apple.com/documentation/uikit/uiimagepickercontroller/1619144-issourcetypeavailable
true if the device supports the specified source type; false if the specified source type is not available.
It tells you if the device supports the source type and not if the app has the permission to access it.
As you already mentioned in the question, PHPhotoLibrary.authorizationStatus() would be correct way to check this.
This (new) behaviour does sound logical to me, here's why. When using UIImagePickerController your app doesn't actually get access to any photos. It only sees the one your user has picked, when that happens; and if the user taps Cancel in the picker none of those become available to the app.
PHPhotoLibrary is part of a separate framework, Photos, where you can do a lot of stuff with the user's photo library, and therefore need permission.
So if you are only using UIImagePickerController I'd suggest not mixing Photos stuff in.
Disclaimer: haven't heard of any official statement from Apple folks. This forum thread looks relevant, maybe we get a reply there. UPD: there it is, same idea.
Also, if you're evil enough you can theoretically fiddle with UIImagePickerController view hierarchy at runtime and examine whatever the user sees there. But that's again for Apple to deal with, we should just be nice :-)
UIImagePickerController and PHPhotoLibrary responsible for different areas.
You should check both: auth status and source availability.
PHAuthorizationStatus
Information about your app’s authorization to access the user’s Photos
library.
isSourceTypeAvailable
Discussion
Because a media source may not be present or may be unavailable,
devices may not always support all source types.
For example, if you
attempt to pick an image from the user’s library and the library is
empty, this method returns false. Similarly, if the camera is already
in use, this method returns false.
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.sourceType = .photoLibrary
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: { })
}
Even if I set access to Photos in Settings to "Never" with above code I can still present image picker and show photos. I'll check for PHPhotoLibrary.authorizationStatus() before showing it, but I would like to know is this expected behaviour?
Okay, you can sort of piece this together from answers and comments already, but to try to tell a more complete story...
In iOS 11, UIImagePickerController runs as a separate process from your app. That means:
Your app can't see the user's whole Photos library — it gets read-only access just for whichever asset(s) the user chooses in the image picker.
Because of (1), your app doesn't need the standard privacy authorization for Photos library access. The user explicitly chooses a specific asset (or multiple) for use in your app, which means the user is granting your app permission to read the asset(s) in question.
You can see more about this in the WWDC17 talk on PhotoKit.
(By the way, this model matches what you've seen in the Contacts framework since iOS 9; if you show contact picker, your app only gets a one-time drop of contact information for the contact(s) the user picked, not ongoing read/write access to the Contacts database, so the contact picker doesn't require special privacy permission.)
PHPhotoLibrary and its authorization status reflect the global read/write permission for Photos access that users can control from Settings > Privacy. (That's the one where your Info.plist needs NSPhotoLibraryUsageDescription.) Any use of the PHPhotoLibrary API requires this permission, regardless of whether your app's use of that API is only for writing or only for reading. This has been true since PhotoKit was introduced in iOS 8.
If you're not using PHPhotoLibrary, PHAsset, etc, there are narrower permission options that are new in iOS 11 (and not part of the Photos.framework API):
As noted above, UIImagePickerController doesn't need blanket Privacy Settings permission because each use grants one-time read access for the specific assets chosen.
If you need only to add new assets to the Photos library, use UIImageWriteToSavedPhotosAlbum or UISaveVideoAtPathToSavedPhotosAlbum. With those you can put NSPhotoLibraryAddUsageDescription in your Info.plist — then the system's Privacy Settings will make clear to the user that they're not giving your permission to see or modify existing assets, only to add new ones.
If the user grants add-only permission, it applies only to those UIKit functions — attempting to use PHPhotoLibrary will still prompt for (and require the Info.plist key for) read/write access.
See this part of the WWDC17 talk for more on the add-only privacy setting.
Is this expected behaviour? - YES.
From the docs - https://developer.apple.com/documentation/uikit/uiimagepickercontroller/1619144-issourcetypeavailable
true if the device supports the specified source type; false if the specified source type is not available.
It tells you if the device supports the source type and not if the app has the permission to access it.
As you already mentioned in the question, PHPhotoLibrary.authorizationStatus() would be correct way to check this.
This (new) behaviour does sound logical to me, here's why. When using UIImagePickerController your app doesn't actually get access to any photos. It only sees the one your user has picked, when that happens; and if the user taps Cancel in the picker none of those become available to the app.
PHPhotoLibrary is part of a separate framework, Photos, where you can do a lot of stuff with the user's photo library, and therefore need permission.
So if you are only using UIImagePickerController I'd suggest not mixing Photos stuff in.
Disclaimer: haven't heard of any official statement from Apple folks. This forum thread looks relevant, maybe we get a reply there. UPD: there it is, same idea.
Also, if you're evil enough you can theoretically fiddle with UIImagePickerController view hierarchy at runtime and examine whatever the user sees there. But that's again for Apple to deal with, we should just be nice :-)
UIImagePickerController and PHPhotoLibrary responsible for different areas.
You should check both: auth status and source availability.
PHAuthorizationStatus
Information about your app’s authorization to access the user’s Photos
library.
isSourceTypeAvailable
Discussion
Because a media source may not be present or may be unavailable,
devices may not always support all source types.
For example, if you
attempt to pick an image from the user’s library and the library is
empty, this method returns false. Similarly, if the camera is already
in use, this method returns false.
Should and event store's requestAccess(to:completion:) be called
as early as possible (e.g. in application(_:didFinishLaunchingWithOptions:)
only before EKEventSource should be used for the first time?
Does Apple recommend one or the other option (for iOS 10)?
Why nag the user any sooner than necessary?
A user will be more comfortable if the request for permission comes when they actually try to do something they know requires access to the event store.
If you request permission too soon, the user is going to wonder why the app is asking when they haven't even done anything with the app yet.
And what if your app needs access to multiple sources such as camera, photo library, contacts, and events? It would be terrible to just nag the user over and over for all of them up front. Only ask when the source is actually needed and the user probably fully understands that the action they just took (like take photo) requires the specific permission.
I'm trying out this code: http://github.com/akpw/AssetLibraryPhotosViewer to access photos on my iPhone.
However when I run the application, I get an alert that says the application is trying to access my photos - and then I can allow this or decline.
Can I disable this when using the AssetLibrary, or does this message always appear?
If I can't turn this off, and I press "Don't Allow", can I still make the app access my photos?
Following on from answer above. This will appear once. If you allow access then it will not show again and you will have access to the photo's. If you disallow it then you will not be allowed to access this and the alert dialog will not appear again.
This permission can be changed at any time by the user in the settings app (Under Location and Privacy, or a variation of that.) This has been around since iOS 6 I believe.
You are never able to programtically state that access has been granted, the system handles the permissions which are shown to the user.
This is a security feature of the OS that cannot be disabled. If a user does not give your app permission to access the photo library your app will not be able to access any photos. Given this ability your app should be able to handle the situation gracefully from a UI/UX perspective.
For more information take a look at this guide from Apple about iOS security guidelines (page 47 takes about accessing personal data) iOS Security