Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将JSON字符串转换为字典?_Json_Swift_Dictionary_Nsjsonserialization - Fatal编程技术网

如何将JSON字符串转换为字典?

如何将JSON字符串转换为字典?,json,swift,dictionary,nsjsonserialization,Json,Swift,Dictionary,Nsjsonserialization,我想在我的swift项目中创建一个函数,将字符串转换为字典json格式,但我遇到一个错误: 无法转换表达式的类型(@lvalue NSData,选项:IntegerLitralConvertible 这是我的代码: func convertStringToDictionary (text:String) -> Dictionary<String,String> { var data :NSData = text.dataUsingEncoding(NSUTF8Stri

我想在我的swift项目中创建一个函数,将字符串转换为字典json格式,但我遇到一个错误:

无法转换表达式的类型(@lvalue NSData,选项:IntegerLitralConvertible

这是我的代码:

func convertStringToDictionary (text:String) -> Dictionary<String,String> {

    var data :NSData = text.dataUsingEncoding(NSUTF8StringEncoding)!
    var json :Dictionary = NSJSONSerialization.JSONObjectWithData(data, options:0, error: nil)
    return json
} 
警告:如果出于某种原因,您必须使用JSON字符串,则这是一种将JSON字符串转换为字典的方便方法。但是,如果您有可用的JSON数据,则应改为不使用字符串

Swift 3

func convertToDictionary(text: String) -> [String: Any]? {
    if let data = text.data(using: .utf8) {
        do {
            return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
        } catch {
            print(error.localizedDescription)
        }
    }
    return nil
}

let str = "{\"name\":\"James\"}"

let dict = convertToDictionary(text: str)
Swift 2

func convertStringToDictionary(text: String) -> [String:AnyObject]? {
    if let data = text.dataUsingEncoding(NSUTF8StringEncoding) {
        do {
            return try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String:AnyObject]
        } catch let error as NSError {
            print(error)
        }
    }
    return nil
}

let str = "{\"name\":\"James\"}"

let result = convertStringToDictionary(str)
原始Swift 1答案:

func convertStringToDictionary(text: String) -> [String:String]? {
    if let data = text.dataUsingEncoding(NSUTF8StringEncoding) {
        var error: NSError?
        let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &error) as? [String:String]
        if error != nil {
            println(error)
        }
        return json
    }
    return nil
}

let str = "{\"name\":\"James\"}"

let result = convertStringToDictionary(str) // ["name": "James"]

if let name = result?["name"] { // The `?` is here because our `convertStringToDictionary` function returns an Optional
    println(name) // "James"
}
在您的版本中,您没有将正确的参数传递给
NSJSONSerialization
,并且忘记了强制转换结果。此外,最好检查可能的错误。最后注意:仅当您的值是字符串时,此操作才有效。如果它可能是另一种类型,则最好按如下方式声明字典转换:

let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &error) as? [String:AnyObject]
当然,您还需要更改函数的返回类型:

func convertStringToDictionary(text: String) -> [String:AnyObject]? { ... }

我已经更新了Eric D对Swift 5的回答:

 func convertStringToDictionary(text: String) -> [String:AnyObject]? {
    if let data = text.data(using: .utf8) {
        do {
            let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:AnyObject]
            return json
        } catch {
            print("Something went wrong")
        }
    }
    return nil
}
if let data = text.data(using: String.Encoding.utf8) {
    do {
        let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:Any]
        print(json)
    } catch {
        print("Something went wrong")
    }
}

Swift 3

 func convertStringToDictionary(text: String) -> [String:AnyObject]? {
    if let data = text.data(using: .utf8) {
        do {
            let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:AnyObject]
            return json
        } catch {
            print("Something went wrong")
        }
    }
    return nil
}
if let data = text.data(using: String.Encoding.utf8) {
    do {
        let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:Any]
        print(json)
    } catch {
        print("Something went wrong")
    }
}

