How to convert a JSON string to a dictionary?

前端 未结 10 919
情深已故
情深已故 2020-11-22 05:57

I want to make one function in my swift project that converts String to Dictionary json format but I got one error:

Cannot convert expression\'s type

10条回答
  •  情话喂你
    2020-11-22 06:39

    With Swift 3, JSONSerialization has a method called json​Object(with:​options:​). json​Object(with:​options:​) has the following declaration:

    class func jsonObject(with data: Data, options opt: JSONSerialization.ReadingOptions = []) throws -> Any
    

    Returns a Foundation object from given JSON data.

    When you use json​Object(with:​options:​), you have to deal with error handling (try, try? or try!) and type casting (from Any). Therefore, you can solve your problem with one of the following patterns.


    #1. Using a method that throws and returns a non-optional type

    import Foundation
    
    func convertToDictionary(from text: String) throws -> [String: String] {
        guard let data = text.data(using: .utf8) else { return [:] }
        let anyResult: Any = try JSONSerialization.jsonObject(with: data, options: [])
        return anyResult as? [String: String] ?? [:]
    }
    

    Usage:

    let string1 = "{\"City\":\"Paris\"}"
    do {
        let dictionary = try convertToDictionary(from: string1)
        print(dictionary) // prints: ["City": "Paris"]
    } catch {
        print(error)
    }
    
    let string2 = "{\"Quantity\":100}"
    do {
        let dictionary = try convertToDictionary(from: string2)
        print(dictionary) // prints [:]
    } catch {
        print(error)
    }
    
    let string3 = "{\"Object\"}"
    do {
        let dictionary = try convertToDictionary(from: string3)
        print(dictionary)
    } catch {
        print(error) // prints: Error Domain=NSCocoaErrorDomain Code=3840 "No value for key in object around character 9." UserInfo={NSDebugDescription=No value for key in object around character 9.}
    }
    

    #2. Using a method that throws and returns an optional type

    import Foundation
    
    func convertToDictionary(from text: String) throws -> [String: String]? {
        guard let data = text.data(using: .utf8) else { return [:] }
        let anyResult: Any = try JSONSerialization.jsonObject(with: data, options: [])
        return anyResult as? [String: String]
    }
    

    Usage:

    let string1 = "{\"City\":\"Paris\"}"
    do {
        let dictionary = try convertToDictionary(from: string1)
        print(String(describing: dictionary)) // prints: Optional(["City": "Paris"])
    } catch {
        print(error)
    }
    
    let string2 = "{\"Quantity\":100}"
    do {
        let dictionary = try convertToDictionary(from: string2)
        print(String(describing: dictionary)) // prints nil
    } catch {
        print(error)
    }
    
    let string3 = "{\"Object\"}"
    do {
        let dictionary = try convertToDictionary(from: string3)
        print(String(describing: dictionary))
    } catch {
        print(error) // prints: Error Domain=NSCocoaErrorDomain Code=3840 "No value for key in object around character 9." UserInfo={NSDebugDescription=No value for key in object around character 9.}
    }
    

    #3. Using a method that does not throw and returns a non-optional type

    import Foundation
    
    func convertToDictionary(from text: String) -> [String: String] {
        guard let data = text.data(using: .utf8) else { return [:] }
        let anyResult: Any? = try? JSONSerialization.jsonObject(with: data, options: [])
        return anyResult as? [String: String] ?? [:]
    }
    

    Usage:

    let string1 = "{\"City\":\"Paris\"}"
    let dictionary1 = convertToDictionary(from: string1)
    print(dictionary1) // prints: ["City": "Paris"]
    
    let string2 = "{\"Quantity\":100}"
    let dictionary2 = convertToDictionary(from: string2)
    print(dictionary2) // prints: [:]
    
    let string3 = "{\"Object\"}"
    let dictionary3 = convertToDictionary(from: string3)
    print(dictionary3) // prints: [:]
    

    #4. Using a method that does not throw and returns an optional type

    import Foundation
    
    func convertToDictionary(from text: String) -> [String: String]? {
        guard let data = text.data(using: .utf8) else { return nil }
        let anyResult = try? JSONSerialization.jsonObject(with: data, options: [])
        return anyResult as? [String: String]
    }
    

    Usage:

    let string1 = "{\"City\":\"Paris\"}"
    let dictionary1 = convertToDictionary(from: string1)
    print(String(describing: dictionary1)) // prints: Optional(["City": "Paris"])
    
    let string2 = "{\"Quantity\":100}"
    let dictionary2 = convertToDictionary(from: string2)
    print(String(describing: dictionary2)) // prints: nil
    
    let string3 = "{\"Object\"}"
    let dictionary3 = convertToDictionary(from: string3)
    print(String(describing: dictionary3)) // prints: nil
    

提交回复
热议问题