Difference between revisions of "PreferenceLoader"

From iPhone Development Wiki
Jump to: navigation, search
Line 6: Line 6:
 
}}
 
}}
  
'''PreferenceLoader''' is a [[MobileSubstrate]] based utility that allows developers to add entries to the [[Preferences.app|Settings app]], similar to the Settings bundles that AppStore apps use.
+
'''PreferenceLoader''' is a [[MobileSubstrate]] based utility that allows developers to add entries to the [[Preferences.app|Settings]] application, similar to the Settings bundles that AppStore apps use.
  
The approach PreferenceLoader takes is different that other approaches in that the Settings plist files are not modified on disk. Entries are dynamically added to the list when the Settings app is loaded. PreferenceLoader gives the developer two options for entries. The first option is to simply create a single plist with basic options like PSSwitchCell or PSEditTextCell. The second option is allows the developer to create a full-blown PreferencesBundle.
+
== Entry ==
  
Regardless of the approach taken, each new entry is specified in its own plist located at <tt>/Library/PreferenceLoader/Preferences/</tt>. The plist must contain a dictionary containing a dictionary element named entry, as shown <tt>TestSettngs.plist</tt>:
+
The approach PreferenceLoader takes is different that other approaches in that the Settings-iPhone.plist and Settings-iPod.plist files are not modified on disk. when the [[Preferences.app|Settings]] application is loaded, entries are read from plists in <tt>/Library/PreferenceLoader/Preferences/</tt> and are dynamically added to the list. Each entry is defined in its own plist and consists of a dictionary containing an element named <tt>entry</tt>, which is also a dictionary. The entry dictionary must define a <tt>cell</tt> of type <tt>PSLinkCell</tt> and have a <tt>label</tt>. Additionally, the <tt>bundle</tt> and <tt>isController</tt> keys can be set for entries referencing [[PreferenceBundles]].
  
 
<source lang="xml">
 
<source lang="xml">
    <?xml version="1.0" encoding="UTF-8"?>
+
<?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">
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
+
<plist version="1.0">
    <dict>
+
<dict>
          <key>entry</key>
+
  <key>entry</key>
          <dict>
+
  <dict>
                <key>cell</key>
+
      <key>cell</key>
                <string>PSLinkCell</string>
+
      <string>PSLinkCell</string>
                <key>icon</key>
+
      <key>icon</key>
                <string>TestIcon.png</string>
+
      <string>TestIcon.png</string>
                <key>label</key>
+
      <key>label</key>
                <string>Test</string>
+
      <string>Test</string>
          </dict>
+
  </dict>
    </dict>
+
</dict>
    </plist>
+
</plist>
 
</source>
 
</source>
  
In this example, a new entry with the label "Test" is created that links to the settings page defined in <tt>Test.plist</tt> using the icon <tt>TestIcon.png</tt>. Both of these files should be placed in the Preferences directory with <tt>TestSettings.plist</tt>. One interesting thing that can be done is to combine the entry plist with the settings plist. This works because the settings plist has elements named items and title, so adding an entry element does not break anything. Here's an example of Test.plist that is combined:
+
== Simple Approach ==
 +
 
 +
In the simple approach the settings page is defined in a plist file located in the <tt>/Library/PreferenceLoader/Preferences/</tt> folder. The name of the plist file must match the label option in the entry dictionary. For example, if the label in the entry dictionary is defined as <tt>Test</tt>, then the plist that defines the settings page must be named <tt>Test.plist</tt>.
 +
 
 +
Typically, the settings and entry plists are combined into a single plist. This works because the settings plist has elements named items and title, so adding an entry element does not break anything. Here's an example of a combined plist:
  
 
<source lang="xml">
 
<source lang="xml">
    <?xml version="1.0" encoding="UTF-8"?>
+
<?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">
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
+
<plist version="1.0">
    <dict>
+
<dict>
          <key>entry</key>
+
  <key>entry</key>
          <dict>
+
  <dict>
                <key>cell</key>
+
      <key>cell</key>
                <string>PSLinkCell</string>
+
        <string>PSLinkCell</string>
                <key>icon</key>
+
        <key>icon</key>
                <string>TestIcon.png</string>
+
        <string>TestIcon.png</string>
                <key>label</key>
+
        <key>label</key>
                <string>Test</string>
+
        <string>Test</string>
          </dict>
+
      </dict>
          <key>items</key>
+
      <key>items</key>
          <array>
+
      <array>
                <dict>
+
        <dict>
                      <key>cell</key>
+
            <key>cell</key>
                      <string>PSSwitchCell</string>
+
            <string>PSSwitchCell</string>
                      <key>default</key>
+
            <key>default</key>
                      <true/>
+
            <true/>
                      <key>defaults</key>
+
            <key>defaults</key>
                      <string>com.test.TestSettings</string>
