TL;DR | Annotate the return variable with a type, e.x. let foo:String? = Utility.nullableValueFromKey(“identifier", dictionary: jsonDictionary) |
---|
Versions: | OS X 10.10.4 | Xcode 6.4 | iOS SDK 8.4 |
---|
When I started working with Objective-C coming from .NET, one of language features that I missed the most was Generics. They solve a whole class of problems that are tedious and/or require way more code than without generics. When Swift was announced with Generics...
But Generics can be hard, thinking in T for any giving problem can make you a little crazy, especially when the compiler keeps yelling at you.
In Swift 1.0, I used generic functions to help parsing JSON server responses, the functions worked, but they were less than ideal.
The typical problem I wanted to solve was getting a primitive type out of the response dictionary that could be null.
I ended up with this function to do the trick:
class func originalNullableValue<T>(valueType: T, key: String, dictionary: NSDictionary) -> T? {var value:T? = nilvar valueTemp = dictionary[key] as AnyObject! as? Tif valueTemp != nil {value = valueTemp!}return value
}
Ugly! Why did I end up with this? Either I wasn’t smart enough to figure this out or the 1.0 compiler wasn’t.
Getting either me or the compiler to figure out what type T was without passing an argument of that type into the method, was, well let’s just say it was the solution I found.
What I wanted was this:
class func nullableValueFromKey<T>(key: String, dictionary: NSDictionary) -> T? {var value:T? = nilvar valueTemp = dictionary[key] as AnyObject! as? Tif valueTemp != nil {value = valueTemp!}return value
}
So I dusted off the original method and tried making it what I wanted with Xcode 6.4 & Swift 1.2.
Defining it works fine, but If you attempt to call it:
let foo = JSONUtility.nullableArrayFromKey("fooBar", json: Dictionary<String, AnyObject>())
The compiler returns this error:
I have no way to know/test if this is the same error that caused me trouble in Swift 1.0, but this time, either I or the compiler were smart enough to figure it out!
All you have to do is add the type to the variable declaration:
let bar:String? = JSONUtility.nullableValueFromKey("name", dictionary: Dictionary<String, AnyObject>())