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

我想在我的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
}

我在Objective-C中创建了这个函数:

- (NSDictionary*)convertStringToDictionary:(NSString*)string {
NSError* error;
//giving error as it takes dic, array,etc only. not custom object.
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
return json;
}
323857 次浏览

警告:如果由于某种原因,您必须从JSON字符串工作,这是一个将JSON字符串转换为字典的方便方法。但是如果你有JSON 数据可用,你应该代替与数据一起工作,而根本不使用字符串。

斯威夫特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)

斯威夫特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对斯威夫特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
}

斯威夫特3:

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有一个名为json​Object(with:​options:​)的方法。json​Object(with:​options:​)有以下声明:

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

从给定的JSON数据返回一个Foundation对象。

当你使用json​Object(with:​options:​)时,你必须处理错误处理(trytry?try!)和类型强制转换(来自Any)。因此,您可以使用以下模式之一来解决问题。


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

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] ?? [:]
}

用法:

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。使用抛出并返回可选类型的方法

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]
}

用法:

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。使用不抛出并返回非可选类型的方法

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] ?? [:]
}

用法:

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。使用不抛出并返回可选类型的方法

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]
}

用法:

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

我发现代码转换json字符串到NSDictionary或NSArray。只需添加扩展。

< em >迅速3.0 < / em >

如何使用

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
}
}

斯威夫特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

解决方案

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()}

斯威夫特5

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

在2022年,我使用JSONDecoder。

struct GroceryProduct: Codable {
var name: String
var points: Int
var description: String?
}


let json = """
{
"name": "Durian",
"points": 600,
"description": "A fruit with a distinctive scent."
}
""".data(using: .utf8)!


let decoder = JSONDecoder()


do {
let product = try decoder.decode(GroceryProduct.self, from: json)
}
catch { //error handle }


print(product.name) // Prints "Durian"