Retrieving Bundle Data From an Application's Info.plist File
Mac OS X Only (Mac OS X Only)


Version 1.1 Required
NOTE: This tip requires version 1.1 of the XML Library.
To get a copy of the XML Library, please go to the XML Library product page.

There may be times where you need to check one of your standalones (or any other application for that matter) to see what version number it is, what file types it supports, or to retrieve any of dozens of pieces of information contained in the Info.pList file for an application.

To locate the Info.pList file, control-click on your standalone in the Finder and choose “Show Package Contents”. This will open a folder that contains a folder called “Contents”. Open that folder and you will see two folders (“MacOS” and “Resources”) along with two files: “PkgInfo” and “Info.pList”. It is the latter file which is formatted in XML, and easy pickings for the XML Library to parse.

If you open the Info.pList file in a text editor, you will see (in general) the names of the “keys” (things like CFBundleDevelopmentRegion and CFBundleName) surrounded with <key></key> tags, and the values for those keys surrounded with <string><string> tags.

Using the XML Library and the function below, you should be able to get any key that is at the following levels (I'll use XPATH or slash notation to denote the levels):

/plist/dict/key
/plist/dict/array/dict/key
This should be able to get every key in a basic standalone created with MetaCard or Revolution.

To retrieve a value, get a file path to the application and pass it and the name of the key you want to the function. If the key contains only a single value (like CFBundleName), you will get back the <string> value that follows it. If the key can contain multiple values (like CFBundleTypeExtensions - you can tell because it has an <array> tag that follows it instead of a <string> tag), you will get back a multiline result, one line for each <string> in the array.

Here’s an example along with the function:

-- Get the short version number (CFBundleShortVersionString) for an application
on mouseUp
  answer file "Select an app to get the version from:"
  if it <> "" then 
    put it into tAppPath
    answer GetInfoPListKeyValue(tAppPath,"CFBundleShortVersionString")
  end if
end mouseUp

function GetInfoPListKeyValue pAppPath,pKeyName
  put url ("file:" & pAppPath & "Contents/Info.plist") into pListXMLData
  put (pKeyName contains "CFBundleType") into inArrayTag
  
  -- Set up a callback in case there are any errors
  xml_setCallBack (long id of me),"parseError"
  
  put XMLLoadData(pListXMLData) into tDocNum
  put XMLGetRoot(tDocNum) into tRootNode
  put XMLGetNamedChildren(tRootNode,"dict") into tDictNode
  put "" into tRetVal
  if not(inArrayTag) then
    put XMLGetNamedChildren(tDictNode,"key") into tKidNodes
    repeat for each line tKidNode in tKidNodes
      put XMLGetFirstChild(tKidNode) into tKid
      put XMLGetText(tKid) into tText
      if tText = pKeyName then
        put XMLGetNextSibling(tKidNode) into tSibNode
        put XMLGetFirstChild(tSibNode) into tSib
        put XMLGetText(tSib) into tRetVal
        return tRetVal
      end if
    end repeat
  else
    put line 1 of XMLGetNamedChildren(tDictNode,"array") into tArrayNode
    put line 1 of XMLGetNamedChildren(tArrayNode,"dict") into tArrayDictNode
    put XMLGetNamedChildren(tArrayDictNode,"key") into tKidNodes
    repeat for each line tKidNode in tKidNodes
      put XMLGetFirstChild(tKidNode) into tKid
      put XMLGetText(tKid) into tText
      if tText = pKeyName then
        put XMLGetNextSibling(tKidNode) into tSibNode
        if XMLGetNodeName(tSibNode) = "array" then
          put XMLGetNamedChildren(tSibNode,"string") into tStringNodes
          repeat for each line tStringNode in tStringNodes
            put XMLGetFirstChild(tStringNode) into tKid
            put XMLGetText(tKid) into tText
            put tText into line (the number of lines of tRetVal)+1 of tRetVal
          end repeat
        else
          put XMLGetFirstChild(tSibNode) into tSib
          put XMLGetText(tSib) into tRetVal
        end if
        return tRetVal
      end if
    end repeat
  end if
  return "Error:  Key name: '" & pKeyName & "' not found in Info.plist file."
end GetInfoPListKeyValue

on ParseError
  -- If this is called, you have an error, so check gXMLError and report
  global gXMLError
  answer gXMLError
end ParseError

Posted 10/16/2002 by Ken Ray