JSON स्ट्रिंग को डिक्शनरी में कैसे बदलें?


178

मैं अपनी स्विफ्ट परियोजना में एक कार्य करना चाहता हूं जो स्ट्रिंग को डिक्शनरी के प्रारूप में रूपांतरित करता है, लेकिन मुझे एक त्रुटि मिली:

अभिव्यक्ति का प्रकार परिवर्तित नहीं कर सकता (@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
} 

मैं उद्देश्य-सी में यह कार्य करता हूं:

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

शब्दकोश में आप क्या चाहते हैं?
अमितो

1
मैं अपने प्रश्न को अद्यतन करता हूँ ... @ अमित not ९ कोई फर्क नहीं पड़ता कि मूल्य और कुंजी क्या है !!!
परेशान

@ Amit89 मैं चाहता हूँ जब समारोह वापसी json शब्दकोश प्रारूप करने के लिए दे पाठ
trousout

let jsonDictionary = try JSONSerialization.jsonObject(with: jsonData, options: []) as! [String: String];
वाहिद अमीरी

जवाबों:


384

चेतावनी: यह एक 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)

मूल स्विफ्ट 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]? { ... }

52

मैंने स्विफ्ट 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
}

यह उदाहरण शून्य देता है। let x = "{\" a \ ": [\" b \ ": \" B \ ", \" c \ ": \" C \ "]}" परिणाम दें = ConvertStringToरोधन (x)
सैयद तारिक

23

स्विफ्ट 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")
    }
}

15

स्विफ्ट 3 के साथ, JSONSerializationएक विधि कहा जाता है json​Object(with:​options:​)json​Object(with:​options:​)निम्नलिखित घोषणा है:

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

दिए गए JSON डेटा से एक फाउंडेशन ऑब्जेक्ट लौटाता है।

जब आप उपयोग करते हैं json​Object(with:​options:​), तो आपको त्रुटि से निपटने ( या try,) से निपटना होगाtry?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

8

स्विफ्ट 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
    }
}

2
बस एक और कॉपी पेस्ट
जे डो

1
यदि आप विकल्पों का उपयोग नहीं करते हैं, तो उन्हें न लिखें: JSONSerialization.jsonObject (साथ: डेटा)
Zaporozhchenko ऑलेक्ज़ेंडर

6

स्विफ्ट 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
    }
}

4

मुझे कोड मिला, जो जस स्ट्रिंग को एनएसएडीआर या एनएसएरे में परिवर्तित करता है। बस एक्सटेंशन जोड़ें।

स्विफ्ट 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
    }
}

}


NSMutable...स्विफ्ट में संग्रह प्रकारों का उपयोग न करें । टाइप कास्ट NSMutable...एक उत्परिवर्तित वस्तु का परिणाम कभी नहीं होगा। और स्विफ्ट 3+ में एक अनिर्दिष्ट प्रकार है Any, नहीं AnyObject
वाडियन

3

विवरण

  • Xcode संस्करण 10.3 (10G8), स्विफ्ट 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.}

0

स्विफ्ट 5 के लिए, मैं इसे सत्यापित करने के लिए एक डेमो लिखता हूं।

extension String {

    /// convert JsonString to Dictionary
    func convertJsonStringToDictionary() -> [String: Any]? {
        if let data = data(using: .utf8) {
            return (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String: Any]
        }

        return nil
    }
}

let str = "{\"name\":\"zgpeace\"}"
let dict = str.convertJsonStringToDictionary()
print("string > \(str)")  
// string > {"name":"zgpeace"}
print("dicionary > \(String(describing: dict))") 
// dicionary > Optional(["name": zgpeace])

-1
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()}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.