How to read a subkey in plist file with CFPreferencesMBS?

Hi All,
How to read the “LastKnownEncryptionState” subkey of the “TimeMachine.plist” file with the class, CFPreferencesMBS/CFStringMBS?
(What exactly does the “Destinations” key with value “0” correspond to? to the first Time machine disk?)

Read too : Comment tester l'existence d'une "clé" dans un fichier plist? - #2 by Emile_Schwarz


You posted into the wrong category.

The plist has an array of dictionaries. You have to first get the array and then the dictionary.

I don’t have code for this situation. Only for dictionaries and arrays of numbers or strings.

Public Function GetPrefDictionary(fieldName As String) As Dictionary
  'Returns a dictionary preference value
  if fieldName = "" then Return Nil
  if not CheckForPrefs then Return Nil
  dim theDictionary as new Dictionary
  if not theCFPrefs.AppSynchronize(theCFPrefs.kCFPreferencesCurrentApplication) Then 
  end if
  Dim theCFObject As CFObjectMBS = theCFPrefs.CopyAppValue(NewCFStringMBS(fieldName), theCFPrefs.kCFPreferencesCurrentApplication)
  if theCFObject = Nil then Return Nil 
  theDictionary = getValueForKey(fieldName)
  Return theDictionary
  exception exc
    theException = new ErrorException(exc, currentMethodName)
End Function
Public Function getPrefNumberArray(fieldName As String) As integer()
  'Returns an integer array preference value
  if fieldName = "" then Return Nil
  dim theDictionary as new Dictionary
  theDictionary = GetPrefDictionary(fieldName)
  if theDictionary = nil then Return nil
  'put dictionary into Array
  dim theIntegerArray(-1) as Integer
  dim curVal as integer
  redim theIntegerArray(theDictionary.KeyCount - 1)
  for curVal = 0 to theDictionary.KeyCount - 1
    if theDictionary.key(curVal) isA CFStringMBS then
      theIntegerArray(val(CFStringMBS(theDictionary.Key(curVal)).str)) = theDictionary.Value(theDictionary.Key(curVal))
      theIntegerArray(theDictionary.Key(curVal)) = theDictionary.Value(theDictionary.Key(curVal))
    end if
  return theIntegerArray
  exception exc
    theException = new ErrorException(exc, currentMethodName)
End Function
Private Function ConvertCFDictionary(Dict As CFDictionaryMBS) As Dictionary
  'convert a CFDictionary to a normal dictionary
  Dim theDictionary As Dictionary
  Dim currentValue As Integer
  Dim CFKey As CFObjectMBS
  Dim Key As Variant
  theDictionary = new Dictionary
  For currentValue = 0 to dict.Count - 1
    CFKey = dict.List.Key(currentValue)
    //Determine the type of key
    Select case CFKey.TypeDescription
    Case "CFBoolean"
      Key = CFBooleanMBS(CFKey).Value
    Case "CFNumber"
      Key = CFNumberMBS(CFKey).integerValue
    Else //Use the string value
      Key = CFStringMBS(CFKey).Str
    End Select
    //Determine value type and create new dictionary value
    Select Case dict.List.Value(currentValue).TypeDescription
    Case "CFBoolean"
      theDictionary.Value(key) = CFBooleanMBS(dict.Value(CFKey)).value
    Case "CFNumber"
      theDictionary.Value(key) = CFNumberMBS(dict.Value(CFKey)).integerValue
    Case "CFDictionary"
      theDictionary.Value(key) = ConvertCFDictionary(CFDictionaryMBS(dict.Value(CFKey)))
    case "CFData"
      theDictionary.Value(key) = CFBinaryDataMBS(dict.Value(CFKey)).mem
    case "CFArray"
      theDictionary.Value(Key) = ConvertCFArray(CFArrayMBS(dict.Value(CFKey)))
    case "CFDate"
      dim theCFDate as CFDateMBS = CFDateMBS(dict.Value(CFKey))
      if theCFDate = nil then theDictionary.Value(key) = nil
      dim theCFTime as CFAbsoluteTimeMBS
      theCFTime = theCFDate.AbsoluteTime
      if theCFTime = nil then theDictionary.Value(key) = nil
      dim theGregDate as CFGregorianDateMBS
      theGregDate = theCFTime.GregorianDate(nil)
      if theGregDate = nil or theGregDate.Year < 1000 then theDictionary.Value(key) = nil
      dim theDate as new Date
      theDate.year = theGregDate.year
      theDate.month = theGregDate.month =
      theDate.Hour = theGregDate.Hour
      theDate.Minute = theGregDate.Minute
      theDate.Second = theGregDate.Second
      theDictionary.Value(key) = theDate
    Else //Use the string value
        theDictionary.Value(key) = CFStringMBS(dict.Value(CFKey)).str
      catch err as IllegalCastException
        'no cast possible, ignore
      end try
    End Select
  Return theDictionary
  exception exc
    theException = new ErrorException(exc, currentMethodName)
End Function

That should get you started.