I\'m trying to fetch a JSON response and store the results in a variable. I\'ve had versions of this code work in previous releases of Swift, until the GM version of Xcode 8
Swift has a powerful type inference. Lets get rid of "if let" or "guard let" boilerplate and force unwraps using functional approach:
let json: Dictionary? = ["current": ["temperature": 10]]
/// Curry
public func curry(_ f: @escaping (A, B) -> C) -> (A) -> (B) -> C {
return { a in
{ f(a, $0) }
}
}
/// Function that takes key and optional dictionary and returns optional value
public func extract(_ key: Key, _ json: Dictionary?) -> Value? {
return json.flatMap {
cast($0[key])
}
}
/// Function that takes key and return function that takes optional dictionary and returns optional value
public func extract(_ key: Key) -> (Dictionary?) -> Value? {
return curry(extract)(key)
}
/// Precedence group for our operator
precedencegroup RightApplyPrecedence {
associativity: right
higherThan: AssignmentPrecedence
lowerThan: TernaryPrecedence
}
/// Apply. g § f § a === g(f(a))
infix operator § : RightApplyPrecedence
public func §(_ f: (A) -> B, _ a: A) -> B {
return f(a)
}
/// Wrapper around operator "as".
public func cast(_ a: A) -> B? {
return a as? B
}
let temperature = (extract("temperature") § extract("current") § json) ?? NSNotFound
Just one line of code and no force unwraps or manual type casting. This code works in playground, so you can copy and check it. Here is an implementation on GitHub.