0

I am receiving a JSON string from the server and it looks like this:

[[{\"type\":\"action\",\"action\":\"courier_on_map\",\"text\":\"\\u0421\\u043c\\u043e\\u0442\\u0440\\u0435\\u0442\\u044c \\u043d\\u0430 \\u043a\\u0430\\u0440\\u0442\\u0435\"}]]

Web parser says "JSON String is valid but JSON Data is not accurate". JSONSerialization however says:

No string key for value in object around character 1

and returns error.

Code:

    func convertToNSDictionary() -> NSDictionary?
    {
        var string = self
        string = string.replacingOccurrences(of: "[", with: "")
        string = string.replacingOccurrences(of: "]", with: "")

        if let data = string.data(using: .utf8) {
            do {
                return try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary
            } catch {
                print(error.localizedDescription)
            }
        }

        return nil
    }
Nirav D
  • 71,513
  • 12
  • 161
  • 183
Eduard
  • 516
  • 1
  • 4
  • 17
  • You can use this best library in your project, that will be simply your code and maybe resolve your problem : https://github.com/SwiftyJSON/SwiftyJSON – ewan Jan 27 '17 at 11:11
  • 1
    Your code is working perfectly for me check that your string is not optional. – Nirav D Jan 27 '17 at 11:19

1 Answers1

0

Do not manipulate the original JSON string manually.

Assuming your code is inside an extension on String, this:

let str = "[[{\"type\":\"action\",\"action\":\"courier_on_map\",\"text\":\"\\u0421\\u043c\\u043e\\u0442\\u0440\\u0435\\u0442\\u044c \\u043d\\u0430 \\u043a\\u0430\\u0440\\u0442\\u0435\"}]]"

extension String {
    func convertToDictionary() -> [String:Any]? {
        let str = self

        guard let data = str.data(using: .utf8),
              let json = try? JSONSerialization.jsonObject(with: data, options: []) as! [[[String:Any]]]
        else {
            return nil
        }

        //debug prints
        print(json)
        let innerArray = json.first!
        print(innerArray)
        let dict = innerArray.first!
        print(dict)
        if let type = dict["type"] {
            print(type)
        }
        //

        return dict
    }
}

let dict = str.convertToDictionary()

print(dict)

Prints:

[[["type": action, "action": courier_on_map, "text": Смотреть на карте]]]
[["type": action, "action": courier_on_map, "text": Смотреть на карте]]
["type": action, "action": courier_on_map, "text": Смотреть на карте]
action
Optional(["type": action, "action": courier_on_map, "text": Смотреть на карте])

If you really need a NSObject, you can cast it:

let nsDict = dict! as NSDictionary
shallowThought
  • 19,212
  • 9
  • 65
  • 112