+
            <string>com.test.TestSettings</string>
                      <key>key</key>
+
            <key>key</key>
                      <string>testKey</string>
+
            <string>testKey</string>
                      <key>label</key>
+
            <key>label</key>
                      <string>Test Setting</string>
+
            <string>Test Setting</string>
                </dict>
+
        </dict>
          </array>
+
      </array>
          <key>title</key>
+
      <key>title</key>
          <string>Test</string>
+
      <string>Test</string>
    </dict>
+
  </dict>
    </plist>
+
</plist>
 
</source>
 
</source>
  
 
There is a good tutorial on how to create these settings plists on MMi at http://modmyi.com/forums/file-mods/22453-how-make-custom-menus-preferences-app-custom-preferences.html.
 
There is a good tutorial on how to create these settings plists on MMi at http://modmyi.com/forums/file-mods/22453-how-make-custom-menus-preferences-app-custom-preferences.html.
  
== PreferenceBundles ==
+
== Localizable Simple Approach<ref name="1.2">PreferenceLoader version 1.2 and later</ref> ==
 +
 
 +
This approach is similar to the Simple Approach, except the settings and entry plists are located in a sub-folder of <tt>/Library/PreferenceLoader/Preferences/</tt>. In addition to the plists and icons, the sub-folder can also contain .lproj folders with appropriate localization strings.
  
For those of you that want to create more complex settings pages, then the [[PreferenceBundles]] is for you. With this technique, you can actually create custom pages that are able to execute code. Skylar Cantu has put together a very useful guide on PreferenceBundles at http://www.touchrepo.com/guides/preferencebundles/PreferenceBundles.doc
+
== PreferenceBundle Approach ==
  
The only difference to his guide that is to be noted is that like the simple approach given above, the developer should create a plist in <tt>/Library/PreferenceLoader/Preferences/</tt>. Here's an example of an updated <tt>TestSettings.plist</tt>:
+
With this technique, you can actually create custom settings pages that are able to execute code. The entry plist for this approach must now include a reference to the name of the [[PreferenceBundles|PreferenceBundle]] and define the <tt>isController</tt> option to <tt>true</tt>. This will cause the [[Preferences.app|Settings]] application to load the corresponding bundle located in <tt>/Library/PreferenceLoader/PreferenceBundles/</tt><ref name="1.2">PreferenceLoader version 1.2 and later</ref><ref>Bundles can also be loaded from /System/Library/PreferenceBundles/, but this is no longer the preferred method as of PreferenceLoader 1.2</ref>. Unlike the simple method, all of the files except the entry plist are located inside the bundle. The following example shows an entry plist for loading a [[PreferenceBundles|PreferenceBundle]]:
  
 
<source lang="xml">
 
<source lang="xml">
    <?xml version="1.0" encoding="UTF-8"?>
+
<?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">
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
+
<plist version="1.0">
    <dict>
+
<dict>
          <key>entry</key>
+
  <key>entry</key>
          <dict>
+
  <dict>
                <key>bundle</key>
+
      <key>bundle</key>
                <string>TestSettings</string>
+
      <string>TestSettings</string>
                <key>cell</key>
+
      <key>cell</key>
                <string>PSLinkCell</string>
+
      <string>PSLinkCell</string>
                <key>icon</key>
+
      <key>icon</key>
                <string>TestIcon.png</string>
+
      <string>TestIcon.png</string>
                <key>isController</key>
+
      <key>isController</key>
                <true/>
+
      <true/>
                <key>label</key>
+
      <key>label</key>
                <string>Test</string>
+
      <string>Test</string>
          </dict>
+
  </dict>
    </dict>
+
</dict>
    </plist>
+
</plist>
 
</source>
 
</source>
  
The difference here is that instead of loading Test.plist, this entry will load the <tt>TestSettings.bundle</tt> located at <tt>/System/Library/PreferenceBundles/</tt>. Unlike the simple method, all of the files except <tt>TestSettings.plist</tt> are located inside the bundle. A skeleton PreferenceBundle project can be found at http://www.volatile-dev.com/PreferenceLoader/TestSettings.zip
+
A skeleton [[PreferenceBundles|PreferenceBundle]] project can be found at http://www.volatile-dev.com/PreferenceLoader/TestSettings.zip
 
 
== PreferenceLoader 1.2 Changes ==
 
  
PreferenceLoader 1.2 now supports sub-folders of the <tt>/Library/PreferenceLoader/Preferences/</tt>
+
==Notes==
folder. These sub folders are similar to a PreferenceBundle, except they contain no executable code. This approach allows developers to create more complex settings pages with multiple plists and localization without the need for writing code. This approach functions exactly the same as the basic approach from the previous version of PreferenceLoader, except the entry dictionary is moved into a plist file inside the sub-folder.
+
<references />
  
