Dies ist ein frustrierendes Problem mit dem iOS SDK. Zuerst empfehle ich die Einreichung einer enhancement request.
Jetzt ist hier eine mögliche Problemumgehung: WENN der ALAsset von Ihnen erstellt wurde (dh seine editable
Eigenschaft ist YES
) dann können Sie grundsätzlich die Daten lesen, mit Metadaten schreiben, erneut lesen, auf Festplatte speichern und dann schreiben mit den ursprünglichen Metadaten.
Dieser Ansatz vermeidet die Erstellung eines Duplikats.
Bitte lesen Sie die Kommentare // als ich ein paar Sachen aus Gründen der Kürze ausgelassen (wie ein Metadaten-Wörterbuch Gebäude):
ALAsset* asset; //get your asset, don't use this empty one
if (asset.editable) {
// get the source data
ALAssetRepresentation *rep = [asset defaultRepresentation];
Byte *buffer = (Byte*)malloc(rep.size);
// add error checking here
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
NSData *sourceData = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
// make your metadata whatever you want
// you should use actual metadata, not a blank dictionary
NSDictionary *metadataDictionary = [NSDictionary dictionary];
// these are __weak to avoid creating an ARC retain cycle
NSData __weak *originalData = sourceData;
NSDictionary __weak *originalMetadata = [rep metadata];
[asset setImageData:sourceData
metadata:metadataDictionary
completionBlock:^(NSURL *assetURL, NSError *error) {
//now get your data and write it to file
if (!error) {
//get your data...
NSString *assetPath = [assetURL path];
NSData *targetData = [[NSFileManager defaultManager] contentsAtPath:assetPath];
//...write to file...
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [searchPaths lastObject];
NSURL *fileURL = [NSURL fileURLWithPath:documentPath];
[targetData writeToURL:fileURL atomically:YES];
//...and put it back the way it was
[asset setImageData:originalData metadata:originalMetadata completionBlock:nil];
} else {
// handle error on setting data
NSLog(@"ERROR: %@", [error localizedDescription]);
}
}];
} else {
// you'll need to make a new ALAsset which you have permission to edit and then try again
}
Wie Sie sehen können, wenn die ALAsset nicht von Ihnen gehört, benötigen Sie um einen zu erstellen, der der Bibliothek des Benutzers ein Foto hinzufügt, was genau das ist, was Sie vermeiden wollten. Wie Sie jedoch vielleicht schon vermutet haben, können Sie ein ALAsset nicht aus der Fotobibliothek des Benutzers löschen, selbst wenn es in Ihrer App erstellt wurde. (Fühlen Sie sich frei, eine weitere Verbesserungsanfrage dafür einzureichen.)
Also, wenn das Foto/Bild in Ihrer App erstellt wurde, wird dies für Sie arbeiten.
Wenn nicht, wird eine zusätzliche Kopie erstellt, die der Benutzer löschen muss.
Die einzige Alternative ist, die NSData selbst zu analysieren, was ein Schmerz wäre. Es gibt keine Open-Source-Bibliothek, die mir bekannt ist, um diese Lücke im iOS SDK zu schließen.
Können Sie ein wenig ausarbeiten - wo bekommen Sie die Bilder von (Kamera? Andere?) – foundry
Es spielt keine Rolle, ich habe sie als undecoded 'NSData' (in der Regel von ALAsset gelesen). –
In Anbetracht der Tatsache, dass Sie aus einer Quelle gelesen haben, ist es bereits codiert, aktualisiert die Meta, wie schlägt es fehl, wenn Sie es nur in eine Datei schreiben? Sie wissen, '[Daten writeToFile: atomically:]'. Ich frage mich nur. –