Use Swifty JSON to parse array
Asked Answered
D

7

0

This is my json to parse (example):

[
  {
    "id": 1,
    "name": "Team name",
    "shower": {
      "id": 1,
      "status": 1,
      "startLocation": {
        "id": 1,
        "name": "abc 16"
      }
    }
  },
  {
    "id": 2,
    "name": "Team name",
    "shower": {
      "id": 2,
      "status": 1,
      "startLocation": {
        "id": 1,
        "name": "efg 16"
      }
    }
  }
]

as you can see, it is an array (of teams). I need to get each team and do something with it.

After many attempts, I tried using SwiftyJSON, because I thought it will be easier. But, it did not worked for me.

This is what I tried:

let array = JSON(response)  

// print each subJSON in array
for team in array.arrayValue {                    
  print(team)                    
}

But the loop does not work. It does not go in to the loop at all. Maybe it does not understand that my json is an array.

I can see the array object in the debugger. It looks like this:

enter image description here

How can I get these sub-JSONs?

Thanks.

Datcha answered 10/12, 2016 at 15:1 Comment(10)
Your JSON is invalid. There shouldn't be a comma on the line after "name": "abc 16" and the line after that.Esau
Use jsoneditoronline.org this to validate your json. Its showing error in your json string.Uwton
ask your server team to remove extraa slashes before each values that creating an issue to fetch because json is key value pair but it seems like string which unable to fetchPreventer
Thanks guys, i edited and fixed the json example.Datcha
Still it is not working after fixing the json string?Uwton
@ShobhakarTiwari, this is the default OOTB response from Hibernate. I think it is probably possible to handle with swifty json.Datcha
BTW, i'm using ObjectMapper. and i have a mappable class object for Team. what i need is to get the teams from this json of array of teams. i could build a dummy class with a property of type [Team] and use ObjectMapper to map it. but i have the feeling it is a workaround and not the best way to handle it.Datcha
yes @Arjuna. it is still not working. It was not the problem (i just made a mistake with the sample json here). thanks.Datcha
Do you want to use SwiftyJSON itself or the one like Ashok mentioned?Uwton
I think you should use let array = JSON(parseJSON: response) instead of let array = JSON(response) .Uwton
U
1

I think you should use

let array = JSON(parseJSON: response) 

instead of

let array = JSON(response)
Uwton answered 10/12, 2016 at 17:27 Comment(1)
I tried your suggestion @Arjuna, it did not worked. still not going in the loop. thanks,Datcha
L
0

SwiftyJSON contains methods to parse JSON string into a JSON object, check documentation

/**
 Parses the JSON string into a JSON object
 - parameter json: the JSON string
 - returns: the created JSON object
*/

 public init(parseJSON jsonString: String) {
   if let data = jsonString.data(using: .utf8) {
                self.init(data)
            } else {
                self.init(NSNull())
            }        
   }       


/**
 Creates a JSON from JSON string
 - parameter string: Normal json string like '{"a":"b"}'

 - returns: The created JSON
 */
@available(*, deprecated: 3.2, message: "Use instead `init(parseJSON: )`")
public static func parse(json: String) -> JSON {
    return json.data(using: String.Encoding.utf8)
        .flatMap{ JSON(data: $0) } ?? JSON(NSNull())
}

or alternatively you can convert son string into son object like

Swift 3:

let dataFromString = response.data(using: .utf8)
let jsonArray = JSON(data: dataFromString!)
Lapith answered 10/12, 2016 at 18:2 Comment(0)
W
0

In the following example, I save team names in an array. I've tested it.

var names = [String]()
if let array = json.array {
    for i in 0..<array.count {
        let name = array[i]["name"]
        names.append(name.stringValue)
    }
}

print(names) // ["Team name", "Team name"]
Wohlen answered 11/12, 2016 at 0:9 Comment(0)
A
0

Here is the answer for Swift 5. In My case data response is something like below :