在Swift 3中,
JSONSerialization
有一个名为.code>json的方法​对象(带:​选项:​)具有以下声明:

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

从给定的JSON数据返回基础对象。

当您使用
json时​对象(带:​选项:​),您必须处理错误处理(
try
try?
try!
)和类型转换(从
任何
)等。因此,您可以使用以下模式之一解决问题


#1.使用抛出并返回非可选类型的方法 用法:

let string1 = "{\"City\":\"Paris\"}"
do {
    let dictionary = try convertToDictionary(from: string1)
    print(dictionary) // prints: ["City": "Paris"]
} catch {
    print(error)
}

#2.使用抛出并返回可选类型的方法 用法:

let string1 = "{\"City\":\"Paris\"}"
do {
    let dictionary = try convertToDictionary(from: string1)
    print(String(describing: dictionary)) // prints: Optional(["City": "Paris"])
} catch {
    print(error)
}
let string1 = "{\"City\":\"Paris\"}"
let dictionary1 = convertToDictionary(from: string1)
print(dictionary1) // prints: ["City": "Paris"]
let string1 = "{\"City\":\"Paris\"}"
let dictionary1 = convertToDictionary(from: string1)
print(String(describing: dictionary1)) // prints: Optional(["City": "Paris"])

#3.使用不抛出并返回非可选类型的方法 用法:

let string1 = "{\"City\":\"Paris\"}"
do {
    let dictionary = try convertToDictionary(from: string1)
    print(String(describing: dictionary)) // prints: Optional(["City": "Paris"])
} catch {
    print(error)
}
let string1 = "{\"City\":\"Paris\"}"
let dictionary1 = convertToDictionary(from: string1)
print(dictionary1) // prints: ["City": "Paris"]
let string1 = "{\"City\":\"Paris\"}"
let dictionary1 = convertToDictionary(from: string1)
print(String(describing: dictionary1)) // prints: Optional(["City": "Paris"])

#4.使用不抛出并返回可选类型的方法 用法:

let string1 = "{\"City\":\"Paris\"}"
do {
    let dictionary = try convertToDictionary(from: string1)
    print(String(describing: dictionary)) // prints: Optional(["City": "Paris"])
} catch {
    print(error)
}
let string1 = "{\"City\":\"Paris\"}"
let dictionary1 = convertToDictionary(from: string1)
print(dictionary1) // prints: ["City": "Paris"]
let string1 = "{\"City\":\"Paris\"}"
let dictionary1 = convertToDictionary(from: string1)
print(String(describing: dictionary1)) // prints: Optional(["City": "Paris"])

我找到了将json字符串转换为NSDictionary或NSArray的代码。只需添加扩展名

SWIFT 3.0

如何使用

let jsonData = (convertedJsonString as! String).parseJSONString
扩展

extension String
{
var parseJSONString: AnyObject?
{
    let data = self.data(using: String.Encoding.utf8, allowLossyConversion: false)
    if let jsonData = data
    {
        // Will return an object or nil if JSON decoding fails
        do
        {
            let message = try JSONSerialization.jsonObject(with: jsonData, options:.mutableContainers)
            if let jsonResult = message as? NSMutableArray {
                return jsonResult //Will return the json array output
            } else if let jsonResult = message as? NSMutableDictionary {
                return jsonResult //Will return the json dictionary output
            } else {
                return nil
            }
        }
        catch let error as NSError
        {
            print("An error occurred: \(error)")
            return nil
        }
    }
    else
    {
        // Lossless conversion of the string was not possible
        return nil
    }
}
}Swift 4

extension String {
    func convertToDictionary() -> [String: Any]? {
        if let data = self.data(using: .utf8) {
            do {
                return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
            } catch {
                print(error.localizedDescription)
            }
        }
        return nil
    }
}
细节
  • Xcode版本10.3(10G8),Swift 5
解决方案 试样 不要忘记将解决方案代码粘贴到此处

