Sunday, 30 August 2009

MonoTouch Settings.bundle

Property Lists (plist) and Bundles are probably so obvious to seasoned Mac/iPhone developers that they're not even worth mentioning, however for someone with a '100% .NET' background you can't take anything for granted. I had a -lot-bit of trouble getting iPhone Settings working with MonoTouch (see here), but now that I've figured it out it seems very simple. Here's a quick guide:

2. Plist files are some sort of hybrid Xml key-value(right-click solution → Add → New File... → Empty Text File) and call it Root.plist. You could add an existing plist-xml-formatted file if you like - but we're just going to create one from scratch (in the next step).

3. Edit Root.plist with the Property List EditorThe structure of the plist is very specific - look for some doco or Chapter 10 of Beginning iPhone Development. In this example I've only used PSGroupSpecifier and PSTextFieldSpecifier but there are many other types (PSMultiValueSpecifier, PSToggleSwitchSpecifier, PSChildPaneSpecifier...).Double-click the Root.plist file inside MonoDevelop to open the Property List Editor - type carefully as there is no 'validation' and if you mis-spell (or mis-capitalize) something it just won't work:

4. Set the correct build action for Root.plistThis is important (and I think the cause of my earlier problem) - you MUST tell the IDE to make sure this file is copied to the phone.

5. Access the settingsUse the NSUserDefaults.StandardUserDefaults property to access the values set by the user.

6. See/Edit "Settings" on the iPhone

It's worthwhile noting that the 'useability' for these kinds of Settings is 'unusual' for desktop applications, but probably familiar to iPhone users... the settings for a whole swag of unrelated applications are grouped under the Settings icon (it's not necessarily obvious from with the application that they are available). The user must also quit the application to get to these settings - which means they're most useful for things that don't change much (eg. the users identity and servers in the Mail.app).

Hey Terry, I saw a comment elsewhere on my blog from someone who found Root.plist worked differently in a 1.2beta... basically delete the file added manually like I suggest and instead "add a new file and pick 'iPhone Application Manifest Template'." and re-create the settings you need using the Plist editor.

The original comment is on this post.HTH (I will d/l and play with 1.2 tonight)

Hi Craig - great tip! - but how do I simply create a local 'file' where I can store a bit of user data - i.e. when I ask the user for their Name I would wish to keep hold of it so next time the program starts I can say Hello 'username' !!Or am I forced to use the 'global' iphone settings environment?

I think NSUserDefaults is an appropriate choice for something like 'username'. It is not 'global' - NSUserDefaults are per-application and nicely suited to small pieces of data.

If you really want to pursue the idea of using a local file to store preferences data, all the regular .NET System.IO functions work as you'd expect (including serialization and deserialization of objects). Check outhttp://github.com/conceptdev/Roget1911/blob/master/MainViewController.cslines 51 - 55 for an example of deserialization from an XML file.