[
  {
    "Name": "Some Type",
    "Data": [
      {
        "ParentId": 111,
        "Code": "Personal",
        "SortOrder": 1,
        "Name": "Personal",
        "Id": 323
      },
      {
        "ParentId": null,
        "Code": "Work",
        "SortOrder": 2,
        "Name": "Work",
        "Id": 324
      }
    ],
    "KeyType": "Integer"
  },
  {
    "Name": "Phone Type",
    "Data": [
      {
        "ParentId": null,
        "Code": "Phone",
        "SortOrder": 1,
        "Name": "Phone",
        "Id": 785
      },
      {
        "ParentId": null,
        "Code": "Cell",
        "SortOrder": 2,
        "Name": "Cell",
        "Id": 786
      },
      {
        "ParentId": null,
        "Code": "Fax",
        "SortOrder": 3,
        "Name": "Fax",
        "Id": 787
      },
      {
        "ParentId": null,
        "Code": "Home",
        "SortOrder": 4,
        "Name": "Home",
        "Id": 788
      },
      {
        "ParentId": null,
        "Code": "Office",
        "SortOrder": 5,
        "Name": "Office",
        "Id": 789
      }
    ],
    "KeyType": "Integer"
  }
]

I was handled it with following code.

struct responseObjectClass:BaseModel {
    var responsearray: [arrayData]? = nil

    init(json: JSON) {
        responsearray = json.arrayValue.map { arrayData(json: $0) }
    }
}

struct arrayData:BaseModel {
    let Name: String?
       var DataValue: [DataLookup]? = nil
       let KeyType: String?
       
       init(json: JSON) {
           Name = json["Name"].stringValue
           DataValue = json["Data"].arrayValue.map { DataLookup(json: $0) }
           KeyType = json["KeyType"].stringValue
       }
}

struct DataLookup:BaseModel {
    
    
    let ParentId: Any?
    let Code: String?
    let SortOrder: Int?
    let Name: String?
    let Id: Int?
    
    init(json: JSON) {
        ParentId = json["ParentId"]
        Code = json["Code"].stringValue
        SortOrder = json["SortOrder"].intValue
        Name = json["Name"].stringValue
        Id = json["Id"].intValue
    }
}

BaseModel is Optional it's just used for init Json.

protocol BaseModel {
  init(json: JSON)
}
Agrobiology answered 21/8, 2020 at 14:3 Comment(0)
B
0

In SwiftyJSON, iterating over a .Array gives a tuple (String, JSON). From the current (SwiftyJSON 5.0.2) documentation at https://github.com/SwiftyJSON/SwiftyJSON:

// If json is .Array
// The `index` is 0..<json.count's string value
for (index,subJson):(String, JSON) in json {
    // Do something you want
}
Budget answered 10/6 at 0:29 Comment(0)
T
-1

Without SwiftyJSON

Below is the valid JSON

data.json File

[{
  "id": 1,
  "name": "Team name",
  "shower": {
        "id": 1,
        "status": 1,
        "startLocation": {
  "id": 1,
  "name": "abc 16"
        }
  }
  }, {
  "id": 2,
  "name": "Team name",
  "shower": {
        "id": 2,
        "status": 1,
        "startLocation": {
  "id": 1,
  "name": "efg 16"
        }
  }
}]

Below is the code to read your json.

if let path = Bundle.main.path(forResource: "data", ofType: "json") {
        let url = URL(fileURLWithPath: path)
        do {
            let data = try Data(contentsOf: url)
            if let jsonArray = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSArray {
                for (_, item) in jsonArray.enumerated() {
                    let itemDict = item as! NSDictionary
                    let id = itemDict["id"] as! Int
                    let name = itemDict["name"] as! String
                    let shower = itemDict["shower"] as! NSDictionary

                    let showerId = shower["id"] as! Int
                    let showerStatus = shower["status"] as! Int
                    let startLocation = shower["startLocation"] as! NSDictionary


                    let startLocationId = startLocation["id"] as! Int
                    let startLocationName = startLocation["name"] as! String

                }
            }
        } catch {
            print("Error: \(error.localizedDescription)")
        }
}
Tatman answered 10/12, 2016 at 16:11 Comment(0)
D
-1

this is what worked for me:

   // Convert JSON to Array
    func JSONToArray(_ json: String) -> Array<Any>? {
        if let data = json.data(using: String.Encoding.utf8) {
            do {
                return try JSONSerialization.jsonObject(with: data, options: []) as? Array
            } catch let error as NSError {
                print(error)
            }
        }
        return nil
    }

After using this function i could loop trough the sub JSONs.

Thanks.

Datcha answered 11/12, 2016 at 21:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.