Work with InfoDictionary in a Swift way
AppInfo — Swift Api for InfoDictionary
This story began when I read a Radek’s article about Swifty APIs: NSUserDefaults
I really liked the idea of having static typed API and making things less verbose and more clean and clear. I looked around and found that there are dozens API in iOS that can be improved by applying that pattern. Here is my first project:
- NSBundle.infoDictionary Swift API
Pain
Let’s start with how was it before and why was it painful.
- Verbose
- String keys hard to remember and no code-completion
- Not static typed
1. Verbose
To get a value for InfoDictionary we have to type this every time
NSBundle.mainBundle().infoDictionary?["KeyName"]
This is quite a lot of code. Would it be better to make it less like this.
I think this is a way better
AppInfo["KeyName"]
2. String keys
Now our API is short and clean but we have to use string keys. There are 2 main problems with string keys:
- It’s hard to remember. There are more than 30 keys …
- Easy to make mistakes “KeyName” vs “KeyNamn” ☺
- No autocomplete Xcode suggestions
Let’s get rid of them by using properties for every item instead
//instead of AppInfo["CFBundleIdentifier"]
AppInfo.CFBundleIdentifier
Now we have both clean API and static typed names instead of string.
And we get rid of all string keys disadvantages
2. Static typed API
The type of infoDictionary of NSBundle is [NSObject : AnyObject]?
var infoDictionary: [NSObject : AnyObject]?
It means that every object we get from infoDictionary has a AnyObject type and to use it we have to cast it.
if let text = AppInfo.CFBundleVersion as? String {
println(text)
}
Instead, the API should know the correct type of that object and return it to us.
CFBundleVersion -> Int
CFBundleName -> Stringlet version = AppInfo.CFBundleVersion
let name = AppInfo.CFBundleName
And this is exactly how it works now!
Check out the code and use it GithHub
Want to Learn More cool thing in Swift?
Check out Swift Hight Performance book