web-dev-qa-db-fra.com

L'accès à la photothèque iOS11 est possible même si les paramètres sont définis sur "jamais"

if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
    let imagePicker = UIImagePickerController()
    imagePicker.sourceType = .photoLibrary
    imagePicker.allowsEditing = true
    self.present(imagePicker, animated: true, completion: { })
}

Même si je règle l'accès aux photos dans les paramètres sur "Jamais" avec le code ci-dessus, je peux quand même présenter le sélecteur d'images et afficher les photos. Je vérifierai PHPhotoLibrary.authorizationStatus() avant de le montrer, mais j'aimerais savoir si ce comportement est attendu?

31
gvuksic

D'accord, vous pouvez déjà regrouper ces réponses à partir de réponses et de commentaires, mais essayez de raconter une histoire plus complète ...


Dans iOS 11, UIImagePickerController s'exécute en tant que processus distinct de votre application. Cela signifie:

  1. Votre application ne peut pas voir la totalité de la bibliothèque de photos de l'utilisateur. Elle dispose d'un accès en lecture seule pour le ou les actifs choisis par l'utilisateur dans le sélecteur d'images.
  2. En raison de (1), votre application n'a pas besoin de l'autorisation de confidentialité standard pour accéder à la bibliothèque de photos. L'utilisateur choisit explicitement un actif spécifique (ou plusieurs) à utiliser dans votre application, ce qui signifie qu'il vous autorise à lire le ou les actifs en question.

Vous pouvez en savoir plus à ce sujet dans la conférence WWDC17 sur PhotoKit .

(Au fait, ce modèle correspond à ce que vous avez vu dans le cadre Contacts depuis iOS 9; si vous affichez le sélecteur de contacts, votre application ne récupère qu'une fois les informations de contact pour le contact ( s) l'utilisateur a choisi l'accès en lecture/écriture à la base de contacts, pas en cours, de sorte que le sélecteur de contacts ne nécessite pas d'autorisation de confidentialité particulière.)


PHPhotoLibrary et son statut d'autorisation reflètent l'autorisation globale en lecture/écriture pour l'accès aux photos que les utilisateurs peuvent contrôler à partir de Paramètres> Confidentialité. (C'est celui où votre Info.plist a besoin de NSPhotoLibraryUsageDescription.) Toute utilisation de l'API PHPhotoLibrary nécessite cette autorisation, que l'utilisation de cette API par votre application soit uniquement en écriture ou en lecture. . C’est vrai depuis l’introduction de PhotoKit dans iOS 8.

Si vous n'utilisez pas PHPhotoLibrary, PHAsset, etc., certaines options d'autorisations plus étroites sont nouvelles dans iOS 11 (et ne font pas partie de l'API Photos.framework):

  • Comme indiqué ci-dessus, UIImagePickerController n'a pas besoin d'une autorisation globale des paramètres de confidentialité, car chaque utilisation accorde un accès en lecture unique aux actifs spécifiques choisis.
  • Si vous devez uniquement ajouter de nouveaux éléments à la bibliothèque Photos, utilisez UIImageWriteToSavedPhotosAlbum ou UISaveVideoAtPathToSavedPhotosAlbum . Avec ceux-ci, vous pouvez mettre NSPhotoLibraryAddUsageDescription dans votre Info.plist - les paramètres de confidentialité du système indiqueront clairement à l'utilisateur qu'ils ne vous autorisent pas à afficher ou à modifier des éléments existants, mais uniquement d'en ajouter de nouveaux.

    Si l'utilisateur accorde une autorisation d'ajout uniquement, il ne s'applique qu'aux fonctions UIKit. Toute tentative d'utilisation de PHPhotoLibrary demandera toujours (et nécessitera la clé Info.plist pour) l'accès en lecture/écriture.

    Voir cette partie de la conférence WWDC17 pour plus d'informations sur le paramètre de confidentialité avec ajout uniquement.

57
rickster

Ce (nouveau) comportement ne me semble pas logique, voici pourquoi. Lorsque vous utilisez UIImagePickerController votre application n’a pas accès aux photos any. Il ne voit que celui que votre utilisateur a choisi, lorsque cela se produit. et si l'utilisateur appuie sur Annuler dans le sélecteur, aucune de celles-ci ne sera disponible pour l'application.

PHPhotoLibrary fait partie d'un framework séparé, Photos , dans lequel vous pouvez faire beaucoup de choses avec la bibliothèque de photos de l'utilisateur, et donc nécessiter une autorisation.

Donc, si vous utilisez uniquement UIImagePickerController, je vous suggérerais de ne pas mélanger du contenu Photos.

Disclaimer: N'a entendu parler d'aucune déclaration officielle de Apple personnes. Ce sujet de forum a l'air pertinent, nous avons peut-être une réponse.) UPD: ça y est , même idée.

En outre, si vous êtes assez maléfique, vous pouvez théoriquement manipuler la hiérarchie des vues UIImagePickerController lors de l'exécution et examiner ce que l'utilisateur y voit. Mais c'est encore pour Apple à traiter, nous devrions simplement être gentils :-)

6
Gleb A.

S'agit-il d'un comportement attendu? - OUI.

À partir de la documentation - https://developer.Apple.com/documentation/uikit/uiimagepickercontroller/1619144-issourcetypeavailable

true si le périphérique prend en charge le type de source spécifié; false si le type de source spécifié n'est pas disponible.

Il vous indique si le périphérique prend en charge le type de source et non si l'application est autorisée à y accéder.

Comme vous l'avez déjà mentionné dans la question, PHPhotoLibrary.authorizationStatus() serait le moyen correct de vérifier cela.

5
Tarun Tyagi

UIImagePickerController et PHPhotoLibrary responsables de différents domaines.

Vous devez vérifier les deux: statut d'authentification et disponibilité de la source.

PHAuthorizationStatus

Informations sur votre application autorisation d'accès la bibliothèque de photos de l'utilisateur.

isSourceTypeAvailable

Discussion

Dans la mesure où une source multimédia peut ne pas être présente ou non disponible, les périphériques ne prennent pas toujours en charge tous les types de source.

Par exemple, si vous essayez de sélectionner une image dans la bibliothèque de l'utilisateur et que la bibliothèque est vide, cette méthode renvoie false. De même, si la caméra est déjà utilisée, cette méthode retourne false.

3
LLIAJLbHOu