Correctly Parsing JSON in Swift 3

前端 未结 9 955
甜味超标
甜味超标 2020-11-21 07:00

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

9条回答
  •  死守一世寂寞
    2020-11-21 07:39

    Swift has a powerful type inference. Lets get rid of "if let" or "guard let" boilerplate and force unwraps using functional approach:

    1. Here is our JSON. We can use optional JSON or usual. I'm using optional in our example:
    
        let json: Dictionary? = ["current": ["temperature": 10]]
    
    
    1. Helper functions. We need to write them only once and then reuse with any dictionary:
    
        /// 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
        }
    
    
    1. And here is our magic - extract the value:
    
        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.

提交回复
热议问题