Miscellany

Bundlegen, tool for iOS development

Working on the iOS version for Word Search Plus I had to define user preferences. For this, iOS uses property lists inside a special folder; Settings.Bundle . Sadly, the plist editor is a pain to use, and the actual xml in a plist is rather verbose:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<dict>
    <key>DisplaySortedByTitle</key>
    <false/>
    <key>Title</key>
    <string>language_title</string>
    <key>DefaultValue</key>
    <string>lang_en</string>
    <key>Titles</key>
    <array>
        <string>language_item_en</string>
        <string>language_item_nl</string>
        <string>language_item_de</string>
    </array>
    <key>Values</key>
    <array>
        <string>en</string>
        <string>nl</string>
        <string>de</string>
    </array>
    <key>Key</key>
    <string>pref_generation_language_key</string>
    <key>Type</key>
    <string>PSMultiValueSpecifier</string>
</dict>

This specifies a MultiValue, where the user can choose one of several options. Properties are defined in pairs of xml tags, key and value.

Adding an item to the settings turned out to be a huge hassle, so I thought I'd make it easier for myself. I decided to write a Python script that takes more readable text and converts it into the plist format.

So now I can specify the same setting using this JSON:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
    "Type": "PSMultiValueSpecifier",
    "Title": "language_title",
    "Key": "pref_generation_language_key",
    "DefaultValue": "lang_en",
    "Values": {
        "datatype": "string",
        "items": [
            "en", //wikiprefix
            "nl",
            "de"
        ]
    },
    "Titles": {
        "datatype": "string",
        "items": [
            "language_item_en",
            "language_item_nl",
            "language_item_de"
        ]
    },
    "DisplaySortedByTitle": false
}

Using the tool

A custom build step is defined, where a shell script is executed. This script contains 1 line:

python ~/code/projects/bundlegenerator/bundlegen.py ./scripts/settingsbundle/ Root ./Settings.bundle/

The first pane in the Settings is usually called Root.plist, so I define a Root.json.

If the tool encounters a Childpane definition (PSChildPaneSpecifier), it looks up the name and remembers it. When done processing the current file, it checks if it has remembered any other files, and processes them. This way the tool can handle an entire Settings tree in one go.

Have a look at the code on Bitbucket.