I have a Swift 3 project running with Xcode 10.2 on Catalina in which I wish to access image file metadata retrieved as shown below:
let metadata:CFDictionary = CGImageSourceCopyPropertiesAtIndex(source!,0,nil)!
I can view all the metadata in the debugger as shown below:
lldb) po metadata as? [String:Any]
▿ Optional<Dictionary<String, Any>>
▿ some : 9 elements
▿ 0 : 2 elements
- key : "Depth"
- value : 8
▿ 1 : 2 elements
- key : "{Exif}"
▿ value : 3 elements
▿ 0 : 2 elements
- key : PixelXDimension
- value : 1668
▿ 1 : 2 elements
- key : PixelYDimension
- value : 2500
▿ 2 : 2 elements
- key : ColorSpace
- value : 1
▿ 2 : 2 elements
- key : "ProfileName"
- value : sRGB IEC61966-2.1
▿ 3 : 2 elements
- key : "PixelWidth"
- value : 1668
▿ 4 : 2 elements
- key : "{TIFF}"
▿ value : 1 element
▿ 0 : 2 elements
- key : Orientation
- value : 1
▿ 5 : 2 elements
- key : "ColorModel"
- value : RGB
▿ 6 : 2 elements
- key : "PixelHeight"
- value : 2500
▿ 7 : 2 elements
- key : "{JFIF}"
▿ value : 4 elements
▿ 0 : 2 elements
- key : DensityUnit
- value : 0
▿ 1 : 2 elements
- key : YDensity
- value : 72
▿ 2 : 2 elements
- key : JFIFVersion
▿ value : 3 elements
- 0 : 1
- 1 : 0
- 2 : 1
▿ 3 : 2 elements
- key : XDensity
- value : 72
▿ 8 : 2 elements
- key : "Orientation"
- value : 1
but if I try to select elements of the metadata I get an error but the corrected code shown seems to be the same as the code causing the error:
lldb) po metadata as? [String:Any]["{Exif}"]
error: <EXPR>:3:26: error: array types are now written with the brackets around the element type
metadata as? [String:Any]["{Exif}"]
How can I select elements of the CFDictionary to display?
CodePudding user response:
To fix your specific problem, replace metadata as? [String:Any]["{Exif}"]
with (metadata as! [String:Any])["{Exif}"]
The problem you are encountering is that metadata as? [String:Any]
is of type [String: Any]?
, since you are using the conditional cast as!
.
However, the idiomatic way to do this in Swift is to use guard-let
statements like so:
guard let metadata:CFDictionary = CGImageSourceCopyPropertiesAtIndex(source!,0,nil) else {
fatalError("Cannot get image properties!")
}
guard let dictionary = metadata as? [String: Any] else {
fatalError("Cannot convert metadata to dictionary!")
}
guard let exifData = dictionary["{Exif}"] as? [SomeCFType: Int] else { //I'm not sure what type PixelXDimension, PixelYDimension, and ColorSpace are
fatalError("Cannot get EXIF data!")
}