Home > Software design >  Cannot access CFDictionary elements from Swift3
Cannot access CFDictionary elements from Swift3

Time:03-30

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!")
}
  • Related