Additionally, PreferenceLoader 1.2 has added support for locating PreferenceBundles externally to <tt>/System/Library/PreferenceBundles/</tt>. PreferenceBundles may now be placed in <tt>/Library/PreferenceLoader/PreferenceBundles/</tt>. This approach follows the same pattern as the sub-folder approach, in that the entry dictionary must be in a plist file located inside the bundle. <b>Entries located in <tt>/Library/PreferenceLoader/Preferences/</tt> can only reference bundles in <tt>/System/Library/PreferenceBundles/</tt></b>.
+
==References==
 +
<div class="references-2column">
 +
* [http://www.touchrepo.com/guides/preferencebundles/PreferenceBundles.doc IPhone Settings Within Settings.app]
 +
</div>
  
 
{{Navbox Library}}
 
{{Navbox Library}}
 
[[Category:Directories in /Library]]
 
[[Category:Directories in /Library]]

Revision as of 19:32, 24 November 2009

PreferenceLoader
PrefLoaderScreenshot.png
Cydia Package
Developer Thomas Moore (volatile-dev)
Package ID preferenceloader
Latest Version 1.1


PreferenceLoader is a MobileSubstrate based utility that allows developers to add entries to the Settings application, similar to the Settings bundles that AppStore apps use.

Entry

The approach PreferenceLoader takes is different that other approaches in that the Settings-iPhone.plist and Settings-iPod.plist files are not modified on disk. when the Settings application is loaded, entries are read from plists in /Library/PreferenceLoader/Preferences/ and are dynamically added to the list. Each entry is defined in its own plist and consists of a dictionary containing an element named entry, which is also a dictionary. The entry dictionary must define a cell of type PSLinkCell and have a label. Additionally, the bundle and isController keys can be set for entries referencing PreferenceBundles.

<?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>entry</key>
   <dict>
      <key>cell</key>
      <string>PSLinkCell</string>
      <key>icon</key>
      <string>TestIcon.png</string>
      <key>label</key>
      <string>Test</string>
   </dict>
</dict>
</plist>

Simple Approach

In the simple approach the settings page is defined in a plist file located in the /Library/PreferenceLoader/Preferences/ folder. The name of the plist file must match the label option in the entry dictionary. For example, if the label in the entry dictionary is defined as Test, then the plist that defines the settings page must be named Test.plist.

Typically, the settings and entry plists are combined into a single plist. This works because the settings plist has elements named items and title, so adding an entry element does not break anything. Here's an example of a combined plist:

<?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>entry</key>
   <dict>
      <key>cell</key>
         <string>PSLinkCell</string>
         <key>icon</key>
         <string>TestIcon.png</string>
         <key>label</key>
         <string>Test</string>
      </dict>
      <key>items</key>
      <array>
         <dict>
            <key>cell</key>
            <string>PSSwitchCell</string>
            <key>default</key>
            <true/>
            <key>defaults</key>
            <string>com.test.TestSettings</string>
            <key>key</key>
            <string>testKey</string>
            <key>label</key>
            <string>Test Setting</string>
         </dict>
      </array>
      <key>title</key>
      <string>Test</string>
   </dict>
</plist>

There is a good tutorial on how to create these settings plists on MMi at http://modmyi.com/forums/file-mods/22453-how-make-custom-menus-preferences-app-custom-preferences.html.

Localizable Simple Approach[1]

This approach is similar to the Simple Approach, except the settings and entry plists are located in a sub-folder of /Library/PreferenceLoader/Preferences/. In addition to the plists and icons, the sub-folder can also contain .lproj folders with appropriate localization strings.

PreferenceBundle Approach

With this technique, you can actually create custom settings pages that are able to execute code. The entry plist for this approach must now include a reference to the name of the PreferenceBundle and define the isController option to true. This will cause the Settings application to load the corresponding bundle located in /Library/PreferenceLoader/PreferenceBundles/[1][2]. Unlike the simple method, all of the files except the entry plist are located inside the bundle. The following example shows an entry plist for loading a PreferenceBundle:

<?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>entry</key>
   <dict>
      <key>bundle</key>
      <string>TestSettings</string>
      <key>cell</key>
      <string>PSLinkCell</string>
      <key>icon</key>
      <string>TestIcon.png</string>
      <key>isController</key>
      <true/>
      <key>label</key>
      <string>Test</string>
   </dict>
</dict>
</plist>

A skeleton PreferenceBundle project can be found at http://www.volatile-dev.com/PreferenceLoader/TestSettings.zip

Notes

  1. 1.0 1.1 PreferenceLoader version 1.2 and later
  2. Bundles can also be loaded from /System/Library/PreferenceBundles/, but this is no longer the preferred method as of PreferenceLoader 1.2

References