Here is what my App does -
I'm stuck in 2) because the newly added metadata is ignored and does not show up in the saved image. The metadata I'm trying to add is a new 'IPTC' section with a 'Keywords' key, value pair. The IPTC section does not exist in the originally captured photo's metadata. Trying to modify an existing section such as an Exif keyword works just fine.
The specific problem seems to be the Data returned by the fileDataRepresentation(with: AVCapturePhotoFileDataRepresentationCustomizer) -> Data? with my Customizer function passed in. A print inside the AVCapturePhotoFileDataRepresentationCustomizer shows the IPTC dict is correctly created. (See below)
A print of the photo.metadata after the fileDataRepresentation() is called does not show it though.
I'm at my wits end! Any pointers are greatly appreciated :)
class PhotoCaptureProcessor : NSObject {
//The data resulting from the photo capture
private var photoData: Data?
//The tagName to add to IPTC Keywords
private var tagName : String
//Process the Captured photo
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
...
if let error = error {
print("Error capturing photo: \(error)")
} else {
//Write the metadata to the photo data
self.photoData = photo.fileDataRepresentation(with: PSFileDataRepresentationCustomizer(tagName: tagName))
//Print metedata Dict after change
print(photo.metaData)
}
...
}
//Save the photo to Photo Library with the modified metadata
func photoOutput(_ output: AVCapturePhotoOutput, didFinishCaptureFor resolvedSettings: AVCaptureResolvedPhotoSettings, error: Error?) {
...
guard let photoData = photoData else {
print("No photo data resource")
didFinish()
return
}
//The localIdentifier for the saved photo
var imageIdentifier: String?
PHPhotoLibrary.requestAuthorization { status in
...
//Save the photo
PHPhotoLibrary.shared().performChanges({
let options = PHAssetResourceCreationOptions()
let creationRequest = PHAssetCreationRequest.forAsset()
options.uniformTypeIdentifier = self.requestedPhotoSettings.processedFileType.map { $0.rawValue }
let placeholder = creationRequest.placeholderForCreatedAsset
imageIdentifier = placeholder?.localIdentifier
//Add the photoAsset to the Photo library
creationRequest.addResource(with: .photo, data: photoData, options: options)
//Now add the photo to the album
let request = PHAssetCollectionChangeRequest(for: album)
request?.addAssets([placeholder!] as NSArray)
...
}
}, completionHandler: { success, error in
...
}
)
} else {
self.didFinish()
}
}
}
}
//The Customizer for fileDataRepresentation that adds the metadata to the photo Data
class PSFileDataRepresentationCustomizer: NSObject, AVCapturePhotoFileDataRepresentationCustomizer {
let tagName : String
init(tagName : String) {
self.tagName = tagName
super.init()
}
public func replacementMetadata(for photo: AVCapturePhoto) -> [String : Any]? {
return getDict(avFoundationMetadata: photo.metadata as NSDictionary) as! [String : Any]
}
func getDict(avFoundationMetadata: NSDictionary)->NSMutableDictionary {
let inDict: NSMutableDictionary = (avFoundationMetadata).mutableCopy() as! NSMutableDictionary
var iptc = inDict[kCGImagePropertyIPTCDictionary] as? [CFString: Any] ?? [:]
iptc[kCGImagePropertyIPTCKeywords] = String(tagName)
inDict[kCGImagePropertyIPTCDictionary] = iptc
//Print Dict Before
print(inDict)
return inDict
}
}
//Print Dict Before shows the Keywords added
{
DPIHeight = 72;
DPIWidth = 72;
Orientation = 6;
kCGImageDestinationICCProfile = {length = 548, bytes = 0x00000224 6170706c 04000000 6d6e7472 ... 000003dc 0000c06e };
"{Exif}" = {
...
};
"{IPTC}" = {
Keywords = laptop;
};
"{MakerApple}" = {
...
}
//Print Dict After does not
User contributions licensed under CC BY-SA 3.0