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 (@lvalue NSData,options:IntegerLitralConvertible ...
This is my code:
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
}
I make this function in 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;
}
To convert json to dict in Python, use the json. load() function. The json. load() is a built-in function that deserializes json data to a Python object.
To convert a Python string to a dictionary, use the json. loads() function. The json. loads() is a built-in Python function that converts a valid string to a dict.
JSON Format JSON at its top-level is a dictionary of attribute/value pairs, or key/value pairs as we've talked about dictionaries in this class. The values are numbers, strings, other dictionaries, and lists.
If you have a JSON string, you can parse it by using the json. loads() method. The result will be a Python dictionary.
Warning: this is a convenience method to convert a JSON string to a dictionary if, for some reason, you have to work from a JSON string. But if you have the JSON data available, you should instead work with the data, without using a string at all.
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)
Original Swift 1 answer:
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"
}
In your version, you didn't pass the proper parameters to NSJSONSerialization and forgot to cast the result. Also, it's better to check for the possible error. Last note: this works only if your value is a String. If it could be another type, it would be better to declare the dictionary conversion like this:
let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &error) as? [String:AnyObject]
and of course you would also need to change the return type of the function:
func convertStringToDictionary(text: String) -> [String:AnyObject]? { ... }
I've updated Eric D's answer for 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
}
Swift 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")
}
}
With Swift 3, JSONSerialization has a method called jsonObject(with:options:). jsonObject(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 jsonObject(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.
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.}
}
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.}
}
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: [:]
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
Swift 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
}
}
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
}
}
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)
Do not forget to paste the solution code here
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.}
I found code which converts the json string to NSDictionary or NSArray. Just add the extension.
SWIFT 3.0
HOW TO USE
let jsonData = (convertedJsonString as! String).parseJSONString
EXTENSION
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
}
}
}
In 2022 year, I'm using 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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With