5

as a coding exercise, I wrote a small program to take MySql data frm the web to the iPhone. On the server side. I wrote the php script to get the script to return the json data.

On xcode I have

[code]
.
.
.
     let jsonString = try? JSONSerialization.jsonObject(with: data!, options:    [])
    print(jsonString!)
    .
    .
    .
[/code]

In xcode console, I have this:

[code]
(
        {
        Address = "1 Infinite Loop Cupertino, CA";
        Latitude = "37.331741";
        Longitude = "-122";
        Name = Apple;
    }
)
[/code]

I have a function
    [code]

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
        }
[/code]

When I pass the jsonString to convertToDictionary(text:)

[code]
let dict = convertToDictionary(text: jsonString as! String)
[/code]

In the console I get an error "Could not cast value of type '__NSSingleObjectArrayI' (0x10369bdb0) to 'NSString' (0x1004eac60)."

but if I hard code the json string then pass it to the convertToDictionary(text:)

[code] 
let hardCodedStr = "{\"Address\":\"1 Infinite Loop Cupertino, CA\",\"Latitude\":\"37.331741\",\"Longitude\":\"-122\",\"Name\":\"Apple\"}"

let dict = convertToDictionary(text: hardCodedStr)
print(dict!)
[/code] 

It works just fine. Why is that? Thanks

Tony
  • 155
  • 1
  • 3
  • 9
  • This is not how you're supposed to use [this](https://stackoverflow.com/a/30480777/2227743). This function is only a convenience way of converting a JSON string to a dictionary *if you only have the string to work with*. But this is not your case: you have the JSON *data*. You should convert the *data* to a dictionary - forget the strings altogether. – Eric Aya Jun 04 '17 at 15:17
  • The variable `jsonString` is already a dictionary converted from a JSON string. – vadian Jun 04 '17 at 15:21

1 Answers1

9

If you look closely at what jsonObject(with:options:) returns, you will see that it is a [String: Any] or a [Any], depending on your JSON.

Therefore, jsonString here actually stores a [String: Any], even thought the compiler thinks it is of type Any:

let jsonString = try? JSONSerialization.jsonObject(with: data!, options:    [])
print(jsonString!)

If you try to pass this to convertToDictionary, which accepts a String, it of course will not work, because a dictionary and String are not compatible types.

How to solve this problem?

The problem is already solved! You don't need convertToDictionary at all. jsonString itself is the dictionary you wanted.

This is what you need to do:

let jsonString = try? JSONSerialization.jsonObject(with: data!, options: []) as! [String: Any]
                                                                             ^^^^^^^^^^^^^^^^^
                                                                             Add this part

After that you can call dictionary methods on jsonString. I also suggest you to rename jsonString to something else.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Thank for the reply. jsonString is already a dictionary? That's how I got confused. I thought a dictionary has format like ["Address":"xyz", "Name":"Apple"...] (with square brackets.) This does look like it at all, that's why I thoght it is a Json string. So I can access it with the dictionary methods? – Tony Jun 04 '17 at 16:50
  • Yes you can. You just need to cast it to a `[String, Any]` first. @Tony – Sweeper Jun 04 '17 at 16:51
  • @Tony See the edit for how to do this! If you think my answer answers your question, please consider accepting it by clicking on the checkmark! – Sweeper Jun 04 '17 at 21:32
  • It gives error " can not invoke jsonObject with an argument list of type (with:String,options:[Any])" – Mansuu.... Jul 05 '17 at 14:48
  • @Sweeper no, I am also using swift 3.0 – Mansuu.... Jul 05 '17 at 14:57
  • I think it does not work if I pass String as a parameter – Mansuu.... Jul 05 '17 at 14:57
  • Oh are you passing a String? You should pass a `Data` as the first parameter @Mansuu.... – Sweeper Jul 05 '17 at 14:58
  • There is some problem with my json format it contains string inside a json object and I only want to parse that particular string into Dictionary @Sweeper – Mansuu.... Jul 05 '17 at 15:01
  • 1
    @Mansuu.... Try to extract the string from the JSON first. I recommend you use SwiftyJSON to do this. Then you can convert the string into a dictionary by using one of SwiftyJSON's features. – Sweeper Jul 05 '17 at 15:05
  • I have installed SwiftyJson how to to using that @Sweeper – Mansuu.... Jul 05 '17 at 15:10
  • @Mansuu.... Check out the README and try out different things yourself. If you still don't understand, please ask another question since the problem that you're facing is out of the scope of this post. – Sweeper Jul 05 '17 at 15:13
  • How to get data that you pass to this method? – zulkarnain shah Nov 29 '17 at 05:51