I normally use the ALAssets library to access photos and display them, but I wanted to provide the user with an alternative in case they didn't feel comfortable giving access to location data. I installed the UIImagePicker, and while it still works fine on iOS5, I noticed on iOS6, when I shut off access to the photos in my app, I get "This app does have access to your photos or videos". Does the UIImagePickerController no long allow non disputed access to the photos?
It doesn't matter which route you take to access the photos, if the user has denied access then none of the options will be permitted to access the photos. The authorisation messages may be a little misleading but the same permissions apply to both access methods.
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.
I am an iPhone user and typically, when you want to upload a photo to an app, there are three steps:first, the app checks whether it has permission to access albums and if it does not ,it will ask you to give permission. Then, you will be presented with an interface from which you can select a photo from the album, and finally, you press a button to upload the selected photo to the app. Previously, I thought the app can only access the photo that the user selects, but then I saw this answer:
https://apple.stackexchange.com/questions/107404/is-it-safe-to-allow-apps-to-access-your-photos
which says: "When you give access to an app to photos...it can read all your photos on the device in an unencrypted form." "For example, once you give permission, iOS apps for popular services like Dropbox, Facebook, Flickr and Google+ can upload all your photos to their services. With iOS 7, these apps can also be allowed to do it in the background (when you're not actively running the app). Most users wouldn't even actively know which photos are being uploaded and when."
Millions of people are using ios system and many photos in the albums are private, including but are not limited to images of having sex, images of getting drunk, etc. so I think the most appropriate design is to let the app only access the photos that users selected, not all the photos on the phone. And I think a lot of users, like me, believe that when you give an app permission to access the album, it can only access the photo selected by users, not every photos on the device.
Since I'm a programmer(but not an ios programmer), I take a look at the ios documentation, and I found a class called UIImagePickerController. I believe it is through this class that the app gets a selected image from the user, so it seems to me that an app can only access the selected image. But on stackoverflow I also found an answer about how to select all photos from the device: IOS Photos framework
So my question is, if you give an app permission to access the album, can it only access the photo users select from UIImagePickerController, or every photo on the device?
Once a user grants permission to access the photo library, that iOS app has complete access to every photo in the user's photo library. The permission is not for a specific photo. And UIImagePickerController is only a graphical means to allow the user to select an image. There are APIs that allow the app to access any photo without user interaction. And all of those APIs are covered by the one single permission to allow access to the photo library.
#rmaddy is correct that the user grants permission to access the entire photo library on the user's device. However, note that iPhone users have the option of hiding photos by viewing the photo and tapping the share button (Tap share and select Hide.) See Apple support article .
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