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


Thanks,

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 
    globals.theErrorLog.DialogErrorProceed(kErrorSynchronize)
  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))
    else
      theIntegerArray(theDictionary.Key(curVal)) = theDictionary.Value(theDictionary.Key(curVal))
    end if
  next
  
  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.day = theGregDate.day
      theDate.Hour = theGregDate.Hour
      theDate.Minute = theGregDate.Minute
      theDate.Second = theGregDate.Second
      
      theDictionary.Value(key) = theDate
      
    Else //Use the string value
      try
        theDictionary.Value(key) = CFStringMBS(dict.Value(CFKey)).str
      catch err as IllegalCastException
        'no cast possible, ignore
      end try
    End Select
    
  Next
  Return theDictionary
  
  exception exc
    theException = new ErrorException(exc, currentMethodName)
    
End Function

That should get you started.