scribble

fill the void - bdunagan

27 Mar 2010
ibtool "Missing object" Confusion

This week, I ran one of my ibtool ruby scripts to localize an app. During the process, it generated the following error:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.ibtool.errors</key>
    <array>
        <dict>
            <key>description</key>
            <string>Missing object referenced from oid-keyed mapping. Object ID 538</string>
        </dict>
    </array>
</dict>
</plist>

The error sounds innocuous. I searched on Google for it and got literally no results. Unfortunately, the result is quite bad: a partially localized XIB/NIB. The error means ibtool has encountered a string in the strings file with an ObjectID that isn't present in the source XIB file. In my case, I had deleted a placeholder string from an NSTextFieldCell element. When ibtool is unable to find this ObjectID in the source XIB, it stops localizing the new XIB. Not a pretty bug (rdar bug #7801770).

To show the confusing result, I reproduced this problem in a new project:

  1. Create a new Mac OS X app project in Xcode.
  2. Open Interface Builder and add a button to the main window in MainMenu.xib.
  3. Generate MainMenu.strings: ibtool --generate-strings-file MainMenu.strings English.lproj/MainMenu.xib.
  4. Open MainMenu.strings and do a search/replace "; for 1"; so that every element name is touched.
  5. Generate the localized XIB with a button: ibtool --strings-file MainMenu.strings --write MainMenu.with.button.xib English.lproj/MainMenu.xib.
  6. Open English.lproj/MainMenu.xib and remove the button. Save that.
  7. Generate the localized XIB with a button: ibtool --strings-file MainMenu.strings --write MainMenu.without.button.xib English.lproj/MainMenu.xib. This command should generate the error.
  8. Dump the strings for first localized XIB: ibtool --generate-strings-file MainMenu.with.button.strings MainMenu.with.button.xib.
  9. Dump the strings for second localized XIB: ibtool --generate-strings-file MainMenu.without.button.strings MainMenu.without.button.xib.
  10. Diff the strings files with Changes: chdiff MainMenu.with.button.strings MainMenu.without.button.strings.
  11. Diff the XIB files with Changes: chdiff MainMenu.with.button.xib MainMenu.without.button.xib.

The problem is clearly visualized in the two screenshots below, taken from Changes. Diff'ing the XIB files shows that ibtool stops localizing the new XIB when it cannot find the missing ObjectID. Look at Changes' scrollbar marks.

However, diff'ing the strings files makes it far less clear how ibtool failed. Changes' scrollbar marks are distributed across the entire file.

Yet another reason to always verify the newly-created localized XIBs by comparing strings files... :)

Previous LinkedIn Twitter GitHub Email Next