func测试描述符(文本:字符串,值:任意){
打印(“\n////
打印(“--\(文本)\n\n类型:\(类型:值))\n值:\(值)”)
}
让json1:[String:Any]=[“key1”:1,“key2”:true,“key3”:[“a”:1,“b”:2],“key4”:[1,2,3]]
var jsonData=try?json1.toData()
testDescriber(文本:“func toDictionary()的示例测试”,值:json1)
如果let data=jsonData{
打印(“结果:\(字符串(描述:try?data.toDictionary())))
}
testDescriber(文本:“func to()->[String:Any]”的示例测试,值:json1)
如果let data=jsonData{
打印(“结果:\(字符串(描述:try?data.to(类型:[String:Any].self))))
}
testDescriber(文本:“func to()->[String]带强制转换错误的示例测试”,值:json1)
如果let data=jsonData{
做{
打印(“结果:\(字符串(描述:try data.to(类型:[String].self))))
}抓住{
打印(“错误:\(错误)”)
}
}
设数组=[1,4,5,6]
testDescriber(文本:“func to()->[Int]的示例测试”,值:数组)
如果let data=try?JSONSerialization.data(使用jsonobject:array){
打印(“结果:\(字符串(描述:try?data.to(类型:[Int].self))))
}
让json2=[“key1”:“a”,“key2”:“b”]
testDescriber(文本:“func to()->[String:String]”的示例测试,值:json2)
如果let data=try?JSONSerialization.data(带jsonobject:json2){
打印(“结果:\(字符串(描述:try?data.to(类型:[String:String].self))))
}
让jsonString=“{\'key1\':\'a\',\'key2\':\'b\}”
testDescriber(文本:“func to()->[String:String]”的示例测试,值:jsonString)
打印(“结果:\(字符串(描述:try?jsonString.asJSON(to:[String:String].self)))
testDescriber(文本:“func to()->[String:String]”的示例测试,值:jsonString)
打印(“结果:\(字符串(描述:try?jsonString.asJSONToDictionary())))
let ErrorJsonString=“{\'key1\':\'a\',\'key2\':}”
testDescriber(文本:“带有JSONSerialization错误的func to()->[String:String]的示例测试”,值:jsonString)
做{
让json=try errowJSONString.asJSON(to:[String:String].self)
打印(“结果:\(字符串(描述:json)))
}抓住{
打印(“错误:\(错误)”)
}
测试日志
//////////////////////////////////////////
--func toDictionary()的样本测试
类型:字典
值:[“key4”:[1,2,3],“key2”:true,“key3”:[“a”:1,“b”:2],“key1”:1]
结果:可选([“键4”:(
1.
2.
3.
)
,“键2”:1,“键3”:{
a=1;
b=2;
},“键1”:1])
//////////////////////////////////////////
--func to()的示例测试->[字符串:任意]
类型:字典
值:[“key4”:[1,2,3],“key2”:true,“key3”:[“a”:1,“b”:2],“key1”:1]
结果:可选([“键4”:(
1.
2.
3.
)
,“键2”:1,“键1”:1,“键3”:{
a=1;
b=2;
}])
//////////////////////////////////////////
--func to()->[String]的示例测试带有强制转换错误
类型:字典
值:[“key4”:[1,2,3],“key2”:true,“key3”:[“a”:1,“b”:2],“key1”:1]
错误:无法从一个数组转换到另一个数组
//////////////////////////////////////////
--func to()的示例测试->[Int]
类型:数组
值:[1,4,5,6]
结果:可选([1,4,5,6])
//////////////////////////////////////////
--func to()的示例测试->[String:String]
类型:字典
值:[“键1”:“a”,“键2”:“b”]
结果:可选([“键1”:“a”,“键2”:“b”])
//////////////////////////////////////////
--func to()的示例测试->[String:String]
类型:字符串
值:{“key1”:“a”,“key2”:“b”}
结果:可选([“键1”:“a”,“键2”:“b”])
//////////////////////////////////////////
--样品试验
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
let jsonData = (convertedJsonString as! String).parseJSONString
extension String
{
var parseJSONString: AnyObject?
{
    let data = self.data(using: String.Encoding.utf8, allowLossyConversion: false)
    if let jsonData = data
    {
        // Will return an object or nil if JSON decoding fails
        do
        {
            let message = try JSONSerialization.jsonObject(with: jsonData, options:.mutableContainers)
            if let jsonResult = message as? NSMutableArray {
                return jsonResult //Will return the json array output
            } else if let jsonResult = message as? NSMutableDictionary {
                return jsonResult //Will return the json dictionary output
            } else {
                return nil
            }
        }
        catch let error as NSError
        {
            print("An error occurred: \(error)")
            return nil
        }
    }
    else
    {
        // Lossless conversion of the string was not possible
        return nil
    }
}
extension String {
    func convertToDictionary() -> [String: Any]? {
        if let data = self.data(using: .utf8) {
            do {
                return try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
            } catch {
                print(error.localizedDescription)
            }
        }
        return nil
    }
}
import Foundation

// MARK: - CastingError

struct CastingError: Error {
    let fromType: Any.Type
    let toType: Any.Type
    init<FromType, ToType>(fromType: FromType.Type, toType: ToType.Type) {
        self.fromType = fromType
        self.toType = toType
    }
}

extension CastingError: LocalizedError {
    var localizedDescription: String { return "Can not cast from \(fromType) to \(toType)" }
}

extension CastingError: CustomStringConvertible { var description: String { return localizedDescription } }

// MARK: - Data cast extensions

extension Data {
    func toDictionary(options: JSONSerialization.ReadingOptions = []) throws -> [String: Any] {
        return try to(type: [String: Any].self, options: options)
    }

    func to<T>(type: T.Type, options: JSONSerialization.ReadingOptions = []) throws -> T {
        guard let result = try JSONSerialization.jsonObject(with: self, options: options) as? T else {
            throw CastingError(fromType: type, toType: T.self)
        }
        return result
    }
}

// MARK: - String cast extensions

extension String {
    func asJSON<T>(to type: T.Type, using encoding: String.Encoding = .utf8) throws -> T {
        guard let data = data(using: encoding) else { throw CastingError(fromType: type, toType: T.self) }
        return try data.to(type: T.self)
    }

    func asJSONToDictionary(using encoding: String.Encoding = .utf8) throws -> [String: Any] {
        return try asJSON(to: [String: Any].self, using: encoding)
    }
}

// MARK: - Dictionary cast extensions

extension Dictionary {
    func toData(options: JSONSerialization.WritingOptions = []) throws -> Data {
        return try JSONSerialization.data(withJSONObject: self, options: options)
    }
}
let value1 = try? data.toDictionary()
let value2 = try? data.to(type: [String: Any].self)
let value3 = try? data.to(type: [String: String].self)
let value4 = try? string.asJSONToDictionary()
let value5 = try? string.asJSON(to: [String: String].self)
func testDescriber(text: String, value: Any) {
    print("\n//////////////////////////////////////////")
    print("-- \(text)\n\n  type: \(type(of: value))\n  value: \(value)")
}

let json1: [String: Any] = ["key1" : 1, "key2": true, "key3" : ["a": 1, "b": 2], "key4": [1,2,3]]
var jsonData = try? json1.toData()
testDescriber(text: "Sample test of func toDictionary()", value: json1)
if let data = jsonData {
    print("  Result: \(String(describing: try? data.toDictionary()))")
}

testDescriber(text: "Sample test of func to<T>() -> [String: Any]", value: json1)
if let data = jsonData {
    print("  Result: \(String(describing: try? data.to(type: [String: Any].self)))")
}

testDescriber(text: "Sample test of func to<T>() -> [String] with cast error", value: json1)
if let data = jsonData {
    do {
        print("  Result: \(String(describing: try data.to(type: [String].self)))")
    } catch {
        print("  ERROR: \(error)")
    }
}

let array = [1,4,5,6]
testDescriber(text: "Sample test of func to<T>() -> [Int]", value: array)
if let data = try? JSONSerialization.data(withJSONObject: array) {
    print("  Result: \(String(describing: try? data.to(type: [Int].self)))")
}

let json2 = ["key1": "a", "key2": "b"]
testDescriber(text: "Sample test of func to<T>() -> [String: String]", value: json2)
if let data = try? JSONSerialization.data(withJSONObject: json2) {
    print("  Result: \(String(describing: try? data.to(type: [String: String].self)))")
}

let jsonString = "{\"key1\": \"a\", \"key2\": \"b\"}"
testDescriber(text: "Sample test of func to<T>() -> [String: String]", value: jsonString)
print("  Result: \(String(describing: try? jsonString.asJSON(to: [String: String].self)))")

testDescriber(text: "Sample test of func to<T>() -> [String: String]", value: jsonString)
print("  Result: \(String(describing: try? jsonString.asJSONToDictionary()))")

let wrongJsonString = "{\"key1\": \"a\", \"key2\":}"
testDescriber(text: "Sample test of func to<T>() -> [String: String] with JSONSerialization error", value: jsonString)
do {
    let json = try wrongJsonString.asJSON(to: [String: String].self)
    print("  Result: \(String(describing: json))")
} catch {
    print("  ERROR: \(error)")
}
//////////////////////////////////////////
-- Sample test of func toDictionary()

  type: Dictionary<String, Any>
  value: ["key4": [1, 2, 3], "key2": true, "key3": ["a": 1, "b": 2], "key1": 1]
  Result: Optional(["key4": <__NSArrayI 0x600002a35380>(
1,
2,
3
)
, "key2": 1, "key3": {
    a = 1;
    b = 2;
}, "key1": 1])

//////////////////////////////////////////
-- Sample test of func to<T>() -> [String: Any]

  type: Dictionary<String, Any>
  value: ["key4": [1, 2, 3], "key2": true, "key3": ["a": 1, "b": 2], "key1": 1]
  Result: Optional(["key4": <__NSArrayI 0x600002a254d0>(
1,
2,
3
)
, "key2": 1, "key1": 1, "key3": {
    a = 1;
    b = 2;
}])

//////////////////////////////////////////
-- Sample test of func to<T>() -> [String] with cast error

  type: Dictionary<String, Any>
  value: ["key4": [1, 2, 3], "key2": true, "key3": ["a": 1, "b": 2], "key1": 1]
  ERROR: Can not cast from Array<String> to Array<String>

//////////////////////////////////////////
-- Sample test of func to<T>() -> [Int]

  type: Array<Int>
  value: [1, 4, 5, 6]
  Result: Optional([1, 4, 5, 6])

//////////////////////////////////////////
-- Sample test of func to<T>() -> [String: String]

  type: Dictionary<String, String>
  value: ["key1": "a", "key2": "b"]
  Result: Optional(["key1": "a", "key2": "b"])

//////////////////////////////////////////
-- Sample test of func to<T>() -> [String: String]

  type: String
  value: {"key1": "a", "key2": "b"}
  Result: Optional(["key1": "a", "key2": "b"])

//////////////////////////////////////////
-- Sample test of func to<T>() -> [String: String]

  type: String
  value: {"key1": "a", "key2": "b"}
  Result: Optional(["key1": a, "key2": b])

//////////////////////////////////////////
-- Sample test of func to<T>() -> [String: String] with JSONSerialization error

  type: String
  value: {"key1": "a", "key2": "b"}
  ERROR: Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 21." UserInfo={NSDebugDescription=Invalid value around character 21.}
let JSONData = jsonString.data(using: .utf8)!

let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)

guard let userDictionary = jsonResult as? Dictionary<String, AnyObject> else {
            throw NSError()}
extension String {
    func convertToDictionary() -> [String: Any]? {
        if let data = data(using: .utf8) {
            return try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
        }
        return nil
    }
}