Ecco una guida completa per iOS 8+ (senza ALAssetLibrary):
Per prima cosa dobbiamo fornire la descrizione dell'utilizzo poiché ora è richiesto da PHPhotoLibrary.
Per fare ciò dobbiamo aprire il info.plist
file, trovare la chiave Privacy - Photo Library Usage Description
e fornire il valore per essa. Se la chiave non esiste, creala e basta.
Ecco un'immagine per esempio:
Assicurati anche che il valore della chiave Bundle name
non sia vuoto nel info.plist
file.
Ora, quando abbiamo la descrizione, possiamo normalmente richiedere l'autorizzazione chiamando il requestAuthorization
metodo:
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
switch (status) {
case PHAuthorizationStatusAuthorized:
NSLog(@"PHAuthorizationStatusAuthorized");
break;
case PHAuthorizationStatusDenied:
NSLog(@"PHAuthorizationStatusDenied");
break;
case PHAuthorizationStatusNotDetermined:
NSLog(@"PHAuthorizationStatusNotDetermined");
break;
case PHAuthorizationStatusRestricted:
NSLog(@"PHAuthorizationStatusRestricted");
break;
}
}];
NOTA 1: in requestAuthorization
realtà non mostra avvisi su ogni chiamata. Viene visualizzato una volta ogni tanto, salva la risposta dell'utente e la restituisce ogni volta invece di mostrare nuovamente l'avviso. Ma poiché non è ciò di cui abbiamo bisogno, ecco un codice utile che mostra sempre un avviso ogni volta che abbiamo bisogno di autorizzazione (con reindirizzamento alle impostazioni):
- (void)requestAuthorizationWithRedirectionToSettings {
dispatch_async(dispatch_get_main_queue(), ^{
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusAuthorized)
{
//We have permission. Do whatever is needed
}
else
{
//No permission. Trying to normally request it
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status != PHAuthorizationStatusAuthorized)
{
//User don't give us permission. Showing alert with redirection to settings
//Getting description string from info.plist file
NSString *accessDescription = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSPhotoLibraryUsageDescription"];
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:accessDescription message:@"To give permissions tap on 'Change Settings' button" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
[alertController addAction:cancelAction];
UIAlertAction *settingsAction = [UIAlertAction actionWithTitle:@"Change Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}];
[alertController addAction:settingsAction];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
}
}];
}
});
}
Problema comune 1: alcuni utenti si lamentano del fatto che l'app non mostra avvisi dopo aver apportato le modifiche sopra menzionate nel info.plist
file.
Soluzione: per testare, provare a passare Bundle Identifier
dal file di progetto a qualcos'altro, pulire e ricostruire l'app. Se ha iniziato a funzionare, va tutto bene, rinominalo di nuovo.
Problema comune 2: esiste un caso specifico in cui i risultati del recupero non vengono aggiornati (e le visualizzazioni che utilizzavano le immagini da quelle richieste di recupero sono ancora vuote di conseguenza) quando l'app ottiene le autorizzazioni per le foto, mentre viene eseguita come promesso nella documentazione.
In realtà succede quando usiamo codice SBAGLIATO come questo:
- (void)viewDidLoad {
if ([PHPhotoLibrary authorizationStatus] != PHAuthorizationStatusAuthorized)
{
//Reloading some view which needs photos
[self reloadCollectionView];
// ...
} else {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized)
[self reloadCollectionView];
// ...
}];
}
// ...
}
In questo caso, se l'utente ha negato di concedere le autorizzazioni, viewDidLoad
quindi è passato alle impostazioni, consentito e è tornato all'app, le visualizzazioni non verranno aggiornate perché [self reloadCollectionView]
e le richieste di recupero non sono state inviate.
Soluzione: dobbiamo solo chiamare [self reloadCollectionView]
ed eseguire altre richieste di recupero prima di richiedere un'autorizzazione come questa:
- (void)viewDidLoad {
//Reloading some view which needs photos
[self reloadCollectionView];
if ([PHPhotoLibrary authorizationStatus] != PHAuthorizationStatusAuthorized)
{
// ...
}