2

I am writing a simple full stack app and I made the return from the backend to be, in certain cases, just like an array of strings like below:

["one","two","three"]

The problem I am having now is that this return can't be parsed in swift like usual JSON data. I searched but found nothing. What I am trying to do is :

let json = try JSONSerialization.jsonObject(with: data!, options: [.mutableContainers, .allowFragments]) as? [String]

Unfortunately, this doesn't work at all How can I parse this just like a normal array?

Thanks in advance.

UPDATE: I am adding some more relevant code below:

let task = URLSession.shared.dataTask(with: request as URLRequest){
        data, response, error in {
            do {
                let json =  try JSONSerialization.jsonObject(with: data!, options: [.mutableContainers, .allowFragments]) as? [String]
                print(json)
            }catch{
                print(error)
            }
 }
datatask.resume()

The error I am getting in the console is "Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}"

Thanks for all of you.

4
  • Show more relevant code. Where does data come from? What is the actual value you are trying to parse? Commented Jan 20, 2018 at 18:12
  • Have a look here:stackoverflow.com/questions/48354401/… Commented Jan 20, 2018 at 18:24
  • I've added more info in the post, please look again. Commented Jan 20, 2018 at 19:55
  • @vadian The console then yells at me complaining that the json return is neither an array nor a dictionary. Commented Jan 20, 2018 at 21:21

2 Answers 2

4

If you're getting the 3840 error, then the JSON is not valid JSON, period.

The JSON string equivalent of the array is supposed to be

let jsonString = "[\"one\",\"two\",\"three\"]"

The Swift 4 literal multiline syntax shows the actual format without the escaping backslashes

let jsonString = """
["one","two","three"]
"""

You are able to parse it without any options (no .allowFragments, and no .mutableContainers)

let data = Data(jsonString.utf8)
do {
    let array = try JSONSerialization.jsonObject(with: data) as! [String]
    print(array) // ["one", "two", "three"]
} catch {
    print(error)
}

Almost everybody misuses the JSONSerialization Reading Options

  • .allowFragments is only needed if the root object is not array and not dictionary
  • .mutableContainers is completely meaningless in Swift

In 99% of the cases you can omit the options parameter

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the answer. Do you have any idea what's that equivalent to in php as I did try to test the return using postman and it seemed fine?
The php equivalent is $array = array('one', 'two','three');
This is what I do! I use array_push($array, $row->Name) where $row is $row = mysqli_fetch_object($result)
Please create a string let string = String(data: data!, encoding: .utf8) before the JSONSerialization line and print and post that.
1

You have to give proper JSON response as data. After that, JSON serialisation will work properly. Your JSON response should be like this:

{
  "array": [
    "one",
    "two",
    "three"
  ]
}

let json =  try JSONSerialization.jsonObject(with: data!, options: [.mutableContainers, .allowFragments]) as? [String]
                print(json)

After that in above line you will your array response like this one - http://jsoneditoronline.org/?id=eafd7ff34b45b2a380ebbe5959607906

Update ####

Your response starts with array and it contains dictionary see below code for your example

    let jsonString = """
[{"Name":"one"},{"Name":"two"},{"Name":"three"}]
"""

if let jsonData = jsonString.data(using: .utf8)
{
    let json =  try JSONSerialization.jsonObject(with: jsonData, options: [.mutableContainers, .allowFragments]) as? [[String:String]]
    print(json)
}

1 Comment

I would do that but it doesn't work also for example I have tried a return of : [{"Name":"one"},{"Name":"two"},{"Name":"three"}] But still couldn't parse it as [Dictionary<String,String>]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.