PhotoKit in Xamarin.iOS
PhotoKit è un framework che consente alle applicazioni di eseguire query sulla libreria di immagini di sistema e creare interfacce utente personalizzate per visualizzarne e modificarne il contenuto. Include una serie di classi che rappresentano asset di immagini e video, nonché raccolte di asset come album e cartelle.
Autorizzazioni
Prima che l'app possa accedere alla raccolta foto, l'utente visualizzerà una finestra di dialogo di autorizzazioni. Devi fornire testo esplicativo nel file Info.plist per spiegare come la tua app usa la raccolta foto, ad esempio:
<key>NSPhotoLibraryUsageDescription</key>
<string>Applies filters to photos and updates the original image</string>
Oggetti modello
PhotoKit rappresenta questi asset in ciò che chiama oggetti modello. Gli oggetti modello che rappresentano le foto e i video stessi sono di tipo PHAsset
. Un PHAsset
oggetto contiene metadati, ad esempio il tipo di supporto dell'asset e la relativa data di creazione.
Analogamente, le PHAssetCollection
classi e PHCollectionList
contengono i metadati relativi rispettivamente alle raccolte di asset e agli elenchi di raccolte. Le raccolte di asset sono gruppi di asset, ad esempio tutte le foto e i video per un determinato anno. Analogamente, gli elenchi di raccolte sono gruppi di raccolte di asset, ad esempio foto e video raggruppati per anno.
Esecuzione di query sui dati del modello
PhotoKit semplifica l'esecuzione di query sui dati del modello tramite diversi metodi di recupero. Ad esempio, per recuperare tutte le immagini, chiamare PHAsset.Fetch
, passando il PHAssetMediaType.Image
tipo di supporto.
PHFetchResult fetchResults = PHAsset.FetchAssets (PHAssetMediaType.Image, null);
L'istanza PHFetchResult
conterrà quindi tutte le istanze che rappresentano le PHAsset
immagini. Per ottenere le immagini stesse, usare ( PHImageManager
o la versione di memorizzazione nella cache, PHCachingImageManager
) per effettuare una richiesta per l'immagine chiamando RequestImageForAsset
. Ad esempio, il codice seguente recupera un'immagine per ogni asset in un PHFetchResult
oggetto da visualizzare in una cella di visualizzazione raccolta:
public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
{
var imageCell = (ImageCell)collectionView.DequeueReusableCell (cellId, indexPath);
imageMgr.RequestImageForAsset (
(PHAsset)fetchResults [(uint)indexPath.Item],
thumbnailSize,
PHImageContentMode.AspectFill, new PHImageRequestOptions (),
(img, info) => {
imageCell.ImageView.Image = img;
}
);
return imageCell;
}
In questo modo si ottiene una griglia di immagini, come illustrato di seguito:
Salvataggio delle modifiche nella raccolta foto
Ecco come gestire l'esecuzione di query e la lettura dei dati. È anche possibile scrivere di nuovo le modifiche nella libreria. Poiché più applicazioni interessate sono in grado di interagire con la libreria di foto di sistema, è possibile registrare un osservatore per ricevere una notifica delle modifiche tramite un oggetto PhotoLibraryObserver
. Quindi, quando vengono apportate modifiche, l'applicazione può aggiornare di conseguenza. Ecco, ad esempio, una semplice implementazione per ricaricare la visualizzazione raccolta precedente:
class PhotoLibraryObserver : PHPhotoLibraryChangeObserver
{
readonly PhotosViewController controller;
public PhotoLibraryObserver (PhotosViewController controller)
{
this.controller = controller;
}
public override void PhotoLibraryDidChange (PHChange changeInstance)
{
DispatchQueue.MainQueue.DispatchAsync (() => {
var changes = changeInstance.GetFetchResultChangeDetails (controller.fetchResults);
controller.fetchResults = changes.FetchResultAfterChanges;
controller.CollectionView.ReloadData ();
});
}
}
Per scrivere effettivamente le modifiche dall'applicazione, creare una richiesta di modifica. Ognuna delle classi del modello ha una classe di richiesta di modifica associata. Ad esempio, per modificare un PHAsset
oggetto , si crea un oggetto PHAssetChangeRequest
. I passaggi per eseguire le modifiche che vengono riscritto nella raccolta foto e inviate agli osservatori come quello precedente sono:
- Eseguire l'operazione di modifica.
- Salvare i dati dell'immagine filtrati in un'istanza
PHContentEditingOutput
di . - Effettuare una richiesta di modifica per pubblicare le modifiche dall'output di modifica.
Ecco un esempio che scrive di nuovo una modifica in un'immagine che applica un filtro noir core image:
void ApplyNoirFilter (object sender, EventArgs e)
{
Asset.RequestContentEditingInput (new PHContentEditingInputRequestOptions (), (input, options) => {
// perform the editing operation, which applies a noir filter in this case
var image = CIImage.FromUrl (input.FullSizeImageUrl);
image = image.CreateWithOrientation((CIImageOrientation)input.FullSizeImageOrientation);
var noir = new CIPhotoEffectNoir {
Image = image
};
var ciContext = CIContext.FromOptions (null);
var output = noir.OutputImage;
var uiImage = UIImage.FromImage (ciContext.CreateCGImage (output, output.Extent));
imageView.Image = uiImage;
//
// save the filtered image data to a PHContentEditingOutput instance
var editingOutput = new PHContentEditingOutput(input);
var adjustmentData = new PHAdjustmentData();
var data = uiImage.AsJPEG();
NSError error;
data.Save(editingOutput.RenderedContentUrl, false, out error);
editingOutput.AdjustmentData = adjustmentData;
//
// make a change request to publish the changes form the editing output
PHPhotoLibrary.GetSharedPhotoLibrary.PerformChanges (() => {
PHAssetChangeRequest request = PHAssetChangeRequest.ChangeRequest(Asset);
request.ContentEditingOutput = editingOutput;
},
(ok, err) => Console.WriteLine ("photo updated successfully: {0}", ok));
});
}
Quando l'utente seleziona il pulsante, viene applicato il filtro:
Grazie a PHPhotoLibraryChangeObserver
, la modifica viene riflessa nella visualizzazione raccolta quando l'utente torna indietro: