NSUserDefaults Boiler Plate Generation
05 Jan 2013NSUserDefaults
boilerplate code made simple.
Creating a category on NSUserDefaults
is a pretty common activity, I believe I first saw the technique in iOS Recipes and I’ve done it ever since. By writing a category you can make your use of NSUserDefaults
follow how you write code everywhere else using accessors and having the compiler check this for you without messing with string keys.
As a result the standard usage of NSUserDefaults
may look something like this
Defaults without properties
The issue here is that there is a lot of noise in the above code which hides what we are doing - simple assignment and retrieval.
By adding a category we can simplify this
NSUserDefaults+PSProperties.h
NSUserDefaults+PSProperties.m
We can now rewrite the first example using this category, which has the nice effect or removing most of the noise and making our intent clearer.
Defaults with properties
This technique is nice but as you can see it requires a fair amount of boiler plate code and all of this was to just add one property.
##Solution
When reading an issue of iOSDevWeekly I saw the class GVUserDefaults mentioned and this got me intrigued. The class uses some Objective-C mataprogramming to lazily add getters and setters at runtime. It’s worth checking out but it does have some limitations, which got me to thinking how would I do this?
I ended up going a different route and making a Ruby gem that uses a simple DSL to generate the category and add it to your Xcodeproj. It’s just a different approach to the same problem.
The best place to read about how to try my gem out is on the project page here.
You can’t use your system version of Ruby (as it is too old) but rvm
or rbenv
are pretty easy to set up and then it’s as simple as
gem install defgen
##Features of Defgen
- Uses the class prefix of your project to prefix all the things
- Uses the organization name of your project in generated class comments
- Uses a simple DSL and supports all the types that
NSUserDefaults
does - You can supply custom getter semantics
- You can edit all of the templates used for code generation on a project by project basis to conform to your coding style
###Conclusion
The process of making this gem was fun but a pretty steep learning curve for me, hopefully if this proves useful I have some other ideas for other things that could do with code generating DSL’s.